From 6ecc99d56dfe32f8af4c6615bd52dd5a50f54a3e Mon Sep 17 00:00:00 2001 From: Tom Rpl Date: Thu, 9 Nov 2023 10:51:18 +0100 Subject: [PATCH] feat(refacto): MM refacto --- .../.github/workflows/formatting.yml | 23 - .../.github/workflows/foundry.yml | 64 - lib/morpho-blue-irm/.gitignore | 14 - lib/morpho-blue-irm/.gitmodules | 9 - lib/morpho-blue-irm/README.md | 5 - ...-blue-and-speed-jump-irm-open-zeppelin.pdf | Bin 408435 -> 0 bytes lib/morpho-blue-irm/foundry.toml | 24 - .../lib/forge-std/.github/workflows/ci.yml | 134 - .../lib/forge-std/.github/workflows/sync.yml | 29 - lib/morpho-blue-irm/lib/forge-std/.gitignore | 4 - lib/morpho-blue-irm/lib/forge-std/.gitmodules | 3 - .../lib/forge-std/LICENSE-APACHE | 203 - lib/morpho-blue-irm/lib/forge-std/LICENSE-MIT | 25 - lib/morpho-blue-irm/lib/forge-std/README.md | 250 - .../lib/forge-std/foundry.toml | 21 - .../lib/ds-test/.github/workflows/build.yml | 41 - .../lib/forge-std/lib/ds-test/.gitignore | 4 - .../lib/forge-std/lib/ds-test/LICENSE | 674 - .../lib/forge-std/lib/ds-test/Makefile | 14 - .../lib/forge-std/lib/ds-test/default.nix | 4 - .../lib/forge-std/lib/ds-test/demo/demo.sol | 222 - .../lib/forge-std/lib/ds-test/package.json | 15 - .../lib/forge-std/lib/ds-test/src/test.sol | 592 - .../lib/forge-std/lib/ds-test/src/test.t.sol | 417 - .../lib/forge-std/package.json | 16 - .../lib/forge-std/src/Base.sol | 35 - .../lib/forge-std/src/Script.sol | 27 - .../lib/forge-std/src/StdAssertions.sol | 376 - .../lib/forge-std/src/StdChains.sol | 229 - .../lib/forge-std/src/StdCheats.sol | 805 - .../lib/forge-std/src/StdError.sol | 15 - .../lib/forge-std/src/StdInvariant.sol | 92 - .../lib/forge-std/src/StdJson.sol | 179 - .../lib/forge-std/src/StdMath.sol | 43 - .../lib/forge-std/src/StdStorage.sol | 331 - .../lib/forge-std/src/StdStyle.sol | 333 - .../lib/forge-std/src/StdUtils.sol | 198 - .../lib/forge-std/src/Test.sol | 34 - lib/morpho-blue-irm/lib/forge-std/src/Vm.sol | 514 - .../lib/forge-std/src/console.sol | 1533 - .../lib/forge-std/src/console2.sol | 1558 - .../lib/forge-std/src/interfaces/IERC1155.sol | 105 - .../lib/forge-std/src/interfaces/IERC165.sol | 12 - .../lib/forge-std/src/interfaces/IERC20.sol | 43 - .../lib/forge-std/src/interfaces/IERC4626.sol | 190 - .../lib/forge-std/src/interfaces/IERC721.sol | 164 - .../forge-std/src/interfaces/IMulticall3.sol | 73 - .../lib/forge-std/src/safeconsole.sol | 13248 ----- .../lib/forge-std/test/StdAssertions.t.sol | 999 - .../lib/forge-std/test/StdChains.t.sol | 215 - .../lib/forge-std/test/StdCheats.t.sol | 602 - .../lib/forge-std/test/StdError.t.sol | 118 - .../lib/forge-std/test/StdMath.t.sol | 212 - .../lib/forge-std/test/StdStorage.t.sol | 293 - .../lib/forge-std/test/StdStyle.t.sol | 110 - .../lib/forge-std/test/StdUtils.t.sol | 342 - .../test/compilation/CompilationScript.sol | 10 - .../compilation/CompilationScriptBase.sol | 10 - .../test/compilation/CompilationTest.sol | 10 - .../test/compilation/CompilationTestBase.sol | 10 - .../test/fixtures/broadcast.log.json | 187 - .../.github/workflows/formatting.yml | 32 - .../morpho-blue/.github/workflows/foundry.yml | 47 - .../morpho-blue/.github/workflows/hardhat.yml | 43 - .../lib/morpho-blue/.gitignore | 22 - .../lib/morpho-blue/.gitmodules | 3 - .../lib/morpho-blue/.husky/commit-msg | 4 - .../lib/morpho-blue/.husky/post-checkout | 5 - .../lib/morpho-blue/.husky/post-merge | 5 - .../lib/morpho-blue/.husky/pre-commit | 4 - lib/morpho-blue-irm/lib/morpho-blue/LICENSE | 103 - lib/morpho-blue-irm/lib/morpho-blue/README.md | 43 - ...-blue-and-speed-jump-irm-open-zeppelin.pdf | Bin 408435 -> 0 bytes .../lib/morpho-blue/foundry.toml | 25 - .../lib/morpho-blue/hardhat.config.ts | 56 - .../lib/forge-std/.github/workflows/ci.yml | 92 - .../lib/forge-std/.github/workflows/sync.yml | 29 - .../lib/morpho-blue/lib/forge-std/.gitignore | 4 - .../lib/morpho-blue/lib/forge-std/.gitmodules | 3 - .../morpho-blue/lib/forge-std/LICENSE-APACHE | 203 - .../lib/morpho-blue/lib/forge-std/LICENSE-MIT | 25 - .../lib/morpho-blue/lib/forge-std/README.md | 250 - .../morpho-blue/lib/forge-std/foundry.toml | 21 - .../lib/ds-test/.github/workflows/build.yml | 41 - .../lib/forge-std/lib/ds-test/.gitignore | 4 - .../lib/forge-std/lib/ds-test/LICENSE | 674 - .../lib/forge-std/lib/ds-test/Makefile | 14 - .../lib/forge-std/lib/ds-test/default.nix | 4 - .../lib/forge-std/lib/ds-test/demo/demo.sol | 222 - .../lib/forge-std/lib/ds-test/package.json | 15 - .../lib/forge-std/lib/ds-test/src/test.sol | 592 - .../lib/forge-std/lib/ds-test/src/test.t.sol | 417 - .../morpho-blue/lib/forge-std/package.json | 16 - .../morpho-blue/lib/forge-std/src/Base.sol | 35 - .../morpho-blue/lib/forge-std/src/Script.sol | 26 - .../lib/forge-std/src/StdAssertions.sol | 376 - .../lib/forge-std/src/StdChains.sol | 231 - .../lib/forge-std/src/StdCheats.sol | 676 - .../lib/forge-std/src/StdError.sol | 15 - .../lib/forge-std/src/StdInvariant.sol | 92 - .../morpho-blue/lib/forge-std/src/StdJson.sol | 179 - .../morpho-blue/lib/forge-std/src/StdMath.sol | 43 - .../lib/forge-std/src/StdStorage.sol | 327 - .../lib/forge-std/src/StdStyle.sol | 333 - .../lib/forge-std/src/StdUtils.sol | 198 - .../morpho-blue/lib/forge-std/src/Test.sol | 32 - .../lib/morpho-blue/lib/forge-std/src/Vm.sol | 502 - .../morpho-blue/lib/forge-std/src/console.sol | 1533 - .../lib/forge-std/src/console2.sol | 1558 - .../lib/forge-std/src/interfaces/IERC1155.sol | 105 - .../lib/forge-std/src/interfaces/IERC165.sol | 12 - .../lib/forge-std/src/interfaces/IERC20.sol | 43 - .../lib/forge-std/src/interfaces/IERC4626.sol | 190 - .../lib/forge-std/src/interfaces/IERC721.sol | 164 - .../forge-std/src/interfaces/IMulticall3.sol | 73 - .../lib/forge-std/src/safeconsole.sol | 13248 ----- .../lib/forge-std/test/StdAssertions.t.sol | 999 - .../lib/forge-std/test/StdChains.t.sol | 160 - .../lib/forge-std/test/StdCheats.t.sol | 507 - .../lib/forge-std/test/StdError.t.sol | 118 - .../lib/forge-std/test/StdMath.t.sol | 197 - .../lib/forge-std/test/StdStorage.t.sol | 283 - .../lib/forge-std/test/StdStyle.t.sol | 110 - .../lib/forge-std/test/StdUtils.t.sol | 312 - .../test/compilation/CompilationScript.sol | 10 - .../compilation/CompilationScriptBase.sol | 10 - .../test/compilation/CompilationTest.sol | 10 - .../test/compilation/CompilationTestBase.sol | 10 - .../test/fixtures/broadcast.log.json | 187 - .../morpho-blue/morpho-blue-whitepaper.pdf | Bin 708090 -> 0 bytes .../lib/morpho-blue/package.json | 72 - .../lib/morpho-blue/src/Morpho.sol | 525 - .../lib/morpho-blue/src/interfaces/IERC20.sol | 9 - .../lib/morpho-blue/src/interfaces/IIrm.sol | 20 - .../morpho-blue/src/interfaces/IMorpho.sol | 300 - .../src/interfaces/IMorphoCallbacks.sol | 52 - .../morpho-blue/src/interfaces/IOracle.sol | 14 - .../lib/morpho-blue/src/interfaces/LICENSE | 389 - .../src/libraries/ConstantsLib.sol | 21 - .../morpho-blue/src/libraries/ErrorsLib.sol | 77 - .../morpho-blue/src/libraries/EventsLib.sol | 147 - .../lib/morpho-blue/src/libraries/LICENSE | 389 - .../src/libraries/MarketParamsLib.sol | 21 - .../lib/morpho-blue/src/libraries/MathLib.sol | 45 - .../src/libraries/SafeTransferLib.sol | 35 - .../src/libraries/SharesMathLib.sol | 42 - .../morpho-blue/src/libraries/UtilsLib.sol | 38 - .../libraries/periphery/MorphoBalancesLib.sol | 120 - .../src/libraries/periphery/MorphoLib.sol | 62 - .../libraries/periphery/MorphoStorageLib.sol | 109 - .../lib/morpho-blue/src/mocks/ERC20Mock.sol | 52 - .../src/mocks/FlashBorrowerMock.sol | 24 - .../lib/morpho-blue/src/mocks/IrmMock.sol | 23 - .../lib/morpho-blue/src/mocks/LICENSE | 389 - .../lib/morpho-blue/src/mocks/OracleMock.sol | 12 - .../src/mocks/interfaces/IERC20.sol | 24 - .../lib/morpho-blue/test/LICENSE | 389 - .../lib/morpho-blue/test/forge/BaseTest.sol | 409 - .../morpho-blue/test/forge/InvariantTest.sol | 142 - .../test/forge/MarketParamsLibTest.sol | 14 - .../test/forge/helpers/ArrayLib.sol | 22 - .../morpho-blue/test/forge/helpers/Math.sol | 16 - .../test/forge/helpers/SigUtils.sol | 30 - .../test/forge/helpers/WadMath.sol | 166 - .../AccrueInterestIntegrationTest.sol | 179 - .../AuthorizationIntegrationTest.sol | 108 - .../integration/BorrowIntegrationTest.sol | 268 - .../integration/CallbacksIntegrationTest.sol | 198 - .../CreateMarketIntegrationTest.sol | 96 - .../integration/ExtSloadIntegrationTest.sol | 22 - .../integration/LiquidateIntegrationTest.sol | 299 - .../integration/OnlyOwnerIntegrationTest.sol | 154 - .../integration/RepayIntegrationTest.sol | 148 - .../SupplyCollateralIntegrationTest.sol | 46 - .../integration/SupplyIntegrationTest.sol | 87 - .../WithdrawCollateralIntegrationTest.sol | 162 - .../integration/WithdrawIntegrationTest.sol | 253 - .../forge/invariant/MorphoInvariantTest.sol | 417 - .../test/forge/libraries/MathLibTest.sol | 87 - .../forge/libraries/SafeTransferLibTest.sol | 95 - .../test/forge/libraries/UtilsLibTest.sol | 34 - .../periphery/MorphoBalancesLibTest.sol | 140 - .../libraries/periphery/MorphoLibTest.sol | 120 - .../periphery/MorphoStorageLibTest.sol | 109 - .../morpho-blue/test/hardhat/Morpho.spec.ts | 218 - .../lib/morpho-blue/test/morpho_tests.tree | 288 - .../lib/morpho-blue/tsconfig.json | 15 - lib/morpho-blue-irm/lib/morpho-blue/yarn.lock | 6226 --- lib/morpho-blue-irm/lib/solmate/.gas-snapshot | 540 - .../lib/solmate/.gitattributes | 1 - .../solmate/.github/pull_request_template.md | 13 - .../lib/solmate/.github/workflows/tests.yml | 29 - lib/morpho-blue-irm/lib/solmate/.gitignore | 3 - lib/morpho-blue-irm/lib/solmate/.gitmodules | 3 - .../lib/solmate/.prettierignore | 1 - lib/morpho-blue-irm/lib/solmate/.prettierrc | 14 - .../lib/solmate/.vscode/settings.json | 9 - lib/morpho-blue-irm/lib/solmate/LICENSE | 661 - lib/morpho-blue-irm/lib/solmate/README.md | 69 - .../audits/v6-Fixed-Point-Solutions.pdf | Bin 170456 -> 0 bytes lib/morpho-blue-irm/lib/solmate/foundry.toml | 7 - .../lib/solmate/lib/ds-test/.gitignore | 3 - .../lib/solmate/lib/ds-test/LICENSE | 674 - .../lib/solmate/lib/ds-test/Makefile | 14 - .../lib/solmate/lib/ds-test/default.nix | 4 - .../lib/solmate/lib/ds-test/demo/demo.sol | 222 - .../lib/solmate/lib/ds-test/package.json | 15 - .../lib/solmate/lib/ds-test/src/test.sol | 469 - .../lib/solmate/package-lock.json | 125 - lib/morpho-blue-irm/lib/solmate/package.json | 20 - .../lib/solmate/src/auth/Auth.sol | 64 - .../lib/solmate/src/auth/Owned.sol | 44 - .../auth/authorities/MultiRolesAuthority.sol | 123 - .../src/auth/authorities/RolesAuthority.sol | 108 - .../lib/solmate/src/mixins/ERC4626.sol | 183 - .../lib/solmate/src/test/Auth.t.sol | 192 - .../solmate/src/test/Bytes32AddressLib.t.sol | 22 - .../lib/solmate/src/test/CREATE3.t.sol | 74 - .../lib/solmate/src/test/DSTestPlus.t.sol | 72 - .../lib/solmate/src/test/ERC1155.t.sol | 1777 - .../lib/solmate/src/test/ERC20.t.sol | 531 - .../lib/solmate/src/test/ERC4626.t.sol | 446 - .../lib/solmate/src/test/ERC721.t.sol | 727 - .../solmate/src/test/FixedPointMathLib.t.sol | 360 - .../lib/solmate/src/test/LibString.t.sol | 148 - .../lib/solmate/src/test/MerkleProofLib.t.sol | 50 - .../src/test/MultiRolesAuthority.t.sol | 321 - .../lib/solmate/src/test/Owned.t.sol | 40 - .../solmate/src/test/ReentrancyGuard.t.sol | 56 - .../lib/solmate/src/test/RolesAuthority.t.sol | 148 - .../lib/solmate/src/test/SSTORE2.t.sol | 152 - .../lib/solmate/src/test/SafeCastLib.t.sol | 644 - .../solmate/src/test/SafeTransferLib.t.sol | 610 - .../lib/solmate/src/test/SignedWadMath.t.sol | 74 - .../lib/solmate/src/test/WETH.t.sol | 146 - .../src/test/utils/DSInvariantTest.sol | 16 - .../lib/solmate/src/test/utils/DSTestPlus.sol | 179 - .../lib/solmate/src/test/utils/Hevm.sol | 107 - .../src/test/utils/mocks/MockAuthChild.sol | 12 - .../src/test/utils/mocks/MockAuthority.sol | 20 - .../src/test/utils/mocks/MockERC1155.sol | 42 - .../src/test/utils/mocks/MockERC20.sol | 20 - .../src/test/utils/mocks/MockERC4626.sol | 28 - .../src/test/utils/mocks/MockERC721.sol | 30 - .../src/test/utils/mocks/MockOwned.sol | 12 - .../utils/weird-tokens/MissingReturnToken.sol | 83 - .../utils/weird-tokens/ReturnsFalseToken.sol | 61 - .../weird-tokens/ReturnsGarbageToken.sol | 115 - .../weird-tokens/ReturnsTooLittleToken.sol | 70 - .../weird-tokens/ReturnsTooMuchToken.sol | 98 - .../utils/weird-tokens/ReturnsTwoToken.sol | 61 - .../utils/weird-tokens/RevertingToken.sol | 61 - .../lib/solmate/src/tokens/ERC1155.sol | 257 - .../lib/solmate/src/tokens/ERC20.sol | 206 - .../lib/solmate/src/tokens/ERC721.sol | 231 - .../lib/solmate/src/tokens/WETH.sol | 35 - .../solmate/src/utils/Bytes32AddressLib.sol | 14 - .../lib/solmate/src/utils/CREATE3.sol | 83 - .../solmate/src/utils/FixedPointMathLib.sol | 255 - .../lib/solmate/src/utils/LibString.sol | 77 - .../lib/solmate/src/utils/MerkleProofLib.sol | 48 - .../lib/solmate/src/utils/ReentrancyGuard.sol | 19 - .../lib/solmate/src/utils/SSTORE2.sol | 101 - .../lib/solmate/src/utils/SafeCastLib.sol | 193 - .../lib/solmate/src/utils/SafeTransferLib.sol | 128 - .../lib/solmate/src/utils/SignedWadMath.sol | 245 - lib/morpho-blue-irm/src/SpeedJumpIrm.sol | 155 - .../src/libraries/ErrorsLib.sol | 23 - lib/morpho-blue-irm/src/libraries/MathLib.sol | 55 - .../src/libraries/UtilsLib.sol | 19 - lib/morpho-blue-irm/test/MathLibTest.sol | 41 - lib/morpho-blue-irm/test/SpeedJumpIrmTest.sol | 219 - lib/morpho-blue-irm/test/UtilsLibTest.sol | 20 - .../.github/workflows/certora.yml | 37 - .../.github/workflows/foundry-gas-diff.yml | 46 - lib/morpho-utils/.gitignore | 53 - lib/morpho-utils/.gitmodules | 13 - lib/morpho-utils/.husky/post-checkout | 5 - lib/morpho-utils/.husky/post-merge | 5 - lib/morpho-utils/.husky/pre-commit | 4 - lib/morpho-utils/.prettierignore | 1 - lib/morpho-utils/.prettierrc.json | 13 - lib/morpho-utils/ISSUES.md | 44 - lib/morpho-utils/LICENSE | 661 - lib/morpho-utils/README.md | 106 - lib/morpho-utils/certora/scripts/verifyAll.sh | 8 - .../certora/scripts/verifyCompoundMath.sh | 7 - .../certora/scripts/verifyMath.sh | 10 - .../certora/scripts/verifyPercentageMath.sh | 7 - .../certora/scripts/verifyWadRayMath.sh | 8 - .../certora/specs/compoundMath.spec | 34 - lib/morpho-utils/certora/specs/math.spec | 67 - .../certora/specs/percentageMath.spec | 140 - .../certora/specs/wadRayMath.spec | 246 - lib/morpho-utils/foundry.toml | 4 - .../lib/aave-v3-core/.giatattributes | 1 - .../lib/aave-v3-core/.github/CODEOWNERS | 1 - .../.github/workflows/node.js.yml | 45 - .../.github/workflows/release.yml | 38 - lib/morpho-utils/lib/aave-v3-core/.gitignore | 21 - .../lib/aave-v3-core/.gitlab-ci.yml | 92 - lib/morpho-utils/lib/aave-v3-core/.npmrc | 2 - lib/morpho-utils/lib/aave-v3-core/.nvmrc | 1 - .../lib/aave-v3-core/.prettierignore | 3 - lib/morpho-utils/lib/aave-v3-core/.prettierrc | 16 - .../lib/aave-v3-core/.solcover.js | 17 - .../lib/aave-v3-core/CHANGELOG.md | 820 - .../Certora/certora/Verification_Report.md | 442 - .../Certora/certora/Verification_Report.pdf | Bin 115198 -> 0 bytes .../Certora/certora/harness/ATokenHarness.sol | 63 - .../certora/harness/DataTypesInitializer.sol | 0 .../certora/harness/EModeLogicHarness.sol | 22 - .../certora/harness/GenericLogicHarness.sol | 244 - .../certora/harness/LendingPoolHarness.sol | 91 - .../harness/PoolConfiguratorHarness.sol | 463 - .../harness/PoolHarnessForConfigurator.sol | 757 - .../PoolHarnessForVariableDebtToken.sol | 203 - .../harness/ReserveConfigurationHarness.sol | 325 - .../Certora/certora/harness/SimpleERC20.sol | 57 - .../harness/StableDebtTokenHarness.sol | 47 - .../certora/harness/SupplyLogicHarness.sol | 47 - .../certora/harness/SymbolicPriceOracle.sol | 23 - .../harness/UserConfigurationHarness.sol | 67 - .../certora/harness/flashLoanHarness.sol | 90 - .../harness/validationLogicHarness.sol | 116 - .../Certora/certora/scripts/PoolSanity.sh | 0 .../Certora/certora/scripts/verifyAToken.sh | 9 - .../scripts/verifyEModeAndIsolation.sh | 5 - .../Certora/certora/scripts/verifyPool.sh | 13 - .../certora/scripts/verifyPoolConfigurator.sh | 9 - .../scripts/verifyReserveConfiguration.sh | 9 - .../Certora/certora/scripts/verifySanity.sh | 11 - .../certora/scripts/verifySanityEModeLogic.sh | 4 - .../verifySanityWithLinksOptimisticLoops.sh | 6 - .../certora/scripts/verifyStableTokenCLI.sh | 5 - .../certora/scripts/verifyUserConfigCLI.sh | 9 - .../certora/scripts/verifyVariableTokenCLI.sh | 7 - .../Certora/certora/specs/AToken.spec | 306 - .../certora/specs/PoolConfigurator.spec | 13 - .../certora/specs/ReserveConfiguration.spec | 171 - .../certora/specs/StableDebtToken.spec | 216 - .../certora/specs/UserConfiguration.spec | 70 - .../certora/specs/VariableDebtToken.spec | 139 - .../Certora/certora/specs/pool.spec | 371 - .../Certora/certora/specs/sanity.spec | 6 - lib/morpho-utils/lib/aave-v3-core/Dockerfile | 7 - lib/morpho-utils/lib/aave-v3-core/LICENSE.md | 97 - lib/morpho-utils/lib/aave-v3-core/README.md | 115 - .../audits/01-11-2021_OpenZeppelin_AaveV3.pdf | Bin 1224058 -> 0 bytes .../audits/07-01-2022_TrailOfBits_AaveV3.pdf | Bin 417141 -> 0 bytes .../audits/14-01-2022_PeckShield_AaveV3.pdf | Bin 395584 -> 0 bytes .../audits/27-01-2022_ABDK_AaveV3.pdf | Bin 1405807 -> 0 bytes .../audits/27-01-2022_SigmaPrime_AaveV3.pdf | Bin 418139 -> 0 bytes .../chainlink/AggregatorInterface.sol | 19 - .../gnosis/contracts/GPv2SafeERC20.sol | 124 - .../openzeppelin/contracts/AccessControl.sol | 220 - .../openzeppelin/contracts/Address.sol | 61 - .../openzeppelin/contracts/Context.sol | 23 - .../openzeppelin/contracts/ERC165.sol | 28 - .../openzeppelin/contracts/ERC20.sol | 344 - .../openzeppelin/contracts/IAccessControl.sol | 91 - .../openzeppelin/contracts/IERC165.sol | 24 - .../openzeppelin/contracts/IERC20.sol | 80 - .../openzeppelin/contracts/IERC20Detailed.sol | 12 - .../openzeppelin/contracts/Ownable.sol | 69 - .../openzeppelin/contracts/SafeCast.sol | 255 - .../openzeppelin/contracts/SafeMath.sol | 59 - .../openzeppelin/contracts/Strings.sol | 66 - .../AdminUpgradeabilityProxy.sol | 36 - .../BaseAdminUpgradeabilityProxy.sol | 126 - .../BaseUpgradeabilityProxy.sol | 66 - .../upgradeability/Initializable.sol | 66 - .../InitializableAdminUpgradeabilityProxy.sol | 42 - .../InitializableUpgradeabilityProxy.sol | 29 - .../openzeppelin/upgradeability/Proxy.sol | 73 - .../upgradeability/UpgradeabilityProxy.sol | 28 - .../contracts/dependencies/weth/WETH9.sol | 758 - .../flashloan/base/FlashLoanReceiverBase.sol | 21 - .../base/FlashLoanSimpleReceiverBase.sol | 21 - .../contracts/flashloan/base/LICENSE.md | 12 - .../interfaces/IFlashLoanReceiver.sol | 36 - .../interfaces/IFlashLoanSimpleReceiver.sol | 36 - .../contracts/flashloan/interfaces/LICENSE.md | 12 - .../contracts/interfaces/IACLManager.sol | 175 - .../contracts/interfaces/IAToken.sol | 150 - .../interfaces/IAaveIncentivesController.sol | 176 - .../contracts/interfaces/IAaveOracle.sol | 71 - .../interfaces/ICreditDelegationToken.sol | 60 - .../contracts/interfaces/IDelegationToken.sol | 15 - .../contracts/interfaces/IERC20WithPermit.sol | 33 - .../interfaces/IInitializableAToken.sol | 56 - .../interfaces/IInitializableDebtToken.sol | 52 - .../contracts/interfaces/IL2Pool.sol | 141 - .../contracts/interfaces/IPool.sol | 747 - .../interfaces/IPoolAddressesProvider.sol | 227 - .../IPoolAddressesProviderRegistry.sol | 61 - .../interfaces/IPoolConfigurator.sol | 468 - .../interfaces/IPoolDataProvider.sol | 52 - .../contracts/interfaces/IPriceOracle.sol | 23 - .../interfaces/IPriceOracleGetter.sol | 30 - .../interfaces/IPriceOracleSentinel.sol | 67 - .../IReserveInterestRateStrategy.sol | 39 - .../interfaces/IScaledBalanceToken.sol | 71 - .../contracts/interfaces/ISequencerOracle.sol | 29 - .../contracts/interfaces/IStableDebtToken.sol | 153 - .../interfaces/IVariableDebtToken.sol | 50 - .../contracts/interfaces/LICENSE.md | 12 - .../contracts/misc/AaveOracle.sol | 152 - .../misc/AaveProtocolDataProvider.sol | 377 - .../aave-v3-core/contracts/misc/L2Encoder.sol | 355 - .../contracts/misc/interfaces/IWETH.sol | 16 - .../contracts/misc/interfaces/LICENSE.md | 12 - .../mocks/flashloan/MockFlashLoanReceiver.sol | 78 - .../flashloan/MockSimpleFlashLoanReceiver.sol | 74 - .../helpers/MockIncentivesController.sol | 87 - .../contracts/mocks/helpers/MockL2Pool.sol | 13 - .../mocks/helpers/MockPeripheryContract.sol | 42 - .../contracts/mocks/helpers/MockPool.sol | 53 - .../helpers/MockReserveConfiguration.sol | 174 - .../mocks/helpers/SelfDestructTransfer.sol | 8 - .../oracle/CLAggregators/MockAggregator.sol | 25 - .../contracts/mocks/oracle/PriceOracle.sol | 32 - .../mocks/oracle/SequencerOracle.sol | 48 - .../mocks/tests/FlashloanAttacker.sol | 57 - .../tests/MockReserveInterestRateStrategy.sol | 88 - .../mocks/tests/WadRayMathWrapper.sol | 46 - .../mocks/tokens/MintableDelegationERC20.sol | 35 - .../contracts/mocks/tokens/MintableERC20.sol | 92 - .../contracts/mocks/tokens/WETH9Mocked.sol | 19 - .../mocks/upgradeability/MockAToken.sol | 14 - .../MockInitializableImplementation.sol | 115 - .../upgradeability/MockStableDebtToken.sol | 13 - .../upgradeability/MockVariableDebtToken.sol | 13 - .../protocol/configuration/ACLManager.sol | 134 - .../configuration/PoolAddressesProvider.sol | 210 - .../PoolAddressesProviderRegistry.sol | 105 - .../configuration/PriceOracleSentinel.sol | 101 - .../BaseImmutableAdminUpgradeabilityProxy.sol | 86 - ...zableImmutableAdminUpgradeabilityProxy.sol | 29 - .../VersionedInitializable.sol | 77 - .../configuration/ReserveConfiguration.sol | 633 - .../configuration/UserConfiguration.sol | 251 - .../protocol/libraries/helpers/Errors.sol | 100 - .../protocol/libraries/helpers/Helpers.sol | 29 - .../protocol/libraries/logic/BorrowLogic.sol | 349 - .../protocol/libraries/logic/BridgeLogic.sol | 141 - .../libraries/logic/CalldataLogic.sol | 322 - .../libraries/logic/ConfiguratorLogic.sol | 268 - .../protocol/libraries/logic/EModeLogic.sol | 121 - .../libraries/logic/FlashLoanLogic.sol | 262 - .../protocol/libraries/logic/GenericLogic.sol | 280 - .../libraries/logic/IsolationModeLogic.sol | 64 - .../libraries/logic/LiquidationLogic.sol | 538 - .../protocol/libraries/logic/PoolLogic.sol | 192 - .../protocol/libraries/logic/ReserveLogic.sol | 362 - .../protocol/libraries/logic/SupplyLogic.sol | 290 - .../libraries/logic/ValidationLogic.sol | 726 - .../protocol/libraries/math/MathUtils.sol | 101 - .../libraries/math/PercentageMath.sol | 61 - .../protocol/libraries/math/WadRayMath.sol | 126 - .../types/ConfiguratorInputTypes.sol | 41 - .../protocol/libraries/types/DataTypes.sol | 268 - .../DefaultReserveInterestRateStrategy.sol | 299 - .../contracts/protocol/pool/L2Pool.sol | 135 - .../contracts/protocol/pool/Pool.sol | 773 - .../protocol/pool/PoolConfigurator.sol | 528 - .../contracts/protocol/pool/PoolStorage.sol | 51 - .../protocol/tokenization/AToken.sol | 272 - .../tokenization/DelegationAwareAToken.sol | 37 - .../protocol/tokenization/StableDebtToken.sol | 430 - .../tokenization/VariableDebtToken.sol | 157 - .../tokenization/base/DebtTokenBase.sol | 112 - .../protocol/tokenization/base/EIP712Base.sol | 70 - .../tokenization/base/IncentivizedERC20.sol | 253 - .../base/MintableIncentivizedERC20.sol | 66 - .../base/ScaledBalanceTokenBase.sol | 129 - .../lib/aave-v3-core/docker-compose.yml | 26 - .../lib/aave-v3-core/hardhat.config.ts | 103 - .../lib/aave-v3-core/helper-hardhat-config.ts | 52 - .../lib/aave-v3-core/helpers/constants.ts | 34 - .../aave-v3-core/helpers/contracts-helpers.ts | 139 - .../lib/aave-v3-core/helpers/misc-utils.ts | 38 - .../aave-v3-core/helpers/tenderly-utils.ts | 8 - .../lib/aave-v3-core/helpers/types.ts | 414 - .../lib/aave-v3-core/package-lock.json | 43504 ---------------- .../lib/aave-v3-core/package.json | 108 - .../lib/aave-v3-core/setup-test-env.sh | 42 - .../techpaper/Aave_V3_Technical_Paper.pdf | Bin 780635 -> 0 bytes .../aave-v3-core/test-suites/__setup.spec.ts | 14 - .../test-suites/aave-oracle.spec.ts | 200 - .../aave-protocol-data-provider.spec.ts | 41 - .../test-suites/acl-manager.spec.ts | 272 - .../addresses-provider-registry.spec.ts | 230 - .../atoken-delegation-aware.spec.ts | 49 - .../test-suites/atoken-edge.spec.ts | 259 - .../atoken-event-accounting.spec.ts | 570 - .../test-suites/atoken-modifiers.spec.ts | 35 - .../test-suites/atoken-permit.spec.ts | 300 - .../test-suites/atoken-repay.spec.ts | 248 - .../test-suites/atoken-transfer.spec.ts | 243 - .../test-suites/bridge-logic.spec.ts | 344 - .../configurator-borrow-cap.spec.ts | 439 - .../test-suites/configurator-edge.spec.ts | 322 - ...figurator-liquidation-protocol-fee.spec.ts | 103 - .../configurator-modifiers.spec.ts | 149 - .../configurator-supply-cap.spec.ts | 354 - .../test-suites/configurator.spec.ts | 1078 - .../debt-token-delegation-permit.spec.ts | 424 - .../aave-v3-core/test-suites/emode.spec.ts | 863 - .../test-suites/emptyrun.coverage.spec.ts | 5 - .../test-suites/helpers/actions.ts | 1049 - .../test-suites/helpers/make-suite.ts | 199 - .../test-suites/helpers/scenario-engine.ts | 302 - .../helpers/scenarios/borrow-negatives.json | 142 - .../scenarios/borrow-repay-stable-edge.json | 95 - .../scenarios/borrow-repay-stable.json | 656 - .../scenarios/borrow-repay-variable.json | 946 - .../borrow-repayWithPermit-variable.json | 194 - .../helpers/scenarios/credit-delegation.json | 157 - .../helpers/scenarios/deposit.json | 266 - .../scenarios/rebalance-stable-rate.json | 274 - .../scenarios/set-use-as-collateral.json | 236 - .../helpers/scenarios/swap-rate-mode.json | 167 - .../helpers/scenarios/withdraw-negatives.json | 114 - .../helpers/scenarios/withdraw.json | 389 - .../test-suites/helpers/utils/calculations.ts | 1585 - .../test-suites/helpers/utils/funds.ts | 18 - .../test-suites/helpers/utils/helpers.ts | 137 - .../helpers/utils/interfaces/index.ts | 44 - .../test-suites/helpers/utils/wadraymath.ts | 79 - .../test-suites/helpers/utils/wallets.ts | 7 - .../test-suites/interest-overflow.spec.ts | 420 - .../test-suites/isolation-mode.spec.ts | 571 - .../test-suites/liquidation-atoken.spec.ts | 454 - .../test-suites/liquidation-edge.spec.ts | 217 - .../liquidation-emode-interest.spec.ts | 250 - .../test-suites/liquidation-emode.spec.ts | 621 - .../liquidation-underlying.spec.ts | 506 - .../test-suites/liquidation-with-fee.spec.ts | 806 - .../test-suites/ltv-validation.spec.ts | 150 - .../test-suites/mint-to-treasury.spec.ts | 76 - .../no-incentives-controller.spec.ts | 295 - .../test-suites/pausable-pool.spec.ts | 402 - .../test-suites/pausable-reserve.spec.ts | 318 - .../pool-addresses-provider.spec.ts | 547 - .../pool-authorized-flashloan.spec.ts | 519 - .../test-suites/pool-drop-reserve.spec.ts | 102 - .../test-suites/pool-edge.spec.ts | 796 - .../test-suites/pool-flashloan.spec.ts | 695 - .../pool-get-reserve-address-by-id.spec.ts | 35 - .../aave-v3-core/test-suites/pool-l2.spec.ts | 728 - .../test-suites/pool-normal-flashloan.spec.ts | 349 - .../test-suites/pool-simple-flashloan.spec.ts | 406 - .../test-suites/price-oracle-sentinel.spec.ts | 630 - .../test-suites/rate-strategy.spec.ts | 426 - .../test-suites/rescue-tokens.spec.ts | 130 - .../test-suites/reserve-configuration.spec.ts | 357 - .../aave-v3-core/test-suites/scenario.spec.ts | 32 - .../test-suites/siloed-borrowing.spec.ts | 188 - .../test-suites/stable-debt-token.spec.ts | 351 - .../test-suites/subgraph-scenarios.spec.ts | 21 - .../test-suites/upgradeability.spec.ts | 561 - .../test-suites/validation-logic.spec.ts | 1023 - .../test-suites/variable-debt-token.spec.ts | 380 - .../test-suites/wadraymath.spec.ts | 99 - .../lib/aave-v3-core/test-wallets.js | 38 - .../lib/aave-v3-core/tsconfig.json | 21 - lib/morpho-utils/lib/aave-v3-core/tslint.json | 12 - .../lib/forge-std/.github/workflows/ci.yml | 58 - lib/morpho-utils/lib/forge-std/.gitignore | 4 - lib/morpho-utils/lib/forge-std/.gitmodules | 3 - lib/morpho-utils/lib/forge-std/LICENSE-APACHE | 203 - lib/morpho-utils/lib/forge-std/LICENSE-MIT | 25 - lib/morpho-utils/lib/forge-std/README.md | 250 - lib/morpho-utils/lib/forge-std/foundry.toml | 21 - .../lib/forge-std/lib/ds-test/.gitignore | 3 - .../lib/forge-std/lib/ds-test/LICENSE | 674 - .../lib/forge-std/lib/ds-test/Makefile | 14 - .../lib/forge-std/lib/ds-test/default.nix | 4 - .../lib/forge-std/lib/ds-test/demo/demo.sol | 222 - .../lib/forge-std/lib/ds-test/package.json | 15 - .../lib/forge-std/lib/ds-test/src/test.sol | 469 - lib/morpho-utils/lib/forge-std/package.json | 16 - lib/morpho-utils/lib/forge-std/src/Common.sol | 13 - .../lib/forge-std/src/Components.sol | 13 - lib/morpho-utils/lib/forge-std/src/Script.sol | 14 - .../lib/forge-std/src/StdAssertions.sol | 209 - .../lib/forge-std/src/StdCheats.sol | 619 - .../lib/forge-std/src/StdError.sol | 15 - .../lib/forge-std/src/StdJson.sol | 71 - .../lib/forge-std/src/StdMath.sol | 43 - .../lib/forge-std/src/StdStorage.sol | 327 - .../lib/forge-std/src/StdUtils.sol | 80 - lib/morpho-utils/lib/forge-std/src/Test.sol | 11 - lib/morpho-utils/lib/forge-std/src/Vm.sol | 252 - .../lib/forge-std/src/console.sol | 1533 - .../lib/forge-std/src/console2.sol | 1538 - .../lib/forge-std/src/interfaces/IERC1155.sol | 104 - .../lib/forge-std/src/interfaces/IERC165.sol | 11 - .../lib/forge-std/src/interfaces/IERC20.sol | 42 - .../lib/forge-std/src/interfaces/IERC4626.sol | 189 - .../lib/forge-std/src/interfaces/IERC721.sol | 163 - .../lib/forge-std/test/StdAssertions.t.sol | 587 - .../lib/forge-std/test/StdCheats.t.sol | 283 - .../lib/forge-std/test/StdError.t.sol | 118 - .../lib/forge-std/test/StdMath.t.sol | 197 - .../lib/forge-std/test/StdStorage.t.sol | 283 - .../lib/forge-std/test/StdUtils.t.sol | 96 - .../test/fixtures/broadcast.log.json | 187 - .../.changeset/new-ways-own.md | 5 - .../.codecov.yml | 12 - .../.editorconfig | 21 - .../.eslintrc | 62 - .../.gitattributes | 1 - .../.github/ISSUE_TEMPLATE/bug_report.md | 21 - .../.github/ISSUE_TEMPLATE/config.yml | 4 - .../.github/ISSUE_TEMPLATE/feature_request.md | 14 - .../.github/PULL_REQUEST_TEMPLATE.md | 20 - .../.github/actions/gas-compare/action.yml | 49 - .../.github/actions/setup/action.yml | 20 - .../.github/workflows/changelog.yml | 28 - .../.github/workflows/checks.yml | 101 - .../.github/workflows/docs.yml | 19 - .../.github/workflows/merge-upstream.yml | 28 - .../.github/workflows/transpile.yml | 27 - .../.gitignore | 64 - .../.gitmodules | 4 - .../.mocharc.js | 4 - .../.prettierrc | 14 - .../.solcover.js | 15 - .../.solhint.json | 14 - .../CHANGELOG.md | 635 - .../CODE_OF_CONDUCT.md | 73 - .../CONTRIBUTING.md | 64 - .../DOCUMENTATION.md | 16 - .../GUIDELINES.md | 105 - .../LICENSE | 22 - .../README.md | 104 - .../RELEASING.md | 36 - .../SECURITY.md | 20 - .../UPGRADEABLE.md | 47 - .../audit/2017-03.md | 292 - .../audit/2018-10.pdf | Bin 1000527 -> 0 bytes .../certora/Makefile | 24 - .../certora/README.md | 56 - .../certora/applyHarness.patch | 101 - .../certora/harnesses/ERC20VotesHarness.sol | 28 - .../harnesses/WizardControlFirstPriority.sol | 150 - .../certora/harnesses/WizardFirstTry.sol | 141 - .../certora/munged/.gitignore | 2 - .../certora/scripts/Governor.sh | 10 - .../GovernorCountingSimple-counting.sh | 10 - .../scripts/WizardControlFirstPriority.sh | 12 - .../certora/scripts/WizardFirstTry.sh | 10 - .../certora/scripts/sanity.sh | 14 - .../certora/scripts/verifyAll.sh | 39 - .../certora/specs/GovernorBase.spec | 333 - .../certora/specs/GovernorCountingSimple.spec | 221 - .../certora/specs/RulesInProgress.spec | 139 - .../certora/specs/sanity.spec | 14 - .../AccessControlCrossChainUpgradeable.sol | 58 - .../AccessControlEnumerableUpgradeable.sol | 77 - .../access/AccessControlUpgradeable.sol | 260 - .../IAccessControlEnumerableUpgradeable.sol | 31 - .../access/IAccessControlUpgradeable.sol | 88 - .../access/Ownable2StepUpgradeable.sol | 71 - .../contracts/access/OwnableUpgradeable.sol | 95 - .../contracts/access/README.adoc | 25 - .../CrossChainEnabledUpgradeable.sol | 67 - .../contracts/crosschain/README.adoc | 34 - .../amb/CrossChainEnabledAMBUpgradeable.sol | 57 - .../crosschain/amb/LibAMBUpgradeable.sol | 35 - ...CrossChainEnabledArbitrumL1Upgradeable.sol | 52 - ...CrossChainEnabledArbitrumL2Upgradeable.sol | 53 - .../arbitrum/LibArbitrumL1Upgradeable.sol | 42 - .../arbitrum/LibArbitrumL2Upgradeable.sol | 45 - .../crosschain/errorsUpgradeable.sol | 7 - .../CrossChainEnabledOptimismUpgradeable.sol | 49 - .../optimism/LibOptimismUpgradeable.sol | 36 - ...ossChainEnabledPolygonChildUpgradeable.sol | 90 - .../finance/PaymentSplitterUpgradeable.sol | 226 - .../contracts/finance/README.adoc | 20 - .../finance/VestingWalletUpgradeable.sol | 167 - .../governance/GovernorUpgradeable.sol | 610 - .../governance/IGovernorUpgradeable.sol | 289 - .../contracts/governance/README.adoc | 176 - .../TimelockControllerUpgradeable.sol | 443 - ...ckControllerWith46MigrationUpgradeable.sol | 56 - .../GovernorCompatibilityBravoUpgradeable.sol | 302 - ...IGovernorCompatibilityBravoUpgradeable.sol | 127 - .../GovernorCountingSimpleUpgradeable.sol | 120 - .../GovernorPreventLateQuorumUpgradeable.sol | 120 - .../GovernorProposalThresholdUpgradeable.sol | 36 - .../GovernorSettingsUpgradeable.sol | 130 - .../GovernorTimelockCompoundUpgradeable.sol | 205 - .../GovernorTimelockControlUpgradeable.sol | 178 - .../GovernorVotesCompUpgradeable.sol | 45 - ...GovernorVotesQuorumFractionUpgradeable.sol | 131 - .../extensions/GovernorVotesUpgradeable.sol | 45 - .../IGovernorTimelockUpgradeable.sol | 39 - .../governance/utils/IVotesUpgradeable.sol | 61 - .../governance/utils/VotesUpgradeable.sol | 224 - .../IERC1155MetadataURIUpgradeable.sol | 6 - .../IERC1155ReceiverUpgradeable.sol | 6 - .../interfaces/IERC1155Upgradeable.sol | 6 - .../interfaces/IERC1271Upgradeable.sol | 19 - .../IERC1363ReceiverUpgradeable.sol | 32 - .../interfaces/IERC1363SpenderUpgradeable.sol | 30 - .../interfaces/IERC1363Upgradeable.sol | 95 - .../interfaces/IERC165Upgradeable.sol | 6 - .../IERC1820ImplementerUpgradeable.sol | 6 - .../IERC1820RegistryUpgradeable.sol | 6 - .../interfaces/IERC1967Upgradeable.sol | 26 - .../interfaces/IERC20MetadataUpgradeable.sol | 6 - .../interfaces/IERC20Upgradeable.sol | 6 - .../interfaces/IERC2309Upgradeable.sol | 21 - .../interfaces/IERC2981Upgradeable.sol | 25 - .../IERC3156FlashBorrowerUpgradeable.sol | 29 - .../IERC3156FlashLenderUpgradeable.sol | 43 - .../interfaces/IERC3156Upgradeable.sol | 7 - .../interfaces/IERC4626Upgradeable.sol | 240 - .../IERC721EnumerableUpgradeable.sol | 6 - .../interfaces/IERC721MetadataUpgradeable.sol | 6 - .../interfaces/IERC721ReceiverUpgradeable.sol | 6 - .../interfaces/IERC721Upgradeable.sol | 6 - .../IERC777RecipientUpgradeable.sol | 6 - .../interfaces/IERC777SenderUpgradeable.sol | 6 - .../interfaces/IERC777Upgradeable.sol | 6 - .../contracts/interfaces/README.adoc | 56 - .../interfaces/draft-IERC1822Upgradeable.sol | 20 - .../interfaces/draft-IERC2612Upgradeable.sol | 8 - .../metatx/ERC2771ContextUpgradeable.sol | 51 - .../metatx/MinimalForwarderUpgradeable.sol | 85 - .../contracts/metatx/README.adoc | 12 - ...AccessControlCrossChainMockUpgradeable.sol | 34 - ...AccessControlEnumerableMockUpgradeable.sol | 29 - .../mocks/AccessControlMockUpgradeable.sol | 29 - .../mocks/AddressImplUpgradeable.sol | 54 - .../contracts/mocks/ArraysMockUpgradeable.sol | 85 - .../contracts/mocks/BadBeaconUpgradeable.sol | 36 - .../contracts/mocks/Base64MockUpgradeable.sol | 24 - .../contracts/mocks/BitmapMockUpgradeable.sol | 40 - .../mocks/CallReceiverMockUpgradeable.sol | 70 - .../mocks/CheckpointsMockUpgradeable.sol | 157 - .../ClashingImplementationUpgradeable.sol | 30 - .../contracts/mocks/ClonesMockUpgradeable.sol | 49 - .../ConditionalEscrowMockUpgradeable.sol | 32 - .../mocks/ContextMockUpgradeable.sol | 58 - .../mocks/CountersImplUpgradeable.sol | 40 - .../mocks/Create2ImplUpgradeable.sol | 47 - .../mocks/DoubleEndedQueueMockUpgradeable.sol | 71 - .../mocks/DummyImplementationUpgradeable.sol | 98 - .../contracts/mocks/ECDSAMockUpgradeable.sol | 54 - .../mocks/EIP712ExternalUpgradeable.sol | 43 - .../mocks/ERC1155BurnableMockUpgradeable.sol | 30 - .../mocks/ERC1155MockUpgradeable.sol | 63 - .../mocks/ERC1155PausableMockUpgradeable.sol | 43 - .../mocks/ERC1155ReceiverMockUpgradeable.sol | 69 - .../mocks/ERC1155SupplyMockUpgradeable.sol | 34 - .../ERC1155URIStorageMockUpgradeable.sol | 36 - .../mocks/ERC1271WalletMockUpgradeable.sol | 51 - .../ERC165InterfacesSupportedUpgradeable.sol | 82 - .../ERC165/ERC165MaliciousDataUpgradeable.sol | 25 - .../ERC165/ERC165MissingDataUpgradeable.sol | 20 - .../ERC165/ERC165NotSupportedUpgradeable.sol | 18 - .../ERC165/ERC165ReturnBombUpgradeable.sol | 31 - .../mocks/ERC165CheckerMockUpgradeable.sol | 42 - .../contracts/mocks/ERC165MockUpgradeable.sol | 20 - .../mocks/ERC165StorageMockUpgradeable.sol | 24 - .../ERC1820ImplementerMockUpgradeable.sol | 24 - .../mocks/ERC20BurnableMockUpgradeable.sol | 34 - .../mocks/ERC20CappedMockUpgradeable.sol | 34 - .../mocks/ERC20DecimalsMockUpgradeable.sol | 46 - .../mocks/ERC20FlashMintMockUpgradeable.sol | 61 - .../contracts/mocks/ERC20MockUpgradeable.sol | 59 - .../mocks/ERC20PausableMockUpgradeable.sol | 52 - .../mocks/ERC20PermitMockUpgradeable.sol | 40 - .../mocks/ERC20SnapshotMockUpgradeable.sol | 46 - .../mocks/ERC20VotesCompMockUpgradeable.sol | 35 - .../mocks/ERC20VotesMockUpgradeable.sol | 35 - .../mocks/ERC20WrapperMockUpgradeable.sol | 34 - .../mocks/ERC2771ContextMockUpgradeable.sol | 30 - .../ERC3156FlashBorrowerMockUpgradeable.sol | 65 - .../mocks/ERC4626MockUpgradeable.sol | 96 - .../mocks/ERC721BurnableMockUpgradeable.sol | 41 - ...21ConsecutiveEnumerableMockUpgradeable.sol | 73 - .../ERC721ConsecutiveMockUpgradeable.sol | 119 - .../mocks/ERC721EnumerableMockUpgradeable.sol | 63 - .../contracts/mocks/ERC721MockUpgradeable.sol | 53 - .../mocks/ERC721PausableMockUpgradeable.sol | 58 - .../mocks/ERC721ReceiverMockUpgradeable.sol | 54 - .../mocks/ERC721RoyaltyMockUpgradeable.sol | 45 - .../mocks/ERC721URIStorageMockUpgradeable.sol | 67 - .../mocks/ERC721VotesMockUpgradeable.sol | 38 - .../contracts/mocks/ERC777MockUpgradeable.sol | 75 - .../ERC777SenderRecipientMockUpgradeable.sol | 176 - .../mocks/EnumerableMapMockUpgradeable.sol | 282 - .../mocks/EnumerableSetMockUpgradeable.sol | 148 - .../mocks/EtherReceiverMockUpgradeable.sol | 30 - .../mocks/GovernorCompMockUpgradeable.sol | 45 - ...ernorCompatibilityBravoMockUpgradeable.sol | 145 - .../mocks/GovernorMockUpgradeable.sol | 67 - ...vernorPreventLateQuorumMockUpgradeable.sol | 79 - ...overnorTimelockCompoundMockUpgradeable.sol | 114 - ...GovernorTimelockControlMockUpgradeable.sol | 111 - .../mocks/GovernorVoteMockUpgradeable.sol | 45 - .../GovernorWithParamsMockUpgradeable.sol | 75 - .../contracts/mocks/InitializableMock.sol | 130 - .../contracts/mocks/MathMockUpgradeable.sol | 61 - .../mocks/MerkleProofWrapperUpgradeable.sol | 78 - .../mocks/MulticallTestUpgradeable.sol | 36 - .../mocks/MulticallTokenMockUpgradeable.sol | 23 - .../MultipleInheritanceInitializableMocks.sol | 136 - .../mocks/Ownable2StepMockUpgradeable.sol | 21 - .../mocks/OwnableMockUpgradeable.sol | 21 - .../mocks/PausableMockUpgradeable.sol | 44 - .../mocks/PullPaymentMockUpgradeable.sol | 27 - .../mocks/ReentrancyAttackUpgradeable.sol | 25 - .../mocks/ReentrancyMockUpgradeable.sol | 56 - .../mocks/RegressionImplementation.sol | 61 - .../mocks/SafeCastMockUpgradeable.sol | 280 - .../mocks/SafeERC20HelperUpgradeable.sol | 257 - .../mocks/SafeMathMockUpgradeable.sol | 151 - .../mocks/SignatureCheckerMockUpgradeable.sol | 30 - .../mocks/SignedMathMockUpgradeable.sol | 36 - .../mocks/SignedSafeMathMockUpgradeable.sol | 36 - .../SingleInheritanceInitializableMocks.sol | 49 - .../mocks/StorageSlotMockUpgradeable.sol | 54 - .../mocks/StringsMockUpgradeable.sol | 36 - .../TimersBlockNumberImplUpgradeable.sol | 52 - .../mocks/TimersTimestampImplUpgradeable.sol | 52 - .../mocks/UUPS/UUPSLegacyUpgradeable.sol | 81 - .../UUPS/UUPSUpgradeableMockUpgradeable.sol | 46 - .../contracts/mocks/VotesMockUpgradeable.sol | 52 - .../contracts/mocks/WithInit.sol | 1373 - .../compound/CompTimelockUpgradeable.sol | 186 - .../mocks/crosschain/bridgesUpgradeable.sol | 199 - .../mocks/crosschain/receiversUpgradeable.sol | 107 - .../mocks/wizard/MyGovernor1Upgradeable.sol | 98 - .../mocks/wizard/MyGovernor2Upgradeable.sol | 104 - .../mocks/wizard/MyGovernor3Upgradeable.sol | 107 - .../contracts/package.json | 32 - .../contracts/proxy/ClonesUpgradeable.sol | 89 - .../ERC1967/ERC1967UpgradeUpgradeable.sol | 198 - .../contracts/proxy/README.adoc | 87 - .../proxy/beacon/IBeaconUpgradeable.sol | 16 - .../contracts/proxy/utils/Initializable.sol | 165 - .../contracts/proxy/utils/UUPSUpgradeable.sol | 108 - .../security/PausableUpgradeable.sol | 117 - .../security/PullPaymentUpgradeable.sol | 89 - .../contracts/security/README.adoc | 20 - .../security/ReentrancyGuardUpgradeable.sol | 81 - .../token/ERC1155/ERC1155Upgradeable.sol | 529 - .../ERC1155/IERC1155ReceiverUpgradeable.sol | 58 - .../token/ERC1155/IERC1155Upgradeable.sol | 125 - .../contracts/token/ERC1155/README.adoc | 49 - .../extensions/ERC1155BurnableUpgradeable.sol | 53 - .../extensions/ERC1155PausableUpgradeable.sol | 58 - .../extensions/ERC1155SupplyUpgradeable.sol | 77 - .../ERC1155URIStorageUpgradeable.sol | 78 - .../IERC1155MetadataURIUpgradeable.sol | 22 - .../ERC1155PresetMinterPauserUpgradeable.sol | 145 - .../contracts/token/ERC1155/presets/README.md | 1 - .../utils/ERC1155HolderUpgradeable.sol | 49 - .../utils/ERC1155ReceiverUpgradeable.sol | 32 - .../token/ERC20/ERC20Upgradeable.sol | 401 - .../token/ERC20/IERC20Upgradeable.sol | 82 - .../contracts/token/ERC20/README.adoc | 86 - .../extensions/ERC20BurnableUpgradeable.sol | 52 - .../extensions/ERC20CappedUpgradeable.sol | 51 - .../extensions/ERC20FlashMintUpgradeable.sol | 122 - .../extensions/ERC20PausableUpgradeable.sol | 53 - .../extensions/ERC20SnapshotUpgradeable.sol | 208 - .../extensions/ERC20VotesCompUpgradeable.sol | 59 - .../extensions/ERC20VotesUpgradeable.sol | 288 - .../extensions/ERC20WrapperUpgradeable.sol | 77 - .../ERC20/extensions/ERC4626Upgradeable.sol | 296 - .../extensions/IERC20MetadataUpgradeable.sol | 28 - .../draft-ERC20PermitUpgradeable.sol | 109 - .../draft-IERC20PermitUpgradeable.sol | 60 - .../ERC20PresetFixedSupplyUpgradeable.sol | 61 - .../ERC20PresetMinterPauserUpgradeable.sol | 111 - .../contracts/token/ERC20/presets/README.md | 1 - .../ERC20/utils/SafeERC20Upgradeable.sol | 116 - .../ERC20/utils/TokenTimelockUpgradeable.sol | 94 - .../token/ERC721/ERC721Upgradeable.sol | 518 - .../ERC721/IERC721ReceiverUpgradeable.sol | 27 - .../token/ERC721/IERC721Upgradeable.sol | 145 - .../contracts/token/ERC721/README.adoc | 70 - .../extensions/ERC721BurnableUpgradeable.sol | 39 - .../ERC721ConsecutiveUpgradeable.sol | 161 - .../ERC721EnumerableUpgradeable.sol | 172 - .../extensions/ERC721PausableUpgradeable.sol | 54 - .../extensions/ERC721RoyaltyUpgradeable.sol | 51 - .../ERC721URIStorageUpgradeable.sol | 75 - .../extensions/ERC721VotesUpgradeable.sol | 54 - .../IERC721EnumerableUpgradeable.sol | 29 - .../extensions/IERC721MetadataUpgradeable.sol | 27 - .../draft-ERC721VotesUpgradeable.sol | 9 - ...721PresetMinterPauserAutoIdUpgradeable.sol | 165 - .../contracts/token/ERC721/presets/README.md | 1 - .../ERC721/utils/ERC721HolderUpgradeable.sol | 41 - .../token/ERC777/ERC777Upgradeable.sol | 563 - .../ERC777/IERC777RecipientUpgradeable.sol | 35 - .../token/ERC777/IERC777SenderUpgradeable.sol | 35 - .../token/ERC777/IERC777Upgradeable.sol | 209 - .../contracts/token/ERC777/README.adoc | 30 - .../ERC777PresetFixedSupplyUpgradeable.sol | 58 - .../token/common/ERC2981Upgradeable.sol | 124 - .../contracts/token/common/README.adoc | 10 - .../contracts/utils/AddressUpgradeable.sol | 219 - .../contracts/utils/ArraysUpgradeable.sol | 96 - .../contracts/utils/Base64Upgradeable.sol | 92 - .../utils/CheckpointsUpgradeable.sol | 554 - .../contracts/utils/ContextUpgradeable.sol | 37 - .../contracts/utils/CountersUpgradeable.sol | 43 - .../contracts/utils/Create2Upgradeable.sol | 83 - .../contracts/utils/MulticallUpgradeable.sol | 51 - .../contracts/utils/README.adoc | 111 - .../utils/StorageSlotUpgradeable.sol | 88 - .../contracts/utils/StringsUpgradeable.sol | 70 - .../contracts/utils/TimersUpgradeable.sol | 73 - .../utils/cryptography/ECDSAUpgradeable.sol | 213 - .../utils/cryptography/EIP712Upgradeable.sol | 121 - .../cryptography/MerkleProofUpgradeable.sol | 223 - .../SignatureCheckerUpgradeable.sol | 42 - .../cryptography/draft-EIP712Upgradeable.sol | 8 - .../escrow/ConditionalEscrowUpgradeable.sol | 39 - .../utils/escrow/EscrowUpgradeable.sol | 84 - .../utils/escrow/RefundEscrowUpgradeable.sol | 113 - .../ERC165CheckerUpgradeable.sol | 127 - .../ERC165StorageUpgradeable.sol | 55 - .../utils/introspection/ERC165Upgradeable.sol | 42 - .../ERC1820ImplementerUpgradeable.sol | 57 - .../introspection/IERC165Upgradeable.sol | 25 - .../IERC1820ImplementerUpgradeable.sol | 20 - .../IERC1820RegistryUpgradeable.sol | 116 - .../contracts/utils/math/MathUpgradeable.sol | 345 - .../utils/math/SafeCastUpgradeable.sol | 1136 - .../utils/math/SafeMathUpgradeable.sol | 227 - .../utils/math/SignedMathUpgradeable.sol | 43 - .../utils/math/SignedSafeMathUpgradeable.sol | 68 - .../utils/structs/BitMapsUpgradeable.sol | 55 - .../structs/DoubleEndedQueueUpgradeable.sol | 170 - .../structs/EnumerableMapUpgradeable.sol | 530 - .../structs/EnumerableSetUpgradeable.sol | 378 - .../contracts/vendor/amb/IAMBUpgradeable.sol | 49 - .../vendor/arbitrum/IArbSysUpgradeable.sol | 141 - .../vendor/arbitrum/IBridgeUpgradeable.sol | 109 - .../IDelayedMessageProviderUpgradeable.sol | 16 - .../vendor/arbitrum/IInboxUpgradeable.sol | 152 - .../vendor/arbitrum/IOutboxUpgradeable.sol | 121 - .../compound/ICompoundTimelockUpgradeable.sol | 86 - .../contracts/vendor/compound/LICENSE | 11 - .../ICrossDomainMessengerUpgradeable.sol | 38 - .../contracts/vendor/optimism/LICENSE | 22 - .../IFxMessageProcessorUpgradeable.sol | 11 - .../hardhat.config.js | 106 - .../hardhat/env-artifacts.js | 20 - .../hardhat/env-contract.js | 10 - .../hardhat/ignore-unreachable-warnings.js | 47 - .../hardhat/skip-foundry-tests.js | 7 - .../hardhat/task-get-compiler-input.js | 10 - .../hardhat/task-test-get-files.js | 19 - .../icon.svg | 13 - .../lib/forge-std/.github/workflows/ci.yml | 92 - .../lib/forge-std/.gitignore | 4 - .../lib/forge-std/.gitmodules | 3 - .../lib/forge-std/LICENSE-APACHE | 203 - .../lib/forge-std/LICENSE-MIT | 25 - .../lib/forge-std/README.md | 250 - .../lib/forge-std/foundry.toml | 21 - .../lib/ds-test/.github/workflows/build.yml | 41 - .../lib/forge-std/lib/ds-test/.gitignore | 4 - .../lib/forge-std/lib/ds-test/LICENSE | 674 - .../lib/forge-std/lib/ds-test/Makefile | 14 - .../lib/forge-std/lib/ds-test/default.nix | 4 - .../lib/forge-std/lib/ds-test/demo/demo.sol | 222 - .../lib/forge-std/lib/ds-test/package.json | 15 - .../lib/forge-std/lib/ds-test/src/test.sol | 469 - .../lib/forge-std/lib/ds-test/src/test.t.sol | 313 - .../lib/forge-std/package.json | 16 - .../lib/forge-std/src/Base.sol | 33 - .../lib/forge-std/src/Script.sol | 26 - .../lib/forge-std/src/StdAssertions.sol | 376 - .../lib/forge-std/src/StdChains.sol | 233 - .../lib/forge-std/src/StdCheats.sol | 624 - .../lib/forge-std/src/StdError.sol | 15 - .../lib/forge-std/src/StdInvariant.sol | 92 - .../lib/forge-std/src/StdJson.sol | 179 - .../lib/forge-std/src/StdMath.sol | 43 - .../lib/forge-std/src/StdStorage.sol | 327 - .../lib/forge-std/src/StdStyle.sol | 333 - .../lib/forge-std/src/StdUtils.sol | 189 - .../lib/forge-std/src/Test.sol | 32 - .../lib/forge-std/src/Vm.sol | 409 - .../lib/forge-std/src/console.sol | 1533 - .../lib/forge-std/src/console2.sol | 1546 - .../lib/forge-std/src/interfaces/IERC1155.sol | 105 - .../lib/forge-std/src/interfaces/IERC165.sol | 12 - .../lib/forge-std/src/interfaces/IERC20.sol | 43 - .../lib/forge-std/src/interfaces/IERC4626.sol | 190 - .../lib/forge-std/src/interfaces/IERC721.sol | 164 - .../forge-std/src/interfaces/IMulticall3.sol | 73 - .../lib/forge-std/test/StdAssertions.t.sol | 954 - .../lib/forge-std/test/StdChains.t.sol | 160 - .../lib/forge-std/test/StdCheats.t.sol | 401 - .../lib/forge-std/test/StdError.t.sol | 118 - .../lib/forge-std/test/StdMath.t.sol | 197 - .../lib/forge-std/test/StdStorage.t.sol | 283 - .../lib/forge-std/test/StdStyle.t.sol | 110 - .../lib/forge-std/test/StdUtils.t.sol | 297 - .../test/compilation/CompilationScript.sol | 10 - .../compilation/CompilationScriptBase.sol | 10 - .../test/compilation/CompilationTest.sol | 10 - .../test/compilation/CompilationTestBase.sol | 10 - .../test/fixtures/broadcast.log.json | 187 - .../logo.svg | 15 - .../netlify.toml | 3 - .../package-lock.json | 28620 ---------- .../package.json | 93 - .../renovate.json | 11 - .../scripts/checks/compareGasReports.js | 211 - .../scripts/checks/generation.sh | 6 - .../scripts/checks/inheritance-ordering.js | 50 - .../scripts/gen-nav.js | 41 - .../scripts/generate/format-lines.js | 16 - .../scripts/generate/run.js | 46 - .../scripts/generate/templates/Checkpoints.js | 303 - .../generate/templates/CheckpointsMock.js | 80 - .../generate/templates/EnumerableMap.js | 278 - .../generate/templates/EnumerableMapMock.js | 66 - .../generate/templates/EnumerableSet.js | 253 - .../generate/templates/EnumerableSetMock.js | 56 - .../scripts/generate/templates/SafeCast.js | 168 - .../generate/templates/SafeCastMock.js | 50 - .../scripts/generate/templates/conversion.js | 30 - .../scripts/git-user-config.sh | 6 - .../scripts/helpers.js | 23 - .../scripts/migrate-imports.js | 177 - .../scripts/prepack.sh | 12 - .../scripts/prepare-contracts-package.sh | 15 - .../scripts/prepare-docs.sh | 15 - .../scripts/prepare.sh | 10 - .../scripts/release/release.sh | 145 - .../scripts/release/synchronize-versions.js | 16 - .../release/update-changelog-release-date.js | 34 - .../scripts/release/update-comment.js | 36 - .../scripts/release/version.sh | 9 - .../scripts/remove-ignored-artifacts.js | 45 - .../scripts/update-docs-branch.js | 55 - .../scripts/upgradeable/git-user-config.sh | 6 - .../scripts/upgradeable/merge-upstream.sh | 33 - .../scripts/upgradeable/patch/.gitkeep | 0 .../scripts/upgradeable/transpile-onto.sh | 38 - .../scripts/upgradeable/transpile.sh | 34 - .../slither.config.json | 5 - .../test/TESTING.md | 3 - .../test/access/AccessControl.behavior.js | 216 - .../test/access/AccessControl.test.js | 13 - .../access/AccessControlCrossChain.test.js | 59 - .../access/AccessControlEnumerable.test.js | 15 - .../test/access/Ownable.test.js | 57 - .../test/access/Ownable2Step.test.js | 57 - .../test/crosschain/CrossChainEnabled.test.js | 88 - .../test/finance/PaymentSplitter.test.js | 217 - .../test/finance/VestingWallet.behavior.js | 74 - .../test/finance/VestingWallet.test.js | 67 - .../test/governance/Governor.test.js | 632 - .../governance/TimelockController.test.js | 1134 - .../GovernorCompatibilityBravo.test.js | 280 - .../extensions/GovernorComp.test.js | 78 - .../extensions/GovernorERC721.test.js | 104 - .../GovernorPreventLateQuorum.test.js | 177 - .../GovernorTimelockCompound.test.js | 368 - .../GovernorTimelockControl.test.js | 420 - .../GovernorVotesQuorumFraction.test.js | 137 - .../extensions/GovernorWithParams.test.js | 166 - .../test/governance/utils/Votes.behavior.js | 344 - .../test/governance/utils/Votes.test.js | 61 - .../test/helpers/create2.js | 12 - .../test/helpers/crosschain.js | 63 - .../test/helpers/customError.js | 24 - .../test/helpers/eip712.js | 30 - .../test/helpers/enums.js | 29 - .../test/helpers/erc1967.js | 24 - .../test/helpers/governance.js | 211 - .../test/helpers/sign.js | 47 - .../test/helpers/txpool.js | 40 - .../test/metatx/ERC2771Context.test.js | 109 - .../test/metatx/MinimalForwarder.test.js | 184 - .../test/migrate-imports.test.js | 29 - .../test/proxy/Clones.behaviour.js | 150 - .../test/proxy/Clones.test.js | 69 - .../test/proxy/ERC1967/ERC1967Proxy.test.js | 13 - .../test/proxy/Proxy.behaviour.js | 224 - .../test/proxy/beacon/BeaconProxy.test.js | 156 - .../proxy/beacon/UpgradeableBeacon.test.js | 50 - .../test/proxy/transparent/ProxyAdmin.test.js | 127 - .../TransparentUpgradeableProxy.behaviour.js | 440 - .../TransparentUpgradeableProxy.test.js | 17 - .../test/proxy/utils/Initializable.test.js | 218 - .../test/proxy/utils/UUPSUpgradeable.test.js | 85 - .../test/security/Pausable.test.js | 89 - .../test/security/PullPayment.test.js | 51 - .../test/security/ReentrancyGuard.test.js | 40 - .../test/token/ERC1155/ERC1155.behavior.js | 774 - .../test/token/ERC1155/ERC1155.test.js | 264 - .../extensions/ERC1155Burnable.test.js | 67 - .../extensions/ERC1155Pausable.test.js | 108 - .../ERC1155/extensions/ERC1155Supply.test.js | 111 - .../extensions/ERC1155URIStorage.test.js | 66 - .../presets/ERC1155PresetMinterPauser.test.js | 146 - .../token/ERC1155/utils/ERC1155Holder.test.js | 62 - .../test/token/ERC20/ERC20.behavior.js | 333 - .../test/token/ERC20/ERC20.test.js | 309 - .../extensions/ERC20Burnable.behavior.js | 109 - .../ERC20/extensions/ERC20Burnable.test.js | 19 - .../ERC20/extensions/ERC20Capped.behavior.js | 32 - .../ERC20/extensions/ERC20Capped.test.js | 27 - .../ERC20/extensions/ERC20FlashMint.test.js | 144 - .../ERC20/extensions/ERC20Pausable.test.js | 134 - .../ERC20/extensions/ERC20Snapshot.test.js | 204 - .../token/ERC20/extensions/ERC20Votes.test.js | 518 - .../ERC20/extensions/ERC20VotesComp.test.js | 496 - .../ERC20/extensions/ERC20Wrapper.test.js | 190 - .../token/ERC20/extensions/ERC4626.test.js | 622 - .../extensions/draft-ERC20Permit.test.js | 109 - .../presets/ERC20PresetFixedSupply.test.js | 42 - .../presets/ERC20PresetMinterPauser.test.js | 113 - .../test/token/ERC20/utils/SafeERC20.test.js | 255 - .../token/ERC20/utils/TokenTimelock.test.js | 71 - .../test/token/ERC721/ERC721.behavior.js | 937 - .../test/token/ERC721/ERC721.test.js | 18 - .../token/ERC721/ERC721Enumerable.test.js | 20 - .../ERC721/extensions/ERC721Burnable.test.js | 78 - .../ERC721/extensions/ERC721Consecutive.t.sol | 120 - .../extensions/ERC721Consecutive.test.js | 212 - .../ERC721/extensions/ERC721Pausable.test.js | 98 - .../ERC721/extensions/ERC721Royalty.test.js | 40 - .../extensions/ERC721URIStorage.test.js | 96 - .../ERC721/extensions/ERC721Votes.test.js | 174 - .../ERC721PresetMinterPauserAutoId.test.js | 125 - .../token/ERC721/utils/ERC721Holder.test.js | 24 - .../test/token/ERC777/ERC777.behavior.js | 555 - .../test/token/ERC777/ERC777.test.js | 610 - .../presets/ERC777PresetFixedSupply.test.js | 49 - .../test/token/common/ERC2981.behavior.js | 160 - .../test/utils/Address.test.js | 382 - .../test/utils/Arrays.test.js | 105 - .../test/utils/Base64.test.js | 33 - .../test/utils/Checkpoints.test.js | 189 - .../test/utils/Context.behavior.js | 42 - .../test/utils/Context.test.js | 17 - .../test/utils/Counters.test.js | 84 - .../test/utils/Create2.test.js | 92 - .../test/utils/Multicall.test.js | 57 - .../test/utils/StorageSlot.test.js | 110 - .../test/utils/Strings.test.js | 86 - .../test/utils/TimersBlockNumberImpl.test.js | 55 - .../test/utils/TimersTimestamp.test.js | 55 - .../test/utils/cryptography/ECDSA.test.js | 204 - .../test/utils/cryptography/EIP712.test.js | 57 - .../utils/cryptography/MerkleProof.test.js | 179 - .../cryptography/SignatureChecker.test.js | 81 - .../utils/escrow/ConditionalEscrow.test.js | 36 - .../test/utils/escrow/Escrow.behavior.js | 94 - .../test/utils/escrow/Escrow.test.js | 14 - .../test/utils/escrow/RefundEscrow.test.js | 148 - .../test/utils/introspection/ERC165.test.js | 13 - .../utils/introspection/ERC165Checker.test.js | 303 - .../utils/introspection/ERC165Storage.test.js | 25 - .../introspection/ERC1820Implementer.test.js | 66 - .../SupportsInterface.behavior.js | 147 - .../test/utils/math/Math.t.sol | 118 - .../test/utils/math/Math.test.js | 312 - .../test/utils/math/SafeCast.test.js | 164 - .../test/utils/math/SafeMath.test.js | 403 - .../test/utils/math/SignedMath.test.js | 93 - .../test/utils/math/SignedSafeMath.test.js | 152 - .../test/utils/structs/BitMap.test.js | 145 - .../utils/structs/DoubleEndedQueue.test.js | 96 - .../utils/structs/EnumerableMap.behavior.js | 181 - .../test/utils/structs/EnumerableMap.test.js | 86 - .../utils/structs/EnumerableSet.behavior.js | 131 - .../test/utils/structs/EnumerableSet.test.js | 46 - .../lib/openzeppelin-contracts/.codecov.yml | 11 - .../lib/openzeppelin-contracts/.editorconfig | 21 - .../lib/openzeppelin-contracts/.eslintrc | 62 - .../lib/openzeppelin-contracts/.gitattributes | 1 - .../.github/ISSUE_TEMPLATE/bug_report.md | 21 - .../.github/ISSUE_TEMPLATE/config.yml | 4 - .../.github/ISSUE_TEMPLATE/feature_request.md | 14 - .../.github/PULL_REQUEST_TEMPLATE.md | 20 - .../.github/actions/gas-compare/action.yml | 49 - .../.github/actions/setup/action.yml | 20 - .../.github/workflows/checks.yml | 65 - .../.github/workflows/docs.yml | 16 - .../.github/workflows/upgradeable.yml | 23 - .../lib/openzeppelin-contracts/.gitignore | 64 - .../lib/openzeppelin-contracts/.mocharc.js | 4 - .../lib/openzeppelin-contracts/.prettierrc | 14 - .../lib/openzeppelin-contracts/.solcover.js | 15 - .../lib/openzeppelin-contracts/.solhint.json | 14 - .../lib/openzeppelin-contracts/CHANGELOG.md | 532 - .../openzeppelin-contracts/CODE_OF_CONDUCT.md | 73 - .../openzeppelin-contracts/CONTRIBUTING.md | 64 - .../openzeppelin-contracts/DOCUMENTATION.md | 16 - .../lib/openzeppelin-contracts/GUIDELINES.md | 105 - .../lib/openzeppelin-contracts/LICENSE | 22 - .../lib/openzeppelin-contracts/README.md | 84 - .../lib/openzeppelin-contracts/RELEASING.md | 36 - .../lib/openzeppelin-contracts/SECURITY.md | 20 - .../openzeppelin-contracts/audit/2017-03.md | 292 - .../openzeppelin-contracts/audit/2018-10.pdf | Bin 1000527 -> 0 bytes .../openzeppelin-contracts/certora/Makefile | 24 - .../openzeppelin-contracts/certora/README.md | 56 - .../certora/applyHarness.patch | 101 - .../certora/harnesses/ERC20VotesHarness.sol | 28 - .../harnesses/WizardControlFirstPriority.sol | 150 - .../certora/harnesses/WizardFirstTry.sol | 141 - .../certora/munged/.gitignore | 2 - .../certora/scripts/Governor.sh | 10 - .../GovernorCountingSimple-counting.sh | 10 - .../scripts/WizardControlFirstPriority.sh | 12 - .../certora/scripts/WizardFirstTry.sh | 10 - .../certora/scripts/sanity.sh | 14 - .../certora/scripts/verifyAll.sh | 39 - .../certora/specs/GovernorBase.spec | 334 - .../certora/specs/GovernorCountingSimple.spec | 221 - .../certora/specs/RulesInProgress.spec | 139 - .../certora/specs/sanity.spec | 14 - .../contracts/access/AccessControl.sol | 247 - .../access/AccessControlCrossChain.sol | 45 - .../access/AccessControlEnumerable.sol | 64 - .../contracts/access/IAccessControl.sol | 88 - .../access/IAccessControlEnumerable.sol | 31 - .../contracts/access/Ownable.sol | 83 - .../contracts/access/README.adoc | 23 - .../crosschain/CrossChainEnabled.sol | 54 - .../contracts/crosschain/README.adoc | 34 - .../crosschain/amb/CrossChainEnabledAMB.sol | 49 - .../contracts/crosschain/amb/LibAMB.sol | 35 - .../arbitrum/CrossChainEnabledArbitrumL1.sol | 44 - .../arbitrum/CrossChainEnabledArbitrumL2.sol | 35 - .../crosschain/arbitrum/LibArbitrumL1.sol | 43 - .../crosschain/arbitrum/LibArbitrumL2.sol | 43 - .../contracts/crosschain/errors.sol | 7 - .../optimism/CrossChainEnabledOptimism.sol | 41 - .../crosschain/optimism/LibOptimism.sol | 36 - .../polygon/CrossChainEnabledPolygonChild.sol | 72 - .../contracts/finance/PaymentSplitter.sol | 214 - .../contracts/finance/README.adoc | 20 - .../contracts/finance/VestingWallet.sol | 135 - .../contracts/governance/Governor.sol | 596 - .../contracts/governance/IGovernor.sol | 276 - .../contracts/governance/README.adoc | 176 - .../governance/TimelockController.sol | 417 - .../GovernorCompatibilityBravo.sol | 285 - .../IGovernorCompatibilityBravo.sol | 114 - .../extensions/GovernorCountingSimple.sol | 107 - .../extensions/GovernorPreventLateQuorum.sol | 108 - .../extensions/GovernorProposalThreshold.sol | 23 - .../extensions/GovernorSettings.sol | 114 - .../extensions/GovernorTimelockCompound.sol | 193 - .../extensions/GovernorTimelockControl.sol | 166 - .../governance/extensions/GovernorVotes.sol | 31 - .../extensions/GovernorVotesComp.sol | 31 - .../GovernorVotesQuorumFraction.sol | 85 - .../extensions/IGovernorTimelock.sol | 26 - .../contracts/governance/utils/IVotes.sol | 61 - .../contracts/governance/utils/Votes.sol | 211 - .../contracts/interfaces/IERC1155.sol | 6 - .../interfaces/IERC1155MetadataURI.sol | 6 - .../contracts/interfaces/IERC1155Receiver.sol | 6 - .../contracts/interfaces/IERC1271.sol | 19 - .../contracts/interfaces/IERC1363.sol | 95 - .../contracts/interfaces/IERC1363Receiver.sol | 32 - .../contracts/interfaces/IERC1363Spender.sol | 30 - .../contracts/interfaces/IERC165.sol | 6 - .../interfaces/IERC1820Implementer.sol | 6 - .../contracts/interfaces/IERC1820Registry.sol | 6 - .../contracts/interfaces/IERC20.sol | 6 - .../contracts/interfaces/IERC20Metadata.sol | 6 - .../contracts/interfaces/IERC2981.sol | 25 - .../contracts/interfaces/IERC3156.sol | 7 - .../interfaces/IERC3156FlashBorrower.sol | 29 - .../interfaces/IERC3156FlashLender.sol | 43 - .../contracts/interfaces/IERC4626.sol | 240 - .../contracts/interfaces/IERC721.sol | 6 - .../interfaces/IERC721Enumerable.sol | 6 - .../contracts/interfaces/IERC721Metadata.sol | 6 - .../contracts/interfaces/IERC721Receiver.sol | 6 - .../contracts/interfaces/IERC777.sol | 6 - .../contracts/interfaces/IERC777Recipient.sol | 6 - .../contracts/interfaces/IERC777Sender.sol | 6 - .../contracts/interfaces/README.adoc | 50 - .../contracts/interfaces/draft-IERC1822.sol | 20 - .../contracts/interfaces/draft-IERC2612.sol | 8 - .../contracts/metatx/ERC2771Context.sol | 43 - .../contracts/metatx/MinimalForwarder.sol | 73 - .../contracts/metatx/README.adoc | 12 - .../mocks/AccessControlCrossChainMock.sol | 22 - .../mocks/AccessControlEnumerableMock.sol | 17 - .../contracts/mocks/AccessControlMock.sol | 17 - .../contracts/mocks/AddressImpl.sol | 46 - .../contracts/mocks/ArraysImpl.sol | 19 - .../contracts/mocks/BadBeacon.sol | 11 - .../contracts/mocks/Base64Mock.sol | 11 - .../contracts/mocks/BitmapMock.sol | 27 - .../contracts/mocks/CallReceiverMock.sol | 57 - .../contracts/mocks/CheckpointsImpl.sol | 27 - .../mocks/ClashingImplementation.sol | 18 - .../contracts/mocks/ClonesMock.sol | 36 - .../contracts/mocks/ConditionalEscrowMock.sol | 18 - .../contracts/mocks/ContextMock.sol | 33 - .../contracts/mocks/CountersImpl.sol | 27 - .../contracts/mocks/Create2Impl.sol | 34 - .../contracts/mocks/DoubleEndedQueueMock.sol | 58 - .../contracts/mocks/DummyImplementation.sol | 61 - .../contracts/mocks/ECDSAMock.sol | 41 - .../contracts/mocks/EIP712External.sol | 31 - .../contracts/mocks/ERC1155BurnableMock.sol | 18 - .../contracts/mocks/ERC1155Mock.sol | 51 - .../contracts/mocks/ERC1155PausableMock.sol | 29 - .../contracts/mocks/ERC1155ReceiverMock.sol | 52 - .../contracts/mocks/ERC1155SupplyMock.sol | 21 - .../contracts/mocks/ERC1155URIStorageMock.sol | 22 - .../contracts/mocks/ERC1271WalletMock.sol | 26 - .../ERC165/ERC165InterfacesSupported.sol | 58 - .../mocks/ERC165/ERC165MaliciousData.sol | 12 - .../mocks/ERC165/ERC165MissingData.sol | 7 - .../mocks/ERC165/ERC165NotSupported.sol | 5 - .../contracts/mocks/ERC165CheckerMock.sol | 29 - .../contracts/mocks/ERC165Mock.sol | 7 - .../contracts/mocks/ERC165StorageMock.sol | 11 - .../mocks/ERC1820ImplementerMock.sol | 11 - .../contracts/mocks/ERC20BurnableMock.sol | 16 - .../contracts/mocks/ERC20CappedMock.sol | 17 - .../contracts/mocks/ERC20DecimalsMock.sol | 29 - .../contracts/mocks/ERC20FlashMintMock.sol | 44 - .../contracts/mocks/ERC20Mock.sol | 41 - .../contracts/mocks/ERC20PausableMock.sol | 33 - .../contracts/mocks/ERC20PermitMock.sol | 20 - .../contracts/mocks/ERC20SnapshotMock.sol | 28 - .../contracts/mocks/ERC20VotesCompMock.sol | 21 - .../contracts/mocks/ERC20VotesMock.sol | 21 - .../contracts/mocks/ERC20WrapperMock.sol | 17 - .../contracts/mocks/ERC2771ContextMock.sol | 22 - .../mocks/ERC3156FlashBorrowerMock.sol | 53 - .../contracts/mocks/ERC4626Mock.sol | 22 - .../contracts/mocks/ERC721BurnableMock.sol | 29 - .../contracts/mocks/ERC721EnumerableMock.sol | 51 - .../contracts/mocks/ERC721Mock.sol | 41 - .../contracts/mocks/ERC721PausableMock.sol | 45 - .../contracts/mocks/ERC721ReceiverMock.sol | 42 - .../contracts/mocks/ERC721RoyaltyMock.sol | 33 - .../contracts/mocks/ERC721URIStorageMock.sol | 55 - .../contracts/mocks/ERC721VotesMock.sol | 25 - .../contracts/mocks/ERC777Mock.sol | 56 - .../mocks/ERC777SenderRecipientMock.sol | 161 - .../contracts/mocks/EnumerableMapMock.sol | 219 - .../contracts/mocks/EnumerableSetMock.sol | 110 - .../contracts/mocks/EtherReceiverMock.sol | 17 - .../contracts/mocks/GovernorCompMock.sol | 31 - .../mocks/GovernorCompatibilityBravoMock.sol | 130 - .../contracts/mocks/GovernorMock.sol | 50 - .../mocks/GovernorPreventLateQuorumMock.sol | 61 - .../mocks/GovernorTimelockCompoundMock.sol | 98 - .../mocks/GovernorTimelockControlMock.sol | 100 - .../contracts/mocks/GovernorVoteMock.sol | 31 - .../mocks/GovernorWithParamsMock.sol | 61 - .../contracts/mocks/InitializableMock.sol | 122 - .../contracts/mocks/MathMock.sol | 36 - .../contracts/mocks/MerkleProofWrapper.sol | 65 - .../contracts/mocks/MulticallTest.sol | 23 - .../contracts/mocks/MulticallTokenMock.sol | 10 - .../MultipleInheritanceInitializableMocks.sol | 136 - .../contracts/mocks/OwnableMock.sol | 7 - .../contracts/mocks/PausableMock.sol | 31 - .../contracts/mocks/PullPaymentMock.sol | 15 - .../contracts/mocks/ReentrancyAttack.sol | 12 - .../contracts/mocks/ReentrancyMock.sol | 43 - .../mocks/RegressionImplementation.sol | 61 - .../contracts/mocks/SafeCastMock.sol | 266 - .../contracts/mocks/SafeERC20Helper.sol | 194 - .../contracts/mocks/SafeMathMock.sol | 138 - .../contracts/mocks/SignatureCheckerMock.sol | 17 - .../contracts/mocks/SignedMathMock.sol | 23 - .../contracts/mocks/SignedSafeMathMock.sol | 23 - .../SingleInheritanceInitializableMocks.sol | 49 - .../contracts/mocks/StorageSlotMock.sol | 41 - .../contracts/mocks/StringsMock.sol | 23 - .../contracts/mocks/TimersBlockNumberImpl.sol | 39 - .../contracts/mocks/TimersTimestampImpl.sol | 39 - .../contracts/mocks/UUPS/UUPSLegacy.sol | 58 - .../mocks/UUPS/UUPSUpgradeableMock.sol | 21 - .../contracts/mocks/VotesMock.sol | 40 - .../contracts/mocks/compound/CompTimelock.sol | 174 - .../contracts/mocks/crosschain/bridges.sol | 106 - .../contracts/mocks/crosschain/receivers.sol | 54 - .../contracts/mocks/wizard/MyGovernor1.sol | 87 - .../contracts/mocks/wizard/MyGovernor2.sol | 93 - .../contracts/mocks/wizard/MyGovernor3.sol | 96 - .../contracts/package.json | 32 - .../contracts/proxy/Clones.sol | 87 - .../contracts/proxy/ERC1967/ERC1967Proxy.sol | 32 - .../proxy/ERC1967/ERC1967Upgrade.sol | 185 - .../contracts/proxy/Proxy.sol | 86 - .../contracts/proxy/README.adoc | 85 - .../contracts/proxy/beacon/BeaconProxy.sol | 61 - .../contracts/proxy/beacon/IBeacon.sol | 16 - .../proxy/beacon/UpgradeableBeacon.sol | 65 - .../proxy/transparent/ProxyAdmin.sol | 81 - .../TransparentUpgradeableProxy.sol | 124 - .../contracts/proxy/utils/Initializable.sol | 138 - .../contracts/proxy/utils/UUPSUpgradeable.sol | 95 - .../contracts/security/Pausable.sol | 105 - .../contracts/security/PullPayment.sol | 74 - .../contracts/security/README.adoc | 20 - .../contracts/security/ReentrancyGuard.sol | 69 - .../contracts/token/ERC1155/ERC1155.sol | 517 - .../contracts/token/ERC1155/IERC1155.sol | 125 - .../token/ERC1155/IERC1155Receiver.sol | 58 - .../contracts/token/ERC1155/README.adoc | 49 - .../ERC1155/extensions/ERC1155Burnable.sol | 40 - .../ERC1155/extensions/ERC1155Pausable.sol | 38 - .../ERC1155/extensions/ERC1155Supply.sol | 64 - .../ERC1155/extensions/ERC1155URIStorage.sol | 63 - .../extensions/IERC1155MetadataURI.sol | 22 - .../presets/ERC1155PresetMinterPauser.sol | 128 - .../contracts/token/ERC1155/presets/README.md | 1 - .../token/ERC1155/utils/ERC1155Holder.sol | 36 - .../token/ERC1155/utils/ERC1155Receiver.sol | 19 - .../contracts/token/ERC20/ERC20.sol | 389 - .../contracts/token/ERC20/IERC20.sol | 82 - .../contracts/token/ERC20/README.adoc | 86 - .../token/ERC20/extensions/ERC20Burnable.sol | 39 - .../token/ERC20/extensions/ERC20Capped.sol | 37 - .../token/ERC20/extensions/ERC20FlashMint.sol | 96 - .../token/ERC20/extensions/ERC20Pausable.sol | 33 - .../token/ERC20/extensions/ERC20Snapshot.sol | 195 - .../token/ERC20/extensions/ERC20Votes.sol | 249 - .../token/ERC20/extensions/ERC20VotesComp.sol | 46 - .../token/ERC20/extensions/ERC20Wrapper.sol | 63 - .../token/ERC20/extensions/ERC4626.sol | 222 - .../token/ERC20/extensions/IERC20Metadata.sol | 28 - .../ERC20/extensions/draft-ERC20Permit.sol | 95 - .../ERC20/extensions/draft-IERC20Permit.sol | 60 - .../ERC20/presets/ERC20PresetFixedSupply.sol | 35 - .../ERC20/presets/ERC20PresetMinterPauser.sol | 94 - .../contracts/token/ERC20/presets/README.md | 1 - .../contracts/token/ERC20/utils/SafeERC20.sol | 116 - .../token/ERC20/utils/TokenTimelock.sol | 76 - .../contracts/token/ERC721/ERC721.sol | 454 - .../contracts/token/ERC721/IERC721.sol | 143 - .../token/ERC721/IERC721Receiver.sol | 27 - .../contracts/token/ERC721/README.adoc | 67 - .../ERC721/extensions/ERC721Burnable.sol | 26 - .../ERC721/extensions/ERC721Enumerable.sol | 163 - .../ERC721/extensions/ERC721Pausable.sol | 33 - .../token/ERC721/extensions/ERC721Royalty.sol | 38 - .../ERC721/extensions/ERC721URIStorage.sol | 62 - .../ERC721/extensions/IERC721Enumerable.sol | 29 - .../ERC721/extensions/IERC721Metadata.sol | 27 - .../ERC721/extensions/draft-ERC721Votes.sol | 40 - .../ERC721PresetMinterPauserAutoId.sol | 139 - .../contracts/token/ERC721/presets/README.md | 1 - .../token/ERC721/utils/ERC721Holder.sol | 28 - .../contracts/token/ERC777/ERC777.sol | 547 - .../contracts/token/ERC777/IERC777.sol | 209 - .../token/ERC777/IERC777Recipient.sol | 35 - .../contracts/token/ERC777/IERC777Sender.sol | 35 - .../contracts/token/ERC777/README.adoc | 30 - .../presets/ERC777PresetFixedSupply.sol | 30 - .../contracts/token/common/ERC2981.sol | 111 - .../contracts/token/common/README.adoc | 10 - .../contracts/utils/Address.sol | 244 - .../contracts/utils/Arrays.sol | 48 - .../contracts/utils/Base64.sol | 92 - .../contracts/utils/Checkpoints.sol | 86 - .../contracts/utils/Context.sol | 24 - .../contracts/utils/Counters.sol | 43 - .../contracts/utils/Create2.sol | 66 - .../contracts/utils/Multicall.sol | 24 - .../contracts/utils/README.adoc | 111 - .../contracts/utils/StorageSlot.sol | 88 - .../contracts/utils/Strings.sol | 75 - .../contracts/utils/Timers.sol | 73 - .../contracts/utils/cryptography/ECDSA.sol | 232 - .../utils/cryptography/MerkleProof.sol | 212 - .../utils/cryptography/SignatureChecker.sol | 42 - .../utils/cryptography/draft-EIP712.sol | 104 - .../utils/escrow/ConditionalEscrow.sol | 25 - .../contracts/utils/escrow/Escrow.sol | 67 - .../contracts/utils/escrow/RefundEscrow.sol | 100 - .../contracts/utils/introspection/ERC165.sol | 29 - .../utils/introspection/ERC165Checker.sol | 113 - .../utils/introspection/ERC165Storage.sol | 42 - .../introspection/ERC1820Implementer.sol | 44 - .../contracts/utils/introspection/IERC165.sol | 25 - .../introspection/IERC1820Implementer.sol | 20 - .../utils/introspection/IERC1820Registry.sol | 116 - .../contracts/utils/math/Math.sol | 226 - .../contracts/utils/math/SafeCast.sol | 1135 - .../contracts/utils/math/SafeMath.sol | 227 - .../contracts/utils/math/SignedMath.sol | 43 - .../contracts/utils/math/SignedSafeMath.sol | 68 - .../contracts/utils/structs/BitMaps.sol | 55 - .../utils/structs/DoubleEndedQueue.sol | 170 - .../contracts/utils/structs/EnumerableMap.sol | 529 - .../contracts/utils/structs/EnumerableSet.sol | 367 - .../contracts/vendor/amb/IAMB.sol | 49 - .../contracts/vendor/arbitrum/IArbSys.sol | 99 - .../contracts/vendor/arbitrum/IBridge.sol | 66 - .../contracts/vendor/arbitrum/IInbox.sol | 92 - .../vendor/arbitrum/IMessageProvider.sol | 26 - .../contracts/vendor/arbitrum/IOutbox.sol | 51 - .../vendor/compound/ICompoundTimelock.sol | 86 - .../contracts/vendor/compound/LICENSE | 11 - .../vendor/optimism/ICrossDomainMessenger.sol | 38 - .../contracts/vendor/optimism/LICENSE | 22 - .../vendor/polygon/IFxMessageProcessor.sol | 11 - .../openzeppelin-contracts/hardhat.config.js | 95 - .../hardhat/env-contract.js | 10 - .../lib/openzeppelin-contracts/logo.svg | 15 - .../migrations/.gitkeep | 0 .../lib/openzeppelin-contracts/netlify.toml | 3 - .../openzeppelin-contracts/package-lock.json | 32840 ------------ .../lib/openzeppelin-contracts/package.json | 89 - .../lib/openzeppelin-contracts/renovate.json | 11 - .../scripts/checks/compareGasReports.js | 189 - .../scripts/checks/generation.sh | 6 - .../scripts/checks/inheritance-ordering.js | 50 - .../openzeppelin-contracts/scripts/gen-nav.js | 43 - .../scripts/generate/format-lines.js | 16 - .../scripts/generate/run.js | 29 - .../scripts/generate/templates/SafeCast.js | 168 - .../generate/templates/SafeCastMock.js | 50 - .../scripts/git-user-config.sh | 6 - .../openzeppelin-contracts/scripts/helpers.js | 23 - .../scripts/migrate-imports.js | 177 - .../openzeppelin-contracts/scripts/prepack.sh | 12 - .../scripts/prepare-contracts-package.sh | 15 - .../scripts/prepare-docs-solc.js | 16 - .../scripts/prepare-docs.sh | 23 - .../openzeppelin-contracts/scripts/prepare.sh | 10 - .../scripts/release/release.sh | 145 - .../scripts/release/synchronize-versions.js | 16 - .../release/update-changelog-release-date.js | 34 - .../scripts/release/update-comment.js | 36 - .../scripts/release/version.sh | 9 - .../scripts/remove-ignored-artifacts.js | 45 - .../scripts/update-docs-branch.js | 55 - .../slither.config.json | 4 - .../openzeppelin-contracts/test/TESTING.md | 3 - .../test/access/AccessControl.behavior.js | 216 - .../test/access/AccessControl.test.js | 13 - .../access/AccessControlCrossChain.test.js | 59 - .../access/AccessControlEnumerable.test.js | 15 - .../test/access/Ownable.test.js | 57 - .../test/crosschain/CrossChainEnabled.test.js | 88 - .../test/finance/PaymentSplitter.test.js | 217 - .../test/finance/VestingWallet.behavior.js | 72 - .../test/finance/VestingWallet.test.js | 67 - .../test/governance/Governor.test.js | 632 - .../governance/TimelockController.test.js | 1121 - .../GovernorCompatibilityBravo.test.js | 265 - .../extensions/GovernorComp.test.js | 78 - .../extensions/GovernorERC721.test.js | 104 - .../GovernorPreventLateQuorum.test.js | 177 - .../GovernorTimelockCompound.test.js | 368 - .../GovernorTimelockControl.test.js | 382 - .../GovernorWeightQuorumFraction.test.js | 130 - .../extensions/GovernorWithParams.test.js | 166 - .../test/governance/utils/Votes.behavior.js | 344 - .../test/governance/utils/Votes.test.js | 61 - .../test/helpers/create2.js | 12 - .../test/helpers/crosschain.js | 63 - .../test/helpers/customError.js | 24 - .../test/helpers/eip712.js | 30 - .../test/helpers/enums.js | 29 - .../test/helpers/erc1967.js | 24 - .../test/helpers/governance.js | 211 - .../test/helpers/sign.js | 47 - .../test/helpers/txpool.js | 40 - .../test/metatx/ERC2771Context.test.js | 109 - .../test/metatx/MinimalForwarder.test.js | 184 - .../test/migrate-imports.test.js | 29 - .../test/proxy/Clones.behaviour.js | 150 - .../test/proxy/Clones.test.js | 69 - .../test/proxy/ERC1967/ERC1967Proxy.test.js | 13 - .../test/proxy/Proxy.behaviour.js | 224 - .../test/proxy/beacon/BeaconProxy.test.js | 156 - .../proxy/beacon/UpgradeableBeacon.test.js | 50 - .../test/proxy/transparent/ProxyAdmin.test.js | 125 - .../TransparentUpgradeableProxy.behaviour.js | 431 - .../TransparentUpgradeableProxy.test.js | 15 - .../test/proxy/utils/Initializable.test.js | 203 - .../test/proxy/utils/UUPSUpgradeable.test.js | 85 - .../test/security/Pausable.test.js | 89 - .../test/security/PullPayment.test.js | 51 - .../test/security/ReentrancyGuard.test.js | 40 - .../test/token/ERC1155/ERC1155.behavior.js | 774 - .../test/token/ERC1155/ERC1155.test.js | 264 - .../extensions/ERC1155Burnable.test.js | 67 - .../extensions/ERC1155Pausable.test.js | 108 - .../ERC1155/extensions/ERC1155Supply.test.js | 111 - .../extensions/ERC1155URIStorage.test.js | 66 - .../presets/ERC1155PresetMinterPauser.test.js | 146 - .../token/ERC1155/utils/ERC1155Holder.test.js | 62 - .../test/token/ERC20/ERC20.behavior.js | 333 - .../test/token/ERC20/ERC20.test.js | 309 - .../extensions/ERC20Burnable.behavior.js | 109 - .../ERC20/extensions/ERC20Burnable.test.js | 19 - .../ERC20/extensions/ERC20Capped.behavior.js | 32 - .../ERC20/extensions/ERC20Capped.test.js | 27 - .../ERC20/extensions/ERC20FlashMint.test.js | 144 - .../ERC20/extensions/ERC20Pausable.test.js | 134 - .../ERC20/extensions/ERC20Snapshot.test.js | 204 - .../token/ERC20/extensions/ERC20Votes.test.js | 505 - .../ERC20/extensions/ERC20VotesComp.test.js | 496 - .../ERC20/extensions/ERC20Wrapper.test.js | 190 - .../token/ERC20/extensions/ERC4626.test.js | 612 - .../extensions/draft-ERC20Permit.test.js | 109 - .../presets/ERC20PresetFixedSupply.test.js | 42 - .../presets/ERC20PresetMinterPauser.test.js | 113 - .../test/token/ERC20/utils/SafeERC20.test.js | 255 - .../token/ERC20/utils/TokenTimelock.test.js | 71 - .../test/token/ERC721/ERC721.behavior.js | 937 - .../test/token/ERC721/ERC721.test.js | 18 - .../token/ERC721/ERC721Enumerable.test.js | 20 - .../ERC721/extensions/ERC721Burnable.test.js | 78 - .../ERC721/extensions/ERC721Pausable.test.js | 98 - .../ERC721/extensions/ERC721Royalty.test.js | 40 - .../extensions/ERC721URIStorage.test.js | 96 - .../ERC721/extensions/ERC721Votes.test.js | 174 - .../ERC721PresetMinterPauserAutoId.test.js | 125 - .../token/ERC721/utils/ERC721Holder.test.js | 24 - .../test/token/ERC777/ERC777.behavior.js | 555 - .../test/token/ERC777/ERC777.test.js | 610 - .../presets/ERC777PresetFixedSupply.test.js | 49 - .../test/token/common/ERC2981.behavior.js | 160 - .../test/utils/Address.test.js | 382 - .../test/utils/Arrays.test.js | 87 - .../test/utils/Base64.test.js | 33 - .../test/utils/Checkpoints.test.js | 74 - .../test/utils/Context.behavior.js | 42 - .../test/utils/Context.test.js | 17 - .../test/utils/Counters.test.js | 84 - .../test/utils/Create2.test.js | 92 - .../test/utils/Multicall.test.js | 57 - .../test/utils/StorageSlot.test.js | 110 - .../test/utils/Strings.test.js | 71 - .../test/utils/TimersBlockNumberImpl.test.js | 55 - .../test/utils/TimersTimestamp.test.js | 55 - .../test/utils/cryptography/ECDSA.test.js | 222 - .../utils/cryptography/MerkleProof.test.js | 179 - .../cryptography/SignatureChecker.test.js | 81 - .../utils/cryptography/draft-EIP712.test.js | 57 - .../utils/escrow/ConditionalEscrow.test.js | 36 - .../test/utils/escrow/Escrow.behavior.js | 94 - .../test/utils/escrow/Escrow.test.js | 14 - .../test/utils/escrow/RefundEscrow.test.js | 148 - .../test/utils/introspection/ERC165.test.js | 13 - .../utils/introspection/ERC165Checker.test.js | 283 - .../utils/introspection/ERC165Storage.test.js | 25 - .../introspection/ERC1820Implementer.test.js | 66 - .../SupportsInterface.behavior.js | 147 - .../test/utils/math/Math.test.js | 219 - .../test/utils/math/SafeCast.test.js | 164 - .../test/utils/math/SafeMath.test.js | 403 - .../test/utils/math/SignedMath.test.js | 93 - .../test/utils/math/SignedSafeMath.test.js | 152 - .../test/utils/structs/BitMap.test.js | 145 - .../utils/structs/DoubleEndedQueue.test.js | 96 - .../utils/structs/EnumerableMap.behavior.js | 181 - .../test/utils/structs/EnumerableMap.test.js | 86 - .../utils/structs/EnumerableSet.behavior.js | 131 - .../test/utils/structs/EnumerableSet.test.js | 46 - lib/morpho-utils/package.json | 20 - lib/morpho-utils/remappings.txt | 5 - lib/morpho-utils/src/DelegateCall.sol | 52 - .../src/ERC4626UpgradeableSafe.sol | 44 - lib/morpho-utils/src/math/CompoundMath.sol | 36 - lib/morpho-utils/src/math/Math.sol | 75 - lib/morpho-utils/src/math/PercentageMath.sol | 194 - lib/morpho-utils/src/math/WadRayMath.sol | 319 - lib/morpho-utils/test/TestCompoundMath.sol | 49 - lib/morpho-utils/test/TestDelegateCall.sol | 222 - lib/morpho-utils/test/TestMath.sol | 64 - lib/morpho-utils/test/TestPercentageMath.sol | 225 - lib/morpho-utils/test/TestWadRayMath.sol | 340 - .../test/mocks/CompoundMathMock.sol | 14 - lib/morpho-utils/test/mocks/MathMock.sol | 26 - .../test/mocks/PercentageMathMock.sol | 42 - .../test/mocks/WadRayMathMock.sol | 70 - .../test/references/CompoundMathRef.sol | 12 - lib/morpho-utils/test/references/MathRef.sol | 38 - .../test/references/PercentageMathRef.sol | 44 - .../test/references/WadRayMathRef.sol | 70 - lib/morpho-utils/yarn.lock | 496 - remappings.txt | 4 +- src/{Snippets.sol => blue/BlueSnippets.sol} | 2 +- src/metamorpho/MetamorphoSnippets.sol | 137 + .../TestBlueSnippets.sol} | 6 +- .../metamorpho/TestMetamorphoSnippets.sol | 291 + 1707 files changed, 435 insertions(+), 361614 deletions(-) delete mode 100644 lib/morpho-blue-irm/.github/workflows/formatting.yml delete mode 100644 lib/morpho-blue-irm/.github/workflows/foundry.yml delete mode 100644 lib/morpho-blue-irm/.gitignore delete mode 100644 lib/morpho-blue-irm/.gitmodules delete mode 100644 lib/morpho-blue-irm/README.md delete mode 100644 lib/morpho-blue-irm/audits/2023-09-27-morpho-blue-and-speed-jump-irm-open-zeppelin.pdf delete mode 100644 lib/morpho-blue-irm/foundry.toml delete mode 100644 lib/morpho-blue-irm/lib/forge-std/.github/workflows/ci.yml delete mode 100644 lib/morpho-blue-irm/lib/forge-std/.github/workflows/sync.yml delete mode 100644 lib/morpho-blue-irm/lib/forge-std/.gitignore delete mode 100644 lib/morpho-blue-irm/lib/forge-std/.gitmodules delete mode 100644 lib/morpho-blue-irm/lib/forge-std/LICENSE-APACHE delete mode 100644 lib/morpho-blue-irm/lib/forge-std/LICENSE-MIT delete mode 100644 lib/morpho-blue-irm/lib/forge-std/README.md delete mode 100644 lib/morpho-blue-irm/lib/forge-std/foundry.toml delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/.github/workflows/build.yml delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/.gitignore delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/Makefile delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/default.nix delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/demo/demo.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/package.json delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/src/test.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/lib/ds-test/src/test.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/package.json delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/Base.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/Script.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdAssertions.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdChains.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdCheats.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdError.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdInvariant.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdJson.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdMath.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdStorage.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdStyle.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/StdUtils.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/Test.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/Vm.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/console.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/console2.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC1155.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC165.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC20.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC4626.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC721.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/interfaces/IMulticall3.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/src/safeconsole.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/StdAssertions.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/StdChains.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/StdCheats.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/StdError.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/StdMath.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/StdStorage.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/StdStyle.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/StdUtils.t.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationScript.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationScriptBase.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationTestBase.sol delete mode 100644 lib/morpho-blue-irm/lib/forge-std/test/fixtures/broadcast.log.json delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/formatting.yml delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/foundry.yml delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/hardhat.yml delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/.gitignore delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/.gitmodules delete mode 100755 lib/morpho-blue-irm/lib/morpho-blue/.husky/commit-msg delete mode 100755 lib/morpho-blue-irm/lib/morpho-blue/.husky/post-checkout delete mode 100755 lib/morpho-blue-irm/lib/morpho-blue/.husky/post-merge delete mode 100755 lib/morpho-blue-irm/lib/morpho-blue/.husky/pre-commit delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/README.md delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/audits/2023-09-27-morpho-blue-and-speed-jump-irm-open-zeppelin.pdf delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/foundry.toml delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/hardhat.config.ts delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/.github/workflows/ci.yml delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/.github/workflows/sync.yml delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/.gitignore delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/.gitmodules delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/LICENSE-APACHE delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/LICENSE-MIT delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/README.md delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/foundry.toml delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/.github/workflows/build.yml delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/.gitignore delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/Makefile delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/default.nix delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/demo/demo.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/package.json delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/src/test.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/src/test.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/package.json delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Base.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Script.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdAssertions.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdChains.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdCheats.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdError.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdInvariant.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdJson.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdMath.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdStorage.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdStyle.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdUtils.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Test.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Vm.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/console.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/console2.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC1155.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC165.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC20.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC4626.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC721.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IMulticall3.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/safeconsole.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdAssertions.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdChains.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdCheats.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdError.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdMath.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdStorage.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdStyle.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdUtils.t.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationScript.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationScriptBase.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationTestBase.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/fixtures/broadcast.log.json delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/morpho-blue-whitepaper.pdf delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/package.json delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/Morpho.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IERC20.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IIrm.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IMorpho.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IOracle.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/ConstantsLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/ErrorsLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/EventsLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/MarketParamsLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/MathLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/SafeTransferLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/SharesMathLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/UtilsLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoStorageLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/mocks/ERC20Mock.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/mocks/FlashBorrowerMock.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/mocks/IrmMock.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/mocks/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/mocks/OracleMock.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/src/mocks/interfaces/IERC20.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/BaseTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/InvariantTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/MarketParamsLibTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/ArrayLib.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/Math.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/SigUtils.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/WadMath.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/AccrueInterestIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/AuthorizationIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/BorrowIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/CallbacksIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/CreateMarketIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/ExtSloadIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/LiquidateIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/OnlyOwnerIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/RepayIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/SupplyCollateralIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/SupplyIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/WithdrawCollateralIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/WithdrawIntegrationTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/invariant/MorphoInvariantTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/MathLibTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/SafeTransferLibTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/UtilsLibTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoBalancesLibTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoLibTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoStorageLibTest.sol delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/hardhat/Morpho.spec.ts delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/test/morpho_tests.tree delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/tsconfig.json delete mode 100644 lib/morpho-blue-irm/lib/morpho-blue/yarn.lock delete mode 100644 lib/morpho-blue-irm/lib/solmate/.gas-snapshot delete mode 100644 lib/morpho-blue-irm/lib/solmate/.gitattributes delete mode 100644 lib/morpho-blue-irm/lib/solmate/.github/pull_request_template.md delete mode 100644 lib/morpho-blue-irm/lib/solmate/.github/workflows/tests.yml delete mode 100644 lib/morpho-blue-irm/lib/solmate/.gitignore delete mode 100644 lib/morpho-blue-irm/lib/solmate/.gitmodules delete mode 100644 lib/morpho-blue-irm/lib/solmate/.prettierignore delete mode 100644 lib/morpho-blue-irm/lib/solmate/.prettierrc delete mode 100644 lib/morpho-blue-irm/lib/solmate/.vscode/settings.json delete mode 100644 lib/morpho-blue-irm/lib/solmate/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/solmate/README.md delete mode 100644 lib/morpho-blue-irm/lib/solmate/audits/v6-Fixed-Point-Solutions.pdf delete mode 100644 lib/morpho-blue-irm/lib/solmate/foundry.toml delete mode 100644 lib/morpho-blue-irm/lib/solmate/lib/ds-test/.gitignore delete mode 100644 lib/morpho-blue-irm/lib/solmate/lib/ds-test/LICENSE delete mode 100644 lib/morpho-blue-irm/lib/solmate/lib/ds-test/Makefile delete mode 100644 lib/morpho-blue-irm/lib/solmate/lib/ds-test/default.nix delete mode 100644 lib/morpho-blue-irm/lib/solmate/lib/ds-test/demo/demo.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/lib/ds-test/package.json delete mode 100644 lib/morpho-blue-irm/lib/solmate/lib/ds-test/src/test.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/package-lock.json delete mode 100644 lib/morpho-blue-irm/lib/solmate/package.json delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/auth/Auth.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/auth/Owned.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/auth/authorities/MultiRolesAuthority.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/auth/authorities/RolesAuthority.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/mixins/ERC4626.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/Auth.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/Bytes32AddressLib.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/CREATE3.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/DSTestPlus.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/ERC1155.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/ERC20.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/ERC4626.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/ERC721.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/FixedPointMathLib.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/LibString.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/MerkleProofLib.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/MultiRolesAuthority.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/Owned.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/ReentrancyGuard.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/RolesAuthority.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/SSTORE2.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/SafeCastLib.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/SafeTransferLib.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/SignedWadMath.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/WETH.t.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/DSInvariantTest.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/DSTestPlus.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/Hevm.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockAuthChild.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockAuthority.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC1155.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC20.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC4626.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC721.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockOwned.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/MissingReturnToken.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsFalseToken.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsGarbageToken.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTooLittleToken.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTooMuchToken.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTwoToken.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/RevertingToken.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/tokens/ERC1155.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/tokens/ERC20.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/tokens/ERC721.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/tokens/WETH.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/Bytes32AddressLib.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/CREATE3.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/FixedPointMathLib.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/LibString.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/MerkleProofLib.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/ReentrancyGuard.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/SSTORE2.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/SafeCastLib.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/SafeTransferLib.sol delete mode 100644 lib/morpho-blue-irm/lib/solmate/src/utils/SignedWadMath.sol delete mode 100644 lib/morpho-blue-irm/src/SpeedJumpIrm.sol delete mode 100644 lib/morpho-blue-irm/src/libraries/ErrorsLib.sol delete mode 100644 lib/morpho-blue-irm/src/libraries/MathLib.sol delete mode 100644 lib/morpho-blue-irm/src/libraries/UtilsLib.sol delete mode 100644 lib/morpho-blue-irm/test/MathLibTest.sol delete mode 100644 lib/morpho-blue-irm/test/SpeedJumpIrmTest.sol delete mode 100644 lib/morpho-blue-irm/test/UtilsLibTest.sol delete mode 100644 lib/morpho-utils/.github/workflows/certora.yml delete mode 100644 lib/morpho-utils/.github/workflows/foundry-gas-diff.yml delete mode 100644 lib/morpho-utils/.gitignore delete mode 100644 lib/morpho-utils/.gitmodules delete mode 100755 lib/morpho-utils/.husky/post-checkout delete mode 100755 lib/morpho-utils/.husky/post-merge delete mode 100755 lib/morpho-utils/.husky/pre-commit delete mode 100644 lib/morpho-utils/.prettierignore delete mode 100644 lib/morpho-utils/.prettierrc.json delete mode 100644 lib/morpho-utils/ISSUES.md delete mode 100644 lib/morpho-utils/LICENSE delete mode 100644 lib/morpho-utils/README.md delete mode 100755 lib/morpho-utils/certora/scripts/verifyAll.sh delete mode 100755 lib/morpho-utils/certora/scripts/verifyCompoundMath.sh delete mode 100755 lib/morpho-utils/certora/scripts/verifyMath.sh delete mode 100755 lib/morpho-utils/certora/scripts/verifyPercentageMath.sh delete mode 100755 lib/morpho-utils/certora/scripts/verifyWadRayMath.sh delete mode 100644 lib/morpho-utils/certora/specs/compoundMath.spec delete mode 100644 lib/morpho-utils/certora/specs/math.spec delete mode 100644 lib/morpho-utils/certora/specs/percentageMath.spec delete mode 100644 lib/morpho-utils/certora/specs/wadRayMath.spec delete mode 100644 lib/morpho-utils/foundry.toml delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.giatattributes delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.github/CODEOWNERS delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.github/workflows/node.js.yml delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.github/workflows/release.yml delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.gitignore delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.gitlab-ci.yml delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.npmrc delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.nvmrc delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.prettierignore delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.prettierrc delete mode 100644 lib/morpho-utils/lib/aave-v3-core/.solcover.js delete mode 100644 lib/morpho-utils/lib/aave-v3-core/CHANGELOG.md delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/Verification_Report.md delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/Verification_Report.pdf delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/ATokenHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/DataTypesInitializer.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/EModeLogicHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/GenericLogicHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/LendingPoolHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolConfiguratorHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolHarnessForConfigurator.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolHarnessForVariableDebtToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/ReserveConfigurationHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SimpleERC20.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/StableDebtTokenHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SupplyLogicHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SymbolicPriceOracle.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/UserConfigurationHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/flashLoanHarness.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/validationLogicHarness.sol delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/PoolSanity.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyAToken.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyEModeAndIsolation.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyPool.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyPoolConfigurator.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyReserveConfiguration.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanity.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanityEModeLogic.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanityWithLinksOptimisticLoops.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyStableTokenCLI.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyUserConfigCLI.sh delete mode 100755 lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyVariableTokenCLI.sh delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/AToken.spec delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/PoolConfigurator.spec delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/ReserveConfiguration.spec delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/StableDebtToken.spec delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/UserConfiguration.spec delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/VariableDebtToken.spec delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/pool.spec delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/sanity.spec delete mode 100644 lib/morpho-utils/lib/aave-v3-core/Dockerfile delete mode 100644 lib/morpho-utils/lib/aave-v3-core/LICENSE.md delete mode 100644 lib/morpho-utils/lib/aave-v3-core/README.md delete mode 100644 lib/morpho-utils/lib/aave-v3-core/audits/01-11-2021_OpenZeppelin_AaveV3.pdf delete mode 100644 lib/morpho-utils/lib/aave-v3-core/audits/07-01-2022_TrailOfBits_AaveV3.pdf delete mode 100644 lib/morpho-utils/lib/aave-v3-core/audits/14-01-2022_PeckShield_AaveV3.pdf delete mode 100644 lib/morpho-utils/lib/aave-v3-core/audits/27-01-2022_ABDK_AaveV3.pdf delete mode 100644 lib/morpho-utils/lib/aave-v3-core/audits/27-01-2022_SigmaPrime_AaveV3.pdf delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/chainlink/AggregatorInterface.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/gnosis/contracts/GPv2SafeERC20.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/AccessControl.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Address.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Context.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC165.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC20.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC165.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Strings.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/weth/WETH9.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/FlashLoanReceiverBase.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/LICENSE.md delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanReceiver.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/LICENSE.md delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IACLManager.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAaveIncentivesController.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAaveOracle.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/ICreditDelegationToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IDelegationToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IERC20WithPermit.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IInitializableAToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IInitializableDebtToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IL2Pool.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPool.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolAddressesProviderRegistry.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolConfigurator.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolDataProvider.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracle.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracleGetter.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracleSentinel.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IReserveInterestRateStrategy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IScaledBalanceToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/ISequencerOracle.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IStableDebtToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IVariableDebtToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/LICENSE.md delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/misc/AaveOracle.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/misc/L2Encoder.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/misc/interfaces/IWETH.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/misc/interfaces/LICENSE.md delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/flashloan/MockFlashLoanReceiver.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockIncentivesController.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockL2Pool.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockPeripheryContract.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockPool.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockReserveConfiguration.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/SelfDestructTransfer.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/PriceOracle.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/FlashloanAttacker.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/MockReserveInterestRateStrategy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/WadRayMathWrapper.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/MintableDelegationERC20.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/MintableERC20.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/WETH9Mocked.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockAToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockInitializableImplementation.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockStableDebtToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockVariableDebtToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/ACLManager.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PoolAddressesProvider.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PriceOracleSentinel.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/helpers/Helpers.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/BridgeLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/CalldataLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/EModeLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/FlashLoanLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/GenericLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/IsolationModeLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/LiquidationLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/PoolLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/SupplyLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ValidationLogic.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/MathUtils.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/L2Pool.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/Pool.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/PoolStorage.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/AToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/DelegationAwareAToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/StableDebtToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/VariableDebtToken.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/DebtTokenBase.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/EIP712Base.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/IncentivizedERC20.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol delete mode 100644 lib/morpho-utils/lib/aave-v3-core/docker-compose.yml delete mode 100644 lib/morpho-utils/lib/aave-v3-core/hardhat.config.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/helper-hardhat-config.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/helpers/constants.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/helpers/contracts-helpers.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/helpers/misc-utils.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/helpers/tenderly-utils.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/helpers/types.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/package-lock.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/package.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/setup-test-env.sh delete mode 100644 lib/morpho-utils/lib/aave-v3-core/techpaper/Aave_V3_Technical_Paper.pdf delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/__setup.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/aave-oracle.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/aave-protocol-data-provider.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/acl-manager.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/addresses-provider-registry.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-delegation-aware.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-edge.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-event-accounting.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-modifiers.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-permit.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-repay.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-transfer.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/bridge-logic.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-borrow-cap.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-edge.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-liquidation-protocol-fee.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-modifiers.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-supply-cap.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/configurator.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/debt-token-delegation-permit.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/emode.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/emptyrun.coverage.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/actions.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/make-suite.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenario-engine.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-negatives.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-stable-edge.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-stable.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-variable.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repayWithPermit-variable.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/credit-delegation.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/deposit.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/rebalance-stable-rate.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/set-use-as-collateral.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/swap-rate-mode.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/withdraw-negatives.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/withdraw.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/calculations.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/funds.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/helpers.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/interfaces/index.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/wadraymath.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/wallets.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/interest-overflow.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/isolation-mode.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-atoken.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-edge.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-emode-interest.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-emode.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-underlying.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-with-fee.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/ltv-validation.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/mint-to-treasury.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/no-incentives-controller.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pausable-pool.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pausable-reserve.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-addresses-provider.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-authorized-flashloan.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-drop-reserve.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-edge.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-flashloan.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-get-reserve-address-by-id.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-l2.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-normal-flashloan.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/pool-simple-flashloan.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/price-oracle-sentinel.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/rate-strategy.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/rescue-tokens.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/reserve-configuration.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/scenario.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/siloed-borrowing.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/stable-debt-token.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/subgraph-scenarios.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/upgradeability.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/validation-logic.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/variable-debt-token.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-suites/wadraymath.spec.ts delete mode 100644 lib/morpho-utils/lib/aave-v3-core/test-wallets.js delete mode 100644 lib/morpho-utils/lib/aave-v3-core/tsconfig.json delete mode 100644 lib/morpho-utils/lib/aave-v3-core/tslint.json delete mode 100644 lib/morpho-utils/lib/forge-std/.github/workflows/ci.yml delete mode 100644 lib/morpho-utils/lib/forge-std/.gitignore delete mode 100644 lib/morpho-utils/lib/forge-std/.gitmodules delete mode 100644 lib/morpho-utils/lib/forge-std/LICENSE-APACHE delete mode 100644 lib/morpho-utils/lib/forge-std/LICENSE-MIT delete mode 100644 lib/morpho-utils/lib/forge-std/README.md delete mode 100644 lib/morpho-utils/lib/forge-std/foundry.toml delete mode 100644 lib/morpho-utils/lib/forge-std/lib/ds-test/.gitignore delete mode 100644 lib/morpho-utils/lib/forge-std/lib/ds-test/LICENSE delete mode 100644 lib/morpho-utils/lib/forge-std/lib/ds-test/Makefile delete mode 100644 lib/morpho-utils/lib/forge-std/lib/ds-test/default.nix delete mode 100644 lib/morpho-utils/lib/forge-std/lib/ds-test/demo/demo.sol delete mode 100644 lib/morpho-utils/lib/forge-std/lib/ds-test/package.json delete mode 100644 lib/morpho-utils/lib/forge-std/lib/ds-test/src/test.sol delete mode 100644 lib/morpho-utils/lib/forge-std/package.json delete mode 100644 lib/morpho-utils/lib/forge-std/src/Common.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/Components.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/Script.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/StdAssertions.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/StdCheats.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/StdError.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/StdJson.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/StdMath.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/StdStorage.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/StdUtils.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/Test.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/Vm.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/console.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/console2.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/interfaces/IERC1155.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/interfaces/IERC165.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/interfaces/IERC20.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/interfaces/IERC4626.sol delete mode 100644 lib/morpho-utils/lib/forge-std/src/interfaces/IERC721.sol delete mode 100644 lib/morpho-utils/lib/forge-std/test/StdAssertions.t.sol delete mode 100644 lib/morpho-utils/lib/forge-std/test/StdCheats.t.sol delete mode 100644 lib/morpho-utils/lib/forge-std/test/StdError.t.sol delete mode 100644 lib/morpho-utils/lib/forge-std/test/StdMath.t.sol delete mode 100644 lib/morpho-utils/lib/forge-std/test/StdStorage.t.sol delete mode 100644 lib/morpho-utils/lib/forge-std/test/StdUtils.t.sol delete mode 100644 lib/morpho-utils/lib/forge-std/test/fixtures/broadcast.log.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.changeset/new-ways-own.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.codecov.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.editorconfig delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.eslintrc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitattributes delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/actions/gas-compare/action.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/actions/setup/action.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/changelog.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/checks.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/docs.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/merge-upstream.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/transpile.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitignore delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitmodules delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.mocharc.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.prettierrc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.solcover.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.solhint.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CHANGELOG.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CODE_OF_CONDUCT.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CONTRIBUTING.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/DOCUMENTATION.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/GUIDELINES.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/LICENSE delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/RELEASING.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/SECURITY.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/UPGRADEABLE.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/audit/2017-03.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/audit/2018-10.pdf delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/Makefile delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/applyHarness.patch delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/ERC20VotesHarness.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/WizardControlFirstPriority.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/WizardFirstTry.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/munged/.gitignore delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/Governor.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/GovernorCountingSimple-counting.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/WizardControlFirstPriority.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/WizardFirstTry.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/sanity.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/verifyAll.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/GovernorBase.spec delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/GovernorCountingSimple.spec delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/RulesInProgress.spec delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/sanity.spec delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlCrossChainUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlEnumerableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlEnumerableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/CrossChainEnabledUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/amb/CrossChainEnabledAMBUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/amb/LibAMBUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/LibArbitrumL1Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/LibArbitrumL2Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/errorsUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/optimism/CrossChainEnabledOptimismUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/optimism/LibOptimismUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/polygon/CrossChainEnabledPolygonChildUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/PaymentSplitterUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/VestingWalletUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/GovernorUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/IGovernorUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerWith46MigrationUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/IGovernorCompatibilityBravoUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorSettingsUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/IGovernorTimelockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/IVotesUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/VotesUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155MetadataURIUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155ReceiverUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1271Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363ReceiverUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363SpenderUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820ImplementerUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820RegistryUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1967Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20MetadataUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2309Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2981Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashBorrowerUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashLenderUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC4626Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721EnumerableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721MetadataUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721ReceiverUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777RecipientUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777SenderUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC1822Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC2612Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/ERC2771ContextUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/MinimalForwarderUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlCrossChainMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlEnumerableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AddressImplUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ArraysMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BadBeaconUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Base64MockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BitmapMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CallReceiverMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CheckpointsMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClashingImplementationUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClonesMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ConditionalEscrowMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ContextMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CountersImplUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Create2ImplUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DoubleEndedQueueMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DummyImplementationUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ECDSAMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EIP712ExternalUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155BurnableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155MockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155PausableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155ReceiverMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155SupplyMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155URIStorageMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1271WalletMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165InterfacesSupportedUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MaliciousDataUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MissingDataUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165NotSupportedUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165ReturnBombUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165CheckerMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165MockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165StorageMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1820ImplementerMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20BurnableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20CappedMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20DecimalsMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20FlashMintMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20MockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PausableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PermitMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20SnapshotMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesCompMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20WrapperMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC2771ContextMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC3156FlashBorrowerMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC4626MockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721BurnableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ConsecutiveEnumerableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ConsecutiveMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721EnumerableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721MockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721PausableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ReceiverMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721RoyaltyMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721URIStorageMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721VotesMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777MockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777SenderRecipientMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableMapMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableSetMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EtherReceiverMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompatibilityBravoMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorPreventLateQuorumMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockCompoundMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockControlMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorVoteMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorWithParamsMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/InitializableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MathMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MerkleProofWrapperUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTestUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTokenMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MultipleInheritanceInitializableMocks.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Ownable2StepMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/OwnableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PausableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PullPaymentMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyAttackUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/RegressionImplementation.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeCastMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeERC20HelperUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeMathMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignatureCheckerMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedMathMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedSafeMathMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SingleInheritanceInitializableMocks.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StorageSlotMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StringsMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersBlockNumberImplUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersTimestampImplUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/UUPSLegacyUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/UUPSUpgradeableMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/VotesMockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/WithInit.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/compound/CompTimelockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/crosschain/bridgesUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/crosschain/receiversUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor1Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor2Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor3Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/package.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ClonesUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/beacon/IBeaconUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/PullPaymentUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155ReceiverUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155PausableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155HolderUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20BurnableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20CappedUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PausableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20WrapperUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetFixedSupplyUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/TokenTimelockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721ReceiverUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721BurnableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721ConsecutiveUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721PausableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721VotesUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721MetadataUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/draft-ERC721VotesUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoIdUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/utils/ERC721HolderUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/ERC777Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777RecipientUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777SenderUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/presets/ERC777PresetFixedSupplyUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/common/ERC2981Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/common/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ArraysUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/Base64Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/CheckpointsUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/CountersUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/Create2Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/StorageSlotUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/TimersUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/ECDSAUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/MerkleProofUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/SignatureCheckerUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/draft-EIP712Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/ConditionalEscrowUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/EscrowUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/RefundEscrowUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165CheckerUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165StorageUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC1820ImplementerUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820ImplementerUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820RegistryUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/MathUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeCastUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeMathUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedMathUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedSafeMathUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/BitMapsUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/DoubleEndedQueueUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableMapUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableSetUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/amb/IAMBUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IArbSysUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IBridgeUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IDelayedMessageProviderUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IInboxUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IOutboxUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/compound/ICompoundTimelockUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/compound/LICENSE delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/optimism/ICrossDomainMessengerUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/optimism/LICENSE delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/polygon/IFxMessageProcessorUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat.config.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/env-artifacts.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/env-contract.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/ignore-unreachable-warnings.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/skip-foundry-tests.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/task-get-compiler-input.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/task-test-get-files.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/icon.svg delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.github/workflows/ci.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.gitignore delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.gitmodules delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/LICENSE-APACHE delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/LICENSE-MIT delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/foundry.toml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/.github/workflows/build.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/.gitignore delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/LICENSE delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/Makefile delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/default.nix delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/demo/demo.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/package.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/test.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/test.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/package.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Base.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Script.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdAssertions.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdChains.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdCheats.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdError.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdInvariant.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdJson.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdMath.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdStorage.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdStyle.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdUtils.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Test.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Vm.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/console.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/console2.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC1155.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC165.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC20.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC4626.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC721.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IMulticall3.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdAssertions.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdChains.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdCheats.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdError.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdMath.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdStorage.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdStyle.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdUtils.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationScript.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationScriptBase.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationTest.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationTestBase.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/fixtures/broadcast.log.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/logo.svg delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/netlify.toml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/package-lock.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/package.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/renovate.json delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/compareGasReports.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/generation.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/inheritance-ordering.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/gen-nav.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/format-lines.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/run.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/Checkpoints.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/CheckpointsMock.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableMap.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableMapMock.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableSet.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableSetMock.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/SafeCast.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/SafeCastMock.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/conversion.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/git-user-config.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/helpers.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/migrate-imports.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepack.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare-contracts-package.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare-docs.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/release.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/synchronize-versions.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/update-changelog-release-date.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/update-comment.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/version.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/remove-ignored-artifacts.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/update-docs-branch.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/git-user-config.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/merge-upstream.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/patch/.gitkeep delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/transpile-onto.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/transpile.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/slither.config.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/TESTING.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControl.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControl.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControlCrossChain.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControlEnumerable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/Ownable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/Ownable2Step.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/crosschain/CrossChainEnabled.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/PaymentSplitter.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/VestingWallet.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/VestingWallet.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/Governor.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/TimelockController.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/compatibility/GovernorCompatibilityBravo.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorComp.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorERC721.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorPreventLateQuorum.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorTimelockCompound.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorTimelockControl.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorVotesQuorumFraction.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorWithParams.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/utils/Votes.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/utils/Votes.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/create2.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/crosschain.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/customError.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/eip712.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/enums.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/erc1967.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/governance.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/sign.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/txpool.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/metatx/ERC2771Context.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/metatx/MinimalForwarder.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/migrate-imports.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Clones.behaviour.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Clones.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/ERC1967/ERC1967Proxy.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Proxy.behaviour.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/beacon/BeaconProxy.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/beacon/UpgradeableBeacon.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/ProxyAdmin.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/TransparentUpgradeableProxy.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/utils/Initializable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/utils/UUPSUpgradeable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/Pausable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/PullPayment.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/ReentrancyGuard.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/ERC1155.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/ERC1155.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Burnable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Pausable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Supply.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155URIStorage.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/presets/ERC1155PresetMinterPauser.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/utils/ERC1155Holder.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/ERC20.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/ERC20.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Burnable.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Burnable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Capped.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Capped.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20FlashMint.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Pausable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Snapshot.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Votes.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20VotesComp.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Wrapper.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC4626.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/draft-ERC20Permit.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/presets/ERC20PresetFixedSupply.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/presets/ERC20PresetMinterPauser.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/utils/SafeERC20.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/utils/TokenTimelock.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721Enumerable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Burnable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Consecutive.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Consecutive.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Pausable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Royalty.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721URIStorage.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Votes.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/presets/ERC721PresetMinterPauserAutoId.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/utils/ERC721Holder.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/ERC777.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/ERC777.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/presets/ERC777PresetFixedSupply.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/common/ERC2981.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Address.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Arrays.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Base64.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Checkpoints.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Context.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Context.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Counters.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Create2.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Multicall.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/StorageSlot.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Strings.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/TimersBlockNumberImpl.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/TimersTimestamp.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/ECDSA.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/EIP712.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/MerkleProof.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/SignatureChecker.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/ConditionalEscrow.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/Escrow.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/Escrow.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/RefundEscrow.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165Checker.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165Storage.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC1820Implementer.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/SupportsInterface.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/Math.t.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/Math.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SafeCast.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SafeMath.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SignedMath.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SignedSafeMath.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/BitMap.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/DoubleEndedQueue.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableMap.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableMap.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableSet.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableSet.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.codecov.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.editorconfig delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.eslintrc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.gitattributes delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/actions/setup/action.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/checks.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/docs.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.gitignore delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.mocharc.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.prettierrc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.solcover.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/.solhint.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/CHANGELOG.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/CONTRIBUTING.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/DOCUMENTATION.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/GUIDELINES.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/LICENSE delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/RELEASING.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/SECURITY.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/audit/2017-03.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/audit/2018-10.pdf delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/Makefile delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/applyHarness.patch delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/ERC20VotesHarness.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/WizardControlFirstPriority.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/WizardFirstTry.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/munged/.gitignore delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/Governor.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/GovernorCountingSimple-counting.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/WizardControlFirstPriority.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/WizardFirstTry.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/sanity.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/verifyAll.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/GovernorBase.spec delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/GovernorCountingSimple.spec delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/RulesInProgress.spec delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/sanity.spec delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControlCrossChain.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControlEnumerable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/IAccessControlEnumerable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/Ownable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/CrossChainEnabled.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/amb/CrossChainEnabledAMB.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/amb/LibAMB.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/LibArbitrumL1.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/LibArbitrumL2.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/errors.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/optimism/LibOptimism.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/polygon/CrossChainEnabledPolygonChild.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/PaymentSplitter.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/Governor.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/TimelockController.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/compatibility/GovernorCompatibilityBravo.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/compatibility/IGovernorCompatibilityBravo.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorProposalThreshold.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesComp.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/IGovernorTimelock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/utils/Votes.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC2612.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/MinimalForwarder.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlCrossChainMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlEnumerableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AddressImpl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ArraysImpl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/BadBeacon.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/Base64Mock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/BitmapMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CheckpointsImpl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ClashingImplementation.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ClonesMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ConditionalEscrowMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CountersImpl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/Create2Impl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/DoubleEndedQueueMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ECDSAMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EIP712External.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155BurnableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155Mock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155PausableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155ReceiverMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155SupplyMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155URIStorageMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165CheckerMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165Mock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165StorageMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1820ImplementerMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20BurnableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20CappedMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20DecimalsMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20FlashMintMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20Mock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20PausableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20PermitMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20SnapshotMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesCompMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20WrapperMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC4626Mock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721BurnableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721EnumerableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721Mock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721PausableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721ReceiverMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721RoyaltyMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721URIStorageMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721VotesMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC777Mock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC777SenderRecipientMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EnumerableMapMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EnumerableSetMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorCompMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorCompatibilityBravoMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorPreventLateQuorumMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockCompoundMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockControlMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorVoteMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorWithParamsMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MathMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MerkleProofWrapper.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MulticallTest.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MulticallTokenMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/OwnableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/PullPaymentMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeCastMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeERC20Helper.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeMathMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignatureCheckerMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignedMathMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignedSafeMathMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/StringsMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/TimersBlockNumberImpl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/TimersTimestampImpl.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/UUPS/UUPSLegacy.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/UUPS/UUPSUpgradeableMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/crosschain/bridges.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/crosschain/receivers.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor1.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor2.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor3.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/package.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/Clones.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/Pausable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/PullPayment.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Receiver.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Snapshot.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20VotesComp.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-ERC20Permit.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/utils/TokenTimelock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/draft-ERC721Votes.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/presets/README.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/ERC777.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Recipient.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Sender.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/presets/ERC777PresetFixedSupply.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/common/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Address.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Arrays.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Base64.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Checkpoints.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Context.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Counters.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Create2.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Multicall.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/README.adoc delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Strings.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Timers.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/draft-EIP712.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/ConditionalEscrow.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/Escrow.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/RefundEscrow.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Storage.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC1820Implementer.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Implementer.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Registry.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/Math.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SignedSafeMath.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/amb/IAMB.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IArbSys.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IBridge.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IInbox.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IMessageProvider.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IOutbox.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/compound/LICENSE delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/optimism/ICrossDomainMessenger.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/optimism/LICENSE delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/polygon/IFxMessageProcessor.sol delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/hardhat.config.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/hardhat/env-contract.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/logo.svg delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/migrations/.gitkeep delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/netlify.toml delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/package-lock.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/package.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/renovate.json delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/generation.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/scripts/gen-nav.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/format-lines.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/run.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/templates/SafeCastMock.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/scripts/git-user-config.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/scripts/helpers.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/migrate-imports.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepack.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-contracts-package.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-docs-solc.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-docs.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/release.sh delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/update-changelog-release-date.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/update-comment.js delete mode 100755 lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/version.sh delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/scripts/update-docs-branch.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/slither.config.json delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/TESTING.md delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControl.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControl.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControlCrossChain.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControlEnumerable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/access/Ownable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/crosschain/CrossChainEnabled.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/finance/PaymentSplitter.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/finance/VestingWallet.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/Governor.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/TimelockController.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/compatibility/GovernorCompatibilityBravo.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorComp.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorWeightQuorumFraction.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/governance/utils/Votes.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/create2.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/crosschain.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/customError.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/eip712.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/enums.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/erc1967.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/governance.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/sign.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/txpool.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/metatx/MinimalForwarder.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/migrate-imports.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Clones.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/security/Pausable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/security/PullPayment.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/security/ReentrancyGuard.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/presets/ERC1155PresetMinterPauser.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Snapshot.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20VotesComp.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/draft-ERC20Permit.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/presets/ERC20PresetFixedSupply.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/presets/ERC20PresetMinterPauser.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/utils/TokenTimelock.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/presets/ERC721PresetMinterPauserAutoId.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/ERC777.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/ERC777.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/presets/ERC777PresetFixedSupply.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Address.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Arrays.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Base64.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Checkpoints.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Context.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Context.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Counters.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Create2.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Multicall.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/StorageSlot.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Strings.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/TimersBlockNumberImpl.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/TimersTimestamp.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/draft-EIP712.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/ConditionalEscrow.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/Escrow.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/Escrow.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/RefundEscrow.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165Storage.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC1820Implementer.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/Math.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SafeMath.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SignedSafeMath.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js delete mode 100644 lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js delete mode 100644 lib/morpho-utils/package.json delete mode 100644 lib/morpho-utils/remappings.txt delete mode 100644 lib/morpho-utils/src/DelegateCall.sol delete mode 100644 lib/morpho-utils/src/ERC4626UpgradeableSafe.sol delete mode 100644 lib/morpho-utils/src/math/CompoundMath.sol delete mode 100644 lib/morpho-utils/src/math/Math.sol delete mode 100644 lib/morpho-utils/src/math/PercentageMath.sol delete mode 100644 lib/morpho-utils/src/math/WadRayMath.sol delete mode 100644 lib/morpho-utils/test/TestCompoundMath.sol delete mode 100644 lib/morpho-utils/test/TestDelegateCall.sol delete mode 100644 lib/morpho-utils/test/TestMath.sol delete mode 100644 lib/morpho-utils/test/TestPercentageMath.sol delete mode 100644 lib/morpho-utils/test/TestWadRayMath.sol delete mode 100644 lib/morpho-utils/test/mocks/CompoundMathMock.sol delete mode 100644 lib/morpho-utils/test/mocks/MathMock.sol delete mode 100644 lib/morpho-utils/test/mocks/PercentageMathMock.sol delete mode 100644 lib/morpho-utils/test/mocks/WadRayMathMock.sol delete mode 100644 lib/morpho-utils/test/references/CompoundMathRef.sol delete mode 100644 lib/morpho-utils/test/references/MathRef.sol delete mode 100644 lib/morpho-utils/test/references/PercentageMathRef.sol delete mode 100644 lib/morpho-utils/test/references/WadRayMathRef.sol delete mode 100644 lib/morpho-utils/yarn.lock rename src/{Snippets.sol => blue/BlueSnippets.sol} (99%) create mode 100644 src/metamorpho/MetamorphoSnippets.sol rename test/forge/{TestIntegrationSnippets.sol => blue/TestBlueSnippets.sol} (99%) create mode 100644 test/forge/metamorpho/TestMetamorphoSnippets.sol diff --git a/lib/morpho-blue-irm/.github/workflows/formatting.yml b/lib/morpho-blue-irm/.github/workflows/formatting.yml deleted file mode 100644 index 7a669e8..0000000 --- a/lib/morpho-blue-irm/.github/workflows/formatting.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Formatting - -on: - push: - branches: - - main - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} - cancel-in-progress: true - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Run Linter - run: forge fmt --check diff --git a/lib/morpho-blue-irm/.github/workflows/foundry.yml b/lib/morpho-blue-irm/.github/workflows/foundry.yml deleted file mode 100644 index 0a39ea2..0000000 --- a/lib/morpho-blue-irm/.github/workflows/foundry.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Foundry - -on: - push: - branches: - - main - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} - cancel-in-progress: true - -jobs: - build: - name: Compilation (via IR) - runs-on: ubuntu-latest - - steps: - - name: Generate a token - id: generate-token - uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 - with: - app_id: ${{ secrets.APP_ID }} - private_key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Checkout - uses: actions/checkout@v3 - with: - token: ${{ steps.generate-token.outputs.token }} - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Build contracts via IR & check sizes - run: forge build --force --sizes # don't use compilation cache - env: - FOUNDRY_PROFILE: build - - test: - name: Tests - runs-on: ubuntu-latest - - steps: - - name: Generate a token - id: generate-token - uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 - with: - app_id: ${{ secrets.APP_ID }} - private_key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Checkout - uses: actions/checkout@v3 - with: - token: ${{ steps.generate-token.outputs.token }} - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Run forge tests - run: forge test -vvv - env: - FOUNDRY_PROFILE: test diff --git a/lib/morpho-blue-irm/.gitignore b/lib/morpho-blue-irm/.gitignore deleted file mode 100644 index 85198aa..0000000 --- a/lib/morpho-blue-irm/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Compiler files -cache/ -out/ - -# Ignores development broadcast logs -!/broadcast -/broadcast/*/31337/ -/broadcast/**/dry-run/ - -# Docs -docs/ - -# Dotenv file -.env diff --git a/lib/morpho-blue-irm/.gitmodules b/lib/morpho-blue-irm/.gitmodules deleted file mode 100644 index d08816b..0000000 --- a/lib/morpho-blue-irm/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "lib/forge-std"] - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "lib/morpho-blue"] - path = lib/morpho-blue - url = https://github.com/morpho-org/morpho-blue -[submodule "lib/solmate"] - path = lib/solmate - url = https://github.com/transmissions11/solmate diff --git a/lib/morpho-blue-irm/README.md b/lib/morpho-blue-irm/README.md deleted file mode 100644 index 2050f99..0000000 --- a/lib/morpho-blue-irm/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Morpho Blue IRM - -## Audits - -All audits are stored in the [audits](./audits/)' folder. \ No newline at end of file diff --git a/lib/morpho-blue-irm/audits/2023-09-27-morpho-blue-and-speed-jump-irm-open-zeppelin.pdf b/lib/morpho-blue-irm/audits/2023-09-27-morpho-blue-and-speed-jump-irm-open-zeppelin.pdf deleted file mode 100644 index 3cc9eb6eb9af5c222064bd357e73efd8e572818e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408435 zcmc$H2|QHa`#(}>L)v9a+6Obkm?29jO09OH;#USpX2a!h_KgAc`&hhp-hWEpZ%7zQ1RNsq!YF&2_(_&E>;AJ=mER~*@?1AYP$=?mJC=~Nj6ETIpNJI(~2jw zLuO3!teQE++@5U1@USTC1*yF*6rd09EQ-d$W=iRp6TuaThC1Gv0-rESj5k`CTOq9Q z78Hat*^*#xPw+IS5XdBir8x;IStKXDHy#WDsg*<(oNXvNBjnY1#3Zu~c(}xf34Y?BZ;R2W|q@4M8Cz zY@7&qYuJ4h3aC@C{WH5=P7Wz4JyEGiAR*x0p{7ZoAP7V#eL2GlKm~{L!Efp@1_T{^ z#_|EEJ)o7ETLF`Rg}`D0$(rm$9IMN}5i$jegA?A80C@;uPj+@jSb<;w%d9{lNL9|D zk&{4219=y!7tB6jN^qx1B)Agn@itHsB{SOPSm!f^5rx7?;wJ2I!aLZTdmzji&V>Ep z05HMcHn*nWoe;L>PFBD~hNqbw(G;0-(ill;3>L#^bWV6j7XlQxi8|s&px7eD>kvpT z4EOy_<(*=m6X?LKps3@WoInL5g0w~fbrB>skfAKdpwNv`ClC}{DB-&kh@ffO6NqpP zAL}Qlz{WteeIi*nn_J^4PUa+MYrGT40|+ZJh%}TfAT>@D1PGTW-iZta-wE#wVgF5@ zK%;SzI60Iwv*9^gk{zI404dGrou{Cfl6#%;mM&1T28qcEZ;vo1Ss^G+F3yxG>Ebuh zmBHXx6FEpQAO*sSf94!9RXKwmYPX<`K@Nw^L^2;=rT_;$9&7t@_5l3_5kUsNawXv1 zAU@_}&=kHYIw?>`0%-)*0_t!ejf}^lzvpuyK@FGLk^#?eI$2qqtR$#RV+oYmn?aQt z>YS|*Bp0FuNLP@6nX~?snmE?=fu0%!1@tE_BoZF<9L@|s|0V&TkI+gf6E z`Cf%9;udQK*w<bPO(?h_^4BYFK@khEcy*bLi=scuKZ;N z#!eho7Io*i!Uk$1v|os(Q7;`IT3oz+$x7>`w7RH$=Ef(MzB(Bo+=da=HGEd6r<#Ch z%PD9$F?h8z{`lg~S|O8)O!BS`nR7!f$_sq=a2!lFAS`&U>-$6R3le>)#(18y-$T)) z3&$JrBzB|kO+VJAI4t_StEL~bt?1XrQTCP2mX%P&XI2m9+Xz(8CcO_pZ(5+HI)Qw^ zd>haPPg~}yWOq?x=w$$E)hIbx@YEoRl|f2ku{b%54D_DENFkzdrj#nvn@S?9MMsW0yBx%uD*p`W7O`jUI+`R&<0 z#qTY>SGPwMh;)o*5ORsse96kn60*ohUy*|`ZGif?!q@vJ`u%f{y09OYNta!26vq{e zd@ky`SxoKjzdHJ(JJj!|^uUJNIBFWPB||y5&7E4JpAn}#GSKWc+7UHc95wPyBbl|5r}lNUi1KD8KgaO2OpO&d-rFFIxI&w`IP)$mn3D$mkbiE|vS? zzn&zQX(@1wbkqEXenpM;%jjf28_gULkM{k64T){Ih8cFtRJ&F0XV%_f*fC&{sVtIN z(&y-Rv!iJ*S0%ZuED004aF}>q&g;`5s`=im`U>Zf;jc+yK3R29mmevOR7oR}z7TT~ z+w@OfuV^8rgqG&7^^7Fti}7}~WPZUvLev!}ih4E@wZa@DSDM&seSN(3)Xlrp>_siP zV%ZNfB-&my79O>Uaa_G&V6E1pMUNKQgc7+1Wr&vM3O2R&TCI*&3O32QZTk5h8ffkokU7lO6zo&w1BD*E0SEIl#++8XE**@s?=L~ zgexI<4!5zJ@?m05gyj&%b|3B&kHdBL99>NKGEeUhRy~Ls#uB_OzwShdbV$SzLIuCC?=@Mu>_# zF7yy1T~}AS>Ze0`-<*0Jez2%2WPAV3TAeh+rnWPSw|gnrYbD$>TGheTo^tD#>2d{A zVuVaA@X=HG`W$Rbq@@Uwdfp`w5IIGJ5fF6lt*++j`&*1^f%|evTLj&y1ZswrXIwYmPYEen|*X_?e@~+?wT8p{N zPrNA7EigXCXLN!)T33vNe()5V{Ia!y`ixUh8lVT4`0Ky~s@^jnZ)&_~hsFv&D_;n5vG-Zd~$oUL(GHj;mR1A$4b8h6HqtS)Poz zzW}(?cEq~s4Jc^&%GI8o9FTbhpCM6stg-O$%RF5zLy5tk))F?yOQ}Ehz0__%Bz9gg zCC5eNMcQl-cx@0-B?Zy9u3&zaJ=`wi~M&AE-u=YUWNDV_aOZ|0%x_%qRvJ!F_ScWd}ALi8Z%k$2cHH^{En> ziedijs}BC!lVpskx(s8WZ-g{XQKb?$fgvwYJei^VcdFPTCt&~*`L@-bJO?}(nkte^ zg&g^bt35Y4z-{yTrueT3*M9c9B5_sJk$rpWMSZSC>0bIsk&)Jyl2(pVriM~6>y0GhPmO&q_Tfsv=NLgaEV*~RPk`$;9 zmyVxqluxQ-=wP`6tJ7m>2J{~$NdW?BvXN)UY*4e5=}WvH6}+?lHo$5{k}~uUGac`ZnGWqP5V1hx;9+3L-*#Zhei@rq-7Z zXPG-G#t|10cGvV3@f0a(wN&fuOv=2er^1``yBGhRo+KywAaMcj{^4eERCrWqdJuFulLdGQMct zx$3rhD$G+z62B2#I({0!^9JGxIL%pXJYfABMNTx?6?n zP!oDFGOr==|0~58b_9JhLYktPWl)$R}fd+OSD(mmfhwQ zPV6d*&8ap{zqL@f0dr5}?(!$K^feUDae%O)nbZt!%cgq9HHIE5Q5(*=4D zf2bfHYJTb9PT_5P(|BQ-aD(fcx=^HIKu~yO-G?kM*EuH3-8*k~thSCjS^3=`8=f4Bb?;=>jbT{?!l0$37e-0nVOsIJZLXbkca4g-%(|lIQM3bjo>cc zHtw)*Uw^0jiHnqQ3+>7x{-pjEqdxN0j zJE5C7G(v7i+x)Ty=k$sqY?1TeVcN#W+{9-mObnYVOzek_Y#_T+uGUEw2`adiJ=@9a z%bk+xCG(e=gjY`S_g2~_cZzXLUc?oV=%5B0AHcqCtLv&pU{=QbS90M(4VT3F<`*~U z&uj87e-T0w3~oGmJtQZN7`o(gImUA%<$Z_aF*Ehr3Pr;&HhS~7xp@sG>rmb+dc-__ z;y9RAPdC5a()seiE1$b9orL>xB5zY;y^QSp_kDRxJ=#ls{MIqkN0dCQS=>-*Ulep2 z2qxrJEdqzTbG|(Gx^a@4QSLZ+kk~I>?wFZZl__5Vu8PBJjJxTQ7|)eJ$Z@fp!%v+D z4?Z`pYkustng~hua{7|>)^Sh@l8&9&Uy; zbRE&OU}1+w6MaEYOjY8{6rwfYA2rW;lXF%dt7%&3WBIeBzNgD69>H zRC)_KHg-hr7A(#2(Mvti+JKSI)?<>JoPj02@(y=wWSn;_(w|eBb2f+<+ckhwLBGlI z5&C+puk&LaR7y3Da0@-T2iuil)-=B~r#SDuD<}|F`jG4OKCH1w^@Ar+MGSYKIyUBc zUhk`xpb0%us5@nya7ieqE9v-1>#<`^2J`b4d`RVzBKdugKw{A;Xu+7CK+qLRG2hKNv1m4*hL9;@ciU%_wWLkZM}i-JJW9108NppraC z{5Uh8&?HJ&9w=hd@u8dwQIc1kky69T|Ldhzz*8MnQs7o4f_`{uiSyX~^2{yKB#M(b{8 zrytzMXT&%KrJVY333zIS31am29j?rZW}|H02p%Wrt7>d#|8Q_0%iXD``r92B(T*J} zXV9y}9pfm!A1#_Te?IdRlEj?|myVzA-*-5bp@ZcPtS+9R8PFF_k^%&tv6EjhX2W*+ z#*J(d<2qn<`-)7@XEtyxUIx@ZnX@@3;D^Y#Zyxg9R;dyF~)+9N&5 zA8%eYZm}9Qx{g)xIC!i&~+#W~n!MM!usV(`ufn}#x}cOCK45nHfnQnkNs-%2vP zLrWEXAF}DVuh*)w;Us+m-Rv*wA%ELJHy?9yWT!}+vg`10K1yAC%buZMPAEGw|Ax%r zH=E85b`@4#-l1N6d522ern9F)7@xpuMw$BHrn8)5=YU4l?$z2`mW)q~ES|r@=hfO{ z;2J(hf@>uHLivr9Q}k=hj}rbu;l#D3t+t^$We@yWmv(pS+U&iC>JEDhIVr!PfoQ>f zhzF*Z2Rz`j#7K8JzYzE|#BE(-z&r=nJc(0G0PwkiN#o{BF(De5@MI>~*HRczqf$!k3M2qw+}q&(uKBkHS~aqZk08?OjnrlPGmf=A=Pa0C^W?ea zw_l6tyGjhww{7%udpany(Y+K)J>hL?s`zbq(fp%p-G}1c!nwH<*K?@GpJuD5P*<^) z<>!;X!Ogcun=?>ffIX%PE)oSrY>_u6DDzJH7am* z&q&EquK`$; zFj+2>5?JF;w_Ph5E32T3pc)mpbY^wkC5`6a@A6rBATGO>_N~FiEw121eiS*?$NJ}z z*EiE6@THW^eOo$AGeTPiO0rPhP7en64#sorC7|vrSLcfORbET@QFi)vV*8EZn##Pl z!^1Hh)Gj3-=M&8iUk9bWzq&6jA0dCM=)QoFj!;GOJN|}9`GC*w_=Vsr9zf`AgYubeaKf}{hO$0k5Sf}9|j5L$o0<1h^$lepo&I5t9l3OnPDx7&`VZN*2GhU4x zWIMOTcjRYZvB!wSva@A_Th{f{UbndnURiFT7r3`;>Gdp^kDZCR_K~7#MjN;jt9ex7 zs(Do7U5=Gk$g_WVC%@e`U5C#oQNUj(Q6NyijWec7o}CVg>9&!g$wnL4A{ktO1N6m! z>nKBzP@(|a6b@EFA=Nw_@h%^4lui~pMgsH%RKcp*Zs z$dRIyG#x&J>42HCYakK;e3GdQVGq9~GzrrW@AZxIbq=+#Op15;(s}gFuQ)sHp@gg| zpT^Q`=f|Vp-D)nI9V~i=`Wk%~QTAY&vyi))TE2-uW5K8R8+;Y}1=h+RRaK2&uTFUv zc&bxYEI`U;A-yc86V#YWyNKN_b&Nvjl>um8f6=<2Di0d7IX6*{3GY~fo1Mjid9 zLKwGVs&qo>P%$}fLvsBWej&y!)%Zx^3cvwwaZw^7a7a$P*d6d%U$(Px1&F+`(n9b` zd{*k=_Tq-B8gec4PCX?3)G>1r2YFz1b5>4B(VJ2|Fko`&UYX(DQy8l|Eu<)?ymOTI zL>fQ*c3u}pO$M*cb;O~4A0Fq}w-HT&4EF*5zRr|7Iy-pNHR(Wsm+xmqToGXr*_b;0%-Er1VY~ne+wV+d35=(-;6VU>ZKASYU<0gsrgTF$I(%Rkm?kCy;jE zDE(WnZ~)%{%Ylb;?>hGnsbtc7DnoaK=0E*0I*jZ zAC|bYQ=Mi6(Ki6zkm6(+=u5&PUZ4W z(_Z|-UAE882kI~6p)XZiVuV~5BYu+8;fxqh;>wHVXT(4P(p24Y5+oN*l{iqsueQVh zxh`6F8rL$lCGr-UY!D61yrg^+%mtW1J`>{+Laqx~re<1+n^ekF0uF^UazXd`)j->a z5JEuxbpS%33jl>c&`*i+B&?jOiy<}X3or_)ujR_dD6oBPmLSuqpu@o4b4BHJu zpM0P4*Lk+dAQ=Ah(5C&pe>ebU-~t$WW!hX-yLyfoSz_~z(g6CL29AoWA`8@iEx4G` zWo-PpuZ-(fw_#GXe%;%yQsI{#ze@3uU6{|Pd+XAU?N;4#kCQTgGf!eP@XbLE?A$AX z`uld-&b{KVvt1%)*})}7+a;oP_wAx{Z{|se2ELib1(=1lOZWpCzy+8==wU9v%png- zLZUAg&flE$WzD2grV?;CG9wqb0aUU_zz89rDsccI3={@I;k?2*T^B=Y4P;OPOwJxT zE?~@305*ULjR}IqQedzFY&Q&j@_qSZyV)j#VE7L-sK56QJ8&*=0r2r8{~4K`D2G0e z^5^?k{@5H?&G>-vnRq^j6x%`&o@d*?Exb^avAla4p9Z<$cs|S z9nbSy4Exmmo9zdpl%n2@#%-}vYX9tD(Lsw+F71;dG+b!5?`$&lO3jR{`?cN_hgJ_l zt5L9M)spLC@)4_U<)For!J!DgiuwGSPpEWZMe}QJgw08M=WD(-rRU0>tWPZlR}R*J zVK6H!!Ofa;{7O7+l7xoHRmY01v&&D@Rdk&ns08;Q%~NzaSfA=FJy$q`E?9aFTFqes zG!SG2!-UWReB9IVF^IDj(40Z&DfpNcg2R($$le(&bhFucWCr-KO>QlfYyeSUi0bsI*g~fmW(bLm(&7{LT&_11rgKt9pMb)$hn(3 zRTrQHf;hAwbqmX1_x|h`nGx39Mi%NeZRd} zsm&MT7iA`c^ZD`omKJSuk77*QmZyVONq6i=?p!g`t^6J@RTZI3lSk2b9<#8km{4 zd=tzCnCDPHiO?pIfGfQwmAFZzOeNq@I3pKy|3WW27DfmG_16Iifi3_P0zudO&Yf_1 zsxF4qhhKm}04yM9mme1}W+?#6!Gy*H!LT&vuJfu~KZXt!rEObkgSol7q{X<8SiiW?r2$ON zs-J()bcnzHA=Xmp>fDM-E80c#emhKbd@yoDjy}pgc@gdvLWTN`&|qIwXGvXVlai`7 zF*mFDWJBJoth=-Zg`cL7Dg}8=9-U3s-l8NUs<_z3Ju;mW*WG~(V=4-W| zXo4nYr8S==zQDfT603EN&TjI{Ju>KYM}$Rjd`+}H%{`~@G4EWVV@l@?%K~JggD^+e zlw0r35lRyF8K08n8_-pBNQEi^W*(VUY?np&<{BZ2P4CFPtbdde9cg)+_!4=Pvmea+ z$k=O3+f&7BFubk{K*_kAmy)M@cVz;*Xa5}6I*kmsoeD=1H(Q8&Cv=})HODiUwBxRG zASeAz=pn&Xug_()R6X?BQZH8(6wn9F#kwldFCLw^+;lMI&6Nt@+)irXfHrY0rEYV* zoKlpP;%yQCvs0#FeLdrlDYlG?D_Z?v(P4v*XrqjD-!|!8EymYfk`t8E=ufC1owFZa;og6tL+_A#7q?$e zMITj|=9`+dZSk$57E$?ai(@`J@(BrZRW!8l8Gu7GbQM(Ii#@eC^f#;^X2wb_ZQ7wU4Aqm-DYdFTQ_>3k==oIF9((K3c1qLwN6APec$>nRjFacp)vzfePc zpnfLiR;;mLMMa{vt&5$wJSc9+N#{u*5!E%|TjAwjt9L>i;1+u%<2L`A890}3Ri$h- zP^TLtb3b`>g#VW1leMaLPr#Rv$99|wnR}Kyaqd|@p#{suvZV~vk01;JA;Jnk7?aK* z9w&r|uuN&TEQHaO3`u+qE4HppW)OhyF<16!+6;D!2P4Dv4iBt-`BYkL!$8zkfo{V- zInjQ+c}B5>)vLaj+X^l&E!(B^+D4&N%P6e%=g!`dp_1;9Ymcd)w2<3vPxGj1?O~IL z4}9`}ar$4nCYtsaXN<&pwn+HEjX<)~*RAIkvN%?_1PqB<94lWU5EyoijRGHFVzoVN zScU{63y$(#d-#lCDwtSoJ@;0mqqfadT@d9G0nRX3UGy}qLKYl_lLbv^U5wm*GH}e80-@)eh2yqPAkDg)`nO*32lA3x1wH(-#!0DMS;*~R zF;~z_jBsG&wp5e;Viiw91Q@TJ#s!##aN_=e250ylt4_6Qgu1XLvsAcTR!ASj>CaZcC8kXi#7lmL^nM~({^vlM_0U_xVp zV6hY!YyjI0L!W$K-f1V>WDpGhfj8{G_YXU8E^qfJy41F;z)0 zs|m~^5;;Z<0RykK-2tr)&kFMAFo#O13vxREO`p3ln1-|-nue6Kr;qrThuih%)RTRk z2Z&%KmLw?Duo=u1vVo+5`D)-lJ|CLQ1fOT9c4DA$+95Emi>imj<7>%tnc`QBu3aAC zW)t^aW%%v>mLCE-l{=5QE*p7R^}y7(k&t48@LBsTKB<&$HWVgggWKSiCUwcnqnOyJ z`0WmLUE2HgF`qH)k??^>h$K+>lDNc(bgA4a++PPi1cp&LDNf;mi!*l}$yqEEkG?crq=z<831Cja$26uH!?SfNKBib;av?C1X=@lPc}zhOkpnws zD+|&ZitFEbMF6-ESPpr3OwfOHG)(*%LJ2u}!q=vib&RO|M@PeT>eV_n*7@ff@?dnA0|5o+Zxe7S9jQR{_rRH(lWdd4(Ui5Lga*cudfLbTmwihfqRJp71rOK#Zu&?C4@U`30A`vUx6d z6wiG{Djvl8HlZ$=`5Hx++eE&tsafjNq%E+~cepLH;E>Jkw|8z9@Lou{UF^`=w#oSB zw>2iYuho9YM{YvcWC{Dx21|TNmWrd{H=Cj|2ku)9Q&U<;Iv!t?J+;{IIQ_hAU|7O- z%8S+NZiZ?{UanRTg0EDyszv3k7Tr>-<}*r}S7A~uinUr4BVorU1g^yFxDhZbEJ4za zd+XShn(ZVB*(IwvgA&*&({u$Thyj)09;A7SE-^d42K=Ic8FazY-3*U^m;em~rNJ;E zw9$ZP%`|*W;;XXUiw&pXV_FCf$JAhZr(4*WGOutG(c`wCJn?>G)lZ)VAH08kPn)aM zmQ@>^dC${xzp~H!5-E+36_(?bsha-gJMj!fFrZnAr zJ~AA;quQ_Lrlo?hmGYf|y1ws?cBk|F1SNHst8T%Ir5#ufhF(sT?=}R3C=2{`U#Z&O z*$Rd+IOvyC_>49!h`Ex&CJ#zNE}tmeZ3qTzrg9|$<_jroSeOf927@RN7sLz(QB>)g zhF}l{j3ZAfWhwy&PJLMA6fWp~$mO|(n_z?hC_4opgmf`MXuMKAGEEmls*^S_2!I9T zbIZpCj9Ypkh0lNijR}IqQh+&N0{WEu;&}FCBMW{Z#G_LoVFs%463Z(pmYk*Ao}NoN zdU^+ie0qmN+FwhI5Rd#z1M22P&PgSIHg8lgviH|BMtuuX9xdt`{Ta7`NdL}&rN{?KH;Ib!9d1cC@%`)%6rW_|d#?8S%cb^50dL(4_f*}6$9^qICkYu9x3erNzrCFh^DuKMUEZo`i948XLzc zU>_UDNtI$N&@MU_qLQ-*{MM!@7nQAEwSW$OvbJrHJ*`%c)EjZKV+~n2qwnDMplIH2 zHL10n{pFkE*@**Iw9$&aUrvDG6UkvPOvHQ4>ok|GV0HbZU)J?MBefeCmX{*mW_-Gr zz^3?}J*PvU9;f?lPPNiYh1d>%1g6m3D{jyJayFKM9Ib{r4d31*zgn*T)joTWk$Rlb za^Tl^eH!`b7V)seTRttR z=xWOs3qM!{#hX;lr{bRR9?D6(H7EH8n^$K2)s6`B;DF6Bzb5~dZt0+@mf;}^cRkhI z*y&SB;J}>f=TEpZ&Up4NyH{Si=?(Xywm{bqsZoJLQg#w;QCSZ;p2L2~$ z4G@LE@AH27E2?U$PX2M27v;i{STd$N{Km>NCteTKO~ZK2oUU;ZX5u-zGbJt>Lb zjBRQUK8?Uv3u|+X9tCyjR}0#-wMwb_+smB~s?4ga%YIV1^p1R|737a(1xFI?Ny>h| zRC><(4d?KV4*t3s*rXVm+5AOn^xJbw>f9%^C5YI)ud)nXvg)WKHBw~zX2lNWlmmtI zBtN(Ok3VfLZ4lQ{HuR}5&w1PVOgQ>S)UR;j&mL>qEt%2JCFBlsg-@eo<<<7$u5Qx4 zqn$b})V*D%!$bX}?Qx@4qa#tgm6ZkFL-m+J@*AO1@3PpDfhR}5g?G$VepZ`jvEglt z>m$#%jq`^K$u#2VLd869Y-jEHr217(`O5^$8-A`+rt;RmxyoDR^YnY4M>-eU6Gy%o z`q3?Hpu6u<%V+QUT%451NJ~-AW7mhd-_4DQ2dldDw(KU(DSkHkprMnup|kdWqi|M_ ze*PNX)U=L4qu1oH^pzHe3+l{{ghp7hx{rqWnOGO`}O{PJ@_?AeN;gM)jM=p-)5V z!R7vaw8lLAQELhY;~P>d4>af;#hDR&d4DSQX!rEhKccn{#3*&v zi7#!s*3k7jmK@7_zg~P#v9_1j&vK&3m&6NHUEjiiyHdKt+`|K-u8j)HY!5RthZTI0 z1h?J!l}Zb>wDivuRA|{DYD2=ML~_F|l>8c%j)!*@x7=M;>bp+F&3nsFql{XA3s0Xi zVPt3Rs-~Myo6-l4w&vw|77)5pOiW*W@5{KJQBrDbsW4<(`bOEbFUhUT-|s*!+UA_w zr(9aawO_76-U?TiH?Aq$fA^obcE?sD2YG+lH%#c~ z(9k!IsebmQUNkOzI+}W;Grf#F%$b0BE*u&f#5+{R`zBkvr_yJeGD`p8v!K7Cj$ro+ zja;bnuKxBt#_?g4Sf9d&;xy%ND@9hvhkO)o@skx6xt<iY$pcKp>sOO5(b zU%X!Vw(>LU4OccviWTSeT}tt=sreP@`mOeGz_;*c`~{cooewM9Kdx>1`6k0zxwD;w z3t8~eG1W}7)T=`^rQ;XMf_KRV0k4Q1D^|wepx(#ZOL^I9Ja-i834Y%q@6@P}w8k^0 z*yXRUo&|oU8uqoz;`)eo1%#RleFGls*v|B}7d>1ZKfi_^9CopC9&{h^KAINA6&l_n zU7Y7Cl;pKtDGV$D$N>qmCp3ba~TTAs5_e~m}` zH6Pr(ZN(uyY~7FZMCQa~7?)CM!yfPLa-Q`Jv{GaHO;XB6cocl=cLox#u90gI3-Kae zZAT{ea8*4YlI*d^HJ)f{e;B;=hsp51?=Rva?*Mkgua9d=4|GUnjFe__DY(7F){3R~ zH?@PGbqi@|i?~*u6mly|y`*TGPOgkPMd96Jw!}nq@m!bYIYhqlIYjui( zmcsQK=kR)3W>jW7iQ3iiS5>*9sh6i&h};9xm-qPY)fSty5v6T zLtbkmJLGuX^xs(~PChCy#Sy;NN7^rSZ{`NI+54u&Utd&s)u`C=^oa7$ zFN32a!=v9n`P^`elprU5ecQSza!dA}oL1ELqf&Xpx09q>`YyCOS6!hrTnPrPkars;s$nYCcrtWbyoW3>)v=-1mx;6;B5YDu< zLAH~?QcqxAM|e3LQ6zJLM#g%KNXGJtNaiYyV~aWhU|@|$#`0-MSgI(Jxu7FM3W^~G z#gGE6CyQe+rXWEfJID?!OJq{uR)$TFnJ zGO#e02xF`r1lEy+70EKBFcupUWv;x4VMu{i2n1M|Ygu56gh?zIffKD1{OJn6vo<;qRge~unZ|!hDBJ06f8pu zmLUbpkb-4M!7`*U7vh9gfCR{J3@Ol>eb5y{3XUNK$B=?!NWn3r;22Vn(hQTpB7+d8 z$-l5*4WwvNYl7>&l&*^f1zzHG4}oL{+6Guw%6P^#F=f%vvVbTI@FhkT3lm`t zQq_gllR6{{R=I&!=M>#IeOa%GRde9h^@k{sVDUth3|bb1gk@>Ye+CBRZc@u$jBC`nl~5((NVt8y0q&(?CNIsTz?7O$hg5}?z)E-lN9 z#f)Bu*Z*VjIg|nZP%}~*1(t}FkpVdptk3$ttA?`9AFBop4-GAMI!QH)$7g3Xl*qev&eo(S&XC%3as0O0gH|OlOW)Sf$ydRL2MKNPEW9|Qw^(-es1V1GGAutq1 zT2dAxgOmYJ8UH@8S!7BSMphCj16GknPeR5Lwtv)Rvq+;Xu^fjmDV89ta?-!+(;b|q ztTM|Iw^^i9uokkUG!|5Ar07K5`DakfCbj+s1z7GECoK)Nxc}N0v&gb60YQOPV`0}% zas?74iT-Usm>v40^;%hCGK-Xp1k0YIak5D8uqyk{1DQ?U1-TuEmBxbSYgQmEZRdaR z2>dGbhuMWCGSX;C*=doH!GeY2e;b*}3$IVa1b&PALj*`P20Z%8p}>0?Q2)z!VVXo?k&QPKHXO@I4wRMwZ~niF@T8qNSVB0991lGaqCoBh<7YDeAc9%s zZzS}vhm}KtAwO0GEG_N7^1&=pGY-^ZBuWkpV1k9>neJu{0vZSHQS-YXjBl>+-*3>t z61rKWYS8e&6M`HXyzBh`$32Vm{u|sAjq?A}-?QiuCaTEh}p#O0kv*{aV#=#P=|G^)#=pk6bGOln^Sim+$j6Jkw zYIuLXM1V-5~a$vdv`d>mbi>F`?f8W~l}L7apEPk1;VugaUgEG6r8K z)d<K)rk7{5W({>|1jJC1`$it z{s|w!Q$qg`5lhgW)jt4X7ODF;5GI23UwUB{$$BCV6S^ij0s1QNw~wV(F3|4ZV82=`u-C8^eiKV1 zW|5!4w^WkSU`D1iPV^rJF^io18xSn9_%A&HPh|hYtilqFacz^Lfsy;0FNS}+6Z1q^ z;OX>#2nGda$e_X2(%>fzV3P0*52#=y`+r0;i>Kw^pkay6|BPl9>6Il=<7y`b3QToC z{eJk%+{q44LEzm9V1sXxB_7)J8rl}!(iU%N2ig*W1okR-ary7ypF=+z)UxcEck^L zH0_2_7ynN{&LZ*u1|&qGOnNO-G_CvfU`EL#0243a|CI+=QvcuVe2T7oWQS&M6#^*1)Uv&2rBPu>u zbFBaC;)5-sMtd7Gzh8}tOOpEeu{CN`F;6k-XYHLhiS$}@z(AXkEOXJ-+Asc1hia>cuHKq0UP}|tZ#MTDJ$0*=U;b|B zJN~FGMKw}2tCkGWMSm2@>(=eIdwyJ9%d;ppvN z+wN=KE3@oyN>%ACyTEq$iMS-nx%E5t(R*^zWUC??tKM1sux?wcJ<8cw_HwmxQbZU= z^=;zy&ApmpgszBduf?i-$*r`r3IRFG*aHNM__n)x&6SG^i@3H(e?`q`q@a$rV8fm= znF=%OftA;!io=qu1_T87W837AUU%I?TW?FBxfAJ)EG=Gfqu}1#wz_CoGb=2{SrjlAoab@MVyY`{grQtaGV+vLkk98&EBA!TU=>S-#@%# zk%suLJv*GQE3bBXjQq@X_`r_?W(vXk3%pfVdwKL&#}7vbhUSufe7#U%v`^z_XO6P> z&3FN;=JJXEKkV(a^I zna9Rb%@h3ETJ~9QGAp0Y3-1ZfX<4@v~k{eur%M-ay9v?g#BThV31VE%lxOGkML!+Yj7vgEZnwYwsg2!?nzm| z+b@>5Vhw*DPaRv{I)114oT$;`737}p#g|*%D$`F5+m)pXUfbZ17kR#Lxw}~U9gY(> zf*0eqO7GaHh0d;#coVd1J7IyDM(>i9(!T4%?|m{qgS31QLYr@W&E%YnBxc#)9Yxm<@;Q`Tl>x^91 z{g8Q-hN-Joqb;TH-?8b{rNSa}8TC7NmIfd~&TLg#XhS@3`F8XRuK5;M>-7G5pMqSv zwqHl5EWkdO|1{~P&gIlOkw&H$4k}+?#r0+du2bq>Ma$vyRYR{{Mm*)P5$#)ILE47h zec-PbxHH>AyBB3VbPAbwblWa$_o;>Vj>QUAuJw|UcqD8?I;Xbxs8&Pj)?2M>HP0-; zsmrNoYCWn;u(&}Ys)X-b+A8Z}92Tw5xj5h{F+OQQ z$rV8cZW>J#Ti}20ZN-59Gj)|(4xW=Jns8R__Uj*S&ExLvKIo8=8mzSt^JD+Z#!u_E zL@!OiKjY##E5uQ}Oti&vfsuCFOOvz>JX>OOIR#fBn^Cd3Yx0kuPLgkG-&&}-$^Cj? z{Eme?HmujEIetY#t8kSj$L@iW5FNcCy>%&RTqk(gQjgSa=8_QEPw71;P-0@Wg!DN! zH~p?elDV$4!Tw;+%>+^`!hY$lT8Hgb-TQQwW70F(_jRoLv`|n&qjqJA%KaDiF2~pT zN^l%KZK3`+F-3<^{w}P#q7z|tRCykcoI{xWO4K3^s&TnP+ZD{y?jS5$ z^{{s}O0V}UCs)l?ew1Fsy_W0u_dc~Qxo9l2?n+u1-;U**7L9E360M5GyRDlOmwY)b zw>nh6CZbBz=8*sL3%$~rTX6GFi)~t$7>eRpZ--)!a@s15(Ab4Aedp?gN(=BNO^m z0{ez*-Nl#q9A9y~3Vr*{GQ}&FBwf)``hDSDt&4lK%AU2G{T2E3YGVWUd|!`ehu7~o z^riVa`!m_Ys5Ngr7Uasu(d3_3efqfi%%wv$`$}`OpP$EB((i|S*&!(GvL`7v#g!QN z7h-3);RrIzCQd>DCFR(z1iwcmAdHqhZ`%G8o6>PZ)(!mXqRTHfLn9% zTJj;mU1#>}R#duwF@K#M`_f&l6;>CAggh4P`zd)^>+XQwV6e%%eUFGvE7sS@dc53S zVtW2|a6f*}R=@2({`ynp!NGjfq(#;unnM)cf4lazbaJnsy5Z@u$e(G&nc%P@smJpw7*_J-AH*epCKl5mrYEtgfFOn%wU6o(mnO9o>deNK(X`F#4>|+P% z_j;}GJlGoi_QI9IM_5hqJdNrI_A5eP>*K{l-c=+tU#qsvY*o{VH91~VNv}DVaq>+$ zz2ZY}3ZZV^yPI$L!ZGJb6k;uA4Hd(^RHMmSHPsRAL?O+2=vsg6gsXgqQi~S3YOmLz zb^VEmJgv*iPn)wRba)@Q5w?nOAWgvOvhn-*+LtPVp6o7v6Y^;DQsV{4KF=ius$5SB zzT6A7?f-w&y>(nx+u8*xE!{{8NH;ItNOwqwba!{RbP19oB@NObNK1!wcZqZ(c^7W? zcieH#Z+pM*{I2&8e0`B{tY@t`pE<`IV{9<%5!C0s?Mjlh54fmmMzkUuWAItMUZNi# z^_sB-Jq~{f*%V`%Wi)|;MonSt17>P6-{~4h9{CtyKPl63)5FalNA`H9jML)!KsN7a zp#RwabWmi0m)#S2Zff4>G_9!7BZ*>d75~s5_uR$p{9%2@?X=OtsExDYrq=WJhKEHs zxCdz2lYR4qfLs68jSdQn)N=FtTd;t6kG^xZaqH<_Wcjtk`KE>ho5DixJR0^9m=Cdu z<;JeZFgVy{A=aMsCtvGK2p7>YYcn<(oFCO49qYuK1w8$$`vi#bFY9c1Jrg4ac|Ch0 zYe%B{##Dhp#>mi2PteAdNb_F5&kAe?GO@GXA7GG7^Wq{x$n#R!5edLU47tL%Zq2sIq&p!U@%C2t zPzTAmr(PcJcu((=CpjpKXV({@wizukrgFf@IVkZdaTg24=Bu?dSe7fLM3y^m_8XoX zseDX((95r&gDacSKD>scueClpq6uzUE036hnFc1fYK1iwqIgzUPe^Y02%UK$OEHA578c!@_qZu{nn?BdXLt1<{XQ{4?UD@J3 z_Od&^=DR(VcBHVQo~NyChYdQ-m$#G1m55R+K4TnbE@dRk+&c&?A^Qka4?;9O4Ja2T zOd^gQTKQ|fI-T1r3RN$3q)q4WK{3HTrEi_-e@~!nt|yf$=$D<|qmOVw>IuiERBJMK zR98j|N|PWGsg@nJLa=*tz{tSU7Ul!?C7sngAj1(c0{F<-XL9t!Z5_HYiWCYcHtLR;C8 zKARTYvFsPUfGKtkiGJr=U)?z`W+8AIUd~p3(m#Ol8TlgMz92}ryo^sZ19f>cgKF8U~MrSyf6k84R<=3fj;OE{Z|+U9DAR=@bS zRfMCSket~T;+09D*HsrXcX9DI2}p+TGaW;(mBaRk<%bh1D}@f{gJnJGn}Ut4gy4A5 z$k3XNNWkVu1UDVIniguaJ@hJnjVxVZdKuBBP|)E_6wFT;Z#=zn_|XiF>&4;6FFZ9= zMXEa&&-epq91bLUxZ=y7igV|Uy|zYX+^9JukzPAymw9Y zmD{5N_kILAieO?z-F`%bbQ+^jsk;7bR@wE@9q;)K)UOQMYwJ97x$j87Pq~rN{*69ErR=pzEkI{+g-J!f!U@dX4*5ALq-&wDdgE+ivsMCZABa zpdHl5)~d67^l~~@WMB1(Npx>kJDJH`V&YN6pZ9)NRH#)Hk`kq(t1YkNZc2vFllpSI zsY{Aq3}crM^W}|2WV0-@skL0<>UQ!6|KuduS36?;JV&oc`Y$G~BcXQRn(tAG=4$Z{ zZxHUOpkJoVX&z?}@QS^<7`IKbR<8|dx-?)aqiQUip9l>&+w4iM6VB)vq`D#tRkx(mt8~m!7ZZB>1NnvbHlI#uIOfP-@Y`o*}GA}sE5`U zjAW0+67AjaeS*2;S&Pu-Zqu$>?q2oLZ4SqDB9x@{xi`g^yX*9v>8>8wY9=}c!NOetUiL4@enOxB?ConD5 z=40ISfJ<JII-Js-d0ycjRf4VKzBSqzv9IEh%8dq8C)JBuz?8%W$hXX z%-@I_e2?65EPV3t1!YESpz5cTC(_g#Zs@NGl}yC3rBrnoEqRqKsV)}VDtUF$Bp#YC zfEa%@2Q@`QAefh5YalOA9a)!lfOnk1RzAc8Y-O8UNeZ2$yea|)KC>crXrfy`exo$863Q37$%L3e zCgvd$foJY;Xl?y>0s6QPP;*IaQ0dA2>ri8L#T|q#_SA+=S0c;6+Qj@iA{(Qm5R7XK zpoSk-P^bphFKHwe$G@A>eKUn>=xN!ifo`Ucx`h*%_)I%33OkV7gc=QY(~p9~)y$ctE=b zz02K%$5I%HQ|-Z7+t^>fBotc*v074->$St@2aDzA=n0XrlOErgBc{UDyn7}M5fn3R z+H$}2d9mMO;fgX@fXfn?ZG=asA{0F2QV=3tBdQ1!A{}g@iHQ4pl4&g;?96Oo=Il)- zntS&FwWd%oX|uTP!R44>aK{TL9{Vrx?{FlJuy7>EPS6xUkuUKt&av=>3&o<0p$O!b z72*ua2$S6hdzUJeaj;r1e!y;7@pyePuP^rK7YJ!ZFJuT}4Ys`VF_7 zgh3_vMQ^I3);bz$fz?k@-f`M`=oo5H^#dj8FXCE6UlXXls)*U=;I?5SGo>EuLUAXD zNf0c5&9&lr*HJ@dO}B?oL?tP1VO{hBI~!6%V30un(cW~??fNFO`6~r!c(^9#HDLKu z+cv<2h&g%?XB^WOa$}u_RuHM05N?)~J|)xc*=ddYaSU5#&^#&5yj>AdF<*H?0go6I z-c~pi7OL+0o{~^0MM84zVNv!7YM2D|l!TJBw1T@qyRfS96zRlR>9cr@IJX^2|1fUC z9tAjy#KI&)D)rdZji98I4%|8=bGa~K`%>-E8G43M>cVN*lN`^o{NjSsnHLV?`fb|v zWK`sFre1>I7C;hl{U44<4`+|C610y?*wQUW_dma7C?$}+7$|wk2rehyr@tI zbe3LgfJ3k*HjS;Y%O{qotrtAvvapJ!)!2soLhC@AD~j6n@p-In&gGOwR!vgEg4feZ z4A@0D{Gxe^5*u~X%aP%$DD$A%12={U3Z#IJ?0y$R_=nI*yExmym^CAqlvw&+Z8W4a zFB4mM!s~*DDLSY`RUgioDHrcOp>aG<03z4aQtRL93b2Cd5!ViDT4K7Xsf#3vnvs#2 zYVPF3F6hssfl1*Nk7*-*_0_0^X3wqGtfUW~C~aNKJhgzcXn(7=J*<1gQe}x)!kel; zSEYVS5bJC;HBn-PhkaCHqxiPoPVt?SHR7&2?pT{U*FN9sr-I9hO7=Xh1NAUrvp8(5 zKnreuiTe9hkU526k`0K46cKJ8m#TG-J+SC0pUEc4qSbQW_+sJPr*h&aE2x#h1tHJp zlOhdq56nCg$S03s7zX6_1QQ2T@#v$vNXh(=Nm+;OCs0tHzzp8{ze#5eI3ksyo_n}g zK#XZ1_5La1rurGDNi~1dC^26$@z!OPORURU@P0?+JYRuD=}{C4a(CD8s_&Ot7dNq_ zIawdaWS5V~;KS4C&UAANPwqIpZIpe4uJ_u{eQs`HAO~(4?4zHb9iLV&dT_QFSnosm zMi98(`Pt22<~m$-1>Dqsn14RkyXXVvII7S3cWa%$5MclNwa#yAn?J90es|jg0roog z9%&%Pd$#EQ^`4Nqf4%2C{woe>zx~R8N@uVD24C#VfXCbqu3t>R(M(2mHfF#f@87w8 z3EbPEDSdNP6EJWD_!I_3A_ipziTe*CN>fKiTL&%%1`{(!Qzw0T0~;%b-xyRnOFeyu z-~X;}>14#iFaQ~{vK#6d8F7L**o=*s^o^N;{|TodGdrsh zgM+;RK-~O`K>zKs{zI(HfT0B&8;BinsQUpd%RQmP2q)H&O!}&e#Eq1VEAvP|$yCr1pPRSUNL%D+YZ_8-1X-#vDdQjBFr7HbXrQLy!T8 zQ=gUDh@FvxmBrYARUdE>Vq($%t+)&l_Ez)`HkN-X@=x%CzxliXdfguo5-|a^J39*_ z8(`#kZxHc!dW&BX_m4J$|6zB74Ny=0VRwUf)|#frZvPsNkKtXVSMvjSFt!z1T~c_P zGuj=F0|?Hz#)tV2y49iNt%$JW%uk$ zwt_p_2xn2W4a^n<<%>xHyNh+AfTUtnZ4IPXU?&qs`N>t8yk%A3lrmE#ZeQ?$&F^oHMO=ToQHNjyN<;7(HH& z4!I*X2qq5#N00iLNOG6S8AAwJ>L z>yH%L$o#F*NmcKNb)#o+81OL!Srme0&ReOl$M%q$ua^0J)ShvFVk=sjY-3RB$Jv&? zDb+nBu#7oVK2^?XlL#<|snBR}&9g@fPH2L_ir#@Pj>lx&+G`WaSWg z7dX7=Q^&-$%jgaHbn$nuj~6#r>W@rQQ{qZ3mq z9@?4HYdZ_+>-CH~7IZZhsDe|R%qX|NDs;kVT)a%eEUQ7gm2Wib`V5$b~^}>+s=ACb{2-a~*w=gr06=nwtCgls*1KAkg zPI670wa{9#j&rdZxK7;4*0GIVjLa~W4^OBM0c+x^+mv@(I9eDkii{e8J*sy?{%(^e z@7FfoPwuCENQkc(cH=#HzjZ1;_Ky~O8ya)T=H{>L=1 z3kQgC57^%Dx?~>Im*-=jVPlP_At-yCBprkgK75@}&dGnAmT=3-YamN29EN3wwR{&g zAla}B`4m%VGyRlzInT93(W5kfyZXFv6aKu=(KaTf%k=tbPmQEb_!<52e*gNgrcOeG z2~%j_CXJ?&RKlK}EJ4tl%w7*{qecShs`wLe+z|d2()YnGAX=Fs>AP+~U(4HIMg{sO#bRx_!e&8!J$x>BtLd@PIR^F7JkWSSu zh4*7FY-+C%7Iy4!`;zo|OyM+*OhLt5Rue~0HjXJCg*@5VWzawggPwGFL5Cv>#w0WR zM2Dfvw+Ea($S8+U;etL_tMbX!aKvzt1hkDXw)>*<4nuNt#9PU2GtR0l{|j7LOGj{~ zI^Lo+j1CE`u9E7sv3mu|utaPz8X z4Lt=FNYh9nH35;tR~+^&hDG_T2^qcVNY>$|A$9?g7!b5^=a!!yV=fIq3?5<`kD{U zMi7VMrnf>NQP$cg;w^zM!*Hym0q$wpp2mCz3rWN)5^UHa7~v0*H6)9hy3o?>HbyxTS6<5U4n72-}7_**Or zyV}_r8F^RkwnPt*$0VllQXz=J$|V~Xrtl*=f|w?pdRMYit9m{aS`)m)!3%KdoMlE*sts$7nQPD_ds(b{l={7nTLkoVJ{Rq80aUm3h7dG^ae z<_WV`Yzc?jY97XLPac->+i2pf+LpPytfTnw7p=X(or`&;5Gm_GeGMi$T~Ic|D|a&N zNb+9qNa#c5;p!I_;oC;~fSu?2RF&_Y21b!ak)0&`d!C8uKCIfYwIr4F4M0sg>K4ys z4av&{A<6prAs``nqj3qfB8QVH$z>un;P60Wy~D$o|7bSKvQx^-MI1g1y2f_gIAP?t zU}Y4{6rcbP*{00gMJVBAqHIT=wLTCX$_-Kdq8=TgxP85_?)BdKOA*>R{z`}GHOqdx z*=H7?(HrbOw(7(qss_y28lg`Juk{<`NHtCCR^TtE5#DO?I!~S%c$2<@=4ac|1xKo= zN9BCvS3rcmh!=ZIq)M2!|FXreT>&IigzF@4EQ~)G`Jy#h61amenXkD>^iLc`*LCOLGMPqXs<{8*B#8A2d2h8;Nx|fhDWhX!sgg@ka3P6A?-Uc_NEx| z);DR+?2C24oNQusS1wTzMt&+4)e@f7b&d8)unTk-2^wQByb4a&G7~m7mSKL-?JId? zp|WB%{8CaWGfw_UvMRm|^o0sy`rzpH0_|m2(rGp%M(@ z*B9=svLiYk?y=Fla9~7%Yj9Y6AK-1Fx$J@W*1@~6{wA+DqN#!oFl@ZQ3$s$=pq}JwZ^P> z3Qxa3nK`pk*EtE4ps49*>|k4t-W2=r zz}V#gK3!{kL?Y%%0FCXHEQKkC(O^SBVPYwB-6KmWK^SDC+w{}VB3i{J_d|cT-cld& z#4;oVdxP=39g*gQ3E!Jo`>mFQJ)j94rp|B?dA{fUCH2lXh<#9_(&FtMXxq9WZ5Zn7SyFSkqkAB&2jbmhj0 zm3^VdJ*XK8u$MAG0A?tpf=JdS56*on6(X%ml64Dwl+Yem_dlxPM{^V7I3yXha3-8=s%*4c1g`ZS+$^IW`={Sm!#%GF8TvDr=`l()XmE}S3z?rT+Y z+m)J1XKSAE^SS+Y_UE02L-X%Ps}c#2m{jR=u$}TD1CmQ#Z=gG9m8xfrG?%SNUc{j?)UbvXQB_|7+S zW(Oh9nLpt!bVYqsZ%sgdpZz|DKc*jHu$J(pR?^ew{3O~k_7*Q{owb>Zk=rMb=AGl) zHWOD$^POVc8z)FJP76#{I*UYV2Iq?B<&NFgb+;xy&@)7|UN0K zDkWaKqNt0KcQ?H|aX3$uKq4QU2Hm;Wjz`U*w%oIJ>U9jZ24fgJ$1B4C=VA9u{7`=_Pk_?ry)ww~3Gqc`A5z3WzMyH1aHLO@4hXqZ9h zq!j#Q#ST19wxhTU5|{dfGp=(PGEn=#Bsf^!l(o&eoODH-H<#IV<+9R)m#ATrp5Is_ zJ8h&NI^j6p(swkN*f5Em?hZKSeR(zE?FMHP?XS?}$*Gsz&Z09mv`y zIJ+)MqOO+(bS&Yciz?kNV`n6yW;a zk(W|wp%$ZRH0+eqnS-(us@Z%xgp*DV!=k|wtv)mUogL1%ebmeaRh{iib%(Pn#xfEq zs>@Y~+yl2_blaSiNXk}4cp<5KwCn+0?&RU8rrY?8T|*V2*0Rw?%$=eunQ?|Vh*7B~ zjy10)3}B2DJMkAj*Pk3n^6r=0nWrx{yv=rF-&KBRd!*FnxloEM+WzKDvw<&6V|8QC zer*_06)~8n_`t>TY$L@Xm3U?uE%Vc2s9xDzW~DohvPTV+j}#?av`fmhDnCHmN+5qRnWRjV61EBQR$c&)G< zpAG95eYOo3N`-Fss^x}!vTp2By}Wjcmux+cG9F}WrB+NbN~(GBQqBy+fsct%RY8Z3 zwL(86-AIJ+c(P2o$2ytLKKbx5l?oVMp?}GjMah*u*UB`<1#0q)ycK zGj^=9_&&(ZcV3KLJ`{3y7n?^eW^rYrx-LX?>o9ht9)u~O<4IYX5HdKZ>iakcr-ILF6Ma$FJ8$o}(OwoZMt^Zj z_32Pp(L%#R7)Ag6(E13AvS&-;mYWHad(;8)i$@p-tumm)dp^%2h=%iAfSKFg6A zD+oSjObSHfEy0qHf4Yn~f0Z&AEKf*`x$O0+9vp@%RwHMAL`s~KSpQ_r9+AnBeZ}F}YZx)(OSs3GLtSvZRAE-Ebf1|$KSfqY5O*OT zo-Rn&q(s&hPBhADgzgNkTe2018V4|37(On@wPfQ9R`4^87L78F5Bq3oPlp!%`tXMSEWf26vX6pB9mgq?WrB~;2fBWLgIx+Qm{mXld6>NEvA*2n0)@3 zq*J*3{$+eL4_~z%|bsQlFd+_R3WDr#7$+p zQKQnD&v;DCkkB_Rm5b{}@gMQx((Fbsgg)b9T!cct z`qKD$VCTbwc=`=MQk@e)dytLDoG z<8LC4stVeb5?^AjrIc@>dj=HK)ruH-_8P#&^S9zT_2Ma&TIFhd30mm>z}|=!U?sT$ z7f_HwfYSKF%u&aJw2~dY=OtzJ+k6dem6zh@!2XWFfKzpnJ!>fZFsC{M>nWXPd~Zrz zsb9BD&!jykg=M{pJxl1~gg(~z%gS|Ja;vze0eT~oPbKDNsT~XnitFftxahUdX_GYz zRQNzOL>XrTCdHA3Hh3P{vrs$+q%=;3?MkgvQ5khHZ3tvkROo1avfQTj@Z_&HM=-|e zwc1082>eH|OyZWK!#E-lslt3hvTU%r;VkC^b2=$WpTRYsp--}iHF4Q_RX<{Q=1H|I z=;4TgX8SY_pUxeT8oUSk1HUp+I%b618o5I~3&%UK+Hf%!2)r|ivsk&qP@ZTKX505O zi0E#3%$};oJDqR$l6z-O=S;7`F|pr#@us(d=(#=oXt+SImLB)O@nr?FQ<(8oh&P^$WB68@d(r7g^K)nr{6qx9s1Bn*rLV-{{rfqs)Np zjBj)+U|as%>vuZ#_c*iP^UOfs=vX4q_e3+$_ee9)_e?X;_fRts)AyhEJ=P3RgZ=h% zzXzLv00+Bozvp|j86ejB?fv&~Gtl>RGtl>VvwIcSx3B*ma0WQye}Dg-F8-cz2KpXy z2H4gA_V3?g&OpEAoc%X~w0^sk|BzY*G?+kG2?z)h`+->nvSsK21vw)S1@>R3k-syI z|C~lcYC;bw*Nu*gA8UIKye;XbCA^3ZD z3gE5=5*vO5&jgsr-}BhNK6a)*W4|A9{wa14VBF2f0vw=V1@L}9Q~(?v0T^|rZy8R2 zk1mi3^cSc6{}1bK28a^ujr9N(0)xcA9(fXJwm;ngKOyD@0r@e&K+FmxKmz{3-_^!M zfHoFzrDbISMmtuf`$U0X>N5NYos;EH*nj3+2@s>h!pg)7Bvt-^9f;NWT@?L`V+Z6e ze**s#XG{L2J^vR<;3OAdTMuGm20}>zYt8Qu#V@2@e^MAk&%!l75|Noz0|3U5l z{S4oIIPl+wq_P0c%pC0OoIt?s4~1t1LM)hAIRMbVeBn9R|M*W98eD??N|5N!t zfd92C{}=E-(dDrKgF0YY!U^R1vatMas_`we42Z|&ypO{G>>z*PX^x5WPo2)UHQPU} z{14y(*Au4STKoIJw*LWtZxDOm@c)v}{9nQUM4Jb!dV$JwvH{uF|Ee+2;M_Z(u(AV7 zY!<*V@$cOJ{&SyaY-VW$913PIwXrf{uy?YyHnL}Mv9Y&c&~q|0b9DG_vh=5SfcLzO zz2hIx4BI$4+B!KhINAT{oanbj_&+T0A25P|V1sXKw;wTr0H2kgF7SUJ<4-he_j583 zGzi!Z{ZKKWO98Ton1D49a6}fcCHlqs^&cBmAQSITWA{%qYkvR_psDM2LChJj^CP6VD|yo9{N{}ft?8;(43uv6WDBGW(VBNf88Ytu)z3Z<$o$x^1dVg z9sGUB@%L?+AHd(I>;1Zw{|oq^=+}Si?Ch+ZfC>fJ zq4`^btp7ZA|AeCBf3p=wBF)OkNC*4@`cwJ;Vp8x;VDq;fD>IOt2zZqOnO#K8K)N8u zZ{@#__+jP*CN4nw08C`RefF1}y8q1;_=(Pq3FugWoHaIJrv6v8i2#G+``8>tVB3Nj z(7gP@og1*V_^0y!MYr|u%YU!+;AG|iDh+5oes5EVfZRJkuPbMqu|5SdIPw9-v-;K8KAB;9`Dl>;RGS$HMnDu}u9|TN;e`kdGi_G(Xh5i?^_}`E5EWiW@u#JGo?+56>t~5OxBO6fo zUmZKJG@+AbVf#~y`;E%|hhzN@wf~Vfw-|J&j1m+U+V8Ry=vxzS3nZR-hAp=yG$^dFVo; zT0EVPS-;bPc{n>F|8O*5C2{M1dyy&=s?KkQ8Bk6M!jRR(mf>S2t&8arB<1xee%JBv zFraQQ!UBf@t3A-G?jo4xm5ZY?uI6H%3myca#UfHLifj%|VzU+R?hRj_&S-fq0;Gp7 zxY0JL_Zl*nm-6HVhp7b*Vi?WmCV9^kPe4v$lxKIV4Gxxov2fxWqCi46 zmxN#sNbTWt<kq!4L{Ux`cMb+QvD+Yw?R0ZRl?0(v&{|-#NC^r9eV;IZ*49@x5xB zHVhD(O?xfJpMERwm@PmM`=F?vQ%%j05tWxVBPSa2u0*jL)ismc=CJv=`7ta3wOk+!KukvE>q}cvyyr?_xK!LFqos12G$=C{>%hUv(^{WP=iM<0 z-i*SM^-|}M<-nnCR(;T_EVkJ~3#oC5sa^qYK;dK3lJ=)Auf~I1_`N%f&vACT&LVh)*8t6SyX`Zb+_w z4Z(GLu)Eb)Rs?PTWanj;!-8)BxPTm&|JlO}#AEDtfoX$xoHtL+Z)f^Nh?*?MpKCuE ztBjG3H9~#sQRtvI=&k1gkxr@PUOGt$zzzpUR;;X5Y}sOkw& zgxPOiYiSZ;o3DGl4PNF4^uimU`VrC{_K{9Q%iFvWF<-&#A~E>X{)HAM8-12FOOWmmn&R zVZvRUzo5J(=h-OKTPy6*VaOlnyL zpZGF;osUq?eWTasAU$bc4{=~u59~HL3+bouogCYQK!(?A_*Cr1e1hj(_1j;Yg}9tV zR4jQ$ms&PqZLfZC5Pb!Ot0$oy0BMfYLf6C1PX=GAE~R)xzp^oFp(nXOHkbFvbdnrt z{cXqc+)Kzt3$_e9HL$$sSu`EwTCxNBHzbVF@5o-5qCBHM3Ua}?z_DqmMuCf6F8PiLB3BW0Q*3F^c2T(^1n(Zby(gf3o0B6BiRy;ldfya1! z1Zak@Vjv8We4^cP#qf2iMRf49LvcT=d)1YHe%q$;@g#bK*C~>Dxm^v6nC=tC9pJkw$I{==7^5CN3EHDSN_#Xb!0^OU zUm%)Fn9v|P=-mu<*T=W#ey|bgLJa2_UNWyl$YYXpW~n~e-_4jyc=N-*>!D-&6s4@# zKz`)g=5qDQ4sIF8Kt+1Ku(M{jwL;%B7Vnhpyma*zvh8yOGXvxZ<7cv@$FDPK46Bu_iRsWMI`0|HFRXo&kHdyFqTqaPh{q&YWUda38BmeC{9Q8SCd z)!W-~)2rf(^>4pCj>K9!SW~NOC3uTlSoN5hno9i+;zOA(2 zQFGyNb^fZmGg#TTZsjQI^EA&JJw4?3Yh80N$uvPP4?(Y!Y5=q0gec5BLOSQ!*==B$>HjN<1e3c@b_4mGtTqXm{?7pe6o}sK!?O=@R znwf8v&mhNSI;*+G5cbf8ucAC!h=AE;5uGMIM{u8^Ae)~76N%* zZxpoj#>%*sdP>0>d~R}p9FKNp?O2Odj8BXZwujW{sVoxkxO9<7)BL-&mkFsB_ z5F0j56T~v6OQ(~X!86^N}#p-2+L-22*}jHar`9=u;@uL@{sQe{4Wv^3XP z7u|O*`l@_b%Zg09j-^`l!TPx!Z{D)ma)a{^Gd>5rDh9o)b)y?|;W~xS)oeVZF-A2w>ZyKKWXW`Q# zQIrI$K_cN^JB;D(Qzt;SLWhf4%-|w5gW)q27(U_&nMFA;xAmKGwxoEo)S-#8X&Wzg z)Vhq-O^up5WGWLrkk$m2{?Q#8-81P5z8*jzInyGuk)4%!NGJFD=hD3v z$Js0XSdyl1dEXX`1ZA<>(2lP`I@`72O5!nCG5Gune8%AWddSj8`?>Q3N!oRa%{+KI zN>Q&qsz~%TeG!F6k}@O_+*DVtn(d`$ni}-OsDcd@K0eL3Js4mo9D){RxAyV=1n1nY zM*Lz&j!tncUF_Z01&K!ldXzqyNr&2XH+}9ZE=GOl;`r)T$)4gmSPrM z%u2Az$yBBkIu4FPV)`t}BW#}(HMI9$SRvI?cEN`jiKWy#T{&uQi*XT*9klN*-F&L3 zDGd>zOntD@#wqYt(T0sT<2lPx=aWE7=q51iHZDW39=p15Z-sh6h`NugEHV@05drP! zq;x>%)u6Js#7rJ-Ch6yV1Z}$!j-%UxFk#NDRkXo@(EkXSK)N#1xrBL_3|QG=2`x;R znfR;@FH13``&YW4Sl%%B-+I;HM=-0+49UWYZcXN_TPG6>M zFuJOs#6nv`%k4fPP6f4NWm2PNM+>->#QWWUglHO#+Ue#+PI66udxCk%4ep;{8jE!N z^i-l_2l^XA^K^C22#p)K!G&E()oAS5JY-`#+3<$2i{KdwRdk7-SiRE*tm~#GXu7Z% zJd1)Ga=*{4g`s2K5Cl-dM#S(_Dt;z(pE9Aqd#f^9gU;YxRmIpyMxTpjeDbaVybndQ z-&1A>BH~yb#8f@)iooxs^=%D;eR!dElLSc3;}_58r%Xm8GC@m5jPV1T4dp}Xp05aE z7KDgEuQAQEoW^awzDcI(y}4{Y^cx{CS(ZVlD{kV$5QvMo^i zr2Y#Sj0@o@M)ec!$F_*c@fDbGIN@4C$KvT6bFCFH*3if|$8K!d;WttqqKm$R`n(WG zb&(Ji#d6@Gt;IzTx;zo4LWMdAcqZ)8m&y-7IIF|tdHYv557;CKzkX$AYSk>&%U~fx z*C00W%6u|0!j%0eF>99*v-{}zhKL1oG)d^Xn9WUu`QAB3-{gZ=staSic<0&a#dz}1 z8dsF%b}X&!gh{QfLmA-C%HG-S74HQcuTtI8o%jhjP`OzKym)&?X!;5jK!=cw6>V zE9mNB_tLI>Dki)$c;@*DY+k{rz5T}MP@eyzekZ}|YHV(E*13ctALF)GyGuz2g9vtBR9) z9N7Fa8w@i>kS4U{42NpxgXVT?;pf!ZCefW6PkUU6PBT`lJOs(AleAn4=!EPVKczLL zEiesvOxy=-2*L&v>M7!s7Xc&X$qP}!Np2^!B1q-1TS*v4xGwWv11jvyrjnpHYBdh(@^ z8Fg2{>qi3@@t#D&Mm_@7jX<8g`4T5V;m(}SDX8ymYuF}!=dh~`ae%@Vx1-CL8MREn z6l{AIlZs>L$N^&%?x%Z%%NSo|ThSV5Pdkt%9xnw`(4vN=>$9H7+cL$ybf^cnhFj8U zqQT4N*N37l9fY1tR53G>O=s!#5G_Ik}h$hk}O+Y9FziZ)|IP>v&YQ?14L) z)gxFPNU;q=iZ>9xwZ4_H7$2iwE1w|fAoOYH#*BuXbbcmZ9Dqii(qNd$O6cC3DK%Df zHv|q-VjWW^6;5}gX~1Oh;&P_Qn6XtBd@!d(<wbys5tPyrJz&dUEt{BC3l|(&TX{@N?PQ zB$dmQc43gRA5T#f+{YErx+%JmM55QmO>sS;gd~o5y>q6#RKU3$wsbi=UOrVwp^F)N z3>EiM6B~?lKKa3GMsVpi4|momBD(r6R8ppM06(jJL{K6}9QfeE%EKJ3`Sd(tIm)Op zXT%4&Vs<$QM0a6Hmf<8lUHWYgTu#_7TSs3KsOZxSoc823rVDpVyvc3|2(V;M#kdZ5<-#Qukl{1h$ZfCd+?wf$h z%o!tB>`4!Axj;?;Hb$rlnMJWITw49U79(}PXSdY2^Ql6vn0A8Gq4_3}mSCQaz z`=0R@!j8mZGoc#!O4i8c&E?tnC5ZxoW zJziBIKCGa#DH1kVQAwq9u$UjD=)_tZ^*W6x(K_8eTlnmJn5WFFZbpRn7OB(O6HNh@ z`DM;aX>sCtQWdp=qTTw;tOXe&diV+|obB=m*t?_%OeOJWEATXz`Xa@GJM@^WqQnIg z7wRf91w0Mvth{Mt<`_B>b)OzX1VPTlV2Fil2c*0+3|YwFiW#Kt}}lM-;W(VPEsE*lX>C5H??}x-`RNt1r;l?;Pac%t+oOwP}1Er?~OA*1mgP zU7(YG#2^dyc$0^ZY){0_S^2e3vN=24oMtV>PW83Bz?Eh4qrrh~YY6AdllDT_>l+`i z<>|PNztK_w#O0rk>Hn{_R6vp-pgsEcS}H)y@J*WpWRCy#`dyR6@=fFPU(p#T$?K1yE?BAl=0L=v>=m(g< zfe#iS8Voq4O~m$%>iuOE2+XX1#{Ls@FAI=<36On23dN7uS%G_i1vuWo`72@vf(7mM z?9BiT3J{Xv;HU?rWJsIo-)qkR^7qe|;-|RZdq-2i&J#G*zzLlD`4({raAE)n4%nr# z11BKZfwO*p6MXsq;WO~>1UZ0Il1>_+u>M4d{y+x*2Tlmk9{w@lgI6n>l-+v&nC5cY zx9{>zlkZ3H&5r3Md%GRi$OevXA-SOw9042O=Z}xhg%n;2E32NL^aJJ=;b)Sx3F6PL z(Q-#-(p&i#HLi7_8`hpH1kNvy&igDTlR@t5AQ3rl09@juWerNs;v#5 zzB%>TYr1na!2{pc^Gma$=eF2IYki60LdZYwb>3&=b8%R!XRY(~$iXUyioS#O06)yKH${|!^ff*4h{%&TStL>A-V?J2xD5e@AuZhpAcKe%${#E7Ly26{~Z3W!^ zhungAcPpP?9keXp`0ViA+IeVrsufENyQN^IfSHc%4Vi#xl(n(SAVyBGg;lIHs%Cr4 zxzgX9T#{L*OuUWS2#KbQ<0JWsQsP3XYa}u3q3N8l*RuKXJvQq}pnUO#0*@)j8ziDr z1ShrrP5IgmG=qbN_VnPZs*8o%;7usyuo;U8-x&qSnS8u=?JS94{KRt%tqn>Q!B;z2 zCNz#qsc+J`zIe2BnaVOZMr#@1d(Lc}F7FMw+?C;Yc+$oTaQx@E4 zC{F3eZGu90Q+qW_axUhd5~gFjpeTERhDJc^jGh1SaL?r004th04K_DAM!G|gUe~J0 zH2MUEy!CGHRfhM)feqo{Zmh@_ThkX#39=ij{RT*F)==DI(#Omj@QI&-X*9x%;bHNy zL@egDSwP4#7Ad28hGJQ!2As8^lHD9V`XHznljNLnhQS2?k8&Kj&WHaGb8i_{$G2wv zCJ-RFyK8V~;}YE6-Q6v?ySuvtXXEY!cM0wgTm!-7?&S2__kT|J?c4I6G5XUUdwqa< zs%lm3wdQ<&lS&v0N0+=jPYPP1-y1TE&c6?33l9gAyU3-7RQC8#t9KoY$dQv#l)uPj znmsSnf(P73utkqKLqi!B;tTYQvA=5+YQvnEH{w0kltswhj8#;i(&}@U#25wZi;82% zaOT%6zWm}$)3^pia{!V#g^;wp3 zWl`_TXspTuM;wxfwY{rW*K3Fn-2;5A17p)sm}OKJez%X&>id=631!uXg93 z&~l_Fb^1yGvwV^)f|UE?y1@X%18*G`{mCG5X@gMDf+4z59BJGJ(^IZo{Y(0m<)!r9 z9;T>V53&8EW4y{+1RfV#-I6CO16$&wwEQ@j_-n(w6Q%6ES~( zS5%%1#ug8X?{{or?Ob2{;qp^xec!rTzDO1XaHND1TUd!HgBu5TLR5!F3vfixQ;ons z1`l%c8c#dJ-x9-jR~&4N}d0-Cq?u&8W}A zTlpbQqKvzW*{{68&u^Ia&2Z3*O8<_AxEa|!te&8c_6GvyJBr6RGvY6N^h^VWogv)X zgUNmJY|E(1(5)d>#JO8K$7rJDd4U}ggWt_5h)Y^HGEvrxPyw1rg#HLsv-0EzIMoo| z0f_K~SdDB;d$%%m)zhVFN<~Nm=y#@le6{x!78iq@5=9x`-1^6gd=e5fi(c1&a*<-% zJL;kFraj9}if;1A6Q*V9uPJwVZIr_JNaN>eNdG)(aAA1K_p zqM>{*N~q9xUid7qvOj|m!!Ueg9^N(~BF=LdL%NZ{yig1|tF^3)PdoK6jm!hYgz>0d zFT?b+iyc)hco1q@BU~7r{x@a|Qp>jJvy1X3Bh&cBG6)*0BIr~weSmMr zixe5#v@DhqFD^j_^@J2gks9pmn(uS+yj4qz2RtEjDHDRb%ASlMKP1bDS2!i#K=88C zRses1K88Js!_Z70_Tp4AoF-T!imh=HCfq*+EkXhcQs_GI{Wc2FS)PVi@DumV>Lro$BHF(YMJf?rJA+}T&L_rlitQhk-*5QhGVpkINJqNFs+miq<|bp_TEwb7 zc619yc0SV%End|3pz9t)2B21ooLud3jq!IO9<7U3Kh>=GsULhZ@%~_gTM_jGf~T>! z5WwBm##5dsZdqUR&b)B?ox;j zh!v{fiJ!U{*1JpAQXeQBjkL^r5~Rmr`yFH03^i>Evxf(X-_>FYAbe}oEPnxDk}+AT z>@uiV6B|RgCi?{~6LDS}dRrxPp$e-~I2lVWQc6_&Itqsu+90^9*@a2Pr=1I-4am2p zvf`tAxI3;{HF)yNAQ0AT%#7aEveaKYF!02nw_%ZaInj`ZI&h{CC}F8~!_XF`YYA|A zXHE3_li_!W=>a_W3?8Y1|JUJ;T_=cVcEW4URgIwmgV90LcG0U)LZ7F0-$#pnhQgMo z&hahps`{`-xMUzBl6oXX03)+8@|`E=_D7P0&*G_k>EW@npN79y9P;q|Mp#>9@yUAr~7aOeWMTBKhJ$He74Caonp05V(g42(yeuvR8hzD zd9-M54#j}qEsj!2(t5_SqE5K?MLyzj1tqaQ2idbW=tq3tLb6vuqd~&Zn)LH`MYOLC zr%{3sCFno=;)mZRWm^?T4Al!`FAo5{{K>#$Dl9aIMC}sh?DOb|k<7(7KxEaVY@AD` zv^ls7(nTzoK}BUj1%Bj7Buk)6`*kF%6xOSpO>-{*(^T)yYsDy_FV3`8T5(?qPb zA=lE&hZARVp=OKpcoyUDHZV*Q+0gBJ?LyuOJ$FV(O9wmkks)#@OJUZ|lMwLy#5@e| z+o47J@nvmX!DKk}4yFU@@gfd7Wg(_~s0!^M5Tz*BbdAPa;+nzmZ{QCNaHjln&kxNT z@C+5~&%_`Hp;wLyyP&+H4p{r24%r5K%WQl$T~h=KkANi08=u}>!>hylT_xx-P=Quc z3LlV5t5Nf=4EBTS(^yY$!NYFuYsMjdp~Q3ZK( z?RB@s%xjX;+QyWRDY*;A1PDn)W6^guVI9SEN1=@jF*SMRph0ZV6~(rjQsG>xr4(dx zT<>6Q+QG`R1b+2~f$lHLt}1&8W^?M-QFbJ<%RHzMOg(&lH*sDewLX8HiroJE5JF=> znZZ-7BEAPEiUZMu3GWLZKZn2hEyWDGx(I=e*QC_gm3#HB;;`+9JAI2sHqG|4h@yA- z(aiERl@|vB4yc8Ff6yDEb3k$IefrHqUNilaey{GwyWe1w=|e7tCr1We4&k zsDb3CD{pB;%r(>s_gEUDB*^xD6=F$qrmg#W0k{F3D?ao4aDH2OzkLR)mLVcS@B^3u zqM;n2+QV!)e}350OY2iG(AB?#4Vj+TH5i9XKZ95~Qkw3^iViTGqP)TCra-e?hgxye zK2bjGDFNw#$F2R}K|k2NqP+Fzy;in<*_c(ZCd_1OdG*Mzb*(R#^Z7|EG0=;8bj^3{ zX>}9xu{2p(U9bLf7fAuiR|u4 zMXSVgYdeb@?rzi*h}j+b{pZc=ZTieu480Ab)MitX&A|k-rXXW0)+omu=ElHE5OP$& z+#SUsi#DT3ppCF62(fgyG>VgkfjIdvPFUw`?-+^wf>5JZu)6@G0mixmhL;3?n8c)X zNoDlaQ(?9g$jNYmD#kl_*TH~URMAns}Sf8k&AQzJs)V@ z-yLGNe;t74b90A=xV-ewB*#NA=mcR)gBtB=c1r z&s-N@U7kro@wn*LfRk(6oAx7;?B*i#E|vX?Jo7f1A69u`F*NFMoKmlvlm*^3;yw#L zY-lq%Fh?h9q{~^3Lvb6vY>wYH2HdrQe5nPJ=%Ss=2`|IW8+~rw>K9H#n;Zx(miHF$ zh=-O{Kk{78OZo4w+0jDQSx3*hY-A&Qu@=Dw`C*3~1bSBi!A@3S3VUJs8|=)6FF5N^ zX{BtMuA4Y>bng+k51EWJ+t1j4*e)!HS6i`(3+F%Ubq=Yh99KFi#I74Q7`Xa=+w|S& zJcySIzULY|8QkhDA9yL~tM@LAVR{ZK|=oT!HoQ64-I?ef58g`D* zn^%f~_+wYTWLMzUgu|;>1LB%Uu{1tz0}$*qb(_ba}b57B-5q zv(0D9Nzss&Y1qP!aC6OcS1{xuK)tf6MnHAp5Y0z0tZ^}=x8as?#_oOvwt5RyiWgY) z9tP!v3kV@}Le_q4?MklNZnmVGi<*PYXYRfwOGN3gNq!f^o47Sk5-%>LU8aGujanc} zD^`^vks!b2-%UhkeS|G0gFE{~=>#9MTQoDf1l}!7Y9`oIzb}6l#Mb{w%&LNt^g9nx z4ic5|;&B6n>ak`&0UokaDGKdOnuL29RH?{g9ou&jW83sEZ9=9VA5;wr-V*19--ETq z@Td)^+YcPU&qO( z$&!Z6Ng_6u(ceRK#Z`DMz1(;<@ZPYT9^D5vvO)5soniwka zZhWk%6Wvf~vSK>b8fSD+BBDeg+F;ArW|E?=Q4e4|WAVl*xhw^%$wJTh9ghK#D3Zmh z5ya>QVv3Oy@#4|=67&<%mnotLA~F5F#%&EU&mU(L+X#tCr0z%+QKy(7HD5lG@8v(m zOJhPy(V6-5`3R5hyt9mc5%=~#qxrR$NtoY>PGi5dU<_qd`$fs>RIJq7A`D%Em3;vI zK-MHZLQpH#Dfm;N0FFox6X0&-rN@8$p<^ zqsP7Zifn9MjY%b;y&yg|VY5ReQnvIcz$6zF`GQ}GEL`?*z+sDs7c?U9Ku?Y!A#74q#Gp~J zvM#=lUgMa`9!XLUBtc(I?90fim~W_wlq5$UX+b!$RRwd`r%ZFOW6F zkweL3Xwq~x;ly=fV6A-xvb;vCkCMyD4#oxTWK?k znOde&fFznTEh_36IMxZ&tWdv)@8vrzheKdXvx3_%$0Ax81ZAIpAB_8+=`xH*8C~77 zqU(w$KE(z-N$YD;U|Bq9X^yA}yKoq`5Vk;T10Q@#CK$O`MEgE-UNb60i9ls|p`6V$ z5eLFXot4f~sKGYKMm)~WArnc)KNC%BZ=pO}E`sh`$?8vRt%~D=s?L#9lI-G|6ww8P z>NvZSPfTj;{huYHgQWMRba*l$;(q443^dNoJK)DnEk6i6eY#JjX*dfZmh>w^aK#Y3x-Kr$sC*iqQ$r`ti;KILCxBln)b_V?1upVRi=sDTkA#Q&|EV>w{X-+=pG*E-KyB~zoFE+>0BQvUX@hL6Y#bmcDX1az zcWWeQ^q*71pH|pE_Y?C!UW)%h5BFcD1QRI8keP{z6C~*Wr3@xkPI|zf(SLdw|3D%D zbA5BtebHY=3Q1>(tN!;te4CZ0a#hiNkq!izB0iBOyy5L6VXb@T9T9Ml8e= zAwE1kbd?|H4E(x$9zVV`zuf1J5$fqaBW)S2C|Py=n(*vS)pV*_9b-?8<$Jhk z2PNl?O_X$A5{5O8@xN|qw{WH=I?;PSPo4cZNR`tQw03T7d}mQxbPVISka!pED7RC$ zS`REsK8P5D$i29Nesn;}ULES%)*$ITcJk-u13E{8pI(i3=UBczCl%;rMqSF!%&w%0}gyVDL-(?|vn`xew60a#2#cf8vo8jIhyr(ReUF7cOP*SuV;;Ry|)v=q~r@ zko6Sqh4&KIjCI7st;evb`%1?-zb*b%p0IcQD!MW3TxD=AeRV_e7n7Y^2I-qk_cPHc z)?4EcKC%L?3^Ld(%rmpvTAVb4PjMShhTNx<#+M@IMIZ`lr_sDncc2Gv_Cem}=P6I8l>mgtl{AF# zPsj7I9f*$(IZx?)a@~?Vw7*(9bJ1^0=((Cne$`jxhrVg80mXW-c@Z>zCOS-UWmiSR zjJKVl7AcT`Xcx8W9Kd7?+>m@-NExU!XCN4VJFdhX-gN;P%tcW9UmXdVCnCDedC zTz&cT7}8OkvwJ(6Gj_npq#=*%2}^zV=|Etp$V(YlxLdb(7{aaxgO7B9oJ{Hnu{#+~ z*XwyAL)X)Ol{qE*v3f}s=IzinfVJBU&V=4}W1!^;OUsrr>;+%drdcsV`F82Di>ipyV&fJ20ecEa`^h-;~!FRIS45AnQ8dTuwCC(PLniQ~kpz9p} zWqqoRx#Q=(tfvxILG)N)xX$-hU7t2eJwk<{GHY?vNXj)XcGW;AtIv#@0rizbo_Tdt1-^y4 z?}S9ax7*&wfWrt5n#>JQ*ei%ASD?oY-SmZPGA(;_3y)XBhJ^^{AqX^_Xn_e?_f|}& z@U(t(>m+M(E;KWKf+R2S-*8cwtq~{I&K);}_IAo(;PjY+i)>Aq3x=X8CHYjw_>_zz zd&kT694-I_11A}T0YON0k#l0QjTUyq zj8p>J*H=5Z`VYhA_-9cy=^s&4g%k3vu~~HU^2b!Q=RZ*0Mx;d3b1oflsR|w2&iFRkz#Bsg-*rZBfqcy+LiO*Q}>RgxQISjn$A$& z+0YRVb4jC)EQ?qoF5$%|KndLkJ(xB-z7MR2{iH`gG;a?)QZ~oIz&$KIq{3&ud7A5HVOll)m}F*rC}e&l`xnD~ahFM_ z{w0zS_%tS-PA#kKVS1FR7taGOKE&DiiV_h7ki@h#IVot@)%`|TZ#}*smXbJnP zlSg%6H3jCPd^V4c5bw2fw84IqgRF}*1J`A#kq3Tu;|UR&Ez{CzSz1f**uec3v-T_t zi*y+?a)cCG7A+cT>J8^o+)+N9&Q7*$v}%$3__c7na+X(-B(}ARBvYAUT_OA!EQ?e4 zmyc!4InE<{Ulmvet0~9O8jnBt%yuCv-!)Y*QfgxtY2~A(;D%zX~&2C@=@f$9OV?ORpQIN;xx&4 ze2SN8DfldxG+aoGc^D*sV-%m!P<(2(hcR{%f@(m_#AnDO7Sn$08ppo2Ny}0w7dWer za~{%Ge0!{eY%M&|?i2dBOK`X>ING`?@iuu}_1J^?@OijOxZgsItOErd#%;c`La~Dn z?E$7ON(N{f=C03K2s|r%y1&?^=o~J$8(YNVVFYz%%Sp}wNQEL~1!FuSwcHKtE?sI+ zPJIk3p(3h+)7fmH!IpFJb0dGx{Xr|${o*at9_CpBNVXp)^a4#T z`XN_4$LD%rv-=)J;(Cjkm!iGr%r)N^q({Zf(EAM8?d1jArgo`45vMh{YCrzOEThG& ztJZD5axb2$*XbRLg>(~T@{)D$_==$mj26?qH|b0Q;8W=NdY;VQ4ZOXxI*p9{_ZHOu z#xnUoUQqw}ZTlZBsQ-D!Ul3mQUw>Br{~>ArvN~V~vBw$zczpl5I$&q}O=bP(xnKX^ zMGn(HfT}>Sp?@voKUf`rAmL1ZT^&r|>BN#YpRITIO}%HHxr0KYjmwkp%Y#qY4`79U z)c5R!hSBqHLVS55r;;ofWT|g*YTcl_Ro#msi`YyuKIsg|jb(dI&B{?6WomgjIy=|n zW)qQ<(+Zsa0cF2zPPm<4zak0?e{a;W`S!H9{t1e=>;?F??EPw5asu}^kcF-ouSufx zO1FFa)1I8~>(9^&zRh+@x-pj0Nu~Q{sXE07g_X_ z&*Mp|Ue|IaBPZ2I2-NbCG)kX1i^u1rRKhZr>4b%x&Po>{CZsaGj`!qqd_@9nD!3F} zK!u?q%ig&WOT4X+AEk50j>J}1x_GVH_pes&lHRUu1^l9B^FMMB5Gjn~H ztk@x*F)O$m^ISIieUV=Yk{uZ?Jq24Hu6)lLWD;X$DC*gl<(Skfu3yh&&C>dZ_Q)T> z%vlCXT^vz>{(xj`+)v5XwH7d(AMEZ*vU`LAz?f>I=`N9INIDrz8@Qw?Seg<(#eHhU z@ej?nN%OKFEjB__H{j1W@O`ogpa(Y#V`BZI(@9o8c2#3jweAbNLmp+`otB1(J zH=Fd6ih@#KRiph@^g-K^>10OGIxH`3!-PE}4BovCIt_<>LsWbm-6%5!PThb6j6ZGI z&kl#i6m5m>5Z79`(yRtK5ez9Wn^2Sqx^7{339##j4j{P@k$V~#I(+vv5Uwh0}LWPFtoBxa|4JW-2NXAuEMht!2YWh~r)d4>pq zpLDOddt3LGJK10y8!$l}b#M3P>qn6r;H!`^oGu4QHHBaLuf{AVw#leH4e+s=Qs;#D zIApPO8@X40b1L77KJ-41ea)XBAH2biq`*L(LZ0`CYO?(~gKh3Oxm}m$2UYQHCeOuC z!Ws#dH*5gkGxL>zJ29i5+XYhP)4}BP2Fuh4oal;uw&S>3dLtPbMggkR*h6_wF*rSs z`{=&X=Y#m6n&&&pL4G}MYmXFcz2qYi%80WIJ81a6GDjF5DJe8kRJSb&Q&_^F9oX#z z>>D^}4}-yuurE{DREq65;OP#{^c~PSY~3*B)M_R{x4eCHOvF$hFBP56vQ33x#RJ}V z*n7mLFJtfp>Gaa(6G!)+Yu2N~er!A@pcp@>UXfd9+1BhplASJIR}5nTD*a+>esyoy zqgg>H+)3h83*K{v{6fdpn11H}f@*~ll|0_saA8P>Dr$S;R?iW&AvptBvxy5e1oFYU0ni0lwriDwi}32Xf9BjUaT!K;KlcS-;tp#j_s)B{{`u^ z(8xMd!I0aVv8m_om$s;vR%ceNlV$oQy9(gJAIVe%#>Hj;Gxir~b;A>cVMISZmusi< zRy10huxd;i0J>3~GHeY3_X&n%0`ql!2&9_YTsWp~2i(QVo~CHCI<$5C4mwQRnxapT zEQ#O8iO`k<{gLUSj4@7sMf`+{m>4AP*6wIJBl})l{xV42lXuoq7EI%pv#)-0_+7=? zW|Q81D>&I&@guf0jy8gAyM`7(G=A~+Ap;YKaz4Hqvobd8iby|h>tdx`ClBl`M-@(8 z9wjW8d!1R;Rs!2G zVgybRP^m`W-JSfFqry(;h}LG1p+~!VuZ8DV&V{gI9-`CkFwk$%qbRGy*+-N4M2>T9 z-%Z%IvlQ|R=pMCyrPpSAKi5*y(4-+Yl`{aDt8>N7LL;e8!Qf7&BJaBpF*Lx#iFp&|3xz(#cqwD8jy9g*_)#Q`uOg` zlm;%%La5Uw=VCecDW_R=amZ8X=s1Ww4y`M2&mbIiB1;z|N__%lbN-;ES~KX?J+8V| z6k;o+_N5P2n#bMlaz7R{?Gaze?n^trdD{7xME&|TI^+lMT`#tieU7OM*-^GAw-+_} zy^2yoZzw0^moraP)ft*|1OTqkd~MaxI#7(uj()IQ;9TO*!O|pUaFS%x1bx8(i1ZasS+M~3Uq)Fm z2(no_ADzuZIlP%WJd~5Wlomh_Cvwok$tz1xanLNBoqh}AYk&gb<%JvR4q5bf0*r%4;myA8mEG+$2wIsD1rsR(?pVL4Lj ze$p~*k>Zf(3bRKm44t5$_8a&3G>OqF+s%6#`fVvMwA4!|uXYp$v#7Jjjv|H#se4CW z1?|4(xB(%*=1HlJ;2uIeqo+pSaP-tm@(s}61Ml+v@OgZRvvK?)b2iH$<8>tU&X=11 z^8TyUz17f9ptee@`C|! zy7!NYire}vUSnme&j?bU*{8@_NF&7+)$kM1v5N-8u^wpIZ!3_}J4 z4e`;f=W5yC`|A+{3bt!b1M|!|jGvGwaS&JeK1PJ}1Ah-Q9t-6iHdXy1kAP9RcNd91 zXQXOhgh@oPN|Zw~`L^iw@!2Hi4ym!>E8=Z{eZLe33NJv*f`hAYfUN+J>==KjqN z5q08GsCRpyu?ZLzhrCY*DJE}oG&^cdUl5f8 zt{q@!68pVAtt+CP9Aq~tBnmCoUcGwDQtK zvnzPUn7^V~`a)xDBMj!!qdQ+Mgo=b3BYgoivo})VzC!i=~mF1mG3LMBVA1c@p(G zDpg1eGaEagcx^IG;Tg|Id&}nEq}6ivzu_R#=HXkABQN;~!r(fWAyq~k2Q`TX`4k2Y z3eQ=NtH4V(2u#kR29EaH5V0wo1tGz~mJ8zdgz(}QIif;C_{zV_JUSCM9yP!UKp}s3 z5J52gEr1LyQmuhQ)jZWJP=vT z4y1x88WD6FGH=)`sk2C3zZKm5WyFs zw*k|kI0C*0oeZ21+GWI^%XTuO2ThjQ}s5 zarP~R81RnLvCRPOT_E&(Q7~gTgNyt}mf^!1#8C|JUY%cljU>Axkf@`zti;=bGW72h z{cCB>g-n?Q7!ARDcKgwW*)*f48a%AQQi(gT20^?9W?KuzF4RQ51uyJ>HuPpiJ08THq zj5O_j(+P?|t&jQX(z6jdP#Mx--xsV|?{$C0C4iUCaWvYBqSjkc1a>+zrHj7?M}a?u zS~AB6sb3Q45T-}tp_GVkDQm+LLl{a)5alw0q48cel(WHiff8#UF!&X%`DnJG05Ear z86P1MW-I-Jh+)X678$_;S9pcalQ;r|_c6q8i;R4&1w^z$uzzpJDvgS9(GlFp^KkBf`kJFq|PpB5b$~xULrunmVtSPB0eZ>~}&>Z-Uk?hXF8yxIYqTSW*G1`%GxA3X4b zBr`C|)bpRxX*toW$}BLw%a8(3v-NpkHt~!2$aQHH5ger%)yidIprC8{!}q#Cj@TSL zPNy-}_!re~2%_I{wVfHOD-e1xh1Mutu(~l5?h10Zx&jjA=aEnbZxHiC$36P2+TQfN za#7Ms#A8CR&YCCEx((l;I}*Xrlu8YH^cl^1{?Hamk!O?IVHp+TYS?;+S8cZLQ_Q6^ zaosG4#9I6(VUc5Uk=CHTk*pJt3m`Qp;q7EZ`j5Lm^flO7Hp_VE)qsSnA_4R4!E1CLmbt`-z*MojgR~m= z8|vl^<1eA;10O|O#6?2UO791^@;f!P%=XO}M9xJ&g@0!s74U!GnDl2C@ITl`1^kOK z31rRqV?+Y{i!liVtp3~ge*rH5{(u+$DF&rKhwz^?#(>((L7S``Y#>Ju00bNV+s-Pe zwVZ>V5#;Cr#b7eBfbtandE2f3qm)xp>3;)S_;cF-8?`fm!XyBHvPAw`J19%y&)`4D zi1L5E_TRVKf3kKaP5l&F>6(|-CGz!9v|1(8~|HhU7D_TL$(ZI;s zaOzk96!o zmv>h1Z)7E@Nse&mUN2sc4@D^;%(@j)+p|jKZ_GNzAIy69+u6;82*Yp8de-aiuEZjA zotCyF*N^%I4`^8v!bw8@+^&Z!VE4l-(3i`q`NK2n6d{QFeG;g+Uyy`&xw{RuDoJ$* z#;;~>_Ku`M$$eu5!$&jMu6yB1=tuxjZ1uYu-rTOPP@{i!*0Ga`%R5e-wpA9aj|Y z0Jg9bQ|fx5)Bf^4GTLr%%untuXJ&G)vXn+l1U&FjP`%$ReKRqNR?C+!8)sou=^Em( zSE)BMC}z{iumEw~z284H+#kZRR`^i|nzF2De#z!_v8b_pA+ zRwZp-=i#X+pi&x>?nAemU#wza$+JSO>jr8u4jJ5ehil1 zRQhbc9)t>(pnDkKiG2#c4-W04EQa6-z2=-z{j9!;^=v5F1CcQi>MF_lCR-(zXI$n4W9pUbn53-582Cs(2!4+X$w$y zGU7wHV?L{F6Yh+1th@@mNdzGhq=jXEz4vrEELeueXxjQ?&Myo;KO$ty(uwHuO zHs6|)$FRA7_aO7WJlu4n&9JD$L*8f$*@V0q93feSTC7yGSjbU8{vcYS-`L5$-rO`7 zXh=+>QxA!t5>x}XnrAE+BFH6bdAlUaT#mYMgb!TzzTO43p|AV;G{;;R{|rY@OP}qX=+CK{&g(N3p};9gMFUew}URyub)9sgkl3CFa`GTh3am*EX#pOI@_VyQI=+fsUE5{@DzC#Zb_y2~it zB)m7iHsHU&Z74Sd511r%7Po*PU!dRso^gTl@LIVO-tA@{%ZC1F-}gw~QhgEM=Moif z#(*I-fkt@QG+*u-v)&pK)qP94_4$l$G2SrfeMKF*<1I)N{}aP?Dv;;?qwL? zww+N$4wAnqf5sEEQ+tH5T2zx5I2Eh|J4Jg=pc@fut=$!a_eGK6C9PlL1@3tDFo-P? zu}WlpF&cjYbDrbHrE)E7)SZE3v#e~RUKR7FGRec2Bd6;~+?2NB6B(eMdou8;!iQo9 zuDzI>{H=+hQ+no%SvA4zG34dgiotDx^N#cypUR|uuU47IX)OFc%L9JnESXPtus>91 z)$MGp!tDK*;KB#59pEad^m@+cp<8*gn?zZW1UjwiLT9ScdxNF-G>+-)DF!FItXyu8WR+U}~zl7c+Q9eLM|HlXXtjOMH`b*>Y@J z^$G##ezchVRCn z9qsH{`7$>_Y)lwOgTBSJxklFOwitB|Z;nCmdo`|S#F(zj4J^zt&h5Nt$=00kh|gzl zl@QM^Kfdt{1Eq^Bc6EV81AhRm+RkR7A3YRb!?>zDS{tY5@x+=c^!j?49`NRYS%ORM z*e(4QH}N{-d#x&6rliM4ZP)31Tkf(-_c|{#qU6-bw7=lJ7fNkrbw+kOWNPCV+bEkK zIA?nLx;<~6uq zZrk65d~Z9xY+y>)DCusyU)j_f4t?-hnwJ(Mqr+1{RTE6y;9O(H*$^`L8V6AxUW}Y9(o-GU!5DdG>-6)N@IL5fyU+C{_ z9?ta?7j1WcjMROT$?OUwv{JW9ZDnXEE%7_shaMoV@lCIO>!`wZKWvlME-~z;gl>*w zZ7r&5o{Ko&u(Z$(Kq)&&yfjd4Z^;PKDq*~yq?UN*Cfn}s2~Ba|b4)y-`Pg538fcWV z%_|$75jfs$8tWCEJp)m%P?0L zY(@Ma`$4+ra4Rd(jqxT-&BZZFVu#n5ZiNXzCkd=|hyJclw!!HDC9%`%RJs%KEs7q{ zOn!K>bW)QO10@6%?4&VdOuljSQ449X2^*^N1hb2*3wQw7Sv>~nNgxUp-@fo3>zT@# z|2dY^ZFdf4JP$y~;>*Rk^4=ar9s7F~)*Oc%UycWN;FEG7Ae|KAuu%b4XvD!m)DxUw ztpZ1YFBgt7u^EzsdYWCpERE-IkBlItqoqfE4W_czRY8TEj6hH%G8CNPB1*xRlXMBv zDwGIF3Up+`_vZc#mZf~<15&yTK}xp~;x^d2nj`MC&9Y(LWWEeNVI2aenCJCd563r{ zzWena)FuOPOft*5Dekhny6Dfr2)^qzU&8JQG%owM)EHFvx?+>Q2dI$W!P0Y9@@YdG zwtv~;a)Q2j!WNOd_73BgPHeuOU(NPByR&uwjwtZsEMcrRRxEZMXHCZ%;IJZ1$hBnf zQXNVxj;90RWuJF_pIFH7l(Ij}&Y4i_b7B-8J$tp^JF$@wV|_2;?rC+wA=>1f@2{0M z34f0KmV@rsiSv5W*2kSC6Nby`L}j6VZ}k>p;UZ;wmubuGGd)MftT&(0eUpWq7@X^g zFEgxn$M26-o_}U&nRAr^U{gaD8Z%gJjkITiu~txKh4yZuexQ|1;O& zW9^$gmEi?yX{R3=Uo3**5XxX3Q~mKi0r@{2T~Y~M$TUIamn;iM`V zzR!X*U3eJxt5Kn+{1(y6hph6Rmj^(`5w3>Ovs#ykNXfWjfrJFi(OJB&rmJW%oyfuN z#AJ?oR}nv~5GZ1naA*0nxchIZak27D!c<&W?S3*;mS*37QKuvV<8Rv5vnBqU+H-Qv z|Ne>l{vkJ!`z;4$>h5BwTYWcNfj{@siX$!n{KrtV?9CcrgSH1|DS*P(Xi^Fnfs8IWVfOaDjfX?5O*hM*GGjGCTh>etG}E>N=r zg}nS9t!IfH?jw*=-EWQqh7I^>iLgib|Do`}Xa=_w^X({>bidOyfmD1*lA?jE{W;Ww%6+a_&6EQUjh+6Ha4yXkhh@uW&P3`AG{AsD8 z(eKm{%^ji0)rgIEf(190*&;(yX?~zR^vhGa#`wW0-{rNzrlp#nM^Ojr_Pl*trznDK zq9=$J()B_O|GT=j;M)w^_1W3UkVP6fq2M+67KYZ)FGB4v>JglOSJ#ed0nnZmJShT+ z2%1>A7=e{`CLQV|9^Qed*XWDTX+=Nro*i-xPE_9vM`n9)nE7bw`4`8p$&n)|#o=yi zNZDjXHHop?i5YP~%c8pdyFWbti?+7nAToVFXz)&Z6zubd3>>}h+S;QqIt(Oj;@+Vo zsl5A>h)i6mewAGU<(pVG)nD{ynpuXgNEE{f9-!D%0u8z}SvO(J zQyq9u!WIjYP74>bpYW1+)v`v95Oqz7@h?~pc?O`DZQ4}|E=}QMX3mDYufm(V4zkN4 zQ<5_BWk0!hS^aaO6xowdx6jdkgY}djP9#G$>QG6vbVXpK480aGrW1H$LW%)kB2Z}W zsUmYVI$;n-Q(;5VUA^0*Gd4JUtJj~2MfS|E!U*GY-U>~8Cb;-3(DT?J^HN-B#$e2kyH*urCg5-mPN1X5c~LH9 zn_HZ&Ui!s7GT9($LaH(=+Wnvszkz||72u$s_GTDN*?&yf4 zJ1HjEdb;Bd&)V1J(9%g0@y!he$WcivY*KDiiP7L4DK|T*l*wjt0x(}1`jbVES_oqV zy^2=X^Ye4mlOt1$D~?LT;ILZ~_)S>*T}rc(PmkmXUZHI|lzx;+Kr7rwzFvdgLKA7} z#+ME+h}|f$BRZU*chY_r)>ftr@bjO}cx9`-UQ-?`IylcHZO}Sl4JvL+`Bg;IPQ7ti zQa4t*!%1*!Iu)zA_q(q4gvSZ-eyjKGTLSFRAG+GXQKmEoE+#%mUd+fYBWRSwgQQ&; zX4nka-*9X~vLon7%=}q44#A`_$Se?TdK~dMTF7zH%aWL#&3`~Wc&LQK2w-|qRuO2# z;^wwvzaTxwh?Q)FA7-cjg7kR$%~}?N#i?#1rZU$uW}(?6)L3$QEvR7arlk}M zh1Gmk-$bzxaalOF$7*XAgb-wE2Q-$4TnP$@1xM7 zOu&&$mlffzBp|Bo$9?>Du>)!%yrzkO^y^`f-r`w}B34_C=rIp=CZMU!LnM>ue4Bst zboxNlX7UkTcJI{%-({nhJ$<>><+C`Cn5ov{p5r`Q7YfL0=YiGHJX|l+_~v5%n#2|o z)1x(sTrDhTuWKyzO0dVNC{W?(Y0ks%=3tjo%2pwD2)$)acY2a@rRK=~I9V){PIn~{-$krjaC*!}`k zeCK(yu>v>^BS85El(GNB@EkiEtrRe``EM}__FqQc|FcRpC)?l50&V7*3pc2Hcl3by z@RC@pN!z;%4eQH$7l4okCHO<-{*loo||6v%g~ODjZJ1A-sUK4RXgZZ?j2btb~D675y2+HzyLy<|q50UN@NLXyzr0LV%l9M*!dG@8(QwHKZ zUlBQWj>bG*36^!`(4Dq6JJtCNEk$0z0>|yahXt`r;k!uRg%9t82lsqJ%RHxdXk^+ww`Wp=gRmFYt+FW{RZn6wE3wFV-yx?GN17sioDo9tGIVO zmden6tbJO!@_;-TMT;4g7?Qj{+{<{pSZZz665`B5$R6@m>x9-hTCsZ{;q&<19qE|! zs+P@A3(rl5qj~#0EA%WWqy4QHnw=(&IqH`A4(0TzvjJzUF%0@5_)vrh{&+$If5_JH zTmflxnOD6&l>+1JmybBeyVY#oT}x+Yh1gm zHTZ0;pJr7Q7Ug~dxobwZLsOSbpG2{{Cv)w%c{46s%{YI3DpDOXaUdfEDb_v2gHA7n zyrMVZHZ|Zs*%z9_C+q8^D1F>@hit-B6$kGi(g=Z9$zDKrn$(x}*3g8KEuO}OZSsZb zF>|y(L$y(^%X+;;kA3)pppDAc*3(o)?J;HPv}vJaCI7B^bFm_%Hw0E;>D^@-SC;EJ zoEx1@OT*&f@XO4lH2xIuqMr*LDR4VG=1mzX=W~+3xr889f$^>xXDNULED2sv$wMmU zsC0U4JLln{y6dUgMsQGtw&(fZsLazsu35FMtW;^29<>bU-t_+Byy-5?c{r?DqWaas5W`

sK{YxX&N5-;k5C##gZC60D*%jrOsbE=hjG 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

wY}l$&rdPnjbL1Wh{v?6Oom4j+i_lQhD4H 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%0D7<8ouFG0nKbxYD@Fm~LEcv>P*w4r8X#Y0NTa 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 uint256) public map_addr; - // mapping(address => Packed) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basicStruct = UnpackedStruct({ - a: 1, - b: 2 - }); - - function hidden() public view returns (bytes32 t) { - // an extremely hidden storage slot - bytes32 slot = keccak256("my.random.var"); - assembly { - t := sload(slot) - } - } -} -``` - -### stdCheats - -This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for address that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. - - -#### Example usage: -```solidity - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; - -// Inherit the stdCheats -contract StdCheatsTest is Test { - Bar test; - function setUp() public { - test = new Bar(); - } - - function testHoax() public { - // we call `hoax`, which gives the target address - // eth and then calls `prank` - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - - // overloaded to allow you to specify how much eth to - // initialize the address with - hoax(address(1337), 1); - test.bar{value: 1}(address(1337)); - } - - function testStartHoax() public { - // we call `startHoax`, which gives the target address - // eth and then calls `startPrank` - // - // it is also overloaded so that you can specify an eth amount - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } -} - -contract Bar { - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } -} -``` - -### Std Assertions - -Expand upon the assertion functions from the `DSTest` library. - -### `console.log` - -Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). -It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console2.sol"; -... -console2.log(someValue); -``` - -If you need compatibility with Hardhat, you must use the standard `console.sol` instead. -Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console.sol"; -... -console.log(someValue); -``` - -## License - -Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. diff --git a/lib/morpho-blue-irm/lib/forge-std/foundry.toml b/lib/morpho-blue-irm/lib/forge-std/foundry.toml deleted file mode 100644 index f9679ee..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/foundry.toml +++ /dev/null @@ -1,21 +0,0 @@ -[profile.default] -fs_permissions = [{ access = "read-write", path = "./"}] - -[rpc_endpoints] -# The RPC URLs are modified versions of the default for testing initialization. -mainnet = "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3" # Different API key. -optimism_goerli = "https://goerli.optimism.io/" # Adds a trailing slash. -arbitrum_one_goerli = "https://goerli-rollup.arbitrum.io/rpc/" # Adds a trailing slash. -needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" - -[fmt] -# These are all the `forge fmt` defaults. -line_length = 120 -tab_width = 4 -bracket_spacing = false -int_types = 'long' -multiline_func_header = 'attributes_first' -quote_style = 'double' -number_underscore = 'preserve' -single_line_statement_blocks = 'preserve' -ignore = ["src/console.sol", "src/console2.sol"] \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/.github/workflows/build.yml b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/.github/workflows/build.yml deleted file mode 100644 index d2ff97d..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/.github/workflows/build.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "Build" -on: - pull_request: - push: -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v20 - with: - nix_path: nixpkgs=channel:nixos-unstable - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - - name: setup dapp binary cache - uses: cachix/cachix-action@v12 - with: - name: dapp - - - name: install dapptools - run: nix profile install github:dapphub/dapptools#dapp --accept-flake-config - - - name: install foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: test with solc-0.5.17 - run: dapp --use solc-0.5.17 test -v - - - name: test with solc-0.6.11 - run: dapp --use solc-0.6.11 test -v - - - name: test with solc-0.7.6 - run: dapp --use solc-0.7.6 test -v - - - name: test with solc-0.8.18 - run: dapp --use solc-0.8.18 test -v - - - name: Run tests with foundry - run: forge test -vvv - diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/.gitignore b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/.gitignore deleted file mode 100644 index 462a994..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/.dapple -/build -/out -/cache/ diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/LICENSE b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/Makefile b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/Makefile deleted file mode 100644 index 661dac4..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all:; dapp build - -test: - -dapp --use solc:0.4.23 build - -dapp --use solc:0.4.26 build - -dapp --use solc:0.5.17 build - -dapp --use solc:0.6.12 build - -dapp --use solc:0.7.5 build - -demo: - DAPP_SRC=demo dapp --use solc:0.7.5 build - -hevm dapp-test --verbose 3 - -.PHONY: test demo diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/default.nix b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/default.nix deleted file mode 100644 index cf65419..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ solidityPackage, dappsys }: solidityPackage { - name = "ds-test"; - src = ./src; -} diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/demo/demo.sol b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/demo/demo.sol deleted file mode 100644 index f3bb48e..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/demo/demo.sol +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.5.0; - -import "../src/test.sol"; - -contract DemoTest is DSTest { - function test_this() public pure { - require(true); - } - function test_logs() public { - emit log("-- log(string)"); - emit log("a string"); - - emit log("-- log_named_uint(string, uint)"); - emit log_named_uint("uint", 512); - - emit log("-- log_named_int(string, int)"); - emit log_named_int("int", -512); - - emit log("-- log_named_address(string, address)"); - emit log_named_address("address", address(this)); - - emit log("-- log_named_bytes32(string, bytes32)"); - emit log_named_bytes32("bytes32", "a string"); - - emit log("-- log_named_bytes(string, bytes)"); - emit log_named_bytes("bytes", hex"cafefe"); - - emit log("-- log_named_string(string, string)"); - emit log_named_string("string", "a string"); - - emit log("-- log_named_decimal_uint(string, uint, uint)"); - emit log_named_decimal_uint("decimal uint", 1.0e18, 18); - - emit log("-- log_named_decimal_int(string, int, uint)"); - emit log_named_decimal_int("decimal int", -1.0e18, 18); - } - event log_old_named_uint(bytes32,uint); - function test_old_logs() public { - emit log_old_named_uint("key", 500); - emit log_named_bytes32("bkey", "val"); - } - function test_trace() public view { - this.echo("string 1", "string 2"); - } - function test_multiline() public { - emit log("a multiline\\nstring"); - emit log("a multiline string"); - emit log_bytes("a string"); - emit log_bytes("a multiline\nstring"); - emit log_bytes("a multiline\\nstring"); - emit logs(hex"0000"); - emit log_named_bytes("0x0000", hex"0000"); - emit logs(hex"ff"); - } - function echo(string memory s1, string memory s2) public pure - returns (string memory, string memory) - { - return (s1, s2); - } - - function prove_this(uint x) public { - emit log_named_uint("sym x", x); - assertGt(x + 1, 0); - } - - function test_logn() public { - assembly { - log0(0x01, 0x02) - log1(0x01, 0x02, 0x03) - log2(0x01, 0x02, 0x03, 0x04) - log3(0x01, 0x02, 0x03, 0x04, 0x05) - } - } - - event MyEvent(uint, uint indexed, uint, uint indexed); - function test_events() public { - emit MyEvent(1, 2, 3, 4); - } - - function test_asserts() public { - string memory err = "this test has failed!"; - emit log("## assertTrue(bool)\n"); - assertTrue(false); - emit log("\n"); - assertTrue(false, err); - - emit log("\n## assertEq(address,address)\n"); - assertEq(address(this), msg.sender); - emit log("\n"); - assertEq(address(this), msg.sender, err); - - emit log("\n## assertEq32(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(uint,uint)\n"); - assertEq(uint(0), 1); - emit log("\n"); - assertEq(uint(0), 1, err); - - emit log("\n## assertEq(int,int)\n"); - assertEq(-1, -2); - emit log("\n"); - assertEq(-1, -2, err); - - emit log("\n## assertEqDecimal(int,int,uint)\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertEqDecimal(uint,uint,uint)\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGt(uint,uint)\n"); - assertGt(uint(0), 0); - emit log("\n"); - assertGt(uint(0), 0, err); - - emit log("\n## assertGt(int,int)\n"); - assertGt(-1, -1); - emit log("\n"); - assertGt(-1, -1, err); - - emit log("\n## assertGtDecimal(int,int,uint)\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGtDecimal(uint,uint,uint)\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGe(uint,uint)\n"); - assertGe(uint(0), 1); - emit log("\n"); - assertGe(uint(0), 1, err); - - emit log("\n## assertGe(int,int)\n"); - assertGe(-1, 0); - emit log("\n"); - assertGe(-1, 0, err); - - emit log("\n## assertGeDecimal(int,int,uint)\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGeDecimal(uint,uint,uint)\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertLt(uint,uint)\n"); - assertLt(uint(0), 0); - emit log("\n"); - assertLt(uint(0), 0, err); - - emit log("\n## assertLt(int,int)\n"); - assertLt(-1, -1); - emit log("\n"); - assertLt(-1, -1, err); - - emit log("\n## assertLtDecimal(int,int,uint)\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLtDecimal(uint,uint,uint)\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertLe(uint,uint)\n"); - assertLe(uint(1), 0); - emit log("\n"); - assertLe(uint(1), 0, err); - - emit log("\n## assertLe(int,int)\n"); - assertLe(0, -1); - emit log("\n"); - assertLe(0, -1, err); - - emit log("\n## assertLeDecimal(int,int,uint)\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLeDecimal(uint,uint,uint)\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertEq(string,string)\n"); - string memory s1 = "string 1"; - string memory s2 = "string 2"; - assertEq(s1, s2); - emit log("\n"); - assertEq(s1, s2, err); - - emit log("\n## assertEq0(bytes,bytes)\n"); - assertEq0(hex"abcdef01", hex"abcdef02"); - emit log("\n"); - assertEq0(hex"abcdef01", hex"abcdef02", err); - } -} - -contract DemoTestWithSetUp { - function setUp() public { - } - function test_pass() public pure { - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/package.json b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/package.json deleted file mode 100644 index 4802ada..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ds-test", - "version": "1.0.0", - "description": "Assertions, equality checks and other test helpers ", - "bugs": "https://github.com/dapphub/ds-test/issues", - "license": "GPL-3.0", - "author": "Contributors to ds-test", - "files": [ - "src/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/dapphub/ds-test.git" - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/src/test.sol b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/src/test.sol deleted file mode 100644 index 2bf3375..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/src/test.sol +++ /dev/null @@ -1,592 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pragma solidity >=0.5.0; - -contract DSTest { - event log (string); - event logs (bytes); - - event log_address (address); - event log_bytes32 (bytes32); - event log_int (int); - event log_uint (uint); - event log_bytes (bytes); - event log_string (string); - - event log_named_address (string key, address val); - event log_named_bytes32 (string key, bytes32 val); - event log_named_decimal_int (string key, int val, uint decimals); - event log_named_decimal_uint (string key, uint val, uint decimals); - event log_named_int (string key, int val); - event log_named_uint (string key, uint val); - event log_named_bytes (string key, bytes val); - event log_named_string (string key, string val); - - bool public IS_TEST = true; - bool private _failed; - - address constant HEVM_ADDRESS = - address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); - - modifier mayRevert() { _; } - modifier testopts(string memory) { _; } - - function failed() public returns (bool) { - if (_failed) { - return _failed; - } else { - bool globalFailed = false; - if (hasHEVMContext()) { - (, bytes memory retdata) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("load(address,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed")) - ) - ); - globalFailed = abi.decode(retdata, (bool)); - } - return globalFailed; - } - } - - function fail() internal virtual { - if (hasHEVMContext()) { - (bool status, ) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("store(address,bytes32,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x01))) - ) - ); - status; // Silence compiler warnings - } - _failed = true; - } - - function hasHEVMContext() internal view returns (bool) { - uint256 hevmCodeSize = 0; - assembly { - hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) - } - return hevmCodeSize > 0; - } - - modifier logs_gas() { - uint startGas = gasleft(); - _; - uint endGas = gasleft(); - emit log_named_uint("gas", startGas - endGas); - } - - function assertTrue(bool condition) internal { - if (!condition) { - emit log("Error: Assertion Failed"); - fail(); - } - } - - function assertTrue(bool condition, string memory err) internal { - if (!condition) { - emit log_named_string("Error", err); - assertTrue(condition); - } - } - - function assertEq(address a, address b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [address]"); - emit log_named_address(" Left", a); - emit log_named_address(" Right", b); - fail(); - } - } - function assertEq(address a, address b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes32 a, bytes32 b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [bytes32]"); - emit log_named_bytes32(" Left", a); - emit log_named_bytes32(" Right", b); - fail(); - } - } - function assertEq(bytes32 a, bytes32 b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - function assertEq32(bytes32 a, bytes32 b) internal { - assertEq(a, b); - } - function assertEq32(bytes32 a, bytes32 b, string memory err) internal { - assertEq(a, b, err); - } - - function assertEq(int a, int b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - fail(); - } - } - function assertEq(int a, int b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEq(uint a, uint b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - fail(); - } - } - function assertEq(uint a, uint b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEqDecimal(int a, int b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - fail(); - } - } - function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - function assertEqDecimal(uint a, uint b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - fail(); - } - } - function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - - function assertNotEq(address a, address b) internal { - if (a == b) { - emit log("Error: a != b not satisfied [address]"); - emit log_named_address(" Left", a); - emit log_named_address(" Right", b); - fail(); - } - } - function assertNotEq(address a, address b, string memory err) internal { - if (a == b) { - emit log_named_string ("Error", err); - assertNotEq(a, b); - } - } - - function assertNotEq(bytes32 a, bytes32 b) internal { - if (a == b) { - emit log("Error: a != b not satisfied [bytes32]"); - emit log_named_bytes32(" Left", a); - emit log_named_bytes32(" Right", b); - fail(); - } - } - function assertNotEq(bytes32 a, bytes32 b, string memory err) internal { - if (a == b) { - emit log_named_string ("Error", err); - assertNotEq(a, b); - } - } - function assertNotEq32(bytes32 a, bytes32 b) internal { - assertNotEq(a, b); - } - function assertNotEq32(bytes32 a, bytes32 b, string memory err) internal { - assertNotEq(a, b, err); - } - - function assertNotEq(int a, int b) internal { - if (a == b) { - emit log("Error: a != b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - fail(); - } - } - function assertNotEq(int a, int b, string memory err) internal { - if (a == b) { - emit log_named_string("Error", err); - assertNotEq(a, b); - } - } - function assertNotEq(uint a, uint b) internal { - if (a == b) { - emit log("Error: a != b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - fail(); - } - } - function assertNotEq(uint a, uint b, string memory err) internal { - if (a == b) { - emit log_named_string("Error", err); - assertNotEq(a, b); - } - } - function assertNotEqDecimal(int a, int b, uint decimals) internal { - if (a == b) { - emit log("Error: a != b not satisfied [decimal int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - fail(); - } - } - function assertNotEqDecimal(int a, int b, uint decimals, string memory err) internal { - if (a == b) { - emit log_named_string("Error", err); - assertNotEqDecimal(a, b, decimals); - } - } - function assertNotEqDecimal(uint a, uint b, uint decimals) internal { - if (a == b) { - emit log("Error: a != b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - fail(); - } - } - function assertNotEqDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a == b) { - emit log_named_string("Error", err); - assertNotEqDecimal(a, b, decimals); - } - } - - function assertGt(uint a, uint b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGt(uint a, uint b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGt(int a, int b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGt(int a, int b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGtDecimal(int a, int b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - function assertGtDecimal(uint a, uint b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - - function assertGe(uint a, uint b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGe(uint a, uint b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGe(int a, int b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGe(int a, int b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGeDecimal(int a, int b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - function assertGeDecimal(uint a, uint b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertLt(uint a, uint b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLt(uint a, uint b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLt(int a, int b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLt(int a, int b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLtDecimal(int a, int b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - function assertLtDecimal(uint a, uint b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - - function assertLe(uint a, uint b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLe(uint a, uint b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLe(int a, int b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLe(int a, int b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLeDecimal(int a, int b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - function assertLeDecimal(uint a, uint b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - - function assertEq(string memory a, string memory b) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log("Error: a == b not satisfied [string]"); - emit log_named_string(" Left", a); - emit log_named_string(" Right", b); - fail(); - } - } - function assertEq(string memory a, string memory b, string memory err) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertNotEq(string memory a, string memory b) internal { - if (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))) { - emit log("Error: a != b not satisfied [string]"); - emit log_named_string(" Left", a); - emit log_named_string(" Right", b); - fail(); - } - } - function assertNotEq(string memory a, string memory b, string memory err) internal { - if (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))) { - emit log_named_string("Error", err); - assertNotEq(a, b); - } - } - - function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { - ok = true; - if (a.length == b.length) { - for (uint i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - ok = false; - } - } - } else { - ok = false; - } - } - function assertEq0(bytes memory a, bytes memory b) internal { - if (!checkEq0(a, b)) { - emit log("Error: a == b not satisfied [bytes]"); - emit log_named_bytes(" Left", a); - emit log_named_bytes(" Right", b); - fail(); - } - } - function assertEq0(bytes memory a, bytes memory b, string memory err) internal { - if (!checkEq0(a, b)) { - emit log_named_string("Error", err); - assertEq0(a, b); - } - } - - function assertNotEq0(bytes memory a, bytes memory b) internal { - if (checkEq0(a, b)) { - emit log("Error: a != b not satisfied [bytes]"); - emit log_named_bytes(" Left", a); - emit log_named_bytes(" Right", b); - fail(); - } - } - function assertNotEq0(bytes memory a, bytes memory b, string memory err) internal { - if (checkEq0(a, b)) { - emit log_named_string("Error", err); - assertNotEq0(a, b); - } - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/src/test.t.sol b/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/src/test.t.sol deleted file mode 100644 index d277a30..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/lib/ds-test/src/test.t.sol +++ /dev/null @@ -1,417 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.5.0; - -import {DSTest} from "./test.sol"; - -contract DemoTest is DSTest { - - // --- assertTrue --- - - function testAssertTrue() public { - assertTrue(true, "msg"); - assertTrue(true); - } - function testFailAssertTrue() public { - assertTrue(false); - } - function testFailAssertTrueWithMsg() public { - assertTrue(false, "msg"); - } - - // --- assertEq (Addr) --- - - function testAssertEqAddr() public { - assertEq(address(0x0), address(0x0), "msg"); - assertEq(address(0x0), address(0x0)); - } - function testFailAssertEqAddr() public { - assertEq(address(0x0), address(0x1)); - } - function testFailAssertEqAddrWithMsg() public { - assertEq(address(0x0), address(0x1), "msg"); - } - - // --- assertEq (Bytes32) --- - - function testAssertEqBytes32() public { - assertEq(bytes32("hi"), bytes32("hi"), "msg"); - assertEq(bytes32("hi"), bytes32("hi")); - } - function testFailAssertEqBytes32() public { - assertEq(bytes32("hi"), bytes32("ho")); - } - function testFailAssertEqBytes32WithMsg() public { - assertEq(bytes32("hi"), bytes32("ho"), "msg"); - } - - // --- assertEq (Int) --- - - function testAssertEqInt() public { - assertEq(-1, -1, "msg"); - assertEq(-1, -1); - } - function testFailAssertEqInt() public { - assertEq(-1, -2); - } - function testFailAssertEqIntWithMsg() public { - assertEq(-1, -2, "msg"); - } - - // --- assertEq (UInt) --- - - function testAssertEqUInt() public { - assertEq(uint(1), uint(1), "msg"); - assertEq(uint(1), uint(1)); - } - function testFailAssertEqUInt() public { - assertEq(uint(1), uint(2)); - } - function testFailAssertEqUIntWithMsg() public { - assertEq(uint(1), uint(2), "msg"); - } - - // --- assertEqDecimal (Int) --- - - function testAssertEqDecimalInt() public { - assertEqDecimal(-1, -1, 18, "msg"); - assertEqDecimal(-1, -1, 18); - } - function testFailAssertEqDecimalInt() public { - assertEqDecimal(-1, -2, 18); - } - function testFailAssertEqDecimalIntWithMsg() public { - assertEqDecimal(-1, -2, 18, "msg"); - } - - // --- assertEqDecimal (UInt) --- - - function testAssertEqDecimalUInt() public { - assertEqDecimal(uint(1), uint(1), 18, "msg"); - assertEqDecimal(uint(1), uint(1), 18); - } - function testFailAssertEqDecimalUInt() public { - assertEqDecimal(uint(1), uint(2), 18); - } - function testFailAssertEqDecimalUIntWithMsg() public { - assertEqDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertNotEq (Addr) --- - - function testAssertNotEqAddr() public { - assertNotEq(address(0x0), address(0x1), "msg"); - assertNotEq(address(0x0), address(0x1)); - } - function testFailAssertNotEqAddr() public { - assertNotEq(address(0x0), address(0x0)); - } - function testFailAssertNotEqAddrWithMsg() public { - assertNotEq(address(0x0), address(0x0), "msg"); - } - - // --- assertNotEq (Bytes32) --- - - function testAssertNotEqBytes32() public { - assertNotEq(bytes32("hi"), bytes32("ho"), "msg"); - assertNotEq(bytes32("hi"), bytes32("ho")); - } - function testFailAssertNotEqBytes32() public { - assertNotEq(bytes32("hi"), bytes32("hi")); - } - function testFailAssertNotEqBytes32WithMsg() public { - assertNotEq(bytes32("hi"), bytes32("hi"), "msg"); - } - - // --- assertNotEq (Int) --- - - function testAssertNotEqInt() public { - assertNotEq(-1, -2, "msg"); - assertNotEq(-1, -2); - } - function testFailAssertNotEqInt() public { - assertNotEq(-1, -1); - } - function testFailAssertNotEqIntWithMsg() public { - assertNotEq(-1, -1, "msg"); - } - - // --- assertNotEq (UInt) --- - - function testAssertNotEqUInt() public { - assertNotEq(uint(1), uint(2), "msg"); - assertNotEq(uint(1), uint(2)); - } - function testFailAssertNotEqUInt() public { - assertNotEq(uint(1), uint(1)); - } - function testFailAssertNotEqUIntWithMsg() public { - assertNotEq(uint(1), uint(1), "msg"); - } - - // --- assertNotEqDecimal (Int) --- - - function testAssertNotEqDecimalInt() public { - assertNotEqDecimal(-1, -2, 18, "msg"); - assertNotEqDecimal(-1, -2, 18); - } - function testFailAssertNotEqDecimalInt() public { - assertNotEqDecimal(-1, -1, 18); - } - function testFailAssertNotEqDecimalIntWithMsg() public { - assertNotEqDecimal(-1, -1, 18, "msg"); - } - - // --- assertNotEqDecimal (UInt) --- - - function testAssertNotEqDecimalUInt() public { - assertNotEqDecimal(uint(1), uint(2), 18, "msg"); - assertNotEqDecimal(uint(1), uint(2), 18); - } - function testFailAssertNotEqDecimalUInt() public { - assertNotEqDecimal(uint(1), uint(1), 18); - } - function testFailAssertNotEqDecimalUIntWithMsg() public { - assertNotEqDecimal(uint(1), uint(1), 18, "msg"); - } - - // --- assertGt (UInt) --- - - function testAssertGtUInt() public { - assertGt(uint(2), uint(1), "msg"); - assertGt(uint(3), uint(2)); - } - function testFailAssertGtUInt() public { - assertGt(uint(1), uint(2)); - } - function testFailAssertGtUIntWithMsg() public { - assertGt(uint(1), uint(2), "msg"); - } - - // --- assertGt (Int) --- - - function testAssertGtInt() public { - assertGt(-1, -2, "msg"); - assertGt(-1, -3); - } - function testFailAssertGtInt() public { - assertGt(-2, -1); - } - function testFailAssertGtIntWithMsg() public { - assertGt(-2, -1, "msg"); - } - - // --- assertGtDecimal (UInt) --- - - function testAssertGtDecimalUInt() public { - assertGtDecimal(uint(2), uint(1), 18, "msg"); - assertGtDecimal(uint(3), uint(2), 18); - } - function testFailAssertGtDecimalUInt() public { - assertGtDecimal(uint(1), uint(2), 18); - } - function testFailAssertGtDecimalUIntWithMsg() public { - assertGtDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertGtDecimal (Int) --- - - function testAssertGtDecimalInt() public { - assertGtDecimal(-1, -2, 18, "msg"); - assertGtDecimal(-1, -3, 18); - } - function testFailAssertGtDecimalInt() public { - assertGtDecimal(-2, -1, 18); - } - function testFailAssertGtDecimalIntWithMsg() public { - assertGtDecimal(-2, -1, 18, "msg"); - } - - // --- assertGe (UInt) --- - - function testAssertGeUInt() public { - assertGe(uint(2), uint(1), "msg"); - assertGe(uint(2), uint(2)); - } - function testFailAssertGeUInt() public { - assertGe(uint(1), uint(2)); - } - function testFailAssertGeUIntWithMsg() public { - assertGe(uint(1), uint(2), "msg"); - } - - // --- assertGe (Int) --- - - function testAssertGeInt() public { - assertGe(-1, -2, "msg"); - assertGe(-1, -1); - } - function testFailAssertGeInt() public { - assertGe(-2, -1); - } - function testFailAssertGeIntWithMsg() public { - assertGe(-2, -1, "msg"); - } - - // --- assertGeDecimal (UInt) --- - - function testAssertGeDecimalUInt() public { - assertGeDecimal(uint(2), uint(1), 18, "msg"); - assertGeDecimal(uint(2), uint(2), 18); - } - function testFailAssertGeDecimalUInt() public { - assertGeDecimal(uint(1), uint(2), 18); - } - function testFailAssertGeDecimalUIntWithMsg() public { - assertGeDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertGeDecimal (Int) --- - - function testAssertGeDecimalInt() public { - assertGeDecimal(-1, -2, 18, "msg"); - assertGeDecimal(-1, -2, 18); - } - function testFailAssertGeDecimalInt() public { - assertGeDecimal(-2, -1, 18); - } - function testFailAssertGeDecimalIntWithMsg() public { - assertGeDecimal(-2, -1, 18, "msg"); - } - - // --- assertLt (UInt) --- - - function testAssertLtUInt() public { - assertLt(uint(1), uint(2), "msg"); - assertLt(uint(1), uint(3)); - } - function testFailAssertLtUInt() public { - assertLt(uint(2), uint(2)); - } - function testFailAssertLtUIntWithMsg() public { - assertLt(uint(3), uint(2), "msg"); - } - - // --- assertLt (Int) --- - - function testAssertLtInt() public { - assertLt(-2, -1, "msg"); - assertLt(-1, 0); - } - function testFailAssertLtInt() public { - assertLt(-1, -2); - } - function testFailAssertLtIntWithMsg() public { - assertLt(-1, -1, "msg"); - } - - // --- assertLtDecimal (UInt) --- - - function testAssertLtDecimalUInt() public { - assertLtDecimal(uint(1), uint(2), 18, "msg"); - assertLtDecimal(uint(2), uint(3), 18); - } - function testFailAssertLtDecimalUInt() public { - assertLtDecimal(uint(1), uint(1), 18); - } - function testFailAssertLtDecimalUIntWithMsg() public { - assertLtDecimal(uint(2), uint(1), 18, "msg"); - } - - // --- assertLtDecimal (Int) --- - - function testAssertLtDecimalInt() public { - assertLtDecimal(-2, -1, 18, "msg"); - assertLtDecimal(-2, -1, 18); - } - function testFailAssertLtDecimalInt() public { - assertLtDecimal(-2, -2, 18); - } - function testFailAssertLtDecimalIntWithMsg() public { - assertLtDecimal(-1, -2, 18, "msg"); - } - - // --- assertLe (UInt) --- - - function testAssertLeUInt() public { - assertLe(uint(1), uint(2), "msg"); - assertLe(uint(1), uint(1)); - } - function testFailAssertLeUInt() public { - assertLe(uint(4), uint(2)); - } - function testFailAssertLeUIntWithMsg() public { - assertLe(uint(3), uint(2), "msg"); - } - - // --- assertLe (Int) --- - - function testAssertLeInt() public { - assertLe(-2, -1, "msg"); - assertLe(-1, -1); - } - function testFailAssertLeInt() public { - assertLe(-1, -2); - } - function testFailAssertLeIntWithMsg() public { - assertLe(-1, -3, "msg"); - } - - // --- assertLeDecimal (UInt) --- - - function testAssertLeDecimalUInt() public { - assertLeDecimal(uint(1), uint(2), 18, "msg"); - assertLeDecimal(uint(2), uint(2), 18); - } - function testFailAssertLeDecimalUInt() public { - assertLeDecimal(uint(1), uint(0), 18); - } - function testFailAssertLeDecimalUIntWithMsg() public { - assertLeDecimal(uint(1), uint(0), 18, "msg"); - } - - // --- assertLeDecimal (Int) --- - - function testAssertLeDecimalInt() public { - assertLeDecimal(-2, -1, 18, "msg"); - assertLeDecimal(-2, -2, 18); - } - function testFailAssertLeDecimalInt() public { - assertLeDecimal(-2, -3, 18); - } - function testFailAssertLeDecimalIntWithMsg() public { - assertLeDecimal(-1, -2, 18, "msg"); - } - - // --- assertNotEq (String) --- - - function testAssertNotEqString() public { - assertNotEq(new string(1), new string(2), "msg"); - assertNotEq(new string(1), new string(2)); - } - function testFailAssertNotEqString() public { - assertNotEq(new string(1), new string(1)); - } - function testFailAssertNotEqStringWithMsg() public { - assertNotEq(new string(1), new string(1), "msg"); - } - - // --- assertNotEq0 (Bytes) --- - - function testAssertNotEq0Bytes() public { - assertNotEq0(bytes("hi"), bytes("ho"), "msg"); - assertNotEq0(bytes("hi"), bytes("ho")); - } - function testFailAssertNotEq0Bytes() public { - assertNotEq0(bytes("hi"), bytes("hi")); - } - function testFailAssertNotEq0BytesWithMsg() public { - assertNotEq0(bytes("hi"), bytes("hi"), "msg"); - } - - // --- fail override --- - - // ensure that fail can be overridden - function fail() internal override { - super.fail(); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/package.json b/lib/morpho-blue-irm/lib/forge-std/package.json deleted file mode 100644 index 310d46c..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "forge-std", - "version": "1.6.0", - "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", - "homepage": "https://book.getfoundry.sh/forge/forge-std", - "bugs": "https://github.com/foundry-rs/forge-std/issues", - "license": "(Apache-2.0 OR MIT)", - "author": "Contributors to Forge Standard Library", - "files": [ - "src/**/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/foundry-rs/forge-std.git" - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/Base.sol b/lib/morpho-blue-irm/lib/forge-std/src/Base.sol deleted file mode 100644 index 851ac0c..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/Base.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {StdStorage} from "./StdStorage.sol"; -import {Vm, VmSafe} from "./Vm.sol"; - -abstract contract CommonBase { - // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. - address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); - // console.sol and console2.sol work by executing a staticcall to this address. - address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; - // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. - address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38. - address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256("foundry default caller")))); - // Address of the test contract, deployed by the DEFAULT_SENDER. - address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; - // Deterministic deployment address of the Multicall3 contract. - address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; - // The order of the secp256k1 curve. - uint256 internal constant SECP256K1_ORDER = - 115792089237316195423570985008687907852837564279074904382605163141518161494337; - - uint256 internal constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - Vm internal constant vm = Vm(VM_ADDRESS); - StdStorage internal stdstore; -} - -abstract contract TestBase is CommonBase {} - -abstract contract ScriptBase is CommonBase { - VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/Script.sol b/lib/morpho-blue-irm/lib/forge-std/src/Script.sol deleted file mode 100644 index fb612ef..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/Script.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -// 💬 ABOUT -// Forge Std's default Script. - -// 🧩 MODULES -import {console} from "./console.sol"; -import {console2} from "./console2.sol"; -import {safeconsole} from "./safeconsole.sol"; -import {StdChains} from "./StdChains.sol"; -import {StdCheatsSafe} from "./StdCheats.sol"; -import {stdJson} from "./StdJson.sol"; -import {stdMath} from "./StdMath.sol"; -import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; -import {StdStyle} from "./StdStyle.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {VmSafe} from "./Vm.sol"; - -// 📦 BOILERPLATE -import {ScriptBase} from "./Base.sol"; - -// ⭐️ SCRIPT -abstract contract Script is StdChains, StdCheatsSafe, StdUtils, ScriptBase { - // Note: IS_SCRIPT() must return true. - bool public IS_SCRIPT = true; -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdAssertions.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdAssertions.sol deleted file mode 100644 index 2778b3a..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdAssertions.sol +++ /dev/null @@ -1,376 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {DSTest} from "ds-test/test.sol"; -import {stdMath} from "./StdMath.sol"; - -abstract contract StdAssertions is DSTest { - event log_array(uint256[] val); - event log_array(int256[] val); - event log_array(address[] val); - event log_named_array(string key, uint256[] val); - event log_named_array(string key, int256[] val); - event log_named_array(string key, address[] val); - - function fail(string memory err) internal virtual { - emit log_named_string("Error", err); - fail(); - } - - function assertFalse(bool data) internal virtual { - assertTrue(!data); - } - - function assertFalse(bool data, string memory err) internal virtual { - assertTrue(!data, err); - } - - function assertEq(bool a, bool b) internal virtual { - if (a != b) { - emit log("Error: a == b not satisfied [bool]"); - emit log_named_string(" Left", a ? "true" : "false"); - emit log_named_string(" Right", b ? "true" : "false"); - fail(); - } - } - - function assertEq(bool a, bool b, string memory err) internal virtual { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes memory a, bytes memory b) internal virtual { - assertEq0(a, b); - } - - function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual { - assertEq0(a, b, err); - } - - function assertEq(uint256[] memory a, uint256[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [uint[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(int256[] memory a, int256[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [int[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(address[] memory a, address[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [address[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - // Legacy helper - function assertEqUint(uint256 a, uint256 b) internal virtual { - assertEq(uint256(a), uint256(b)); - } - - function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbs(a, b, maxDelta); - } - } - - function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); - emit log_named_decimal_uint(" Delta", delta, decimals); - fail(); - } - } - - function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err) - internal - virtual - { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - } - - function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbs(a, b, maxDelta); - } - } - - function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); - emit log_named_decimal_uint(" Delta", delta, decimals); - fail(); - } - } - - function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err) - internal - virtual - { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - } - - function assertApproxEqRel( - uint256 a, - uint256 b, - uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% - ) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); - emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); - fail(); - } - } - - function assertApproxEqRel( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRel(a, b, maxPercentDelta); - } - } - - function assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); - emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); - fail(); - } - } - - function assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - } - - function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); - emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); - fail(); - } - } - - function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRel(a, b, maxPercentDelta); - } - } - - function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); - emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); - fail(); - } - } - - function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err) - internal - virtual - { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - } - - function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { - assertEqCall(target, callDataA, target, callDataB, true); - } - - function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) - internal - virtual - { - assertEqCall(targetA, callDataA, targetB, callDataB, true); - } - - function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) - internal - virtual - { - assertEqCall(target, callDataA, target, callDataB, strictRevertData); - } - - function assertEqCall( - address targetA, - bytes memory callDataA, - address targetB, - bytes memory callDataB, - bool strictRevertData - ) internal virtual { - (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); - (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); - - if (successA && successB) { - assertEq(returnDataA, returnDataB, "Call return data does not match"); - } - - if (!successA && !successB && strictRevertData) { - assertEq(returnDataA, returnDataB, "Call revert data does not match"); - } - - if (!successA && successB) { - emit log("Error: Calls were not equal"); - emit log_named_bytes(" Left call revert data", returnDataA); - emit log_named_bytes(" Right call return data", returnDataB); - fail(); - } - - if (successA && !successB) { - emit log("Error: Calls were not equal"); - emit log_named_bytes(" Left call return data", returnDataA); - emit log_named_bytes(" Right call revert data", returnDataB); - fail(); - } - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdChains.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdChains.sol deleted file mode 100644 index 12db076..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdChains.sol +++ /dev/null @@ -1,229 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {VmSafe} from "./Vm.sol"; - -/** - * StdChains provides information about EVM compatible chains that can be used in scripts/tests. - * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are - * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of - * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the - * alias used in this contract, which can be found as the first argument to the - * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. - * - * There are two main ways to use this contract: - * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or - * `setChain(string memory chainAlias, Chain memory chain)` - * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. - * - * The first time either of those are used, chains are initialized with the default set of RPC URLs. - * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in - * `defaultRpcUrls`. - * - * The `setChain` function is straightforward, and it simply saves off the given chain data. - * - * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say - * we want to retrieve the RPC URL for `mainnet`: - * - If you have specified data with `setChain`, it will return that. - * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it - * is valid (e.g. a URL is specified, or an environment variable is given and exists). - * - If neither of the above conditions is met, the default data is returned. - * - * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. - */ -abstract contract StdChains { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - bool private stdChainsInitialized; - - struct ChainData { - string name; - uint256 chainId; - string rpcUrl; - } - - struct Chain { - // The chain name. - string name; - // The chain's Chain ID. - uint256 chainId; - // The chain's alias. (i.e. what gets specified in `foundry.toml`). - string chainAlias; - // A default RPC endpoint for this chain. - // NOTE: This default RPC URL is included for convenience to facilitate quick tests and - // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy - // usage as you will be throttled and this is a disservice to others who need this endpoint. - string rpcUrl; - } - - // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. - mapping(string => Chain) private chains; - // Maps from the chain's alias to it's default RPC URL. - mapping(string => string) private defaultRpcUrls; - // Maps from a chain ID to it's alias. - mapping(uint256 => string) private idToAlias; - - bool private fallbackToDefaultRpcUrls = true; - - // The RPC URL will be fetched from config or defaultRpcUrls if possible. - function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { - require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); - - initializeStdChains(); - chain = chains[chainAlias]; - require( - chain.chainId != 0, - string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) - ); - - chain = getChainWithUpdatedRpcUrl(chainAlias, chain); - } - - function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { - require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); - initializeStdChains(); - string memory chainAlias = idToAlias[chainId]; - - chain = chains[chainAlias]; - - require( - chain.chainId != 0, - string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) - ); - - chain = getChainWithUpdatedRpcUrl(chainAlias, chain); - } - - // set chain info, with priority to argument's rpcUrl field. - function setChain(string memory chainAlias, ChainData memory chain) internal virtual { - require( - bytes(chainAlias).length != 0, - "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." - ); - - require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); - - initializeStdChains(); - string memory foundAlias = idToAlias[chain.chainId]; - - require( - bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), - string( - abi.encodePacked( - "StdChains setChain(string,ChainData): Chain ID ", - vm.toString(chain.chainId), - " already used by \"", - foundAlias, - "\"." - ) - ) - ); - - uint256 oldChainId = chains[chainAlias].chainId; - delete idToAlias[oldChainId]; - - chains[chainAlias] = - Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); - idToAlias[chain.chainId] = chainAlias; - } - - // set chain info, with priority to argument's rpcUrl field. - function setChain(string memory chainAlias, Chain memory chain) internal virtual { - setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); - } - - function _toUpper(string memory str) private pure returns (string memory) { - bytes memory strb = bytes(str); - bytes memory copy = new bytes(strb.length); - for (uint256 i = 0; i < strb.length; i++) { - bytes1 b = strb[i]; - if (b >= 0x61 && b <= 0x7A) { - copy[i] = bytes1(uint8(b) - 32); - } else { - copy[i] = b; - } - } - return string(copy); - } - - // lookup rpcUrl, in descending order of priority: - // current -> config (foundry.toml) -> environment variable -> default - function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) { - if (bytes(chain.rpcUrl).length == 0) { - try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { - chain.rpcUrl = configRpcUrl; - } catch (bytes memory err) { - string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); - if (fallbackToDefaultRpcUrls) { - chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); - } else { - chain.rpcUrl = vm.envString(envName); - } - // distinguish 'not found' from 'cannot read' - bytes memory notFoundError = - abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); - if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, err), mload(err)) - } - } - } - } - return chain; - } - - function setFallbackToDefaultRpcUrls(bool useDefault) internal { - fallbackToDefaultRpcUrls = useDefault; - } - - function initializeStdChains() private { - if (stdChainsInitialized) return; - - stdChainsInitialized = true; - - // If adding an RPC here, make sure to test the default RPC URL in `testRpcs` - setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); - setChainWithDefaultRpcUrl( - "mainnet", ChainData("Mainnet", 1, "https://mainnet.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") - ); - setChainWithDefaultRpcUrl( - "goerli", ChainData("Goerli", 5, "https://goerli.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") - ); - setChainWithDefaultRpcUrl( - "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") - ); - setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); - setChainWithDefaultRpcUrl("optimism_goerli", ChainData("Optimism Goerli", 420, "https://goerli.optimism.io")); - setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl( - "arbitrum_one_goerli", ChainData("Arbitrum One Goerli", 421613, "https://goerli-rollup.arbitrum.io/rpc") - ); - setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); - setChainWithDefaultRpcUrl( - "polygon_mumbai", ChainData("Polygon Mumbai", 80001, "https://rpc-mumbai.maticvigil.com") - ); - setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); - setChainWithDefaultRpcUrl( - "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") - ); - setChainWithDefaultRpcUrl( - "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") - ); - setChainWithDefaultRpcUrl( - "bnb_smart_chain_testnet", - ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") - ); - setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); - } - - // set chain info, with priority to chainAlias' rpc url in foundry.toml - function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { - string memory rpcUrl = chain.rpcUrl; - defaultRpcUrls[chainAlias] = rpcUrl; - chain.rpcUrl = ""; - setChain(chainAlias, chain); - chain.rpcUrl = rpcUrl; // restore argument - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdCheats.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdCheats.sol deleted file mode 100644 index 1b01726..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdCheats.sol +++ /dev/null @@ -1,805 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {Vm} from "./Vm.sol"; - -abstract contract StdCheatsSafe { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - uint256 private constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - bool private gasMeteringOff; - - // Data structures to parse Transaction objects from the broadcast artifact - // that conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawTx1559 { - string[] arguments; - address contractAddress; - string contractName; - // json value name = function - string functionSig; - bytes32 hash; - // json value name = tx - RawTx1559Detail txDetail; - // json value name = type - string opcode; - } - - struct RawTx1559Detail { - AccessList[] accessList; - bytes data; - address from; - bytes gas; - bytes nonce; - address to; - bytes txType; - bytes value; - } - - struct Tx1559 { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - bytes32 hash; - Tx1559Detail txDetail; - string opcode; - } - - struct Tx1559Detail { - AccessList[] accessList; - bytes data; - address from; - uint256 gas; - uint256 nonce; - address to; - uint256 txType; - uint256 value; - } - - // Data structures to parse Transaction objects from the broadcast artifact - // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct TxLegacy { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - string hash; - string opcode; - TxDetailLegacy transaction; - } - - struct TxDetailLegacy { - AccessList[] accessList; - uint256 chainId; - bytes data; - address from; - uint256 gas; - uint256 gasPrice; - bytes32 hash; - uint256 nonce; - bytes1 opcode; - bytes32 r; - bytes32 s; - uint256 txType; - address to; - uint8 v; - uint256 value; - } - - struct AccessList { - address accessAddress; - bytes32[] storageKeys; - } - - // Data structures to parse Receipt objects from the broadcast artifact. - // The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawReceipt { - bytes32 blockHash; - bytes blockNumber; - address contractAddress; - bytes cumulativeGasUsed; - bytes effectiveGasPrice; - address from; - bytes gasUsed; - RawReceiptLog[] logs; - bytes logsBloom; - bytes status; - address to; - bytes32 transactionHash; - bytes transactionIndex; - } - - struct Receipt { - bytes32 blockHash; - uint256 blockNumber; - address contractAddress; - uint256 cumulativeGasUsed; - uint256 effectiveGasPrice; - address from; - uint256 gasUsed; - ReceiptLog[] logs; - bytes logsBloom; - uint256 status; - address to; - bytes32 transactionHash; - uint256 transactionIndex; - } - - // Data structures to parse the entire broadcast artifact, assuming the - // transactions conform to EIP1559. - - struct EIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - Receipt[] receipts; - uint256 timestamp; - Tx1559[] transactions; - TxReturn[] txReturns; - } - - struct RawEIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - RawReceipt[] receipts; - TxReturn[] txReturns; - uint256 timestamp; - RawTx1559[] transactions; - } - - struct RawReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - bytes blockNumber; - bytes data; - bytes logIndex; - bool removed; - bytes32[] topics; - bytes32 transactionHash; - bytes transactionIndex; - bytes transactionLogIndex; - } - - struct ReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - uint256 blockNumber; - bytes data; - uint256 logIndex; - bytes32[] topics; - uint256 transactionIndex; - uint256 transactionLogIndex; - bool removed; - } - - struct TxReturn { - string internalType; - string value; - } - - struct Account { - address addr; - uint256 key; - } - - enum AddressType { - Payable, - NonPayable, - ZeroAddress, - Precompile, - ForgeAddress - } - - // Checks that `addr` is not blacklisted by token contracts that have a blacklist. - function assumeNotBlacklisted(address token, address addr) internal view virtual { - // Nothing to check if `token` is not a contract. - uint256 tokenCodeSize; - assembly { - tokenCodeSize := extcodesize(token) - } - require(tokenCodeSize > 0, "StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); - - bool success; - bytes memory returnData; - - // 4-byte selector for `isBlacklisted(address)`, used by USDC. - (success, returnData) = token.staticcall(abi.encodeWithSelector(0xfe575a87, addr)); - vm.assume(!success || abi.decode(returnData, (bool)) == false); - - // 4-byte selector for `isBlackListed(address)`, used by USDT. - (success, returnData) = token.staticcall(abi.encodeWithSelector(0xe47d6060, addr)); - vm.assume(!success || abi.decode(returnData, (bool)) == false); - } - - // Checks that `addr` is not blacklisted by token contracts that have a blacklist. - // This is identical to `assumeNotBlacklisted(address,address)` but with a different name, for - // backwards compatibility, since this name was used in the original PR which has already has - // a release. This function can be removed in a future release once we want a breaking change. - function assumeNoBlacklisted(address token, address addr) internal view virtual { - assumeNotBlacklisted(token, addr); - } - - function assumeAddressIsNot(address addr, AddressType addressType) internal virtual { - if (addressType == AddressType.Payable) { - assumeNotPayable(addr); - } else if (addressType == AddressType.NonPayable) { - assumePayable(addr); - } else if (addressType == AddressType.ZeroAddress) { - assumeNotZeroAddress(addr); - } else if (addressType == AddressType.Precompile) { - assumeNotPrecompile(addr); - } else if (addressType == AddressType.ForgeAddress) { - assumeNotForgeAddress(addr); - } - } - - function assumeAddressIsNot(address addr, AddressType addressType1, AddressType addressType2) internal virtual { - assumeAddressIsNot(addr, addressType1); - assumeAddressIsNot(addr, addressType2); - } - - function assumeAddressIsNot( - address addr, - AddressType addressType1, - AddressType addressType2, - AddressType addressType3 - ) internal virtual { - assumeAddressIsNot(addr, addressType1); - assumeAddressIsNot(addr, addressType2); - assumeAddressIsNot(addr, addressType3); - } - - function assumeAddressIsNot( - address addr, - AddressType addressType1, - AddressType addressType2, - AddressType addressType3, - AddressType addressType4 - ) internal virtual { - assumeAddressIsNot(addr, addressType1); - assumeAddressIsNot(addr, addressType2); - assumeAddressIsNot(addr, addressType3); - assumeAddressIsNot(addr, addressType4); - } - - // This function checks whether an address, `addr`, is payable. It works by sending 1 wei to - // `addr` and checking the `success` return value. - // NOTE: This function may result in state changes depending on the fallback/receive logic - // implemented by `addr`, which should be taken into account when this function is used. - function _isPayable(address addr) private returns (bool) { - require( - addr.balance < UINT256_MAX, - "StdCheats _isPayable(address): Balance equals max uint256, so it cannot receive any more funds" - ); - uint256 origBalanceTest = address(this).balance; - uint256 origBalanceAddr = address(addr).balance; - - vm.deal(address(this), 1); - (bool success,) = payable(addr).call{value: 1}(""); - - // reset balances - vm.deal(address(this), origBalanceTest); - vm.deal(addr, origBalanceAddr); - - return success; - } - - // NOTE: This function may result in state changes depending on the fallback/receive logic - // implemented by `addr`, which should be taken into account when this function is used. See the - // `_isPayable` method for more information. - function assumePayable(address addr) internal virtual { - vm.assume(_isPayable(addr)); - } - - function assumeNotPayable(address addr) internal virtual { - vm.assume(!_isPayable(addr)); - } - - function assumeNotZeroAddress(address addr) internal pure virtual { - vm.assume(addr != address(0)); - } - - function assumeNotPrecompile(address addr) internal pure virtual { - assumeNotPrecompile(addr, _pureChainId()); - } - - function assumeNotPrecompile(address addr, uint256 chainId) internal pure virtual { - // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific - // address), but the same rationale for excluding them applies so we include those too. - - // These should be present on all EVM-compatible chains. - vm.assume(addr < address(0x1) || addr > address(0x9)); - - // forgefmt: disable-start - if (chainId == 10 || chainId == 420) { - // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 - vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); - } else if (chainId == 42161 || chainId == 421613) { - // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains - vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); - } else if (chainId == 43114 || chainId == 43113) { - // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 - vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); - vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); - vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); - } - // forgefmt: disable-end - } - - function assumeNotForgeAddress(address addr) internal pure virtual { - // vm and console addresses - vm.assume(addr != address(vm) || addr != 0x000000000000000000636F6e736F6c652e6c6f67); - } - - function readEIP1559ScriptArtifact(string memory path) - internal - view - virtual - returns (EIP1559ScriptArtifact memory) - { - string memory data = vm.readFile(path); - bytes memory parsedData = vm.parseJson(data); - RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); - EIP1559ScriptArtifact memory artifact; - artifact.libraries = rawArtifact.libraries; - artifact.path = rawArtifact.path; - artifact.timestamp = rawArtifact.timestamp; - artifact.pending = rawArtifact.pending; - artifact.txReturns = rawArtifact.txReturns; - artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); - artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); - return artifact; - } - - function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { - Tx1559[] memory txs = new Tx1559[](rawTxs.length); - for (uint256 i; i < rawTxs.length; i++) { - txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); - } - return txs; - } - - function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { - Tx1559 memory transaction; - transaction.arguments = rawTx.arguments; - transaction.contractName = rawTx.contractName; - transaction.functionSig = rawTx.functionSig; - transaction.hash = rawTx.hash; - transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); - transaction.opcode = rawTx.opcode; - return transaction; - } - - function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) - internal - pure - virtual - returns (Tx1559Detail memory) - { - Tx1559Detail memory txDetail; - txDetail.data = rawDetail.data; - txDetail.from = rawDetail.from; - txDetail.to = rawDetail.to; - txDetail.nonce = _bytesToUint(rawDetail.nonce); - txDetail.txType = _bytesToUint(rawDetail.txType); - txDetail.value = _bytesToUint(rawDetail.value); - txDetail.gas = _bytesToUint(rawDetail.gas); - txDetail.accessList = rawDetail.accessList; - return txDetail; - } - - function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); - RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); - return rawToConvertedEIPTx1559s(rawTxs); - } - - function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); - return rawToConvertedEIPTx1559(rawTx); - } - - // Analogous to readTransactions, but for receipts. - function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); - RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); - return rawToConvertedReceipts(rawReceipts); - } - - function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); - return rawToConvertedReceipt(rawReceipt); - } - - function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { - Receipt[] memory receipts = new Receipt[](rawReceipts.length); - for (uint256 i; i < rawReceipts.length; i++) { - receipts[i] = rawToConvertedReceipt(rawReceipts[i]); - } - return receipts; - } - - function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { - Receipt memory receipt; - receipt.blockHash = rawReceipt.blockHash; - receipt.to = rawReceipt.to; - receipt.from = rawReceipt.from; - receipt.contractAddress = rawReceipt.contractAddress; - receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); - receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); - receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); - receipt.status = _bytesToUint(rawReceipt.status); - receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); - receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); - receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); - receipt.logsBloom = rawReceipt.logsBloom; - receipt.transactionHash = rawReceipt.transactionHash; - return receipt; - } - - function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) - internal - pure - virtual - returns (ReceiptLog[] memory) - { - ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); - for (uint256 i; i < rawLogs.length; i++) { - logs[i].logAddress = rawLogs[i].logAddress; - logs[i].blockHash = rawLogs[i].blockHash; - logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); - logs[i].data = rawLogs[i].data; - logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); - logs[i].topics = rawLogs[i].topics; - logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); - logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); - logs[i].removed = rawLogs[i].removed; - } - return logs; - } - - // Deploy a contract by fetching the contract bytecode from - // the artifacts directory - // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` - function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); - } - - function deployCode(string memory what) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); - } - - /// @dev deploy contract with value on construction - function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); - } - - function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); - } - - // creates a labeled address and the corresponding private key - function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { - privateKey = uint256(keccak256(abi.encodePacked(name))); - addr = vm.addr(privateKey); - vm.label(addr, name); - } - - // creates a labeled address - function makeAddr(string memory name) internal virtual returns (address addr) { - (addr,) = makeAddrAndKey(name); - } - - // Destroys an account immediately, sending the balance to beneficiary. - // Destroying means: balance will be zero, code will be empty, and nonce will be 0 - // This is similar to selfdestruct but not identical: selfdestruct destroys code and nonce - // only after tx ends, this will run immediately. - function destroyAccount(address who, address beneficiary) internal virtual { - uint256 currBalance = who.balance; - vm.etch(who, abi.encode()); - vm.deal(who, 0); - vm.resetNonce(who); - - uint256 beneficiaryBalance = beneficiary.balance; - vm.deal(beneficiary, currBalance + beneficiaryBalance); - } - - // creates a struct containing both a labeled address and the corresponding private key - function makeAccount(string memory name) internal virtual returns (Account memory account) { - (account.addr, account.key) = makeAddrAndKey(name); - } - - function deriveRememberKey(string memory mnemonic, uint32 index) - internal - virtual - returns (address who, uint256 privateKey) - { - privateKey = vm.deriveKey(mnemonic, index); - who = vm.rememberKey(privateKey); - } - - function _bytesToUint(bytes memory b) private pure returns (uint256) { - require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); - return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); - } - - function isFork() internal view virtual returns (bool status) { - try vm.activeFork() { - status = true; - } catch (bytes memory) {} - } - - modifier skipWhenForking() { - if (!isFork()) { - _; - } - } - - modifier skipWhenNotForking() { - if (isFork()) { - _; - } - } - - modifier noGasMetering() { - vm.pauseGasMetering(); - // To prevent turning gas monitoring back on with nested functions that use this modifier, - // we check if gasMetering started in the off position. If it did, we don't want to turn - // it back on until we exit the top level function that used the modifier - // - // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. - // funcA will have `gasStartedOff` as false, funcB will have it as true, - // so we only turn metering back on at the end of the funcA - bool gasStartedOff = gasMeteringOff; - gasMeteringOff = true; - - _; - - // if gas metering was on when this modifier was called, turn it back on at the end - if (!gasStartedOff) { - gasMeteringOff = false; - vm.resumeGasMetering(); - } - } - - // We use this complex approach of `_viewChainId` and `_pureChainId` to ensure there are no - // compiler warnings when accessing chain ID in any solidity version supported by forge-std. We - // can't simply access the chain ID in a normal view or pure function because the solc View Pure - // Checker changed `chainid` from pure to view in 0.8.0. - function _viewChainId() private view returns (uint256 chainId) { - // Assembly required since `block.chainid` was introduced in 0.8.0. - assembly { - chainId := chainid() - } - - address(this); // Silence warnings in older Solc versions. - } - - function _pureChainId() private pure returns (uint256 chainId) { - function() internal view returns (uint256) fnIn = _viewChainId; - function() internal pure returns (uint256) pureChainId; - assembly { - pureChainId := fnIn - } - chainId = pureChainId(); - } -} - -// Wrappers around cheatcodes to avoid footguns -abstract contract StdCheats is StdCheatsSafe { - using stdStorage for StdStorage; - - StdStorage private stdstore; - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - // Skip forward or rewind time by the specified number of seconds - function skip(uint256 time) internal virtual { - vm.warp(block.timestamp + time); - } - - function rewind(uint256 time) internal virtual { - vm.warp(block.timestamp - time); - } - - // Setup a prank from an address that has some ether - function hoax(address msgSender) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.prank(msgSender); - } - - function hoax(address msgSender, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.prank(msgSender); - } - - function hoax(address msgSender, address origin) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.prank(msgSender, origin); - } - - function hoax(address msgSender, address origin, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.prank(msgSender, origin); - } - - // Start perpetual prank from an address that has some ether - function startHoax(address msgSender) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.startPrank(msgSender); - } - - function startHoax(address msgSender, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.startPrank(msgSender); - } - - // Start perpetual prank from an address that has some ether - // tx.origin is set to the origin parameter - function startHoax(address msgSender, address origin) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.startPrank(msgSender, origin); - } - - function startHoax(address msgSender, address origin, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.startPrank(msgSender, origin); - } - - function changePrank(address msgSender) internal virtual { - vm.stopPrank(); - vm.startPrank(msgSender); - } - - function changePrank(address msgSender, address txOrigin) internal virtual { - vm.stopPrank(); - vm.startPrank(msgSender, txOrigin); - } - - // The same as Vm's `deal` - // Use the alternative signature for ERC20 tokens - function deal(address to, uint256 give) internal virtual { - vm.deal(to, give); - } - - // Set the balance of an account for any ERC20 token - // Use the alternative signature to update `totalSupply` - function deal(address token, address to, uint256 give) internal virtual { - deal(token, to, give, false); - } - - // Set the balance of an account for any ERC1155 token - // Use the alternative signature to update `totalSupply` - function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { - dealERC1155(token, to, id, give, false); - } - - function deal(address token, address to, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0x18160ddd)); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0x18160ddd).checked_write(totSup); - } - } - - function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x00fdd58e, to, id)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0xbd85b039, id)); - require( - totSupData.length != 0, - "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." - ); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); - } - } - - function dealERC721(address token, address to, uint256 id) internal virtual { - // check if token id is already minted and the actual owner. - (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); - require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); - - // get owner current balance - (, bytes memory fromBalData) = - token.staticcall(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); - uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); - - // get new user current balance - (, bytes memory toBalData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); - uint256 toPrevBal = abi.decode(toBalData, (uint256)); - - // update balances - stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); - - // update owner - stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); - } - - function deployCodeTo(string memory what, address where) internal virtual { - deployCodeTo(what, "", 0, where); - } - - function deployCodeTo(string memory what, bytes memory args, address where) internal virtual { - deployCodeTo(what, args, 0, where); - } - - function deployCodeTo(string memory what, bytes memory args, uint256 value, address where) internal virtual { - bytes memory creationCode = vm.getCode(what); - vm.etch(where, abi.encodePacked(creationCode, args)); - (bool success, bytes memory runtimeBytecode) = where.call{value: value}(""); - require(success, "StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); - vm.etch(where, runtimeBytecode); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdError.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdError.sol deleted file mode 100644 index a302191..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdError.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test -pragma solidity >=0.6.2 <0.9.0; - -library stdError { - bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); - bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); - bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); - bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); - bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); - bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); - bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); - bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); - bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdInvariant.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdInvariant.sol deleted file mode 100644 index fd9d0a1..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdInvariant.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -abstract contract StdInvariant { - struct FuzzSelector { - address addr; - bytes4[] selectors; - } - - address[] private _excludedContracts; - address[] private _excludedSenders; - address[] private _targetedContracts; - address[] private _targetedSenders; - - string[] private _excludedArtifacts; - string[] private _targetedArtifacts; - - FuzzSelector[] private _targetedArtifactSelectors; - FuzzSelector[] private _targetedSelectors; - - // Functions for users: - // These are intended to be called in tests. - - function excludeContract(address newExcludedContract_) internal { - _excludedContracts.push(newExcludedContract_); - } - - function excludeSender(address newExcludedSender_) internal { - _excludedSenders.push(newExcludedSender_); - } - - function excludeArtifact(string memory newExcludedArtifact_) internal { - _excludedArtifacts.push(newExcludedArtifact_); - } - - function targetArtifact(string memory newTargetedArtifact_) internal { - _targetedArtifacts.push(newTargetedArtifact_); - } - - function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal { - _targetedArtifactSelectors.push(newTargetedArtifactSelector_); - } - - function targetContract(address newTargetedContract_) internal { - _targetedContracts.push(newTargetedContract_); - } - - function targetSelector(FuzzSelector memory newTargetedSelector_) internal { - _targetedSelectors.push(newTargetedSelector_); - } - - function targetSender(address newTargetedSender_) internal { - _targetedSenders.push(newTargetedSender_); - } - - // Functions for forge: - // These are called by forge to run invariant tests and don't need to be called in tests. - - function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { - excludedArtifacts_ = _excludedArtifacts; - } - - function excludeContracts() public view returns (address[] memory excludedContracts_) { - excludedContracts_ = _excludedContracts; - } - - function excludeSenders() public view returns (address[] memory excludedSenders_) { - excludedSenders_ = _excludedSenders; - } - - function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { - targetedArtifacts_ = _targetedArtifacts; - } - - function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) { - targetedArtifactSelectors_ = _targetedArtifactSelectors; - } - - function targetContracts() public view returns (address[] memory targetedContracts_) { - targetedContracts_ = _targetedContracts; - } - - function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { - targetedSelectors_ = _targetedSelectors; - } - - function targetSenders() public view returns (address[] memory targetedSenders_) { - targetedSenders_ = _targetedSenders; - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdJson.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdJson.sol deleted file mode 100644 index 014e6b1..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdJson.sol +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.0 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {VmSafe} from "./Vm.sol"; - -// Helpers for parsing and writing JSON files -// To parse: -// ``` -// using stdJson for string; -// string memory json = vm.readFile("some_peth"); -// json.parseUint(""); -// ``` -// To write: -// ``` -// using stdJson for string; -// string memory json = "deploymentArtifact"; -// Contract contract = new Contract(); -// json.serialize("contractAddress", address(contract)); -// json = json.serialize("deploymentTimes", uint(1)); -// // store the stringified JSON to the 'json' variable we have been using as a key -// // as we won't need it any longer -// string memory json2 = "finalArtifact"; -// string memory final = json2.serialize("depArtifact", json); -// final.write(""); -// ``` - -library stdJson { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { - return vm.parseJson(json, key); - } - - function readUint(string memory json, string memory key) internal returns (uint256) { - return vm.parseJsonUint(json, key); - } - - function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) { - return vm.parseJsonUintArray(json, key); - } - - function readInt(string memory json, string memory key) internal returns (int256) { - return vm.parseJsonInt(json, key); - } - - function readIntArray(string memory json, string memory key) internal returns (int256[] memory) { - return vm.parseJsonIntArray(json, key); - } - - function readBytes32(string memory json, string memory key) internal returns (bytes32) { - return vm.parseJsonBytes32(json, key); - } - - function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) { - return vm.parseJsonBytes32Array(json, key); - } - - function readString(string memory json, string memory key) internal returns (string memory) { - return vm.parseJsonString(json, key); - } - - function readStringArray(string memory json, string memory key) internal returns (string[] memory) { - return vm.parseJsonStringArray(json, key); - } - - function readAddress(string memory json, string memory key) internal returns (address) { - return vm.parseJsonAddress(json, key); - } - - function readAddressArray(string memory json, string memory key) internal returns (address[] memory) { - return vm.parseJsonAddressArray(json, key); - } - - function readBool(string memory json, string memory key) internal returns (bool) { - return vm.parseJsonBool(json, key); - } - - function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) { - return vm.parseJsonBoolArray(json, key); - } - - function readBytes(string memory json, string memory key) internal returns (bytes memory) { - return vm.parseJsonBytes(json, key); - } - - function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) { - return vm.parseJsonBytesArray(json, key); - } - - function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bool[] memory value) - internal - returns (string memory) - { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256[] memory value) - internal - returns (string memory) - { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256[] memory value) - internal - returns (string memory) - { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address[] memory value) - internal - returns (string memory) - { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string[] memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function write(string memory jsonKey, string memory path) internal { - vm.writeJson(jsonKey, path); - } - - function write(string memory jsonKey, string memory path, string memory valueKey) internal { - vm.writeJson(jsonKey, path, valueKey); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdMath.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdMath.sol deleted file mode 100644 index 459523b..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdMath.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -library stdMath { - int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; - - function abs(int256 a) internal pure returns (uint256) { - // Required or it will fail when `a = type(int256).min` - if (a == INT256_MIN) { - return 57896044618658097711785492504343953926634992332820282019728792003956564819968; - } - - return uint256(a > 0 ? a : -a); - } - - function delta(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? a - b : b - a; - } - - function delta(int256 a, int256 b) internal pure returns (uint256) { - // a and b are of the same sign - // this works thanks to two's complement, the left-most bit is the sign bit - if ((a ^ b) > -1) { - return delta(abs(a), abs(b)); - } - - // a and b are of opposite signs - return abs(a) + abs(b); - } - - function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - - return absDelta * 1e18 / b; - } - - function percentDelta(int256 a, int256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - uint256 absB = abs(b); - - return absDelta * 1e18 / absB; - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdStorage.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdStorage.sol deleted file mode 100644 index 708db32..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdStorage.sol +++ /dev/null @@ -1,331 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {Vm} from "./Vm.sol"; - -struct StdStorage { - mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; - mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds; - bytes32[] _keys; - bytes4 _sig; - uint256 _depth; - address _target; - bytes32 _set; -} - -library stdStorageSafe { - event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); - event WARNING_UninitedSlot(address who, uint256 slot); - - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return bytes4(keccak256(bytes(sigStr))); - } - - /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against - // slot complexity: - // if flat, will be bytes32(uint256(uint)); - // if map, will be keccak256(abi.encode(key, uint(slot))); - // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); - // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); - function find(StdStorage storage self) internal returns (uint256) { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - // calldata to test against - if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - vm.record(); - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - (bytes32[] memory reads,) = vm.accesses(address(who)); - if (reads.length == 1) { - bytes32 curr = vm.load(who, reads[0]); - if (curr == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[0])); - } - if (fdat != curr) { - require( - false, - "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." - ); - } - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - } else if (reads.length > 1) { - for (uint256 i = 0; i < reads.length; i++) { - bytes32 prev = vm.load(who, reads[i]); - if (prev == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[i])); - } - // store - vm.store(who, reads[i], bytes32(hex"1337")); - bool success; - bytes memory rdat; - { - (success, rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - if (success && fdat == bytes32(hex"1337")) { - // we found which of the slots is the actual one - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - vm.store(who, reads[i], prev); - break; - } - vm.store(who, reads[i], prev); - } - } else { - revert("stdStorage find(StdStorage): No storage use detected for target."); - } - - require( - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], - "stdStorage find(StdStorage): Slot(s) not found." - ); - - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - self._target = _target; - return self; - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - self._sig = _sig; - return self; - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - self._sig = sigs(_sig); - return self; - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - self._keys.push(bytes32(uint256(uint160(who)))); - return self; - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - self._keys.push(bytes32(amt)); - return self; - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - self._keys.push(key); - return self; - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - self._depth = _depth; - return self; - } - - function read(StdStorage storage self) private returns (bytes memory) { - address t = self._target; - uint256 s = find(self); - return abi.encode(vm.load(t, bytes32(s))); - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return abi.decode(read(self), (bytes32)); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - int256 v = read_int(self); - if (v == 0) return false; - if (v == 1) return true; - revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - } - - function read_address(StdStorage storage self) internal returns (address) { - return abi.decode(read(self), (address)); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return abi.decode(read(self), (uint256)); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return abi.decode(read(self), (int256)); - } - - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} - -library stdStorage { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return stdStorageSafe.sigs(sigStr); - } - - function find(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.find(self); - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - return stdStorageSafe.target(self, _target); - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, who); - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, amt); - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, key); - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - return stdStorageSafe.depth(self, _depth); - } - - function checked_write(StdStorage storage self, address who) internal { - checked_write(self, bytes32(uint256(uint160(who)))); - } - - function checked_write(StdStorage storage self, uint256 amt) internal { - checked_write(self, bytes32(amt)); - } - - function checked_write_int(StdStorage storage self, int256 val) internal { - checked_write(self, bytes32(uint256(val))); - } - - function checked_write(StdStorage storage self, bool write) internal { - bytes32 t; - /// @solidity memory-safe-assembly - assembly { - t := write - } - checked_write(self, t); - } - - function checked_write(StdStorage storage self, bytes32 set) internal { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - find(self); - } - bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]); - - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - bytes32 curr = vm.load(who, slot); - - if (fdat != curr) { - require( - false, - "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." - ); - } - vm.store(who, slot, set); - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return stdStorageSafe.read_bytes32(self); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - return stdStorageSafe.read_bool(self); - } - - function read_address(StdStorage storage self) internal returns (address) { - return stdStorageSafe.read_address(self); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.read_uint(self); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return stdStorageSafe.read_int(self); - } - - // Private function so needs to be copied over - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - // Private function so needs to be copied over - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdStyle.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdStyle.sol deleted file mode 100644 index d371e0c..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdStyle.sol +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -import {VmSafe} from "./Vm.sol"; - -library StdStyle { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - string constant RED = "\u001b[91m"; - string constant GREEN = "\u001b[92m"; - string constant YELLOW = "\u001b[93m"; - string constant BLUE = "\u001b[94m"; - string constant MAGENTA = "\u001b[95m"; - string constant CYAN = "\u001b[96m"; - string constant BOLD = "\u001b[1m"; - string constant DIM = "\u001b[2m"; - string constant ITALIC = "\u001b[3m"; - string constant UNDERLINE = "\u001b[4m"; - string constant INVERSE = "\u001b[7m"; - string constant RESET = "\u001b[0m"; - - function styleConcat(string memory style, string memory self) private pure returns (string memory) { - return string(abi.encodePacked(style, self, RESET)); - } - - function red(string memory self) internal pure returns (string memory) { - return styleConcat(RED, self); - } - - function red(uint256 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(int256 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(address self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(bool self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function redBytes(bytes memory self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function redBytes32(bytes32 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function green(string memory self) internal pure returns (string memory) { - return styleConcat(GREEN, self); - } - - function green(uint256 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(int256 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(address self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(bool self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function greenBytes(bytes memory self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function greenBytes32(bytes32 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function yellow(string memory self) internal pure returns (string memory) { - return styleConcat(YELLOW, self); - } - - function yellow(uint256 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(int256 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(address self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(bool self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellowBytes(bytes memory self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellowBytes32(bytes32 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function blue(string memory self) internal pure returns (string memory) { - return styleConcat(BLUE, self); - } - - function blue(uint256 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(int256 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(address self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(bool self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blueBytes(bytes memory self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blueBytes32(bytes32 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function magenta(string memory self) internal pure returns (string memory) { - return styleConcat(MAGENTA, self); - } - - function magenta(uint256 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(int256 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(address self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(bool self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magentaBytes(bytes memory self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magentaBytes32(bytes32 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function cyan(string memory self) internal pure returns (string memory) { - return styleConcat(CYAN, self); - } - - function cyan(uint256 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(int256 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(address self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(bool self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyanBytes(bytes memory self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyanBytes32(bytes32 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function bold(string memory self) internal pure returns (string memory) { - return styleConcat(BOLD, self); - } - - function bold(uint256 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(int256 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(address self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(bool self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function boldBytes(bytes memory self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function boldBytes32(bytes32 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function dim(string memory self) internal pure returns (string memory) { - return styleConcat(DIM, self); - } - - function dim(uint256 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(int256 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(address self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(bool self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dimBytes(bytes memory self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dimBytes32(bytes32 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function italic(string memory self) internal pure returns (string memory) { - return styleConcat(ITALIC, self); - } - - function italic(uint256 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(int256 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(address self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(bool self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italicBytes(bytes memory self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italicBytes32(bytes32 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function underline(string memory self) internal pure returns (string memory) { - return styleConcat(UNDERLINE, self); - } - - function underline(uint256 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(int256 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(address self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(bool self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underlineBytes(bytes memory self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underlineBytes32(bytes32 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function inverse(string memory self) internal pure returns (string memory) { - return styleConcat(INVERSE, self); - } - - function inverse(uint256 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(int256 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(address self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(bool self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverseBytes(bytes memory self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverseBytes32(bytes32 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/StdUtils.sol b/lib/morpho-blue-irm/lib/forge-std/src/StdUtils.sol deleted file mode 100644 index ad9566e..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/StdUtils.sol +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {IMulticall3} from "./interfaces/IMulticall3.sol"; -import {VmSafe} from "./Vm.sol"; - -abstract contract StdUtils { - /*////////////////////////////////////////////////////////////////////////// - CONSTANTS - //////////////////////////////////////////////////////////////////////////*/ - - IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; - uint256 private constant INT256_MIN_ABS = - 57896044618658097711785492504343953926634992332820282019728792003956564819968; - uint256 private constant SECP256K1_ORDER = - 115792089237316195423570985008687907852837564279074904382605163141518161494337; - uint256 private constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. - address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - - /*////////////////////////////////////////////////////////////////////////// - INTERNAL FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { - require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); - // If x is between min and max, return x directly. This is to ensure that dictionary values - // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 - if (x >= min && x <= max) return x; - - uint256 size = max - min + 1; - - // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. - // This helps ensure coverage of the min/max values. - if (x <= 3 && size > x) return min + x; - if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); - - // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. - if (x > max) { - uint256 diff = x - max; - uint256 rem = diff % size; - if (rem == 0) return max; - result = min + rem - 1; - } else if (x < min) { - uint256 diff = min - x; - uint256 rem = diff % size; - if (rem == 0) return min; - result = max - rem + 1; - } - } - - function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) { - result = _bound(x, min, max); - console2_log("Bound Result", result); - } - - function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { - require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); - - // Shifting all int256 values to uint256 to use _bound function. The range of two types are: - // int256 : -(2**255) ~ (2**255 - 1) - // uint256: 0 ~ (2**256 - 1) - // So, add 2**255, INT256_MIN_ABS to the integer values. - // - // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. - // So, use `~uint256(x) + 1` instead. - uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); - uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); - uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); - - uint256 y = _bound(_x, _min, _max); - - // To move it back to int256 value, subtract INT256_MIN_ABS at here. - result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); - } - - function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) { - result = _bound(x, min, max); - console2_log("Bound result", vm.toString(result)); - } - - function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) { - result = _bound(privateKey, 1, SECP256K1_ORDER - 1); - } - - function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { - require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); - return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); - } - - /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce - /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol) - function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { - // forgefmt: disable-start - // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0. - // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it. - if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))); - if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))); - - // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length. - if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))); - if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))); - if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)))); - // forgefmt: disable-end - - // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp - // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) - // We assume nobody can have a nonce large enough to require more than 32 bytes. - return addressFromLast20Bytes( - keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) - ); - } - - function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) - internal - pure - virtual - returns (address) - { - return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash))); - } - - /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { - return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY); - } - - /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments - /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode - function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { - return hashInitCode(creationCode, ""); - } - - /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 - /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode - /// @param args the ABI-encoded arguments to the constructor of C - function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(creationCode, args)); - } - - // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. - function getTokenBalances(address token, address[] memory addresses) - internal - virtual - returns (uint256[] memory balances) - { - uint256 tokenCodeSize; - assembly { - tokenCodeSize := extcodesize(token) - } - require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); - - // ABI encode the aggregate call to Multicall3. - uint256 length = addresses.length; - IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); - for (uint256 i = 0; i < length; ++i) { - // 0x70a08231 = bytes4("balanceOf(address)")) - calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); - } - - // Make the aggregate call. - (, bytes[] memory returnData) = multicall.aggregate(calls); - - // ABI decode the return data and return the balances. - balances = new uint256[](length); - for (uint256 i = 0; i < length; ++i) { - balances[i] = abi.decode(returnData[i], (uint256)); - } - } - - /*////////////////////////////////////////////////////////////////////////// - PRIVATE FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { - return address(uint160(uint256(bytesValue))); - } - - // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. - - function console2_log(string memory p0, uint256 p1) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - status; - } - - function console2_log(string memory p0, string memory p1) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,string)", p0, p1)); - status; - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/Test.sol b/lib/morpho-blue-irm/lib/forge-std/src/Test.sol deleted file mode 100644 index 40c0064..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/Test.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -// 💬 ABOUT -// Forge Std's default Test. - -// 🧩 MODULES -import {console} from "./console.sol"; -import {console2} from "./console2.sol"; -import {safeconsole} from "./safeconsole.sol"; -import {StdAssertions} from "./StdAssertions.sol"; -import {StdChains} from "./StdChains.sol"; -import {StdCheats} from "./StdCheats.sol"; -import {stdError} from "./StdError.sol"; -import {StdInvariant} from "./StdInvariant.sol"; -import {stdJson} from "./StdJson.sol"; -import {stdMath} from "./StdMath.sol"; -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {StdStyle} from "./StdStyle.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {Vm} from "./Vm.sol"; - -// 📦 BOILERPLATE -import {TestBase} from "./Base.sol"; -import {DSTest} from "ds-test/test.sol"; - -// ⭐️ TEST -// Note: DSTest and any contracts that inherit it must be inherited first, https://github.com/foundry-rs/forge-std/pull/241 -abstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase { -// Note: IS_TEST() must return true. -// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76. -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/Vm.sol b/lib/morpho-blue-irm/lib/forge-std/src/Vm.sol deleted file mode 100644 index a31db14..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/Vm.sol +++ /dev/null @@ -1,514 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -// Cheatcodes are marked as view/pure/none using the following rules: -// 0. A call's observable behaviour includes its return value, logs, reverts and state writes, -// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc), -// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`, -// 3. Otherwise you're `pure`. - -interface VmSafe { - enum CallerMode { - None, - Broadcast, - RecurrentBroadcast, - Prank, - RecurrentPrank - } - - struct Log { - bytes32[] topics; - bytes data; - address emitter; - } - - struct Rpc { - string key; - string url; - } - - struct DirEntry { - string errorMessage; - string path; - uint64 depth; - bool isDir; - bool isSymlink; - } - - struct FsMetadata { - bool isDir; - bool isSymlink; - uint256 length; - bool readOnly; - uint256 modified; - uint256 accessed; - uint256 created; - } - - // Loads a storage slot from an address - function load(address target, bytes32 slot) external view returns (bytes32 data); - // Signs data - function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - // Gets the address for a given private key - function addr(uint256 privateKey) external pure returns (address keyAddr); - // Gets the nonce of an account - function getNonce(address account) external view returns (uint64 nonce); - // Performs a foreign function call via the terminal - function ffi(string[] calldata commandInput) external returns (bytes memory result); - // Sets environment variables - function setEnv(string calldata name, string calldata value) external; - // Reads environment variables, (name) => (value) - function envBool(string calldata name) external view returns (bool value); - function envUint(string calldata name) external view returns (uint256 value); - function envInt(string calldata name) external view returns (int256 value); - function envAddress(string calldata name) external view returns (address value); - function envBytes32(string calldata name) external view returns (bytes32 value); - function envString(string calldata name) external view returns (string memory value); - function envBytes(string calldata name) external view returns (bytes memory value); - // Reads environment variables as arrays - function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); - function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); - function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); - function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); - function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); - function envString(string calldata name, string calldata delim) external view returns (string[] memory value); - function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); - // Read environment variables with default value - function envOr(string calldata name, bool defaultValue) external returns (bool value); - function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value); - function envOr(string calldata name, int256 defaultValue) external returns (int256 value); - function envOr(string calldata name, address defaultValue) external returns (address value); - function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value); - function envOr(string calldata name, string calldata defaultValue) external returns (string memory value); - function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value); - // Read environment variables as arrays with default value - function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) - external - returns (bool[] memory value); - function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) - external - returns (uint256[] memory value); - function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) - external - returns (int256[] memory value); - function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) - external - returns (address[] memory value); - function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) - external - returns (bytes32[] memory value); - function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) - external - returns (string[] memory value); - function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) - external - returns (bytes[] memory value); - // Records all storage reads and writes - function record() external; - // Gets all accessed reads and write slot from a recording session, for a given address - function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); - // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file - function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); - // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file - function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); - // Labels an address in call traces - function label(address account, string calldata newLabel) external; - // Gets the label for the specified address - function getLabel(address account) external returns (string memory currentLabel); - // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain - function broadcast() external; - // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain - function broadcast(address signer) external; - // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain - function broadcast(uint256 privateKey) external; - // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain - function startBroadcast() external; - // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain - function startBroadcast(address signer) external; - // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain - function startBroadcast(uint256 privateKey) external; - // Stops collecting onchain transactions - function stopBroadcast() external; - - // Get the path of the current project root. - function projectRoot() external view returns (string memory path); - // Reads the entire content of file to string. `path` is relative to the project root. - function readFile(string calldata path) external view returns (string memory data); - // Reads the entire content of file as binary. `path` is relative to the project root. - function readFileBinary(string calldata path) external view returns (bytes memory data); - // Reads next line of file to string. - function readLine(string calldata path) external view returns (string memory line); - // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. - // `path` is relative to the project root. - function writeFile(string calldata path, string calldata data) external; - // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. - // `path` is relative to the project root. - function writeFileBinary(string calldata path, bytes calldata data) external; - // Writes line to file, creating a file if it does not exist. - // `path` is relative to the project root. - function writeLine(string calldata path, string calldata data) external; - // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. - // `path` is relative to the project root. - function closeFile(string calldata path) external; - // Removes a file from the filesystem. - // This cheatcode will revert in the following situations, but is not limited to just these cases: - // - `path` points to a directory. - // - The file doesn't exist. - // - The user lacks permissions to remove the file. - // `path` is relative to the project root. - function removeFile(string calldata path) external; - // Creates a new, empty directory at the provided path. - // This cheatcode will revert in the following situations, but is not limited to just these cases: - // - User lacks permissions to modify `path`. - // - A parent of the given path doesn't exist and `recursive` is false. - // - `path` already exists and `recursive` is false. - // `path` is relative to the project root. - function createDir(string calldata path, bool recursive) external; - // Removes a directory at the provided path. - // This cheatcode will revert in the following situations, but is not limited to just these cases: - // - `path` doesn't exist. - // - `path` isn't a directory. - // - User lacks permissions to modify `path`. - // - The directory is not empty and `recursive` is false. - // `path` is relative to the project root. - function removeDir(string calldata path, bool recursive) external; - // Reads the directory at the given path recursively, up to `max_depth`. - // `max_depth` defaults to 1, meaning only the direct children of the given directory will be returned. - // Follows symbolic links if `follow_links` is true. - function readDir(string calldata path) external view returns (DirEntry[] memory entries); - function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); - function readDir(string calldata path, uint64 maxDepth, bool followLinks) - external - view - returns (DirEntry[] memory entries); - // Reads a symbolic link, returning the path that the link points to. - // This cheatcode will revert in the following situations, but is not limited to just these cases: - // - `path` is not a symbolic link. - // - `path` does not exist. - function readLink(string calldata linkPath) external view returns (string memory targetPath); - // Given a path, query the file system to get information about a file, directory, etc. - function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); - - // Convert values to a string - function toString(address value) external pure returns (string memory stringifiedValue); - function toString(bytes calldata value) external pure returns (string memory stringifiedValue); - function toString(bytes32 value) external pure returns (string memory stringifiedValue); - function toString(bool value) external pure returns (string memory stringifiedValue); - function toString(uint256 value) external pure returns (string memory stringifiedValue); - function toString(int256 value) external pure returns (string memory stringifiedValue); - // Convert values from a string - function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); - function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); - function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); - function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); - function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); - function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); - // Record all the transaction logs - function recordLogs() external; - // Gets all the recorded logs - function getRecordedLogs() external returns (Log[] memory logs); - // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index} - function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); - // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index} - function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) - external - pure - returns (uint256 privateKey); - // Adds a private key to the local forge wallet and returns the address - function rememberKey(uint256 privateKey) external returns (address keyAddr); - // - // parseJson - // - // ---- - // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects - // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in - // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that - // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded - // as tuples, with the attributes in the order in which they are defined. - // For example: json = { 'a': 1, 'b': 0xa4tb......3xs} - // a: uint256 - // b: address - // To decode that json, we need to define a struct or a tuple as follows: - // struct json = { uint256 a; address b; } - // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to - // decode the tuple in that order, and thus fail. - // ---- - // Given a string of JSON, return it as ABI-encoded - function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); - function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); - - // The following parseJson cheatcodes will do type coercion, for the type that they indicate. - // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12' - // and hex numbers '0xEF'. - // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not - // a JSON object. - function parseJsonUint(string calldata, string calldata) external returns (uint256); - function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory); - function parseJsonInt(string calldata, string calldata) external returns (int256); - function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory); - function parseJsonBool(string calldata, string calldata) external returns (bool); - function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory); - function parseJsonAddress(string calldata, string calldata) external returns (address); - function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory); - function parseJsonString(string calldata, string calldata) external returns (string memory); - function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory); - function parseJsonBytes(string calldata, string calldata) external returns (bytes memory); - function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory); - function parseJsonBytes32(string calldata, string calldata) external returns (bytes32); - function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory); - - // Serialize a key and value to a JSON object stored in-memory that can be later written to a file - // It returns the stringified version of the specific JSON file up to that moment. - function serializeBool(string calldata objectKey, string calldata valueKey, bool value) - external - returns (string memory json); - function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) - external - returns (string memory json); - function serializeAddress(string calldata objectKey, string calldata valueKey, address value) - external - returns (string memory json); - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) - external - returns (string memory json); - function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) - external - returns (string memory json); - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) - external - returns (string memory json); - - function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) - external - returns (string memory json); - function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) - external - returns (string memory json); - function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) - external - returns (string memory json); - function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) - external - returns (string memory json); - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) - external - returns (string memory json); - function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) - external - returns (string memory json); - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) - external - returns (string memory json); - - // - // writeJson - // - // ---- - // Write a serialized JSON object to a file. If the file exists, it will be overwritten. - // Let's assume we want to write the following JSON to a file: - // - // { "boolean": true, "number": 342, "object": { "title": "finally json serialization" } } - // - // ``` - // string memory json1 = "some key"; - // vm.serializeBool(json1, "boolean", true); - // vm.serializeBool(json1, "number", uint256(342)); - // json2 = "some other key"; - // string memory output = vm.serializeString(json2, "title", "finally json serialization"); - // string memory finalJson = vm.serialize(json1, "object", output); - // vm.writeJson(finalJson, "./output/example.json"); - // ``` - // The critical insight is that every invocation of serialization will return the stringified version of the JSON - // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version - // to serialize them as values to another JSON object. - // - // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..) - // will find the object in-memory that is keyed by "some key". - function writeJson(string calldata json, string calldata path) external; - // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = - // This is useful to replace a specific value of a JSON file, without having to parse the entire thing - function writeJson(string calldata json, string calldata path, string calldata valueKey) external; - // Returns the RPC url for the given alias - function rpcUrl(string calldata rpcAlias) external view returns (string memory json); - // Returns all rpc urls and their aliases `[alias, url][]` - function rpcUrls() external view returns (string[2][] memory urls); - // Returns all rpc urls and their aliases as structs. - function rpcUrlStructs() external view returns (Rpc[] memory urls); - // If the condition is false, discard this run's fuzz inputs and generate new ones. - function assume(bool condition) external pure; - // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. - function pauseGasMetering() external; - // Resumes gas metering (i.e. gas usage is counted again). Noop if already on. - function resumeGasMetering() external; - // Writes a breakpoint to jump to in the debugger - function breakpoint(string calldata char) external; - // Writes a conditional breakpoint to jump to in the debugger - function breakpoint(string calldata char, bool value) external; -} - -interface Vm is VmSafe { - // Sets block.timestamp - function warp(uint256 newTimestamp) external; - // Sets block.height - function roll(uint256 newHeight) external; - // Sets block.basefee - function fee(uint256 newBasefee) external; - // Sets block.difficulty - // Not available on EVM versions from Paris onwards. Use `prevrandao` instead. - // If used on unsupported EVM versions it will revert. - function difficulty(uint256 newDifficulty) external; - // Sets block.prevrandao - // Not available on EVM versions before Paris. Use `difficulty` instead. - // If used on unsupported EVM versions it will revert. - function prevrandao(bytes32 newPrevrandao) external; - // Sets block.chainid - function chainId(uint256 newChainId) external; - // Sets tx.gasprice - function txGasPrice(uint256 newGasPrice) external; - // Stores a value to an address' storage slot. - function store(address target, bytes32 slot, bytes32 value) external; - // Sets the nonce of an account; must be higher than the current nonce of the account - function setNonce(address account, uint64 newNonce) external; - // Sets the nonce of an account to an arbitrary value - function setNonceUnsafe(address account, uint64 newNonce) external; - // Resets the nonce of an account to 0 for EOAs and 1 for contract accounts - function resetNonce(address account) external; - // Sets the *next* call's msg.sender to be the input address - function prank(address msgSender) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called - function startPrank(address msgSender) external; - // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input - function prank(address msgSender, address txOrigin) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input - function startPrank(address msgSender, address txOrigin) external; - // Resets subsequent calls' msg.sender to be `address(this)` - function stopPrank() external; - // Reads the current `msg.sender` and `tx.origin` from state and reports if there is any active caller modification - function readCallers() external returns (CallerMode callerMode, address msgSender, address txOrigin); - // Sets an address' balance - function deal(address account, uint256 newBalance) external; - // Sets an address' code - function etch(address target, bytes calldata newRuntimeBytecode) external; - // Marks a test as skipped. Must be called at the top of the test. - function skip(bool skipTest) external; - // Expects an error on next call - function expectRevert(bytes calldata revertData) external; - function expectRevert(bytes4 revertData) external; - function expectRevert() external; - - // Prepare an expected log with all four checks enabled. - // Call this function, then emit an event, then call a function. Internally after the call, we check if - // logs were emitted in the expected order with the expected topics and data. - // Second form also checks supplied address against emitting contract. - function expectEmit() external; - function expectEmit(address emitter) external; - - // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). - // Call this function, then emit an event, then call a function. Internally after the call, we check if - // logs were emitted in the expected order with the expected topics and data (as specified by the booleans). - // Second form also checks supplied address against emitting contract. - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) - external; - - // Mocks a call to an address, returning specified data. - // Calldata can either be strict or a partial match, e.g. if you only - // pass a Solidity selector to the expected calldata, then the entire Solidity - // function will be mocked. - function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; - // Mocks a call to an address with a specific msg.value, returning specified data. - // Calldata match takes precedence over msg.value in case of ambiguity. - function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; - // Reverts a call to an address with specified revert data. - function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; - // Reverts a call to an address with a specific msg.value, with specified revert data. - function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) - external; - // Clears all mocked calls - function clearMockedCalls() external; - // Expects a call to an address with the specified calldata. - // Calldata can either be a strict or a partial match - function expectCall(address callee, bytes calldata data) external; - // Expects given number of calls to an address with the specified calldata. - function expectCall(address callee, bytes calldata data, uint64 count) external; - // Expects a call to an address with the specified msg.value and calldata - function expectCall(address callee, uint256 msgValue, bytes calldata data) external; - // Expects given number of calls to an address with the specified msg.value and calldata - function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; - // Expect a call to an address with the specified msg.value, gas, and calldata. - function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; - // Expects given number of calls to an address with the specified msg.value, gas, and calldata. - function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; - // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas. - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; - // Expect given number of calls to an address with the specified msg.value and calldata, and a *minimum* amount of gas. - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) - external; - // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other - // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. - function expectSafeMemory(uint64 min, uint64 max) external; - // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. - // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges - // to the set. - function expectSafeMemoryCall(uint64 min, uint64 max) external; - // Sets block.coinbase - function coinbase(address newCoinbase) external; - // Snapshot the current state of the evm. - // Returns the id of the snapshot that was created. - // To revert a snapshot use `revertTo` - function snapshot() external returns (uint256 snapshotId); - // Revert the state of the EVM to a previous snapshot - // Takes the snapshot id to revert to. - // This deletes the snapshot and all snapshots taken after the given snapshot id. - function revertTo(uint256 snapshotId) external returns (bool success); - // Creates a new fork with the given endpoint and block and returns the identifier of the fork - function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); - // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork - function createFork(string calldata urlOrAlias) external returns (uint256 forkId); - // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction, - // and returns the identifier of the fork - function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); - // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); - // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before - // the transaction, returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); - // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); - // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. - function selectFork(uint256 forkId) external; - /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. - function activeFork() external view returns (uint256 forkId); - // Updates the currently active fork to given block number - // This is similar to `roll` but for the currently active fork - function rollFork(uint256 blockNumber) external; - // Updates the currently active fork to given transaction - // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block - function rollFork(bytes32 txHash) external; - // Updates the given fork to given block number - function rollFork(uint256 forkId, uint256 blockNumber) external; - // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block - function rollFork(uint256 forkId, bytes32 txHash) external; - // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup - // Meaning, changes made to the state of this account will be kept when switching forks - function makePersistent(address account) external; - function makePersistent(address account0, address account1) external; - function makePersistent(address account0, address account1, address account2) external; - function makePersistent(address[] calldata accounts) external; - // Revokes persistent status from the address, previously added via `makePersistent` - function revokePersistent(address account) external; - function revokePersistent(address[] calldata accounts) external; - // Returns true if the account is marked as persistent - function isPersistent(address account) external view returns (bool persistent); - // In forking mode, explicitly grant the given address cheatcode access - function allowCheatcodes(address account) external; - // Fetches the given transaction from the active fork and executes it on the current state - function transact(bytes32 txHash) external; - // Fetches the given transaction from the given fork and executes it on the current state - function transact(uint256 forkId, bytes32 txHash) external; -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/console.sol b/lib/morpho-blue-irm/lib/forge-std/src/console.sol deleted file mode 100644 index ad57e53..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/console.sol +++ /dev/null @@ -1,1533 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -library console { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _sendLogPayload(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal view { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); - } - - function logUint(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function logString(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function log(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); - } - - function log(uint p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); - } - - function log(uint p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); - } - - function log(uint p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); - } - - function log(string memory p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); - } - - function log(bool p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); - } - - function log(address p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); - } - - function log(uint p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); - } - - function log(uint p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); - } - - function log(uint p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); - } - - function log(uint p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); - } - - function log(uint p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); - } - - function log(uint p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); - } - - function log(uint p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); - } - - function log(uint p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); - } - - function log(uint p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); - } - - function log(uint p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); - } - - function log(uint p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); - } - - function log(bool p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); - } - - function log(bool p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); - } - - function log(bool p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); - } - - function log(address p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); - } - - function log(address p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); - } - - function log(address p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/forge-std/src/console2.sol b/lib/morpho-blue-irm/lib/forge-std/src/console2.sol deleted file mode 100644 index c1e2cd7..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/console2.sol +++ /dev/null @@ -1,1558 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should -/// use `int256` and `uint256`. This modified version fixes that. This version is recommended -/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in -/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`. -/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178 -library console2 { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _castLogPayloadViewToPure( - function(bytes memory) internal view fnIn - ) internal pure returns (function(bytes memory) internal pure fnOut) { - assembly { - fnOut := fnIn - } - } - - function _sendLogPayload(bytes memory payload) internal pure { - _castLogPayloadViewToPure(_sendLogPayloadView)(payload); - } - - function _sendLogPayloadView(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal pure { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function logUint(uint256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function logString(string memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function log(int256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function log(string memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint256 p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); - } - - function log(uint256 p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); - } - - function log(uint256 p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); - } - - function log(uint256 p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); - } - - function log(string memory p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - } - - function log(string memory p0, int256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); - } - - function log(bool p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); - } - - function log(address p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint256 p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC1155.sol b/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC1155.sol deleted file mode 100644 index f7dd2b4..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC1155.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC165.sol"; - -/// @title ERC-1155 Multi Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-1155 -/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. -interface IERC1155 is IERC165 { - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_id` argument MUST be the token type being transferred. - /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferSingle( - address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value - ); - - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_ids` argument MUST be the list of tokens being transferred. - /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferBatch( - address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values - ); - - /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. - /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". - event URI(string _value, uint256 indexed _id); - - /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. - /// - MUST revert on any other error. - /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). - /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _id ID of the token type - /// @param _value Transfer amount - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` - function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; - - /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if length of `_ids` is not the same as length of `_values`. - /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. - /// - MUST revert on any other error. - /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). - /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). - /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _ids IDs of each token type (order and length must match _values array) - /// @param _values Transfer amounts per token type (order and length must match _ids array) - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` - function safeBatchTransferFrom( - address _from, - address _to, - uint256[] calldata _ids, - uint256[] calldata _values, - bytes calldata _data - ) external; - - /// @notice Get the balance of an account's tokens. - /// @param _owner The address of the token holder - /// @param _id ID of the token - /// @return The _owner's balance of the token type requested - function balanceOf(address _owner, uint256 _id) external view returns (uint256); - - /// @notice Get the balance of multiple account/token pairs - /// @param _owners The addresses of the token holders - /// @param _ids ID of the tokens - /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) - function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) - external - view - returns (uint256[] memory); - - /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. - /// @dev MUST emit the ApprovalForAll event on success. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Queries the approval status of an operator for a given owner. - /// @param _owner The owner of the tokens - /// @param _operator Address of authorized operator - /// @return True if the operator is approved, false if not - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC165.sol b/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC165.sol deleted file mode 100644 index 9af4bf8..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC165.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -interface IERC165 { - /// @notice Query if a contract implements an interface - /// @param interfaceID The interface identifier, as specified in ERC-165 - /// @dev Interface identification is specified in ERC-165. This function - /// uses less than 30,000 gas. - /// @return `true` if the contract implements `interfaceID` and - /// `interfaceID` is not 0xffffffff, `false` otherwise - function supportsInterface(bytes4 interfaceID) external view returns (bool); -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC20.sol b/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC20.sol deleted file mode 100644 index ba40806..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC20.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -/// @dev Interface of the ERC20 standard as defined in the EIP. -/// @dev This includes the optional name, symbol, and decimals metadata. -interface IERC20 { - /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). - event Transfer(address indexed from, address indexed to, uint256 value); - - /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` - /// is the new allowance. - event Approval(address indexed owner, address indexed spender, uint256 value); - - /// @notice Returns the amount of tokens in existence. - function totalSupply() external view returns (uint256); - - /// @notice Returns the amount of tokens owned by `account`. - function balanceOf(address account) external view returns (uint256); - - /// @notice Moves `amount` tokens from the caller's account to `to`. - function transfer(address to, uint256 amount) external returns (bool); - - /// @notice Returns the remaining number of tokens that `spender` is allowed - /// to spend on behalf of `owner` - function allowance(address owner, address spender) external view returns (uint256); - - /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. - /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - function approve(address spender, uint256 amount) external returns (bool); - - /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. - /// `amount` is then deducted from the caller's allowance. - function transferFrom(address from, address to, uint256 amount) external returns (bool); - - /// @notice Returns the name of the token. - function name() external view returns (string memory); - - /// @notice Returns the symbol of the token. - function symbol() external view returns (string memory); - - /// @notice Returns the decimals places of the token. - function decimals() external view returns (uint8); -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC4626.sol b/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC4626.sol deleted file mode 100644 index bfe3a11..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC4626.sol +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC20.sol"; - -/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in -/// https://eips.ethereum.org/EIPS/eip-4626 -interface IERC4626 is IERC20 { - event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares - ); - - /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. - /// @dev - /// - MUST be an ERC-20 token contract. - /// - MUST NOT revert. - function asset() external view returns (address assetTokenAddress); - - /// @notice Returns the total amount of the underlying asset that is “managed” by Vault. - /// @dev - /// - SHOULD include any compounding that occurs from yield. - /// - MUST be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT revert. - function totalAssets() external view returns (uint256 totalManagedAssets); - - /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToShares(uint256 assets) external view returns (uint256 shares); - - /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToAssets(uint256 shares) external view returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, - /// through a deposit call. - /// @dev - /// - MUST return a limited value if receiver is subject to some deposit limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. - /// - MUST NOT revert. - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit - /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called - /// in the same transaction. - /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the - /// deposit would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewDeposit(uint256 assets) external view returns (uint256 shares); - - /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// deposit execution, and are accounted for during deposit. - /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - - /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. - /// @dev - /// - MUST return a limited value if receiver is subject to some mint limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. - /// - MUST NOT revert. - function maxMint(address receiver) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call - /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the - /// same transaction. - /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint - /// would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by minting. - function previewMint(uint256 shares) external view returns (uint256 assets); - - /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint - /// execution, and are accounted for during mint. - /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function mint(uint256 shares, address receiver) external returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the - /// Vault, through a withdraw call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST NOT revert. - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw - /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if - /// called - /// in the same transaction. - /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though - /// the withdrawal would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - - /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// withdraw execution, and are accounted for during withdraw. - /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); - - /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, - /// through a redeem call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. - /// - MUST NOT revert. - function maxRedeem(address owner) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call - /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the - /// same transaction. - /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the - /// redemption would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. - function previewRedeem(uint256 shares) external view returns (uint256 assets); - - /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// redeem execution, and are accounted for during redeem. - /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC721.sol b/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC721.sol deleted file mode 100644 index 0a16f45..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IERC721.sol +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC165.sol"; - -/// @title ERC-721 Non-Fungible Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. -interface IERC721 is IERC165 { - /// @dev This emits when ownership of any NFT changes by any mechanism. - /// This event emits when NFTs are created (`from` == 0) and destroyed - /// (`to` == 0). Exception: during contract creation, any number of NFTs - /// may be created and assigned without emitting Transfer. At the time of - /// any transfer, the approved address for that NFT (if any) is reset to none. - event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); - - /// @dev This emits when the approved address for an NFT is changed or - /// reaffirmed. The zero address indicates there is no approved address. - /// When a Transfer event emits, this also indicates that the approved - /// address for that NFT (if any) is reset to none. - event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); - - /// @dev This emits when an operator is enabled or disabled for an owner. - /// The operator can manage all NFTs of the owner. - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @notice Count all NFTs assigned to an owner - /// @dev NFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. - /// @param _owner An address for whom to query the balance - /// @return The number of NFTs owned by `_owner`, possibly zero - function balanceOf(address _owner) external view returns (uint256); - - /// @notice Find the owner of an NFT - /// @dev NFTs assigned to zero address are considered invalid, and queries - /// about them do throw. - /// @param _tokenId The identifier for an NFT - /// @return The address of the owner of the NFT - function ownerOf(uint256 _tokenId) external view returns (address); - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. When transfer is complete, this function - /// checks if `_to` is a smart contract (code size > 0). If so, it calls - /// `onERC721Received` on `_to` and throws if the return value is not - /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - /// @param data Additional data with no specified format, sent in call to `_to` - function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev This works identically to the other function with an extra data parameter, - /// except this function just sets data to "". - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE - /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE - /// THEY MAY BE PERMANENTLY LOST - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function transferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Change or reaffirm the approved address for an NFT - /// @dev The zero address indicates there is no approved address. - /// Throws unless `msg.sender` is the current NFT owner, or an authorized - /// operator of the current owner. - /// @param _approved The new approved NFT controller - /// @param _tokenId The NFT to approve - function approve(address _approved, uint256 _tokenId) external payable; - - /// @notice Enable or disable approval for a third party ("operator") to manage - /// all of `msg.sender`'s assets - /// @dev Emits the ApprovalForAll event. The contract MUST allow - /// multiple operators per owner. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Get the approved address for a single NFT - /// @dev Throws if `_tokenId` is not a valid NFT. - /// @param _tokenId The NFT to find the approved address for - /// @return The approved address for this NFT, or the zero address if there is none - function getApproved(uint256 _tokenId) external view returns (address); - - /// @notice Query if an address is an authorized operator for another address - /// @param _owner The address that owns the NFTs - /// @param _operator The address that acts on behalf of the owner - /// @return True if `_operator` is an approved operator for `_owner`, false otherwise - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} - -/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. -interface IERC721TokenReceiver { - /// @notice Handle the receipt of an NFT - /// @dev The ERC721 smart contract calls this function on the recipient - /// after a `transfer`. This function MAY throw to revert and reject the - /// transfer. Return of other than the magic value MUST result in the - /// transaction being reverted. - /// Note: the contract address is always the message sender. - /// @param _operator The address which called `safeTransferFrom` function - /// @param _from The address which previously owned the token - /// @param _tokenId The NFT identifier which is being transferred - /// @param _data Additional data with no specified format - /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - /// unless throwing - function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) - external - returns (bytes4); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. -interface IERC721Metadata is IERC721 { - /// @notice A descriptive name for a collection of NFTs in this contract - function name() external view returns (string memory _name); - - /// @notice An abbreviated name for NFTs in this contract - function symbol() external view returns (string memory _symbol); - - /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. - /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC - /// 3986. The URI may point to a JSON file that conforms to the "ERC721 - /// Metadata JSON Schema". - function tokenURI(uint256 _tokenId) external view returns (string memory); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x780e9d63. -interface IERC721Enumerable is IERC721 { - /// @notice Count NFTs tracked by this contract - /// @return A count of valid NFTs tracked by this contract, where each one of - /// them has an assigned and queryable owner not equal to the zero address - function totalSupply() external view returns (uint256); - - /// @notice Enumerate valid NFTs - /// @dev Throws if `_index` >= `totalSupply()`. - /// @param _index A counter less than `totalSupply()` - /// @return The token identifier for the `_index`th NFT, - /// (sort order not specified) - function tokenByIndex(uint256 _index) external view returns (uint256); - - /// @notice Enumerate NFTs assigned to an owner - /// @dev Throws if `_index` >= `balanceOf(_owner)` or if - /// `_owner` is the zero address, representing invalid NFTs. - /// @param _owner An address where we are interested in NFTs owned by them - /// @param _index A counter less than `balanceOf(_owner)` - /// @return The token identifier for the `_index`th NFT assigned to `_owner`, - /// (sort order not specified) - function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IMulticall3.sol b/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IMulticall3.sol deleted file mode 100644 index 0d031b7..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/interfaces/IMulticall3.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -interface IMulticall3 { - struct Call { - address target; - bytes callData; - } - - struct Call3 { - address target; - bool allowFailure; - bytes callData; - } - - struct Call3Value { - address target; - bool allowFailure; - uint256 value; - bytes callData; - } - - struct Result { - bool success; - bytes returnData; - } - - function aggregate(Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes[] memory returnData); - - function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); - - function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); - - function blockAndAggregate(Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); - - function getBasefee() external view returns (uint256 basefee); - - function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); - - function getBlockNumber() external view returns (uint256 blockNumber); - - function getChainId() external view returns (uint256 chainid); - - function getCurrentBlockCoinbase() external view returns (address coinbase); - - function getCurrentBlockDifficulty() external view returns (uint256 difficulty); - - function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); - - function getCurrentBlockTimestamp() external view returns (uint256 timestamp); - - function getEthBalance(address addr) external view returns (uint256 balance); - - function getLastBlockHash() external view returns (bytes32 blockHash); - - function tryAggregate(bool requireSuccess, Call[] calldata calls) - external - payable - returns (Result[] memory returnData); - - function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); -} diff --git a/lib/morpho-blue-irm/lib/forge-std/src/safeconsole.sol b/lib/morpho-blue-irm/lib/forge-std/src/safeconsole.sol deleted file mode 100644 index 5714d09..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/src/safeconsole.sol +++ /dev/null @@ -1,13248 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -/// @author philogy -/// @dev Code generated automatically by script. -library safeconsole { - uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67; - - // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374) - // for the view-to-pure log trick. - function _sendLogPayload(uint256 offset, uint256 size) private pure { - function(uint256, uint256) internal view fnIn = _sendLogPayloadView; - function(uint256, uint256) internal pure pureSendLogPayload; - assembly { - pureSendLogPayload := fnIn - } - pureSendLogPayload(offset, size); - } - - function _sendLogPayloadView(uint256 offset, uint256 size) private view { - assembly { - pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0)) - } - } - - function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure { - function(uint256, uint256, uint256) internal view fnIn = _memcopyView; - function(uint256, uint256, uint256) internal pure pureMemcopy; - assembly { - pureMemcopy := fnIn - } - pureMemcopy(fromOffset, toOffset, length); - } - - function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view { - assembly { - pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length)) - } - } - - function logMemory(uint256 offset, uint256 length) internal pure { - if (offset >= 0x60) { - // Sufficient memory before slice to prepare call header. - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(sub(offset, 0x60)) - m1 := mload(sub(offset, 0x40)) - m2 := mload(sub(offset, 0x20)) - // Selector of `logBytes(bytes)`. - mstore(sub(offset, 0x60), 0xe17bf956) - mstore(sub(offset, 0x40), 0x20) - mstore(sub(offset, 0x20), length) - } - _sendLogPayload(offset - 0x44, length + 0x44); - assembly { - mstore(sub(offset, 0x60), m0) - mstore(sub(offset, 0x40), m1) - mstore(sub(offset, 0x20), m2) - } - } else { - // Insufficient space, so copy slice forward, add header and reverse. - bytes32 m0; - bytes32 m1; - bytes32 m2; - uint256 endOffset = offset + length; - assembly { - m0 := mload(add(endOffset, 0x00)) - m1 := mload(add(endOffset, 0x20)) - m2 := mload(add(endOffset, 0x40)) - } - _memcopy(offset, offset + 0x60, length); - assembly { - // Selector of `logBytes(bytes)`. - mstore(add(offset, 0x00), 0xe17bf956) - mstore(add(offset, 0x20), 0x20) - mstore(add(offset, 0x40), length) - } - _sendLogPayload(offset + 0x1c, length + 0x44); - _memcopy(offset + 0x60, offset, length); - assembly { - mstore(add(endOffset, 0x00), m0) - mstore(add(endOffset, 0x20), m1) - mstore(add(endOffset, 0x40), m2) - } - } - } - - function log(address p0) internal pure { - bytes32 m0; - bytes32 m1; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(address)`. - mstore(0x00, 0x2c2ecbc2) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(bool p0) internal pure { - bytes32 m0; - bytes32 m1; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(bool)`. - mstore(0x00, 0x32458eed) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(uint256 p0) internal pure { - bytes32 m0; - bytes32 m1; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(uint256)`. - mstore(0x00, 0xf82c50f1) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(bytes32 p0) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(string)`. - mstore(0x00, 0x41304fac) - mstore(0x20, 0x20) - writeString(0x40, p0) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,address)`. - mstore(0x00, 0xdaf0d4aa) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,bool)`. - mstore(0x00, 0x75b605d3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,uint256)`. - mstore(0x00, 0x8309e8a8) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,string)`. - mstore(0x00, 0x759f86bb) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,address)`. - mstore(0x00, 0x853c4849) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,bool)`. - mstore(0x00, 0x2a110e83) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,uint256)`. - mstore(0x00, 0x399174d3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,string)`. - mstore(0x00, 0x8feac525) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,address)`. - mstore(0x00, 0x69276c86) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,bool)`. - mstore(0x00, 0x1c9d7eb3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,uint256)`. - mstore(0x00, 0xf666715a) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,string)`. - mstore(0x00, 0x643fd0df) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,address)`. - mstore(0x00, 0x319af333) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,bool)`. - mstore(0x00, 0xc3b55635) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,uint256)`. - mstore(0x00, 0xb60e72cc) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,string)`. - mstore(0x00, 0x4b5c4277) - mstore(0x20, 0x40) - mstore(0x40, 0x80) - writeString(0x60, p0) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,address)`. - mstore(0x00, 0x018c84c2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,bool)`. - mstore(0x00, 0xf2a66286) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,uint256)`. - mstore(0x00, 0x17fe6185) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,address,string)`. - mstore(0x00, 0x007150be) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,address)`. - mstore(0x00, 0xf11699ed) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,bool)`. - mstore(0x00, 0xeb830c92) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,uint256)`. - mstore(0x00, 0x9c4f99fb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,bool,string)`. - mstore(0x00, 0x212255cc) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,address)`. - mstore(0x00, 0x7bc0d848) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,bool)`. - mstore(0x00, 0x678209a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,uint256)`. - mstore(0x00, 0xb69bcaf6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,uint256,string)`. - mstore(0x00, 0xa1f2e8aa) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,address)`. - mstore(0x00, 0xf08744e8) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,bool)`. - mstore(0x00, 0xcf020fb1) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,uint256)`. - mstore(0x00, 0x67dd6ff1) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(address,string,string)`. - mstore(0x00, 0xfb772265) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bool p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,address)`. - mstore(0x00, 0xd2763667) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,bool)`. - mstore(0x00, 0x18c9c746) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,uint256)`. - mstore(0x00, 0x5f7b9afb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,address,string)`. - mstore(0x00, 0xde9a9270) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,address)`. - mstore(0x00, 0x1078f68d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,bool)`. - mstore(0x00, 0x50709698) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,uint256)`. - mstore(0x00, 0x12f21602) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,bool,string)`. - mstore(0x00, 0x2555fa46) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,address)`. - mstore(0x00, 0x088ef9d2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,bool)`. - mstore(0x00, 0xe8defba9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,uint256)`. - mstore(0x00, 0x37103367) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,uint256,string)`. - mstore(0x00, 0xc3fc3970) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,address)`. - mstore(0x00, 0x9591b953) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,bool)`. - mstore(0x00, 0xdbb4c247) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,uint256)`. - mstore(0x00, 0x1093ee11) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(bool,string,string)`. - mstore(0x00, 0xb076847f) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(uint256 p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,address)`. - mstore(0x00, 0xbcfd9be0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,bool)`. - mstore(0x00, 0x9b6ec042) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,uint256)`. - mstore(0x00, 0x5a9b5ed5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,address,string)`. - mstore(0x00, 0x63cb41f9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,address)`. - mstore(0x00, 0x35085f7b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,bool)`. - mstore(0x00, 0x20718650) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,uint256)`. - mstore(0x00, 0x20098014) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,bool,string)`. - mstore(0x00, 0x85775021) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,address)`. - mstore(0x00, 0x5c96b331) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,bool)`. - mstore(0x00, 0x4766da72) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,uint256)`. - mstore(0x00, 0xd1ed7a3c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,uint256,string)`. - mstore(0x00, 0x71d04af2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,address)`. - mstore(0x00, 0x7afac959) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,bool)`. - mstore(0x00, 0x4ceda75a) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,uint256)`. - mstore(0x00, 0x37aa7d4c) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(uint256,string,string)`. - mstore(0x00, 0xb115611f) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,address)`. - mstore(0x00, 0xfcec75e0) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,bool)`. - mstore(0x00, 0xc91d5ed4) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,uint256)`. - mstore(0x00, 0x0d26b925) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,address,string)`. - mstore(0x00, 0xe0e9ad4f) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,address)`. - mstore(0x00, 0x932bbb38) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,bool)`. - mstore(0x00, 0x850b7ad6) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,uint256)`. - mstore(0x00, 0xc95958d6) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,bool,string)`. - mstore(0x00, 0xe298f47d) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,address)`. - mstore(0x00, 0x1c7ec448) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,bool)`. - mstore(0x00, 0xca7733b1) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,uint256)`. - mstore(0x00, 0xca47c4eb) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,uint256,string)`. - mstore(0x00, 0x5970e089) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,address)`. - mstore(0x00, 0x95ed0195) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,bool)`. - mstore(0x00, 0xb0e0f9b5) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,uint256)`. - mstore(0x00, 0x5821efa1) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - // Selector of `log(string,string,string)`. - mstore(0x00, 0x2ced7cef) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, 0xe0) - writeString(0x80, p0) - writeString(0xc0, p1) - writeString(0x100, p2) - } - _sendLogPayload(0x1c, 0x124); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - } - } - - function log(address p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,address)`. - mstore(0x00, 0x665bf134) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,bool)`. - mstore(0x00, 0x0e378994) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,uint256)`. - mstore(0x00, 0x94250d77) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,address,string)`. - mstore(0x00, 0xf808da20) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,address)`. - mstore(0x00, 0x9f1bc36e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,bool)`. - mstore(0x00, 0x2cd4134a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,uint256)`. - mstore(0x00, 0x3971e78c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,bool,string)`. - mstore(0x00, 0xaa6540c8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,address)`. - mstore(0x00, 0x8da6def5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,bool)`. - mstore(0x00, 0x9b4254e2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,uint256)`. - mstore(0x00, 0xbe553481) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,uint256,string)`. - mstore(0x00, 0xfdb4f990) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,address)`. - mstore(0x00, 0x8f736d16) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,bool)`. - mstore(0x00, 0x6f1a594e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,uint256)`. - mstore(0x00, 0xef1cefe7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,address,string,string)`. - mstore(0x00, 0x21bdaf25) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,address)`. - mstore(0x00, 0x660375dd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,bool)`. - mstore(0x00, 0xa6f50b0f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,uint256)`. - mstore(0x00, 0xa75c59de) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,address,string)`. - mstore(0x00, 0x2dd778e6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,address)`. - mstore(0x00, 0xcf394485) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,bool)`. - mstore(0x00, 0xcac43479) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,uint256)`. - mstore(0x00, 0x8c4e5de6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,bool,string)`. - mstore(0x00, 0xdfc4a2e8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,address)`. - mstore(0x00, 0xccf790a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,bool)`. - mstore(0x00, 0xc4643e20) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,uint256)`. - mstore(0x00, 0x386ff5f4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,uint256,string)`. - mstore(0x00, 0x0aa6cfad) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,address)`. - mstore(0x00, 0x19fd4956) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,bool)`. - mstore(0x00, 0x50ad461d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,uint256)`. - mstore(0x00, 0x80e6a20b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,bool,string,string)`. - mstore(0x00, 0x475c5c33) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,address)`. - mstore(0x00, 0x478d1c62) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,bool)`. - mstore(0x00, 0xa1bcc9b3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,uint256)`. - mstore(0x00, 0x100f650e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,address,string)`. - mstore(0x00, 0x1da986ea) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,address)`. - mstore(0x00, 0xa31bfdcc) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,bool)`. - mstore(0x00, 0x3bf5e537) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,uint256)`. - mstore(0x00, 0x22f6b999) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,bool,string)`. - mstore(0x00, 0xc5ad85f9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,address)`. - mstore(0x00, 0x20e3984d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,bool)`. - mstore(0x00, 0x66f1bc67) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,uint256)`. - mstore(0x00, 0x34f0e636) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,uint256,string)`. - mstore(0x00, 0x4a28c017) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,address)`. - mstore(0x00, 0x5c430d47) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,bool)`. - mstore(0x00, 0xcf18105c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,uint256)`. - mstore(0x00, 0xbf01f891) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,uint256,string,string)`. - mstore(0x00, 0x88a8c406) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,address)`. - mstore(0x00, 0x0d36fa20) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,bool)`. - mstore(0x00, 0x0df12b76) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,uint256)`. - mstore(0x00, 0x457fe3cf) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,address,string)`. - mstore(0x00, 0xf7e36245) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,address)`. - mstore(0x00, 0x205871c2) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,bool)`. - mstore(0x00, 0x5f1d5c9f) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,uint256)`. - mstore(0x00, 0x515e38b6) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,bool,string)`. - mstore(0x00, 0xbc0b61fe) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,address)`. - mstore(0x00, 0x63183678) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,bool)`. - mstore(0x00, 0x0ef7e050) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,uint256)`. - mstore(0x00, 0x1dc8e1b8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,uint256,string)`. - mstore(0x00, 0x448830a8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,address)`. - mstore(0x00, 0xa04e2f87) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,bool)`. - mstore(0x00, 0x35a5071f) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,uint256)`. - mstore(0x00, 0x159f8927) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(address,string,string,string)`. - mstore(0x00, 0x5d02c50b) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bool p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,address)`. - mstore(0x00, 0x1d14d001) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,bool)`. - mstore(0x00, 0x46600be0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,uint256)`. - mstore(0x00, 0x0c66d1be) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,address,string)`. - mstore(0x00, 0xd812a167) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,address)`. - mstore(0x00, 0x1c41a336) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,bool)`. - mstore(0x00, 0x6a9c478b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,uint256)`. - mstore(0x00, 0x07831502) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,bool,string)`. - mstore(0x00, 0x4a66cb34) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,address)`. - mstore(0x00, 0x136b05dd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,bool)`. - mstore(0x00, 0xd6019f1c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,uint256)`. - mstore(0x00, 0x7bf181a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,uint256,string)`. - mstore(0x00, 0x51f09ff8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,address)`. - mstore(0x00, 0x6f7c603e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,bool)`. - mstore(0x00, 0xe2bfd60b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,uint256)`. - mstore(0x00, 0xc21f64c7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,address,string,string)`. - mstore(0x00, 0xa73c1db6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,address)`. - mstore(0x00, 0xf4880ea4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,bool)`. - mstore(0x00, 0xc0a302d8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,uint256)`. - mstore(0x00, 0x4c123d57) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,address,string)`. - mstore(0x00, 0xa0a47963) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,address)`. - mstore(0x00, 0x8c329b1a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,bool)`. - mstore(0x00, 0x3b2a5ce0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,uint256)`. - mstore(0x00, 0x6d7045c1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,bool,string)`. - mstore(0x00, 0x2ae408d4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,address)`. - mstore(0x00, 0x54a7a9a0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,bool)`. - mstore(0x00, 0x619e4d0e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,uint256)`. - mstore(0x00, 0x0bb00eab) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,uint256,string)`. - mstore(0x00, 0x7dd4d0e0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,address)`. - mstore(0x00, 0xf9ad2b89) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,bool)`. - mstore(0x00, 0xb857163a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,uint256)`. - mstore(0x00, 0xe3a9ca2f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,bool,string,string)`. - mstore(0x00, 0x6d1e8751) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,address)`. - mstore(0x00, 0x26f560a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,bool)`. - mstore(0x00, 0xb4c314ff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,uint256)`. - mstore(0x00, 0x1537dc87) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,address,string)`. - mstore(0x00, 0x1bb3b09a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,address)`. - mstore(0x00, 0x9acd3616) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,bool)`. - mstore(0x00, 0xceb5f4d7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,uint256)`. - mstore(0x00, 0x7f9bbca2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,bool,string)`. - mstore(0x00, 0x9143dbb1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,address)`. - mstore(0x00, 0x00dd87b9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,bool)`. - mstore(0x00, 0xbe984353) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,uint256)`. - mstore(0x00, 0x374bb4b2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,uint256,string)`. - mstore(0x00, 0x8e69fb5d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,address)`. - mstore(0x00, 0xfedd1fff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,bool)`. - mstore(0x00, 0xe5e70b2b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,uint256)`. - mstore(0x00, 0x6a1199e2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,uint256,string,string)`. - mstore(0x00, 0xf5bc2249) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,address)`. - mstore(0x00, 0x2b2b18dc) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,bool)`. - mstore(0x00, 0x6dd434ca) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,uint256)`. - mstore(0x00, 0xa5cada94) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,address,string)`. - mstore(0x00, 0x12d6c788) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,address)`. - mstore(0x00, 0x538e06ab) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,bool)`. - mstore(0x00, 0xdc5e935b) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,uint256)`. - mstore(0x00, 0x1606a393) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,bool,string)`. - mstore(0x00, 0x483d0416) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,address)`. - mstore(0x00, 0x1596a1ce) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,bool)`. - mstore(0x00, 0x6b0e5d53) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,uint256)`. - mstore(0x00, 0x28863fcb) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,uint256,string)`. - mstore(0x00, 0x1ad96de6) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,address)`. - mstore(0x00, 0x97d394d8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,bool)`. - mstore(0x00, 0x1e4b87e5) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,uint256)`. - mstore(0x00, 0x7be0c3eb) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(bool,string,string,string)`. - mstore(0x00, 0x1762e32a) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(uint256 p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,address)`. - mstore(0x00, 0x2488b414) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,bool)`. - mstore(0x00, 0x091ffaf5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,uint256)`. - mstore(0x00, 0x736efbb6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,address,string)`. - mstore(0x00, 0x031c6f73) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,address)`. - mstore(0x00, 0xef72c513) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,bool)`. - mstore(0x00, 0xe351140f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,uint256)`. - mstore(0x00, 0x5abd992a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,bool,string)`. - mstore(0x00, 0x90fb06aa) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,address)`. - mstore(0x00, 0x15c127b5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,bool)`. - mstore(0x00, 0x5f743a7c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,uint256)`. - mstore(0x00, 0x0c9cd9c1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,uint256,string)`. - mstore(0x00, 0xddb06521) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,address)`. - mstore(0x00, 0x9cba8fff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,bool)`. - mstore(0x00, 0xcc32ab07) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,uint256)`. - mstore(0x00, 0x46826b5d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,address,string,string)`. - mstore(0x00, 0x3e128ca3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,address)`. - mstore(0x00, 0xa1ef4cbb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,bool)`. - mstore(0x00, 0x454d54a5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,uint256)`. - mstore(0x00, 0x078287f5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,address,string)`. - mstore(0x00, 0xade052c7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,address)`. - mstore(0x00, 0x69640b59) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,bool)`. - mstore(0x00, 0xb6f577a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,uint256)`. - mstore(0x00, 0x7464ce23) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,bool,string)`. - mstore(0x00, 0xdddb9561) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,address)`. - mstore(0x00, 0x88cb6041) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,bool)`. - mstore(0x00, 0x91a02e2a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,uint256)`. - mstore(0x00, 0xc6acc7a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,uint256,string)`. - mstore(0x00, 0xde03e774) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,address)`. - mstore(0x00, 0xef529018) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,bool)`. - mstore(0x00, 0xeb928d7f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,uint256)`. - mstore(0x00, 0x2c1d0746) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,bool,string,string)`. - mstore(0x00, 0x68c8b8bd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,address)`. - mstore(0x00, 0x56a5d1b1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,bool)`. - mstore(0x00, 0x15cac476) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,uint256)`. - mstore(0x00, 0x88f6e4b2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,address,string)`. - mstore(0x00, 0x6cde40b8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,address)`. - mstore(0x00, 0x9a816a83) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,bool)`. - mstore(0x00, 0xab085ae6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,uint256)`. - mstore(0x00, 0xeb7f6fd2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,bool,string)`. - mstore(0x00, 0xa5b4fc99) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,address)`. - mstore(0x00, 0xfa8185af) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,bool)`. - mstore(0x00, 0xc598d185) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,uint256)`. - mstore(0x00, 0x193fb800) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,uint256,string)`. - mstore(0x00, 0x59cfcbe3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,address)`. - mstore(0x00, 0x42d21db7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,bool)`. - mstore(0x00, 0x7af6ab25) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,uint256)`. - mstore(0x00, 0x5da297eb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,uint256,string,string)`. - mstore(0x00, 0x27d8afd2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,address)`. - mstore(0x00, 0x6168ed61) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,bool)`. - mstore(0x00, 0x90c30a56) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,uint256)`. - mstore(0x00, 0xe8d3018d) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,address,string)`. - mstore(0x00, 0x9c3adfa1) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,address)`. - mstore(0x00, 0xae2ec581) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,bool)`. - mstore(0x00, 0xba535d9c) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,uint256)`. - mstore(0x00, 0xcf009880) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,bool,string)`. - mstore(0x00, 0xd2d423cd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,address)`. - mstore(0x00, 0x3b2279b4) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,bool)`. - mstore(0x00, 0x691a8f74) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,uint256)`. - mstore(0x00, 0x82c25b74) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,uint256,string)`. - mstore(0x00, 0xb7b914ca) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,address)`. - mstore(0x00, 0xd583c602) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,bool)`. - mstore(0x00, 0xb3a6b6bd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,uint256)`. - mstore(0x00, 0xb028c9bd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(uint256,string,string,string)`. - mstore(0x00, 0x21ad0683) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,address)`. - mstore(0x00, 0xed8f28f6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,bool)`. - mstore(0x00, 0xb59dbd60) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,uint256)`. - mstore(0x00, 0x8ef3f399) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,address,string)`. - mstore(0x00, 0x800a1c67) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,address)`. - mstore(0x00, 0x223603bd) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,bool)`. - mstore(0x00, 0x79884c2b) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,uint256)`. - mstore(0x00, 0x3e9f866a) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,bool,string)`. - mstore(0x00, 0x0454c079) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,address)`. - mstore(0x00, 0x63fb8bc5) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,bool)`. - mstore(0x00, 0xfc4845f0) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,uint256)`. - mstore(0x00, 0xf8f51b1e) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,uint256,string)`. - mstore(0x00, 0x5a477632) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,address)`. - mstore(0x00, 0xaabc9a31) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,bool)`. - mstore(0x00, 0x5f15d28c) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,uint256)`. - mstore(0x00, 0x91d1112e) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,address,string,string)`. - mstore(0x00, 0x245986f2) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,address)`. - mstore(0x00, 0x33e9dd1d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,bool)`. - mstore(0x00, 0x958c28c6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,uint256)`. - mstore(0x00, 0x5d08bb05) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,address,string)`. - mstore(0x00, 0x2d8e33a4) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,address)`. - mstore(0x00, 0x7190a529) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,bool)`. - mstore(0x00, 0x895af8c5) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,uint256)`. - mstore(0x00, 0x8e3f78a9) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,bool,string)`. - mstore(0x00, 0x9d22d5dd) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,address)`. - mstore(0x00, 0x935e09bf) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,bool)`. - mstore(0x00, 0x8af7cf8a) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,uint256)`. - mstore(0x00, 0x64b5bb67) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,uint256,string)`. - mstore(0x00, 0x742d6ee7) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,address)`. - mstore(0x00, 0xe0625b29) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,bool)`. - mstore(0x00, 0x3f8a701d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,uint256)`. - mstore(0x00, 0x24f91465) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,bool,string,string)`. - mstore(0x00, 0xa826caeb) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,address)`. - mstore(0x00, 0x5ea2b7ae) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,bool)`. - mstore(0x00, 0x82112a42) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,uint256)`. - mstore(0x00, 0x4f04fdc6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,address,string)`. - mstore(0x00, 0x9ffb2f93) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,address)`. - mstore(0x00, 0xe0e95b98) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,bool)`. - mstore(0x00, 0x354c36d6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,uint256)`. - mstore(0x00, 0xe41b6f6f) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,bool,string)`. - mstore(0x00, 0xabf73a98) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,address)`. - mstore(0x00, 0xe21de278) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,bool)`. - mstore(0x00, 0x7626db92) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,uint256)`. - mstore(0x00, 0xa7a87853) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,uint256,string)`. - mstore(0x00, 0x854b3496) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,address)`. - mstore(0x00, 0x7c4632a4) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,bool)`. - mstore(0x00, 0x7d24491d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,uint256)`. - mstore(0x00, 0xc67ea9d1) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,uint256,string,string)`. - mstore(0x00, 0x5ab84e1f) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,address)`. - mstore(0x00, 0x439c7bef) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,bool)`. - mstore(0x00, 0x5ccd4e37) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,uint256)`. - mstore(0x00, 0x7cc3c607) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,address,string)`. - mstore(0x00, 0xeb1bff80) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,address)`. - mstore(0x00, 0xc371c7db) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,bool)`. - mstore(0x00, 0x40785869) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,uint256)`. - mstore(0x00, 0xd6aefad2) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,bool,string)`. - mstore(0x00, 0x5e84b0ea) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,address)`. - mstore(0x00, 0x1023f7b2) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,bool)`. - mstore(0x00, 0xc3a8a654) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,uint256)`. - mstore(0x00, 0xf45d7d2c) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,uint256,string)`. - mstore(0x00, 0x5d1a971a) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,address)`. - mstore(0x00, 0x6d572f44) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,bool)`. - mstore(0x00, 0x2c1754ed) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,uint256)`. - mstore(0x00, 0x8eafb02b) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - bytes32 m11; - bytes32 m12; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - m11 := mload(0x160) - m12 := mload(0x180) - // Selector of `log(string,string,string,string)`. - mstore(0x00, 0xde68f20a) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, 0x140) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - writeString(0x160, p3) - } - _sendLogPayload(0x1c, 0x184); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - mstore(0x160, m11) - mstore(0x180, m12) - } - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/StdAssertions.t.sol b/lib/morpho-blue-irm/lib/forge-std/test/StdAssertions.t.sol deleted file mode 100644 index fcc346b..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/StdAssertions.t.sol +++ /dev/null @@ -1,999 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdAssertionsTest is Test { - string constant CUSTOM_ERROR = "guh!"; - - bool constant EXPECT_PASS = false; - bool constant EXPECT_FAIL = true; - - bool constant SHOULD_REVERT = true; - bool constant SHOULD_RETURN = false; - - bool constant STRICT_REVERT_DATA = true; - bool constant NON_STRICT_REVERT_DATA = false; - - TestTest t = new TestTest(); - - /*////////////////////////////////////////////////////////////////////////// - FAIL(STRING) - //////////////////////////////////////////////////////////////////////////*/ - - function testShouldFail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._fail(CUSTOM_ERROR); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_FALSE - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertFalse_Pass() external { - t._assertFalse(false, EXPECT_PASS); - } - - function testAssertFalse_Fail() external { - vm.expectEmit(false, false, false, true); - emit log("Error: Assertion Failed"); - t._assertFalse(true, EXPECT_FAIL); - } - - function testAssertFalse_Err_Pass() external { - t._assertFalse(false, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertFalse_Err_Fail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertFalse(true, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(BOOL) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_Bool_Pass(bool a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testAssertEq_Bool_Fail(bool a, bool b) external { - vm.assume(a != b); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [bool]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_BoolErr_Pass(bool a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertEq_BoolErr_Fail(bool a, bool b) external { - vm.assume(a != b); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(BYTES) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_Bytes_Pass(bytes calldata a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testAssertEq_Bytes_Fail(bytes calldata a, bytes calldata b) external { - vm.assume(keccak256(a) != keccak256(b)); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [bytes]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_BytesErr_Pass(bytes calldata a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertEq_BytesErr_Fail(bytes calldata a, bytes calldata b) external { - vm.assume(keccak256(a) != keccak256(b)); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(ARRAY) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_UintArr_Pass(uint256 e0, uint256 e1, uint256 e2) public { - uint256[] memory a = new uint256[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - uint256[] memory b = new uint256[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_IntArr_Pass(int256 e0, int256 e1, int256 e2) public { - int256[] memory a = new int256[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - int256[] memory b = new int256[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_AddressArr_Pass(address e0, address e1, address e2) public { - address[] memory a = new address[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - address[] memory b = new address[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_UintArr_FailEl(uint256 e1) public { - vm.assume(e1 != 0); - uint256[] memory a = new uint256[](3); - uint256[] memory b = new uint256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_IntArr_FailEl(int256 e1) public { - vm.assume(e1 != 0); - int256[] memory a = new int256[](3); - int256[] memory b = new int256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_AddressArr_FailEl(address e1) public { - vm.assume(e1 != address(0)); - address[] memory a = new address[](3); - address[] memory b = new address[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_UintArrErr_FailEl(uint256 e1) public { - vm.assume(e1 != 0); - uint256[] memory a = new uint256[](3); - uint256[] memory b = new uint256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_IntArrErr_FailEl(int256 e1) public { - vm.assume(e1 != 0); - int256[] memory a = new int256[](3); - int256[] memory b = new int256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_AddressArrErr_FailEl(address e1) public { - vm.assume(e1 != address(0)); - address[] memory a = new address[](3); - address[] memory b = new address[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_UintArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - uint256[] memory a = new uint256[](lenA); - uint256[] memory b = new uint256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_IntArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - int256[] memory a = new int256[](lenA); - int256[] memory b = new int256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_AddressArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - address[] memory a = new address[](lenA); - address[] memory b = new address[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_UintArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - uint256[] memory a = new uint256[](lenA); - uint256[] memory b = new uint256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_IntArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - int256[] memory a = new int256[](lenA); - int256[] memory b = new int256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_AddressArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - address[] memory a = new address[](lenA); - address[] memory b = new address[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEqUint() public { - assertEqUint(uint8(1), uint128(1)); - assertEqUint(uint64(2), uint64(2)); - } - - function testFailAssertEqUint() public { - assertEqUint(uint64(1), uint96(2)); - assertEqUint(uint160(3), uint160(4)); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbs_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testAssertApproxEqAbs_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); - } - - function testAssertApproxEqAbs_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbs_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS_DECIMAL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbsDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqAbsDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbs_Int_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testAssertApproxEqAbs_Int_Fail(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); - } - - function testAssertApproxEqAbs_IntErr_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbs_IntErr_Fail(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS_DECIMAL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbsDecimal_Int_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_Int_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqAbsDecimal_IntErr_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_IntErr_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRel_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); - } - - function testAssertApproxEqRel_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); - } - - function testAssertApproxEqRel_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRel_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL_DECIMAL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRelDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqRelDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRel_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); - } - - function testAssertApproxEqRel_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); - } - - function testAssertApproxEqRel_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRel_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL_DECIMAL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRelDecimal_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqRelDecimal_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ_CALL - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEqCall_Return_Pass( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnData, - bool strictRevertData - ) external { - address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); - - t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_PASS); - } - - function testAssertEqCall_Return_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData - ) external { - vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); - - address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); - - vm.expectEmit(true, true, true, true); - emit log_named_string("Error", "Call return data does not match"); - t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); - } - - function testAssertEqCall_Revert_Pass( - bytes memory callDataA, - bytes memory callDataB, - bytes memory revertDataA, - bytes memory revertDataB - ) external { - address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); - address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); - - t._assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA, EXPECT_PASS); - } - - function testAssertEqCall_Revert_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory revertDataA, - bytes memory revertDataB - ) external { - vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); - - address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); - address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); - - vm.expectEmit(true, true, true, true); - emit log_named_string("Error", "Call revert data does not match"); - t._assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA, EXPECT_FAIL); - } - - function testAssertEqCall_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData - ) external { - address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); - - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Left call return data", returnDataA); - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Right call revert data", returnDataB); - t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); - - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Left call revert data", returnDataB); - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Right call return data", returnDataA); - t._assertEqCall(targetB, callDataB, targetA, callDataA, strictRevertData, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_NOT_EQ(BYTES) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertNotEq_Bytes_Pass(bytes32 a, bytes32 b) external { - vm.assume(a != b); - t._assertNotEq(a, b, EXPECT_PASS); - } - - function testAssertNotEq_Bytes_Fail(bytes32 a) external { - vm.expectEmit(false, false, false, true); - emit log("Error: a != b not satisfied [bytes32]"); - t._assertNotEq(a, a, EXPECT_FAIL); - } - - function testAssertNotEq_BytesErr_Pass(bytes32 a, bytes32 b) external { - vm.assume(a != b); - t._assertNotEq(a, b, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAsserNottEq_BytesErr_Fail(bytes32 a) external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertNotEq(a, a, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_NOT_EQ(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertNotEqUint() public { - assertNotEq(uint8(1), uint128(2)); - assertNotEq(uint64(3), uint64(4)); - } - - function testFailAssertNotEqUint() public { - assertNotEq(uint64(1), uint96(1)); - assertNotEq(uint160(2), uint160(2)); - } -} - -contract TestTest is Test { - modifier expectFailure(bool expectFail) { - bool preState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); - _; - bool postState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); - - if (preState == true) { - return; - } - - if (expectFail) { - require(postState == true, "expected failure not triggered"); - - // unwind the expected failure - vm.store(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x00))); - } else { - require(postState == false, "unexpected failure was triggered"); - } - } - - function _fail(string memory err) external expectFailure(true) { - fail(err); - } - - function _assertFalse(bool data, bool expectFail) external expectFailure(expectFail) { - assertFalse(data); - } - - function _assertFalse(bool data, string memory err, bool expectFail) external expectFailure(expectFail) { - assertFalse(data, err); - } - - function _assertEq(bool a, bool b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(bool a, bool b, string memory err, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b, err); - } - - function _assertEq(bytes memory a, bytes memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(bytes memory a, bytes memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(uint256[] memory a, uint256[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(int256[] memory a, int256[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(address[] memory a, address[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(uint256[] memory a, uint256[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(int256[] memory a, int256[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(address[] memory a, address[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertNotEq(bytes32 a, bytes32 b, bool expectFail) external expectFailure(expectFail) { - assertNotEq32(a, b); - } - - function _assertNotEq(bytes32 a, bytes32 b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertNotEq32(a, b, err); - } - - function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta); - } - - function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta, err); - } - - function _assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - - function _assertApproxEqAbsDecimal( - uint256 a, - uint256 b, - uint256 maxDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); - } - - function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta); - } - - function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta, err); - } - - function _assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - - function _assertApproxEqAbsDecimal( - int256 a, - int256 b, - uint256 maxDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); - } - - function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta); - } - - function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta, err); - } - - function _assertApproxEqRelDecimal(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - - function _assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); - } - - function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta); - } - - function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta, err); - } - - function _assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - - function _assertApproxEqRelDecimal( - int256 a, - int256 b, - uint256 maxPercentDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); - } - - function _assertEqCall( - address targetA, - bytes memory callDataA, - address targetB, - bytes memory callDataB, - bool strictRevertData, - bool expectFail - ) external expectFailure(expectFail) { - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } -} - -contract TestMockCall { - bytes returnData; - bool shouldRevert; - - constructor(bytes memory returnData_, bool shouldRevert_) { - returnData = returnData_; - shouldRevert = shouldRevert_; - } - - fallback() external payable { - bytes memory returnData_ = returnData; - - if (shouldRevert) { - assembly { - revert(add(returnData_, 0x20), mload(returnData_)) - } - } else { - assembly { - return(add(returnData_, 0x20), mload(returnData_)) - } - } - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/StdChains.t.sol b/lib/morpho-blue-irm/lib/forge-std/test/StdChains.t.sol deleted file mode 100644 index 7480e48..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/StdChains.t.sol +++ /dev/null @@ -1,215 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdChainsMock is Test { - function exposed_getChain(string memory chainAlias) public returns (Chain memory) { - return getChain(chainAlias); - } - - function exposed_getChain(uint256 chainId) public returns (Chain memory) { - return getChain(chainId); - } - - function exposed_setChain(string memory chainAlias, ChainData memory chainData) public { - setChain(chainAlias, chainData); - } - - function exposed_setFallbackToDefaultRpcUrls(bool useDefault) public { - setFallbackToDefaultRpcUrls(useDefault); - } -} - -contract StdChainsTest is Test { - function testChainRpcInitialization() public { - // RPCs specified in `foundry.toml` should be updated. - assertEq(getChain(1).rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); - assertEq(getChain("optimism_goerli").rpcUrl, "https://goerli.optimism.io/"); - assertEq(getChain("arbitrum_one_goerli").rpcUrl, "https://goerli-rollup.arbitrum.io/rpc/"); - - // Environment variables should be the next fallback - assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); - vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); - assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); - vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); - - // Cannot override RPCs defined in `foundry.toml` - vm.setEnv("MAINNET_RPC_URL", "myoverride2"); - assertEq(getChain("mainnet").rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); - - // Other RPCs should remain unchanged. - assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); - assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); - } - - function testRpc(string memory rpcAlias) internal { - string memory rpcUrl = getChain(rpcAlias).rpcUrl; - vm.createSelectFork(rpcUrl); - } - - // Ensure we can connect to the default RPC URL for each chain. - // function testRpcs() public { - // testRpc("mainnet"); - // testRpc("goerli"); - // testRpc("sepolia"); - // testRpc("optimism"); - // testRpc("optimism_goerli"); - // testRpc("arbitrum_one"); - // testRpc("arbitrum_one_goerli"); - // testRpc("arbitrum_nova"); - // testRpc("polygon"); - // testRpc("polygon_mumbai"); - // testRpc("avalanche"); - // testRpc("avalanche_fuji"); - // testRpc("bnb_smart_chain"); - // testRpc("bnb_smart_chain_testnet"); - // testRpc("gnosis_chain"); - // } - - function testChainNoDefault() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); - stdChainsMock.exposed_getChain("does_not_exist"); - } - - function testSetChainFirstFails() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); - stdChainsMock.exposed_setChain("anvil2", ChainData("Anvil", 31337, "URL")); - } - - function testChainBubbleUp() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - stdChainsMock.exposed_setChain("needs_undefined_env_var", ChainData("", 123456789, "")); - vm.expectRevert( - "Failed to resolve env var `UNDEFINED_RPC_URL_PLACEHOLDER` in `${UNDEFINED_RPC_URL_PLACEHOLDER}`: environment variable not found" - ); - stdChainsMock.exposed_getChain("needs_undefined_env_var"); - } - - function testCannotSetChain_ChainIdExists() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - stdChainsMock.exposed_setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - - vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); - - stdChainsMock.exposed_setChain("another_custom_chain", ChainData("", 123456789, "")); - } - - function testSetChain() public { - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - Chain memory customChain = getChain("custom_chain"); - assertEq(customChain.name, "Custom Chain"); - assertEq(customChain.chainId, 123456789); - assertEq(customChain.chainAlias, "custom_chain"); - assertEq(customChain.rpcUrl, "https://custom.chain/"); - Chain memory chainById = getChain(123456789); - assertEq(chainById.name, customChain.name); - assertEq(chainById.chainId, customChain.chainId); - assertEq(chainById.chainAlias, customChain.chainAlias); - assertEq(chainById.rpcUrl, customChain.rpcUrl); - customChain.name = "Another Custom Chain"; - customChain.chainId = 987654321; - setChain("another_custom_chain", customChain); - Chain memory anotherCustomChain = getChain("another_custom_chain"); - assertEq(anotherCustomChain.name, "Another Custom Chain"); - assertEq(anotherCustomChain.chainId, 987654321); - assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); - assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); - // Verify the first chain data was not overwritten - chainById = getChain(123456789); - assertEq(chainById.name, "Custom Chain"); - assertEq(chainById.chainId, 123456789); - } - - function testSetNoEmptyAlias() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); - stdChainsMock.exposed_setChain("", ChainData("", 123456789, "")); - } - - function testSetNoChainId0() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); - stdChainsMock.exposed_setChain("alias", ChainData("", 0, "")); - } - - function testGetNoChainId0() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); - stdChainsMock.exposed_getChain(0); - } - - function testGetNoEmptyAlias() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); - stdChainsMock.exposed_getChain(""); - } - - function testChainIdNotFound() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); - stdChainsMock.exposed_getChain("no_such_alias"); - } - - function testChainAliasNotFound() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); - - stdChainsMock.exposed_getChain(321); - } - - function testSetChain_ExistingOne() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - assertEq(getChain(123456789).chainId, 123456789); - - setChain("custom_chain", ChainData("Modified Chain", 999999999, "https://modified.chain/")); - vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); - stdChainsMock.exposed_getChain(123456789); - - Chain memory modifiedChain = getChain(999999999); - assertEq(modifiedChain.name, "Modified Chain"); - assertEq(modifiedChain.chainId, 999999999); - assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); - } - - function testDontUseDefaultRpcUrl() public { - // We deploy a mock to properly test the revert. - StdChainsMock stdChainsMock = new StdChainsMock(); - - // Should error if default RPCs flag is set to false. - stdChainsMock.exposed_setFallbackToDefaultRpcUrls(false); - vm.expectRevert( - "Failed to get environment variable `ANVIL_RPC_URL` as type `string`: environment variable not found" - ); - stdChainsMock.exposed_getChain(31337); - vm.expectRevert( - "Failed to get environment variable `SEPOLIA_RPC_URL` as type `string`: environment variable not found" - ); - stdChainsMock.exposed_getChain("sepolia"); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/StdCheats.t.sol b/lib/morpho-blue-irm/lib/forge-std/test/StdCheats.t.sol deleted file mode 100644 index 05a5688..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/StdCheats.t.sol +++ /dev/null @@ -1,602 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdCheats.sol"; -import "../src/Test.sol"; -import "../src/StdJson.sol"; - -contract StdCheatsTest is Test { - Bar test; - - using stdJson for string; - - function setUp() public { - test = new Bar(); - } - - function testSkip() public { - vm.warp(100); - skip(25); - assertEq(block.timestamp, 125); - } - - function testRewind() public { - vm.warp(100); - rewind(25); - assertEq(block.timestamp, 75); - } - - function testHoax() public { - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - } - - function testHoaxOrigin() public { - hoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - } - - function testHoaxDifferentAddresses() public { - hoax(address(1337), address(7331)); - test.origin{value: 100}(address(1337), address(7331)); - } - - function testStartHoax() public { - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testStartHoaxOrigin() public { - startHoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - test.origin{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testChangePrankMsgSender() public { - vm.startPrank(address(1337)); - test.bar(address(1337)); - changePrank(address(0xdead)); - test.bar(address(0xdead)); - changePrank(address(1337)); - test.bar(address(1337)); - vm.stopPrank(); - } - - function testChangePrankMsgSenderAndTxOrigin() public { - vm.startPrank(address(1337), address(1338)); - test.origin(address(1337), address(1338)); - changePrank(address(0xdead), address(0xbeef)); - test.origin(address(0xdead), address(0xbeef)); - changePrank(address(1337), address(1338)); - test.origin(address(1337), address(1338)); - vm.stopPrank(); - } - - function testMakeAccountEquivalence() public { - Account memory account = makeAccount("1337"); - (address addr, uint256 key) = makeAddrAndKey("1337"); - assertEq(account.addr, addr); - assertEq(account.key, key); - } - - function testMakeAddrEquivalence() public { - (address addr,) = makeAddrAndKey("1337"); - assertEq(makeAddr("1337"), addr); - } - - function testMakeAddrSigning() public { - (address addr, uint256 key) = makeAddrAndKey("1337"); - bytes32 hash = keccak256("some_message"); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); - assertEq(ecrecover(hash, v, r, s), addr); - } - - function testDeal() public { - deal(address(this), 1 ether); - assertEq(address(this).balance, 1 ether); - } - - function testDealToken() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18); - assertEq(barToken.balanceOf(address(this)), 10000e18); - } - - function testDealTokenAdjustTotalSupply() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18, true); - assertEq(barToken.balanceOf(address(this)), 10000e18); - assertEq(barToken.totalSupply(), 20000e18); - deal(bar, address(this), 0, true); - assertEq(barToken.balanceOf(address(this)), 0); - assertEq(barToken.totalSupply(), 10000e18); - } - - function testDealERC1155Token() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, false); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - } - - function testDealERC1155TokenAdjustTotalSupply() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, true); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - assertEq(barToken.totalSupply(0), 20000e18); - dealERC1155(bar, address(this), 0, 0, true); - assertEq(barToken.balanceOf(address(this), 0), 0); - assertEq(barToken.totalSupply(0), 10000e18); - } - - function testDealERC721Token() public { - BarERC721 barToken = new BarERC721(); - address bar = address(barToken); - dealERC721(bar, address(2), 1); - assertEq(barToken.balanceOf(address(2)), 1); - assertEq(barToken.balanceOf(address(1)), 0); - dealERC721(bar, address(1), 2); - assertEq(barToken.balanceOf(address(1)), 1); - assertEq(barToken.balanceOf(bar), 1); - } - - function testDeployCode() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function testDestroyAccount() public { - // deploy something to destroy it - BarERC721 barToken = new BarERC721(); - address bar = address(barToken); - vm.setNonce(bar, 10); - deal(bar, 100); - - uint256 prevThisBalance = address(this).balance; - uint256 size; - assembly { - size := extcodesize(bar) - } - - assertGt(size, 0); - assertEq(bar.balance, 100); - assertEq(vm.getNonce(bar), 10); - - destroyAccount(bar, address(this)); - assembly { - size := extcodesize(bar) - } - assertEq(address(this).balance, prevThisBalance + 100); - assertEq(vm.getNonce(bar), 0); - assertEq(size, 0); - assertEq(bar.balance, 0); - } - - function testDeployCodeNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar"); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function testDeployCodeVal() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - function testDeployCodeValNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - // We need this so we can call "this.deployCode" rather than "deployCode" directly - function deployCodeHelper(string memory what) external { - deployCode(what); - } - - function testDeployCodeFail() public { - vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); - this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); - } - - function getCode(address who) internal view returns (bytes memory o_code) { - /// @solidity memory-safe-assembly - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(who) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(who, add(o_code, 0x20), 0, size) - } - } - - function testDeriveRememberKey() public { - string memory mnemonic = "test test test test test test test test test test test junk"; - - (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); - assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); - } - - function testBytesToUint() public { - assertEq(3, bytesToUint_test(hex"03")); - assertEq(2, bytesToUint_test(hex"02")); - assertEq(255, bytesToUint_test(hex"ff")); - assertEq(29625, bytesToUint_test(hex"73b9")); - } - - function testParseJsonTxDetail() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - string memory json = vm.readFile(path); - bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); - RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); - Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); - assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); - assertEq( - txDetail.data, - hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" - ); - assertEq(txDetail.nonce, 3); - assertEq(txDetail.txType, 2); - assertEq(txDetail.gas, 29625); - assertEq(txDetail.value, 0); - } - - function testReadEIP1559Transaction() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 0; - Tx1559 memory transaction = readTx1559(path, index); - transaction; - } - - function testReadEIP1559Transactions() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Tx1559[] memory transactions = readTx1559s(path); - transactions; - } - - function testReadReceipt() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 5; - Receipt memory receipt = readReceipt(path, index); - assertEq( - receipt.logsBloom, - hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" - ); - } - - function testReadReceipts() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Receipt[] memory receipts = readReceipts(path); - receipts; - } - - function testGasMeteringModifier() public { - uint256 gas_start_normal = gasleft(); - addInLoop(); - uint256 gas_used_normal = gas_start_normal - gasleft(); - - uint256 gas_start_single = gasleft(); - addInLoopNoGas(); - uint256 gas_used_single = gas_start_single - gasleft(); - - uint256 gas_start_double = gasleft(); - addInLoopNoGasNoGas(); - uint256 gas_used_double = gas_start_double - gasleft(); - - emit log_named_uint("Normal gas", gas_used_normal); - emit log_named_uint("Single modifier gas", gas_used_single); - emit log_named_uint("Double modifier gas", gas_used_double); - assertTrue(gas_used_double + gas_used_single < gas_used_normal); - } - - function addInLoop() internal pure returns (uint256) { - uint256 b; - for (uint256 i; i < 10000; i++) { - b += i; - } - return b; - } - - function addInLoopNoGas() internal noGasMetering returns (uint256) { - return addInLoop(); - } - - function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { - return addInLoopNoGas(); - } - - function bytesToUint_test(bytes memory b) private pure returns (uint256) { - uint256 number; - for (uint256 i = 0; i < b.length; i++) { - number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); - } - return number; - } - - function testAssumeAddressIsNot(address addr) external { - // skip over Payable and NonPayable enums - for (uint8 i = 2; i < uint8(type(AddressType).max); i++) { - assumeAddressIsNot(addr, AddressType(i)); - } - assertTrue(addr != address(0)); - assertTrue(addr < address(1) || addr > address(9)); - assertTrue(addr != address(vm) || addr != 0x000000000000000000636F6e736F6c652e6c6f67); - } - - function testAssumePayable() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - - // all should revert since these addresses are not payable - - // VM address - vm.expectRevert(); - stdCheatsMock.exposed_assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - // Console address - vm.expectRevert(); - stdCheatsMock.exposed_assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); - - // Create2Deployer - vm.expectRevert(); - stdCheatsMock.exposed_assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); - - // all should pass since these addresses are payable - - // vitalik.eth - stdCheatsMock.exposed_assumePayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); - - // mock payable contract - MockContractPayable cp = new MockContractPayable(); - stdCheatsMock.exposed_assumePayable(address(cp)); - } - - function testAssumeNotPayable() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - - // all should pass since these addresses are not payable - - // VM address - stdCheatsMock.exposed_assumeNotPayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - // Console address - stdCheatsMock.exposed_assumeNotPayable(0x000000000000000000636F6e736F6c652e6c6f67); - - // Create2Deployer - stdCheatsMock.exposed_assumeNotPayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); - - // all should revert since these addresses are payable - - // vitalik.eth - vm.expectRevert(); - stdCheatsMock.exposed_assumeNotPayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); - - // mock payable contract - MockContractPayable cp = new MockContractPayable(); - vm.expectRevert(); - stdCheatsMock.exposed_assumeNotPayable(address(cp)); - } - - function testAssumeNotPrecompile(address addr) external { - assumeNotPrecompile(addr, getChain("optimism_goerli").chainId); - assertTrue( - addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) - || addr > address(0x4200000000000000000000000000000000000800) - ); - } - - function testCannotDeployCodeTo() external { - vm.expectRevert("StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); - this._revertDeployCodeTo(); - } - - function _revertDeployCodeTo() external { - deployCodeTo("StdCheats.t.sol:RevertingContract", address(0)); - } - - function testDeployCodeTo() external { - address arbitraryAddress = makeAddr("arbitraryAddress"); - - deployCodeTo( - "StdCheats.t.sol:MockContractWithConstructorArgs", - abi.encode(uint256(6), true, bytes20(arbitraryAddress)), - 1 ether, - arbitraryAddress - ); - - MockContractWithConstructorArgs ct = MockContractWithConstructorArgs(arbitraryAddress); - - assertEq(arbitraryAddress.balance, 1 ether); - assertEq(ct.x(), 6); - assertTrue(ct.y()); - assertEq(ct.z(), bytes20(arbitraryAddress)); - } -} - -contract StdCheatsMock is StdCheats { - function exposed_assumePayable(address addr) external { - assumePayable(addr); - } - - function exposed_assumeNotPayable(address addr) external { - assumeNotPayable(addr); - } - - // We deploy a mock version so we can properly test expected reverts. - function exposed_assumeNotBlacklisted(address token, address addr) external view { - return assumeNotBlacklisted(token, addr); - } -} - -contract StdCheatsForkTest is Test { - address internal constant SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; - address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; - address internal constant USDC_BLACKLISTED_USER = 0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD; - address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; - address internal constant USDT_BLACKLISTED_USER = 0x8f8a8F4B54a2aAC7799d7bc81368aC27b852822A; - - function setUp() public { - // All tests of the `assumeNotBlacklisted` method are fork tests using live contracts. - vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); - } - - function testCannotAssumeNoBlacklisted_EOA() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - address eoa = vm.addr({privateKey: 1}); - vm.expectRevert("StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); - stdCheatsMock.exposed_assumeNotBlacklisted(eoa, address(0)); - } - - function testAssumeNotBlacklisted_TokenWithoutBlacklist(address addr) external { - assumeNotBlacklisted(SHIB, addr); - assertTrue(true); - } - - function testAssumeNoBlacklisted_USDC() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - vm.expectRevert(); - stdCheatsMock.exposed_assumeNotBlacklisted(USDC, USDC_BLACKLISTED_USER); - } - - function testAssumeNotBlacklisted_USDC(address addr) external { - assumeNotBlacklisted(USDC, addr); - assertFalse(USDCLike(USDC).isBlacklisted(addr)); - } - - function testAssumeNoBlacklisted_USDT() external { - // We deploy a mock version so we can properly test the revert. - StdCheatsMock stdCheatsMock = new StdCheatsMock(); - vm.expectRevert(); - stdCheatsMock.exposed_assumeNotBlacklisted(USDT, USDT_BLACKLISTED_USER); - } - - function testAssumeNotBlacklisted_USDT(address addr) external { - assumeNotBlacklisted(USDT, addr); - assertFalse(USDTLike(USDT).isBlackListed(addr)); - } -} - -contract Bar { - constructor() payable { - /// `DEAL` STDCHEAT - totalSupply = 10000e18; - balanceOf[address(this)] = totalSupply; - } - - /// `HOAX` and `CHANGEPRANK` STDCHEATS - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } - - function origin(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedSender, "!prank"); - } - - function origin(address expectedSender, address expectedOrigin) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedOrigin, "!prank"); - } - - /// `DEAL` STDCHEAT - mapping(address => uint256) public balanceOf; - uint256 public totalSupply; -} - -contract BarERC1155 { - constructor() payable { - /// `DEALERC1155` STDCHEAT - _totalSupply[0] = 10000e18; - _balances[0][address(this)] = _totalSupply[0]; - } - - function balanceOf(address account, uint256 id) public view virtual returns (uint256) { - return _balances[id][account]; - } - - function totalSupply(uint256 id) public view virtual returns (uint256) { - return _totalSupply[id]; - } - - /// `DEALERC1155` STDCHEAT - mapping(uint256 => mapping(address => uint256)) private _balances; - mapping(uint256 => uint256) private _totalSupply; -} - -contract BarERC721 { - constructor() payable { - /// `DEALERC721` STDCHEAT - _owners[1] = address(1); - _balances[address(1)] = 1; - _owners[2] = address(this); - _owners[3] = address(this); - _balances[address(this)] = 2; - } - - function balanceOf(address owner) public view virtual returns (uint256) { - return _balances[owner]; - } - - function ownerOf(uint256 tokenId) public view virtual returns (address) { - address owner = _owners[tokenId]; - return owner; - } - - mapping(uint256 => address) private _owners; - mapping(address => uint256) private _balances; -} - -interface USDCLike { - function isBlacklisted(address) external view returns (bool); -} - -interface USDTLike { - function isBlackListed(address) external view returns (bool); -} - -contract RevertingContract { - constructor() { - revert(); - } -} - -contract MockContractWithConstructorArgs { - uint256 public immutable x; - bool public y; - bytes20 public z; - - constructor(uint256 _x, bool _y, bytes20 _z) payable { - x = _x; - y = _y; - z = _z; - } -} - -contract MockContractPayable { - receive() external payable {} -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/StdError.t.sol b/lib/morpho-blue-irm/lib/forge-std/test/StdError.t.sol deleted file mode 100644 index ccd3efa..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/StdError.t.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import "../src/StdError.sol"; -import "../src/Test.sol"; - -contract StdErrorsTest is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectAssertion() public { - vm.expectRevert(stdError.assertionError); - test.assertionError(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } - - function testExpectDiv() public { - vm.expectRevert(stdError.divisionError); - test.divError(0); - } - - function testExpectMod() public { - vm.expectRevert(stdError.divisionError); - test.modError(0); - } - - function testExpectEnum() public { - vm.expectRevert(stdError.enumConversionError); - test.enumConversion(1); - } - - function testExpectEncodeStg() public { - vm.expectRevert(stdError.encodeStorageError); - test.encodeStgError(); - } - - function testExpectPop() public { - vm.expectRevert(stdError.popError); - test.pop(); - } - - function testExpectOOB() public { - vm.expectRevert(stdError.indexOOBError); - test.indexOOBError(1); - } - - function testExpectMem() public { - vm.expectRevert(stdError.memOverflowError); - test.mem(); - } - - function testExpectIntern() public { - vm.expectRevert(stdError.zeroVarError); - test.intern(); - } -} - -contract ErrorsTest { - enum T {T1} - - uint256[] public someArr; - bytes someBytes; - - function assertionError() public pure { - assert(false); - } - - function arithmeticError(uint256 a) public pure { - a -= 100; - } - - function divError(uint256 a) public pure { - 100 / a; - } - - function modError(uint256 a) public pure { - 100 % a; - } - - function enumConversion(uint256 a) public pure { - T(a); - } - - function encodeStgError() public { - /// @solidity memory-safe-assembly - assembly { - sstore(someBytes.slot, 1) - } - keccak256(someBytes); - } - - function pop() public { - someArr.pop(); - } - - function indexOOBError(uint256 a) public pure { - uint256[] memory t = new uint256[](0); - t[a]; - } - - function mem() public pure { - uint256 l = 2 ** 256 / 32; - new uint256[](l); - } - - function intern() public returns (uint256) { - function(uint256) internal returns (uint256) x; - x(2); - return 7; - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/StdMath.t.sol b/lib/morpho-blue-irm/lib/forge-std/test/StdMath.t.sol deleted file mode 100644 index 31c8a31..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/StdMath.t.sol +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import "../src/StdMath.sol"; -import "../src/Test.sol"; - -contract StdMathMock is Test { - function exposed_percentDelta(uint256 a, uint256 b) public pure returns (uint256) { - return stdMath.percentDelta(a, b); - } - - function exposed_percentDelta(int256 a, int256 b) public pure returns (uint256) { - return stdMath.percentDelta(a, b); - } -} - -contract StdMathTest is Test { - function testGetAbs() external { - assertEq(stdMath.abs(-50), 50); - assertEq(stdMath.abs(50), 50); - assertEq(stdMath.abs(-1337), 1337); - assertEq(stdMath.abs(0), 0); - - assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); - assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); - } - - function testGetAbs_Fuzz(int256 a) external { - uint256 manualAbs = getAbs(a); - - uint256 abs = stdMath.abs(a); - - assertEq(abs, manualAbs); - } - - function testGetDelta_Uint() external { - assertEq(stdMath.delta(uint256(0), uint256(0)), 0); - assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); - assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); - assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); - assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); - - assertEq(stdMath.delta(0, uint256(0)), 0); - assertEq(stdMath.delta(1337, uint256(0)), 1337); - assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); - assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); - assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); - - assertEq(stdMath.delta(1337, uint256(1337)), 0); - assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); - assertEq(stdMath.delta(5000, uint256(1250)), 3750); - } - - function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external { - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function testGetDelta_Int() external { - assertEq(stdMath.delta(int256(0), int256(0)), 0); - assertEq(stdMath.delta(int256(0), int256(1337)), 1337); - assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); - assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); - assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); - - assertEq(stdMath.delta(0, int256(0)), 0); - assertEq(stdMath.delta(1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); - assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); - assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); - - assertEq(stdMath.delta(-0, int256(0)), 0); - assertEq(stdMath.delta(-1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(int256(0), -0), 0); - assertEq(stdMath.delta(int256(0), -1337), 1337); - assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(1337, int256(1337)), 0); - assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); - assertEq(stdMath.delta(5000, int256(1250)), 3750); - } - - function testGetDelta_Int_Fuzz(int256 a, int256 b) external { - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function testGetPercentDelta_Uint() external { - StdMathMock stdMathMock = new StdMathMock(); - - assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); - assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); - assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); - assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMathMock.exposed_percentDelta(uint256(1), 0); - } - - function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external { - vm.assume(b != 0); - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / b; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - function testGetPercentDelta_Int() external { - // We deploy a mock version so we can properly test the revert. - StdMathMock stdMathMock = new StdMathMock(); - - assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); - assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, int256(1337)), 0); - assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); - assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); - - assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, int256(2500)), 0); - assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMathMock.exposed_percentDelta(int256(1), 0); - } - - function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external { - vm.assume(b != 0); - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / absB; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - /*////////////////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////////////////*/ - - function getAbs(int256 a) private pure returns (uint256) { - if (a < 0) { - return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); - } - - return uint256(a); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/StdStorage.t.sol b/lib/morpho-blue-irm/lib/forge-std/test/StdStorage.t.sol deleted file mode 100644 index fbf169d..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/StdStorage.t.sol +++ /dev/null @@ -1,293 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdStorage.sol"; -import "../src/Test.sol"; - -contract StdStorageTest is Test { - using stdStorage for StdStorage; - - StorageTest internal test; - - function setUp() public { - test = new StorageTest(); - } - - function testStorageHidden() public { - assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); - } - - function testStorageObvious() public { - assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); - } - - function testStorageCheckedWriteHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); - assertEq(uint256(test.hidden()), 100); - } - - function testStorageCheckedWriteObvious() public { - stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); - assertEq(test.exists(), 100); - } - - function testStorageCheckedWriteSignedIntegerHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write_int(-100); - assertEq(int256(uint256(test.hidden())), -100); - } - - function testStorageCheckedWriteSignedIntegerObvious() public { - stdstore.target(address(test)).sig(test.tG.selector).checked_write_int(-100); - assertEq(test.tG(), -100); - } - - function testStorageMapStructA() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); - } - - function testStorageMapStructB() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); - } - - function testStorageDeepMap() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( - address(this) - ).find(); - assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); - } - - function testStorageCheckedWriteDeepMap() public { - stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) - .checked_write(100); - assertEq(100, test.deep_map(address(this), address(this))); - } - - function testStorageDeepMapStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(0).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), - bytes32(slot) - ); - } - - function testStorageDeepMapStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(1).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), - bytes32(slot) - ); - } - - function testStorageCheckedWriteDeepMapStructA() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(100, a); - assertEq(0, b); - } - - function testStorageCheckedWriteDeepMapStructB() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(0, a); - assertEq(100, b); - } - - function testStorageCheckedWriteMapStructA() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 100); - assertEq(b, 0); - } - - function testStorageCheckedWriteMapStructB() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 0); - assertEq(b, 100); - } - - function testStorageStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); - assertEq(uint256(7), slot); - } - - function testStorageStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); - assertEq(uint256(7) + 1, slot); - } - - function testStorageCheckedWriteStructA() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 100); - assertEq(b, 1337); - } - - function testStorageCheckedWriteStructB() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 1337); - assertEq(b, 100); - } - - function testStorageMapAddrFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); - assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); - } - - function testStorageMapUintFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); - assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); - } - - function testStorageCheckedWriteMapUint() public { - stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); - assertEq(100, test.map_uint(100)); - } - - function testStorageCheckedWriteMapAddr() public { - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); - assertEq(100, test.map_addr(address(this))); - } - - function testStorageCheckedWriteMapBool() public { - stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); - assertTrue(test.map_bool(address(this))); - } - - function testFailStorageCheckedWriteMapPacked() public { - // expect PackedSlot error but not external call so cant expectRevert - stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337))) - .checked_write(100); - } - - function testStorageCheckedWriteMapPackedSuccess() public { - uint256 full = test.map_packed(address(1337)); - // keep upper 128, set lower 128 to 1337 - full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; - stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( - full - ); - assertEq(1337, test.read_struct_lower(address(1337))); - } - - function testFailStorageConst() public { - // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); - stdstore.target(address(test)).sig("const()").find(); - } - - function testFailStorageNativePack() public { - stdstore.target(address(test)).sig(test.tA.selector).find(); - stdstore.target(address(test)).sig(test.tB.selector).find(); - - // these both would fail - stdstore.target(address(test)).sig(test.tC.selector).find(); - stdstore.target(address(test)).sig(test.tD.selector).find(); - } - - function testStorageReadBytes32() public { - bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); - assertEq(val, hex"1337"); - } - - function testStorageReadBool_False() public { - bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); - assertEq(val, false); - } - - function testStorageReadBool_True() public { - bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); - assertEq(val, true); - } - - function testStorageReadBool_Revert() public { - vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - this.readNonBoolValue(); - } - - function readNonBoolValue() public { - stdstore.target(address(test)).sig(test.tE.selector).read_bool(); - } - - function testStorageReadAddress() public { - address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); - assertEq(val, address(1337)); - } - - function testStorageReadUint() public { - uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); - assertEq(val, 1); - } - - function testStorageReadInt() public { - int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); - assertEq(val, type(int256).min); - } -} - -contract StorageTest { - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - mapping(uint256 => uint256) public map_uint; - mapping(address => uint256) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basic; - - uint248 public tA; - bool public tB; - - bool public tC = false; - uint248 public tD = 1; - - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - mapping(address => bool) public map_bool; - - bytes32 public tE = hex"1337"; - address public tF = address(1337); - int256 public tG = type(int256).min; - bool public tH = true; - - constructor() { - basic = UnpackedStruct({a: 1337, b: 1337}); - - uint256 two = (1 << 128) | 1; - map_packed[msg.sender] = two; - map_packed[address(uint160(1337))] = 1 << 128; - } - - function read_struct_upper(address who) public view returns (uint256) { - return map_packed[who] >> 128; - } - - function read_struct_lower(address who) public view returns (uint256) { - return map_packed[who] & ((1 << 128) - 1); - } - - function hidden() public view returns (bytes32 t) { - bytes32 slot = keccak256("my.random.var"); - /// @solidity memory-safe-assembly - assembly { - t := sload(slot) - } - } - - function const() public pure returns (bytes32 t) { - t = bytes32(hex"1337"); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/StdStyle.t.sol b/lib/morpho-blue-irm/lib/forge-std/test/StdStyle.t.sol deleted file mode 100644 index f6fffe7..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/StdStyle.t.sol +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdStyleTest is Test { - function testStyleColor() public pure { - console2.log(StdStyle.red("StdStyle.red String Test")); - console2.log(StdStyle.red(uint256(10e18))); - console2.log(StdStyle.red(int256(-10e18))); - console2.log(StdStyle.red(true)); - console2.log(StdStyle.red(address(0))); - console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); - console2.log(StdStyle.green("StdStyle.green String Test")); - console2.log(StdStyle.green(uint256(10e18))); - console2.log(StdStyle.green(int256(-10e18))); - console2.log(StdStyle.green(true)); - console2.log(StdStyle.green(address(0))); - console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); - console2.log(StdStyle.yellow("StdStyle.yellow String Test")); - console2.log(StdStyle.yellow(uint256(10e18))); - console2.log(StdStyle.yellow(int256(-10e18))); - console2.log(StdStyle.yellow(true)); - console2.log(StdStyle.yellow(address(0))); - console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); - console2.log(StdStyle.blue("StdStyle.blue String Test")); - console2.log(StdStyle.blue(uint256(10e18))); - console2.log(StdStyle.blue(int256(-10e18))); - console2.log(StdStyle.blue(true)); - console2.log(StdStyle.blue(address(0))); - console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); - console2.log(StdStyle.magenta("StdStyle.magenta String Test")); - console2.log(StdStyle.magenta(uint256(10e18))); - console2.log(StdStyle.magenta(int256(-10e18))); - console2.log(StdStyle.magenta(true)); - console2.log(StdStyle.magenta(address(0))); - console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); - console2.log(StdStyle.cyan("StdStyle.cyan String Test")); - console2.log(StdStyle.cyan(uint256(10e18))); - console2.log(StdStyle.cyan(int256(-10e18))); - console2.log(StdStyle.cyan(true)); - console2.log(StdStyle.cyan(address(0))); - console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); - } - - function testStyleFontWeight() public pure { - console2.log(StdStyle.bold("StdStyle.bold String Test")); - console2.log(StdStyle.bold(uint256(10e18))); - console2.log(StdStyle.bold(int256(-10e18))); - console2.log(StdStyle.bold(address(0))); - console2.log(StdStyle.bold(true)); - console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); - console2.log(StdStyle.dim("StdStyle.dim String Test")); - console2.log(StdStyle.dim(uint256(10e18))); - console2.log(StdStyle.dim(int256(-10e18))); - console2.log(StdStyle.dim(address(0))); - console2.log(StdStyle.dim(true)); - console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); - console2.log(StdStyle.italic("StdStyle.italic String Test")); - console2.log(StdStyle.italic(uint256(10e18))); - console2.log(StdStyle.italic(int256(-10e18))); - console2.log(StdStyle.italic(address(0))); - console2.log(StdStyle.italic(true)); - console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); - console2.log(StdStyle.underline("StdStyle.underline String Test")); - console2.log(StdStyle.underline(uint256(10e18))); - console2.log(StdStyle.underline(int256(-10e18))); - console2.log(StdStyle.underline(address(0))); - console2.log(StdStyle.underline(true)); - console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); - console2.log(StdStyle.inverse("StdStyle.inverse String Test")); - console2.log(StdStyle.inverse(uint256(10e18))); - console2.log(StdStyle.inverse(int256(-10e18))); - console2.log(StdStyle.inverse(address(0))); - console2.log(StdStyle.inverse(true)); - console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); - } - - function testStyleCombined() public pure { - console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); - console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); - console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); - console2.log(StdStyle.blue(StdStyle.underline(address(0)))); - console2.log(StdStyle.magenta(StdStyle.inverse(true))); - } - - function testStyleCustom() public pure { - console2.log(h1("Custom Style 1")); - console2.log(h2("Custom Style 2")); - } - - function h1(string memory a) private pure returns (string memory) { - return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); - } - - function h2(string memory a) private pure returns (string memory) { - return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/StdUtils.t.sol b/lib/morpho-blue-irm/lib/forge-std/test/StdUtils.t.sol deleted file mode 100644 index d648512..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/StdUtils.t.sol +++ /dev/null @@ -1,342 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdUtilsMock is StdUtils { - // We deploy a mock version so we can properly test expected reverts. - function exposed_getTokenBalances(address token, address[] memory addresses) - external - returns (uint256[] memory balances) - { - return getTokenBalances(token, addresses); - } - - function exposed_bound(int256 num, int256 min, int256 max) external view returns (int256) { - return bound(num, min, max); - } - - function exposed_bound(uint256 num, uint256 min, uint256 max) external view returns (uint256) { - return bound(num, min, max); - } - - function exposed_bytesToUint(bytes memory b) external pure returns (uint256) { - return bytesToUint(b); - } -} - -contract StdUtilsTest is Test { - /*////////////////////////////////////////////////////////////////////////// - BOUND UINT - //////////////////////////////////////////////////////////////////////////*/ - - function testBound() public { - assertEq(bound(uint256(5), 0, 4), 0); - assertEq(bound(uint256(0), 69, 69), 69); - assertEq(bound(uint256(0), 68, 69), 68); - assertEq(bound(uint256(10), 150, 190), 174); - assertEq(bound(uint256(300), 2800, 3200), 3107); - assertEq(bound(uint256(9999), 1337, 6666), 4669); - } - - function testBound_WithinRange() public { - assertEq(bound(uint256(51), 50, 150), 51); - assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); - assertEq(bound(uint256(149), 50, 150), 149); - assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); - } - - function testBound_EdgeCoverage() public { - assertEq(bound(uint256(0), 50, 150), 50); - assertEq(bound(uint256(1), 50, 150), 51); - assertEq(bound(uint256(2), 50, 150), 52); - assertEq(bound(uint256(3), 50, 150), 53); - assertEq(bound(type(uint256).max, 50, 150), 150); - assertEq(bound(type(uint256).max - 1, 50, 150), 149); - assertEq(bound(type(uint256).max - 2, 50, 150), 148); - assertEq(bound(type(uint256).max - 3, 50, 150), 147); - } - - function testBound_DistributionIsEven(uint256 min, uint256 size) public { - size = size % 100 + 1; - min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); - uint256 max = min + size - 1; - uint256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + i, min, max); - assertEq(result, min + (i - 1) % size); - // x < min - result = bound(min - i, min, max); - assertEq(result, max - (i - 1) % size); - } - } - - function testBound(uint256 num, uint256 min, uint256 max) public { - if (min > max) (min, max) = (max, min); - - uint256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function testBoundUint256Max() public { - assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); - assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); - } - - function testCannotBoundMaxLessThanMin() public { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - stdUtils.exposed_bound(uint256(5), 100, 10); - } - - function testCannotBoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - stdUtils.exposed_bound(num, min, max); - } - - /*////////////////////////////////////////////////////////////////////////// - BOUND INT - //////////////////////////////////////////////////////////////////////////*/ - - function testBoundInt() public { - assertEq(bound(-3, 0, 4), 2); - assertEq(bound(0, -69, -69), -69); - assertEq(bound(0, -69, -68), -68); - assertEq(bound(-10, 150, 190), 154); - assertEq(bound(-300, 2800, 3200), 2908); - assertEq(bound(9999, -1337, 6666), 1995); - } - - function testBoundInt_WithinRange() public { - assertEq(bound(51, -50, 150), 51); - assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); - assertEq(bound(149, -50, 150), 149); - assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); - } - - function testBoundInt_EdgeCoverage() public { - assertEq(bound(type(int256).min, -50, 150), -50); - assertEq(bound(type(int256).min + 1, -50, 150), -49); - assertEq(bound(type(int256).min + 2, -50, 150), -48); - assertEq(bound(type(int256).min + 3, -50, 150), -47); - assertEq(bound(type(int256).min, 10, 150), 10); - assertEq(bound(type(int256).min + 1, 10, 150), 11); - assertEq(bound(type(int256).min + 2, 10, 150), 12); - assertEq(bound(type(int256).min + 3, 10, 150), 13); - - assertEq(bound(type(int256).max, -50, 150), 150); - assertEq(bound(type(int256).max - 1, -50, 150), 149); - assertEq(bound(type(int256).max - 2, -50, 150), 148); - assertEq(bound(type(int256).max - 3, -50, 150), 147); - assertEq(bound(type(int256).max, -50, -10), -10); - assertEq(bound(type(int256).max - 1, -50, -10), -11); - assertEq(bound(type(int256).max - 2, -50, -10), -12); - assertEq(bound(type(int256).max - 3, -50, -10), -13); - } - - function testBoundInt_DistributionIsEven(int256 min, uint256 size) public { - size = size % 100 + 1; - min = bound(min, -int256(size / 2), int256(size - size / 2)); - int256 max = min + int256(size) - 1; - int256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + int256(i), min, max); - assertEq(result, min + int256((i - 1) % size)); - // x < min - result = bound(min - int256(i), min, max); - assertEq(result, max - int256((i - 1) % size)); - } - } - - function testBoundInt(int256 num, int256 min, int256 max) public { - if (min > max) (min, max) = (max, min); - - int256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function testBoundIntInt256Max() public { - assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); - assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); - } - - function testBoundIntInt256Min() public { - assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); - assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); - } - - function testCannotBoundIntMaxLessThanMin() public { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); - stdUtils.exposed_bound(-5, 100, 10); - } - - function testCannotBoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); - stdUtils.exposed_bound(num, min, max); - } - - /*////////////////////////////////////////////////////////////////////////// - BOUND PRIVATE KEY - //////////////////////////////////////////////////////////////////////////*/ - - function testBoundPrivateKey() public { - assertEq(boundPrivateKey(0), 1); - assertEq(boundPrivateKey(1), 1); - assertEq(boundPrivateKey(300), 300); - assertEq(boundPrivateKey(9999), 9999); - assertEq(boundPrivateKey(SECP256K1_ORDER - 1), SECP256K1_ORDER - 1); - assertEq(boundPrivateKey(SECP256K1_ORDER), 1); - assertEq(boundPrivateKey(SECP256K1_ORDER + 1), 2); - assertEq(boundPrivateKey(UINT256_MAX), UINT256_MAX & SECP256K1_ORDER - 1); // x&y is equivalent to x-x%y - } - - /*////////////////////////////////////////////////////////////////////////// - BYTES TO UINT - //////////////////////////////////////////////////////////////////////////*/ - - function testBytesToUint() external { - bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - bytes memory two = hex"02"; - bytes memory millionEther = hex"d3c21bcecceda1000000"; - - assertEq(bytesToUint(maxUint), type(uint256).max); - assertEq(bytesToUint(two), 2); - assertEq(bytesToUint(millionEther), 1_000_000 ether); - } - - function testCannotConvertGT32Bytes() external { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); - stdUtils.exposed_bytesToUint(thirty3Bytes); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function testComputeCreateAddress() external { - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - uint256 nonce = 14; - address createAddress = computeCreateAddress(deployer, nonce); - assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE2 ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function testComputeCreate2Address() external { - bytes32 salt = bytes32(uint256(31415)); - bytes32 initcodeHash = keccak256(abi.encode(0x6080)); - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - address create2Address = computeCreate2Address(salt, initcodeHash, deployer); - assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); - } - - function testComputeCreate2AddressWithDefaultDeployer() external { - bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; - bytes32 initcodeHash = hashInitCode(hex"6080", ""); - assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); - address create2Address = computeCreate2Address(salt, initcodeHash); - assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); - } -} - -contract StdUtilsForkTest is Test { - /*////////////////////////////////////////////////////////////////////////// - GET TOKEN BALANCES - //////////////////////////////////////////////////////////////////////////*/ - - address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; - address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; - address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; - address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; - - address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; - address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; - address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; - - function setUp() public { - // All tests of the `getTokenBalances` method are fork tests using live contracts. - vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); - } - - function testCannotGetTokenBalances_NonTokenContract() external { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, - // so the `balanceOf` call should revert. - address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); - address[] memory addresses = new address[](1); - addresses[0] = USDC_HOLDER_0; - - vm.expectRevert("Multicall3: call failed"); - stdUtils.exposed_getTokenBalances(token, addresses); - } - - function testCannotGetTokenBalances_EOA() external { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - address eoa = vm.addr({privateKey: 1}); - address[] memory addresses = new address[](1); - addresses[0] = USDC_HOLDER_0; - vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); - stdUtils.exposed_getTokenBalances(eoa, addresses); - } - - function testGetTokenBalances_Empty() external { - address[] memory addresses = new address[](0); - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances.length, 0); - } - - function testGetTokenBalances_USDC() external { - address[] memory addresses = new address[](2); - addresses[0] = USDC_HOLDER_0; - addresses[1] = USDC_HOLDER_1; - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances[0], 159_000_000_000_000); - assertEq(balances[1], 131_350_000_000_000); - } - - function testGetTokenBalances_SHIB() external { - address[] memory addresses = new address[](3); - addresses[0] = SHIB_HOLDER_0; - addresses[1] = SHIB_HOLDER_1; - addresses[2] = SHIB_HOLDER_2; - uint256[] memory balances = getTokenBalances(SHIB, addresses); - assertEq(balances[0], 3_323_256_285_484.42e18); - assertEq(balances[1], 1_271_702_771_149.99999928e18); - assertEq(balances[2], 606_357_106_247e18); - } -} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationScript.sol b/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationScript.sol deleted file mode 100644 index e205cff..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationScript.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Script.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationScript is Script {} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationScriptBase.sol b/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationScriptBase.sol deleted file mode 100644 index ce8e0e9..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationScriptBase.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Script.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationScriptBase is ScriptBase {} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationTest.sol b/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationTest.sol deleted file mode 100644 index 9beeafe..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationTest.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Test.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationTest is Test {} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationTestBase.sol b/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationTestBase.sol deleted file mode 100644 index e993535..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/compilation/CompilationTestBase.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Test.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationTestBase is TestBase {} diff --git a/lib/morpho-blue-irm/lib/forge-std/test/fixtures/broadcast.log.json b/lib/morpho-blue-irm/lib/forge-std/test/fixtures/broadcast.log.json deleted file mode 100644 index 0a0200b..0000000 --- a/lib/morpho-blue-irm/lib/forge-std/test/fixtures/broadcast.log.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "transactions": [ - { - "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", - "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0x73b9", - "value": "0x0", - "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", - "nonce": "0x3", - "accessList": [] - } - }, - { - "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "inc():(uint256)", - "arguments": [], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0xdcb2", - "value": "0x0", - "data": "0x371303c0", - "nonce": "0x4", - "accessList": [] - } - }, - { - "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "function": "t(uint256):(uint256)", - "arguments": ["1"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "gas": "0x8599", - "value": "0x0", - "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", - "nonce": "0x5", - "accessList": [] - } - } - ], - "receipts": [ - { - "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", - "transactionIndex": "0x0", - "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", - "blockNumber": "0x1", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x13f3a", - "gasUsed": "0x13f3a", - "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", - "transactionIndex": "0x0", - "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", - "blockNumber": "0x2", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x45d80", - "gasUsed": "0x45d80", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", - "transactionIndex": "0x0", - "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", - "blockNumber": "0x3", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "cumulativeGasUsed": "0x45feb", - "gasUsed": "0x45feb", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "transactionIndex": "0x0", - "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", - "blockNumber": "0x4", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0x5905", - "gasUsed": "0x5905", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "transactionIndex": "0x0", - "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", - "blockNumber": "0x5", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0xa9c4", - "gasUsed": "0xa9c4", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x0", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "cumulativeGasUsed": "0x66c5", - "gasUsed": "0x66c5", - "contractAddress": null, - "logs": [ - { - "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "topics": [ - "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x1", - "logIndex": "0x0", - "transactionLogIndex": "0x0", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", - "transactionIndex": "0x0", - "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", - "blockNumber": "0x7", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x0000000000000000000000000000000000001337", - "cumulativeGasUsed": "0x5208", - "gasUsed": "0x5208", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - } - ], - "libraries": [ - "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" - ], - "pending": [], - "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", - "returns": {}, - "timestamp": 1655140035 -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/formatting.yml b/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/formatting.yml deleted file mode 100644 index 14d4942..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/formatting.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Formatting - -on: - push: - branches: - - main - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} - cancel-in-progress: true - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Install node - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: yarn - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Run Linter - run: yarn lint diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/foundry.yml b/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/foundry.yml deleted file mode 100644 index c44ea75..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/foundry.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Foundry - -on: - push: - branches: - - main - pull_request: - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} - cancel-in-progress: true - -jobs: - forge-test: - strategy: - fail-fast: true - matrix: - type: ["slow", "fast"] - include: - - type: "slow" - fuzz-runs: 10000 - max-test-rejects: 500000 - invariant-runs: 48 - invariant-depth: 2048 - - type: "fast" - fuzz-runs: 256 - max-test-rejects: 65536 - invariant-runs: 16 - invariant-depth: 256 - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Run Forge tests in ${{ matrix.type }} mode - run: forge test -vvv - env: - FOUNDRY_FUZZ_RUNS: ${{ matrix.fuzz-runs }} - FOUNDRY_FUZZ_MAX_TEST_REJECTS: ${{ matrix.max-test-rejects }} - FOUNDRY_INVARIANT_RUNS: ${{ matrix.invariant-runs }} - FOUNDRY_INVARIANT_DEPTH: ${{ matrix.invariant-depth }} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/hardhat.yml b/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/hardhat.yml deleted file mode 100644 index 490707a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.github/workflows/hardhat.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Hardhat - -on: - push: - branches: - - main - pull_request: - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} - cancel-in-progress: true - -jobs: - yarn-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Install node - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: yarn - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Save hardhat cache - uses: actions/cache@v3 - with: - path: | - cache_hardhat - artifacts - key: ${{ github.ref_name }}-hardhat - - - name: Run Hardhat tests - run: yarn test:hardhat diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.gitignore b/lib/morpho-blue-irm/lib/morpho-blue/.gitignore deleted file mode 100644 index 6f19847..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Compiler files -cache/ -out/ - -# Ignores development broadcast logs -!/broadcast -/broadcast/*/31337/ -/broadcast/**/dry-run/ - -# Docs -docs/ - -# Dotenv file -.env - -# Node modules -/node_modules - -# Hardhat -/types -/cache_hardhat -/artifacts diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.gitmodules b/lib/morpho-blue-irm/lib/morpho-blue/.gitmodules deleted file mode 100644 index 888d42d..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/forge-std"] - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.husky/commit-msg b/lib/morpho-blue-irm/lib/morpho-blue/.husky/commit-msg deleted file mode 100755 index 313a5f2..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.husky/commit-msg +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -yarn commitlint --edit "${1}" diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.husky/post-checkout b/lib/morpho-blue-irm/lib/morpho-blue/.husky/post-checkout deleted file mode 100755 index 00af394..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.husky/post-checkout +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -forge install -yarn diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.husky/post-merge b/lib/morpho-blue-irm/lib/morpho-blue/.husky/post-merge deleted file mode 100755 index 00af394..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.husky/post-merge +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -forge install -yarn diff --git a/lib/morpho-blue-irm/lib/morpho-blue/.husky/pre-commit b/lib/morpho-blue-irm/lib/morpho-blue/.husky/pre-commit deleted file mode 100755 index d2ae35e..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -yarn lint-staged diff --git a/lib/morpho-blue-irm/lib/morpho-blue/LICENSE b/lib/morpho-blue-irm/lib/morpho-blue/LICENSE deleted file mode 100644 index 88a7eaa..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/LICENSE +++ /dev/null @@ -1,103 +0,0 @@ -Business Source License 1.1 - -License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. -"Business Source License" is a trademark of MariaDB Corporation Ab. - ------------------------------------------------------------------------------ - -Parameters - -Licensor: Morpho Association - -Licensed Work: Morpho Blue Core - The Licensed Work is (c) 2023 Morpho Association - -Additional Use Grant: Any uses listed and defined at - morpho-blue-core-license-grants.morpho.eth - -Change Date: The earlier of (i) 2026-01-01, or (ii) a date specified - at morpho-blue-core-license-date.morpho.eth, or (iii) - upon the activation of the setFee function of the - Licensed Work’s applicable protocol smart contracts - deployed for production use. - -Change License: GNU General Public License v2.0 or later - ------------------------------------------------------------------------------ - -Terms - -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited -production use. - -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. - -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND -TITLE. - -MariaDB hereby grants you permission to use this License’s text to license -your works, and to refer to it using the trademark "Business Source License", -as long as you comply with the Covenants of Licensor below. - ------------------------------------------------------------------------------ - -Covenants of Licensor - -In consideration of the right to use this License’s text and the "Business -Source License" name and trademark, Licensor covenants to MariaDB, and to all -other recipients of the licensed work to be provided by Licensor: - -1. To specify as the Change License the GPL Version 2.0 or any later version, - or a license that is compatible with GPL Version 2.0 or a later version, - where "compatible" means that software provided under the Change License can - be included in a program with software provided under GPL Version 2.0 or a - later version. Licensor may specify additional Change Licenses without - limitation. - -2. To either: (a) specify an additional grant of rights to use that does not - impose any additional restriction on the right granted in this License, as - the Additional Use Grant; or (b) insert the text "None". - -3. To specify a Change Date. - -4. Not to modify this License in any other way. - ------------------------------------------------------------------------------ - -Notice - -The Business Source License (this document, or the "License") is not an Open -Source license. However, the Licensed Work will eventually be made available -under an Open Source License, as stated in this License. diff --git a/lib/morpho-blue-irm/lib/morpho-blue/README.md b/lib/morpho-blue-irm/lib/morpho-blue/README.md deleted file mode 100644 index 978c43a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Morpho Blue - -Morpho Blue is a noncustodial lending protocol implemented for the Ethereum Virtual Machine. -Morpho Blue offers a new trustless primitive with increased efficiency and flexibility compared to existing lending platforms. -It provides permissionless risk management and permissionless market creation with oracle agnostic pricing. -It also enables higher collateralization factors, improved interest rates, and lower gas consumption. -The protocol is designed to be a simple, immutable, and governance-minimized base layer that allows for a wide variety of other layers to be built on top. -Morpho Blue also offers a convenient developer experience with a singleton implementation, callbacks, free flash loans, and account management features. - -## Whitepaper - -The protocol is described in detail in the [Morpho Blue Whitepaper](./morpho-blue-whitepaper.pdf). - -## Repository Structure - -[`Morpho.sol`](./src/Morpho.sol) contains most of the source code of the core contract of Morpho Blue. -It solely relies on internal libraries in the [`src/libraries`](./src/libraries) subdirectory. - -Libraries in the [`src/libraries/periphery`](./src/libraries/periphery) directory are not used by Morpho Blue. -They are useful helpers that integrators can reuse or adapt to their own needs. - -The [`src/mocks`](./src/mocks) directory contains contracts designed exclusively for testing. - -You'll find relevant comments in [`IMorpho.sol`](./src/interfaces/IMorpho.sol), notably a list of requirements about market dependencies. - -## Getting Started - -Install dependencies: `yarn` - -Run forge tests: `yarn test:forge` - -Run hardhat tests: `yarn test:hardhat` - -You will find other useful commands in the [`package.json`](./package.json) file. - -## Audits - -All audits are stored in the [audits](./audits/)' folder. - -## Licences - -The primary license for Morpho Blue is the Business Source License 1.1 (`BUSL-1.1`), see [`LICENSE`](./LICENSE). -However, all files in the following folders can also be licensed under `GPL-2.0-or-later` (as indicated in their SPDX headers): [`src/interfaces`](./src/interfaces), [`src/libraries`](./src/libraries), [`src/mocks`](./src/mocks), [`test`](./test). diff --git a/lib/morpho-blue-irm/lib/morpho-blue/audits/2023-09-27-morpho-blue-and-speed-jump-irm-open-zeppelin.pdf b/lib/morpho-blue-irm/lib/morpho-blue/audits/2023-09-27-morpho-blue-and-speed-jump-irm-open-zeppelin.pdf deleted file mode 100644 index 3cc9eb6eb9af5c222064bd357e73efd8e572818e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408435 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

sK{YxX&N5-;k5C##gZC60D*%jrOsbE=hjG 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

wY}l$&rdPnjbL1Wh{v?6Oom4j+i_lQhD4H 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%0D7<8ouFG0nKbxYD@Fm~LEcv>P*w4r8X#Y0NTa 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 uint256) public map_addr; - // mapping(address => Packed) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basicStruct = UnpackedStruct({ - a: 1, - b: 2 - }); - - function hidden() public view returns (bytes32 t) { - // an extremely hidden storage slot - bytes32 slot = keccak256("my.random.var"); - assembly { - t := sload(slot) - } - } -} -``` - -### stdCheats - -This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for address that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. - - -#### Example usage: -```solidity - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; - -// Inherit the stdCheats -contract StdCheatsTest is Test { - Bar test; - function setUp() public { - test = new Bar(); - } - - function testHoax() public { - // we call `hoax`, which gives the target address - // eth and then calls `prank` - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - - // overloaded to allow you to specify how much eth to - // initialize the address with - hoax(address(1337), 1); - test.bar{value: 1}(address(1337)); - } - - function testStartHoax() public { - // we call `startHoax`, which gives the target address - // eth and then calls `startPrank` - // - // it is also overloaded so that you can specify an eth amount - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } -} - -contract Bar { - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } -} -``` - -### Std Assertions - -Expand upon the assertion functions from the `DSTest` library. - -### `console.log` - -Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). -It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console2.sol"; -... -console2.log(someValue); -``` - -If you need compatibility with Hardhat, you must use the standard `console.sol` instead. -Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console.sol"; -... -console.log(someValue); -``` - -## License - -Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/foundry.toml b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/foundry.toml deleted file mode 100644 index f9679ee..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/foundry.toml +++ /dev/null @@ -1,21 +0,0 @@ -[profile.default] -fs_permissions = [{ access = "read-write", path = "./"}] - -[rpc_endpoints] -# The RPC URLs are modified versions of the default for testing initialization. -mainnet = "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3" # Different API key. -optimism_goerli = "https://goerli.optimism.io/" # Adds a trailing slash. -arbitrum_one_goerli = "https://goerli-rollup.arbitrum.io/rpc/" # Adds a trailing slash. -needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" - -[fmt] -# These are all the `forge fmt` defaults. -line_length = 120 -tab_width = 4 -bracket_spacing = false -int_types = 'long' -multiline_func_header = 'attributes_first' -quote_style = 'double' -number_underscore = 'preserve' -single_line_statement_blocks = 'preserve' -ignore = ["src/console.sol", "src/console2.sol"] \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/.github/workflows/build.yml b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/.github/workflows/build.yml deleted file mode 100644 index d2ff97d..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/.github/workflows/build.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "Build" -on: - pull_request: - push: -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v20 - with: - nix_path: nixpkgs=channel:nixos-unstable - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - - name: setup dapp binary cache - uses: cachix/cachix-action@v12 - with: - name: dapp - - - name: install dapptools - run: nix profile install github:dapphub/dapptools#dapp --accept-flake-config - - - name: install foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: test with solc-0.5.17 - run: dapp --use solc-0.5.17 test -v - - - name: test with solc-0.6.11 - run: dapp --use solc-0.6.11 test -v - - - name: test with solc-0.7.6 - run: dapp --use solc-0.7.6 test -v - - - name: test with solc-0.8.18 - run: dapp --use solc-0.8.18 test -v - - - name: Run tests with foundry - run: forge test -vvv - diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/.gitignore b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/.gitignore deleted file mode 100644 index 462a994..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/.dapple -/build -/out -/cache/ diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/LICENSE b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/Makefile b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/Makefile deleted file mode 100644 index 661dac4..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all:; dapp build - -test: - -dapp --use solc:0.4.23 build - -dapp --use solc:0.4.26 build - -dapp --use solc:0.5.17 build - -dapp --use solc:0.6.12 build - -dapp --use solc:0.7.5 build - -demo: - DAPP_SRC=demo dapp --use solc:0.7.5 build - -hevm dapp-test --verbose 3 - -.PHONY: test demo diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/default.nix b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/default.nix deleted file mode 100644 index cf65419..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ solidityPackage, dappsys }: solidityPackage { - name = "ds-test"; - src = ./src; -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/demo/demo.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/demo/demo.sol deleted file mode 100644 index f3bb48e..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/demo/demo.sol +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.5.0; - -import "../src/test.sol"; - -contract DemoTest is DSTest { - function test_this() public pure { - require(true); - } - function test_logs() public { - emit log("-- log(string)"); - emit log("a string"); - - emit log("-- log_named_uint(string, uint)"); - emit log_named_uint("uint", 512); - - emit log("-- log_named_int(string, int)"); - emit log_named_int("int", -512); - - emit log("-- log_named_address(string, address)"); - emit log_named_address("address", address(this)); - - emit log("-- log_named_bytes32(string, bytes32)"); - emit log_named_bytes32("bytes32", "a string"); - - emit log("-- log_named_bytes(string, bytes)"); - emit log_named_bytes("bytes", hex"cafefe"); - - emit log("-- log_named_string(string, string)"); - emit log_named_string("string", "a string"); - - emit log("-- log_named_decimal_uint(string, uint, uint)"); - emit log_named_decimal_uint("decimal uint", 1.0e18, 18); - - emit log("-- log_named_decimal_int(string, int, uint)"); - emit log_named_decimal_int("decimal int", -1.0e18, 18); - } - event log_old_named_uint(bytes32,uint); - function test_old_logs() public { - emit log_old_named_uint("key", 500); - emit log_named_bytes32("bkey", "val"); - } - function test_trace() public view { - this.echo("string 1", "string 2"); - } - function test_multiline() public { - emit log("a multiline\\nstring"); - emit log("a multiline string"); - emit log_bytes("a string"); - emit log_bytes("a multiline\nstring"); - emit log_bytes("a multiline\\nstring"); - emit logs(hex"0000"); - emit log_named_bytes("0x0000", hex"0000"); - emit logs(hex"ff"); - } - function echo(string memory s1, string memory s2) public pure - returns (string memory, string memory) - { - return (s1, s2); - } - - function prove_this(uint x) public { - emit log_named_uint("sym x", x); - assertGt(x + 1, 0); - } - - function test_logn() public { - assembly { - log0(0x01, 0x02) - log1(0x01, 0x02, 0x03) - log2(0x01, 0x02, 0x03, 0x04) - log3(0x01, 0x02, 0x03, 0x04, 0x05) - } - } - - event MyEvent(uint, uint indexed, uint, uint indexed); - function test_events() public { - emit MyEvent(1, 2, 3, 4); - } - - function test_asserts() public { - string memory err = "this test has failed!"; - emit log("## assertTrue(bool)\n"); - assertTrue(false); - emit log("\n"); - assertTrue(false, err); - - emit log("\n## assertEq(address,address)\n"); - assertEq(address(this), msg.sender); - emit log("\n"); - assertEq(address(this), msg.sender, err); - - emit log("\n## assertEq32(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(uint,uint)\n"); - assertEq(uint(0), 1); - emit log("\n"); - assertEq(uint(0), 1, err); - - emit log("\n## assertEq(int,int)\n"); - assertEq(-1, -2); - emit log("\n"); - assertEq(-1, -2, err); - - emit log("\n## assertEqDecimal(int,int,uint)\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertEqDecimal(uint,uint,uint)\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGt(uint,uint)\n"); - assertGt(uint(0), 0); - emit log("\n"); - assertGt(uint(0), 0, err); - - emit log("\n## assertGt(int,int)\n"); - assertGt(-1, -1); - emit log("\n"); - assertGt(-1, -1, err); - - emit log("\n## assertGtDecimal(int,int,uint)\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGtDecimal(uint,uint,uint)\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGe(uint,uint)\n"); - assertGe(uint(0), 1); - emit log("\n"); - assertGe(uint(0), 1, err); - - emit log("\n## assertGe(int,int)\n"); - assertGe(-1, 0); - emit log("\n"); - assertGe(-1, 0, err); - - emit log("\n## assertGeDecimal(int,int,uint)\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGeDecimal(uint,uint,uint)\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertLt(uint,uint)\n"); - assertLt(uint(0), 0); - emit log("\n"); - assertLt(uint(0), 0, err); - - emit log("\n## assertLt(int,int)\n"); - assertLt(-1, -1); - emit log("\n"); - assertLt(-1, -1, err); - - emit log("\n## assertLtDecimal(int,int,uint)\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLtDecimal(uint,uint,uint)\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertLe(uint,uint)\n"); - assertLe(uint(1), 0); - emit log("\n"); - assertLe(uint(1), 0, err); - - emit log("\n## assertLe(int,int)\n"); - assertLe(0, -1); - emit log("\n"); - assertLe(0, -1, err); - - emit log("\n## assertLeDecimal(int,int,uint)\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLeDecimal(uint,uint,uint)\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertEq(string,string)\n"); - string memory s1 = "string 1"; - string memory s2 = "string 2"; - assertEq(s1, s2); - emit log("\n"); - assertEq(s1, s2, err); - - emit log("\n## assertEq0(bytes,bytes)\n"); - assertEq0(hex"abcdef01", hex"abcdef02"); - emit log("\n"); - assertEq0(hex"abcdef01", hex"abcdef02", err); - } -} - -contract DemoTestWithSetUp { - function setUp() public { - } - function test_pass() public pure { - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/package.json b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/package.json deleted file mode 100644 index 4802ada..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ds-test", - "version": "1.0.0", - "description": "Assertions, equality checks and other test helpers ", - "bugs": "https://github.com/dapphub/ds-test/issues", - "license": "GPL-3.0", - "author": "Contributors to ds-test", - "files": [ - "src/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/dapphub/ds-test.git" - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/src/test.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/src/test.sol deleted file mode 100644 index 2bf3375..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/src/test.sol +++ /dev/null @@ -1,592 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pragma solidity >=0.5.0; - -contract DSTest { - event log (string); - event logs (bytes); - - event log_address (address); - event log_bytes32 (bytes32); - event log_int (int); - event log_uint (uint); - event log_bytes (bytes); - event log_string (string); - - event log_named_address (string key, address val); - event log_named_bytes32 (string key, bytes32 val); - event log_named_decimal_int (string key, int val, uint decimals); - event log_named_decimal_uint (string key, uint val, uint decimals); - event log_named_int (string key, int val); - event log_named_uint (string key, uint val); - event log_named_bytes (string key, bytes val); - event log_named_string (string key, string val); - - bool public IS_TEST = true; - bool private _failed; - - address constant HEVM_ADDRESS = - address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); - - modifier mayRevert() { _; } - modifier testopts(string memory) { _; } - - function failed() public returns (bool) { - if (_failed) { - return _failed; - } else { - bool globalFailed = false; - if (hasHEVMContext()) { - (, bytes memory retdata) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("load(address,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed")) - ) - ); - globalFailed = abi.decode(retdata, (bool)); - } - return globalFailed; - } - } - - function fail() internal virtual { - if (hasHEVMContext()) { - (bool status, ) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("store(address,bytes32,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x01))) - ) - ); - status; // Silence compiler warnings - } - _failed = true; - } - - function hasHEVMContext() internal view returns (bool) { - uint256 hevmCodeSize = 0; - assembly { - hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) - } - return hevmCodeSize > 0; - } - - modifier logs_gas() { - uint startGas = gasleft(); - _; - uint endGas = gasleft(); - emit log_named_uint("gas", startGas - endGas); - } - - function assertTrue(bool condition) internal { - if (!condition) { - emit log("Error: Assertion Failed"); - fail(); - } - } - - function assertTrue(bool condition, string memory err) internal { - if (!condition) { - emit log_named_string("Error", err); - assertTrue(condition); - } - } - - function assertEq(address a, address b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [address]"); - emit log_named_address(" Left", a); - emit log_named_address(" Right", b); - fail(); - } - } - function assertEq(address a, address b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes32 a, bytes32 b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [bytes32]"); - emit log_named_bytes32(" Left", a); - emit log_named_bytes32(" Right", b); - fail(); - } - } - function assertEq(bytes32 a, bytes32 b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - function assertEq32(bytes32 a, bytes32 b) internal { - assertEq(a, b); - } - function assertEq32(bytes32 a, bytes32 b, string memory err) internal { - assertEq(a, b, err); - } - - function assertEq(int a, int b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - fail(); - } - } - function assertEq(int a, int b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEq(uint a, uint b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - fail(); - } - } - function assertEq(uint a, uint b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEqDecimal(int a, int b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - fail(); - } - } - function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - function assertEqDecimal(uint a, uint b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - fail(); - } - } - function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - - function assertNotEq(address a, address b) internal { - if (a == b) { - emit log("Error: a != b not satisfied [address]"); - emit log_named_address(" Left", a); - emit log_named_address(" Right", b); - fail(); - } - } - function assertNotEq(address a, address b, string memory err) internal { - if (a == b) { - emit log_named_string ("Error", err); - assertNotEq(a, b); - } - } - - function assertNotEq(bytes32 a, bytes32 b) internal { - if (a == b) { - emit log("Error: a != b not satisfied [bytes32]"); - emit log_named_bytes32(" Left", a); - emit log_named_bytes32(" Right", b); - fail(); - } - } - function assertNotEq(bytes32 a, bytes32 b, string memory err) internal { - if (a == b) { - emit log_named_string ("Error", err); - assertNotEq(a, b); - } - } - function assertNotEq32(bytes32 a, bytes32 b) internal { - assertNotEq(a, b); - } - function assertNotEq32(bytes32 a, bytes32 b, string memory err) internal { - assertNotEq(a, b, err); - } - - function assertNotEq(int a, int b) internal { - if (a == b) { - emit log("Error: a != b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - fail(); - } - } - function assertNotEq(int a, int b, string memory err) internal { - if (a == b) { - emit log_named_string("Error", err); - assertNotEq(a, b); - } - } - function assertNotEq(uint a, uint b) internal { - if (a == b) { - emit log("Error: a != b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - fail(); - } - } - function assertNotEq(uint a, uint b, string memory err) internal { - if (a == b) { - emit log_named_string("Error", err); - assertNotEq(a, b); - } - } - function assertNotEqDecimal(int a, int b, uint decimals) internal { - if (a == b) { - emit log("Error: a != b not satisfied [decimal int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - fail(); - } - } - function assertNotEqDecimal(int a, int b, uint decimals, string memory err) internal { - if (a == b) { - emit log_named_string("Error", err); - assertNotEqDecimal(a, b, decimals); - } - } - function assertNotEqDecimal(uint a, uint b, uint decimals) internal { - if (a == b) { - emit log("Error: a != b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - fail(); - } - } - function assertNotEqDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a == b) { - emit log_named_string("Error", err); - assertNotEqDecimal(a, b, decimals); - } - } - - function assertGt(uint a, uint b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGt(uint a, uint b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGt(int a, int b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGt(int a, int b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGtDecimal(int a, int b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - function assertGtDecimal(uint a, uint b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - - function assertGe(uint a, uint b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGe(uint a, uint b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGe(int a, int b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGe(int a, int b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGeDecimal(int a, int b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - function assertGeDecimal(uint a, uint b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertLt(uint a, uint b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLt(uint a, uint b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLt(int a, int b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLt(int a, int b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLtDecimal(int a, int b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - function assertLtDecimal(uint a, uint b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - - function assertLe(uint a, uint b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLe(uint a, uint b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLe(int a, int b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLe(int a, int b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLeDecimal(int a, int b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - function assertLeDecimal(uint a, uint b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - - function assertEq(string memory a, string memory b) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log("Error: a == b not satisfied [string]"); - emit log_named_string(" Left", a); - emit log_named_string(" Right", b); - fail(); - } - } - function assertEq(string memory a, string memory b, string memory err) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertNotEq(string memory a, string memory b) internal { - if (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))) { - emit log("Error: a != b not satisfied [string]"); - emit log_named_string(" Left", a); - emit log_named_string(" Right", b); - fail(); - } - } - function assertNotEq(string memory a, string memory b, string memory err) internal { - if (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))) { - emit log_named_string("Error", err); - assertNotEq(a, b); - } - } - - function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { - ok = true; - if (a.length == b.length) { - for (uint i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - ok = false; - } - } - } else { - ok = false; - } - } - function assertEq0(bytes memory a, bytes memory b) internal { - if (!checkEq0(a, b)) { - emit log("Error: a == b not satisfied [bytes]"); - emit log_named_bytes(" Left", a); - emit log_named_bytes(" Right", b); - fail(); - } - } - function assertEq0(bytes memory a, bytes memory b, string memory err) internal { - if (!checkEq0(a, b)) { - emit log_named_string("Error", err); - assertEq0(a, b); - } - } - - function assertNotEq0(bytes memory a, bytes memory b) internal { - if (checkEq0(a, b)) { - emit log("Error: a != b not satisfied [bytes]"); - emit log_named_bytes(" Left", a); - emit log_named_bytes(" Right", b); - fail(); - } - } - function assertNotEq0(bytes memory a, bytes memory b, string memory err) internal { - if (checkEq0(a, b)) { - emit log_named_string("Error", err); - assertNotEq0(a, b); - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/src/test.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/src/test.t.sol deleted file mode 100644 index d277a30..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/lib/ds-test/src/test.t.sol +++ /dev/null @@ -1,417 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.5.0; - -import {DSTest} from "./test.sol"; - -contract DemoTest is DSTest { - - // --- assertTrue --- - - function testAssertTrue() public { - assertTrue(true, "msg"); - assertTrue(true); - } - function testFailAssertTrue() public { - assertTrue(false); - } - function testFailAssertTrueWithMsg() public { - assertTrue(false, "msg"); - } - - // --- assertEq (Addr) --- - - function testAssertEqAddr() public { - assertEq(address(0x0), address(0x0), "msg"); - assertEq(address(0x0), address(0x0)); - } - function testFailAssertEqAddr() public { - assertEq(address(0x0), address(0x1)); - } - function testFailAssertEqAddrWithMsg() public { - assertEq(address(0x0), address(0x1), "msg"); - } - - // --- assertEq (Bytes32) --- - - function testAssertEqBytes32() public { - assertEq(bytes32("hi"), bytes32("hi"), "msg"); - assertEq(bytes32("hi"), bytes32("hi")); - } - function testFailAssertEqBytes32() public { - assertEq(bytes32("hi"), bytes32("ho")); - } - function testFailAssertEqBytes32WithMsg() public { - assertEq(bytes32("hi"), bytes32("ho"), "msg"); - } - - // --- assertEq (Int) --- - - function testAssertEqInt() public { - assertEq(-1, -1, "msg"); - assertEq(-1, -1); - } - function testFailAssertEqInt() public { - assertEq(-1, -2); - } - function testFailAssertEqIntWithMsg() public { - assertEq(-1, -2, "msg"); - } - - // --- assertEq (UInt) --- - - function testAssertEqUInt() public { - assertEq(uint(1), uint(1), "msg"); - assertEq(uint(1), uint(1)); - } - function testFailAssertEqUInt() public { - assertEq(uint(1), uint(2)); - } - function testFailAssertEqUIntWithMsg() public { - assertEq(uint(1), uint(2), "msg"); - } - - // --- assertEqDecimal (Int) --- - - function testAssertEqDecimalInt() public { - assertEqDecimal(-1, -1, 18, "msg"); - assertEqDecimal(-1, -1, 18); - } - function testFailAssertEqDecimalInt() public { - assertEqDecimal(-1, -2, 18); - } - function testFailAssertEqDecimalIntWithMsg() public { - assertEqDecimal(-1, -2, 18, "msg"); - } - - // --- assertEqDecimal (UInt) --- - - function testAssertEqDecimalUInt() public { - assertEqDecimal(uint(1), uint(1), 18, "msg"); - assertEqDecimal(uint(1), uint(1), 18); - } - function testFailAssertEqDecimalUInt() public { - assertEqDecimal(uint(1), uint(2), 18); - } - function testFailAssertEqDecimalUIntWithMsg() public { - assertEqDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertNotEq (Addr) --- - - function testAssertNotEqAddr() public { - assertNotEq(address(0x0), address(0x1), "msg"); - assertNotEq(address(0x0), address(0x1)); - } - function testFailAssertNotEqAddr() public { - assertNotEq(address(0x0), address(0x0)); - } - function testFailAssertNotEqAddrWithMsg() public { - assertNotEq(address(0x0), address(0x0), "msg"); - } - - // --- assertNotEq (Bytes32) --- - - function testAssertNotEqBytes32() public { - assertNotEq(bytes32("hi"), bytes32("ho"), "msg"); - assertNotEq(bytes32("hi"), bytes32("ho")); - } - function testFailAssertNotEqBytes32() public { - assertNotEq(bytes32("hi"), bytes32("hi")); - } - function testFailAssertNotEqBytes32WithMsg() public { - assertNotEq(bytes32("hi"), bytes32("hi"), "msg"); - } - - // --- assertNotEq (Int) --- - - function testAssertNotEqInt() public { - assertNotEq(-1, -2, "msg"); - assertNotEq(-1, -2); - } - function testFailAssertNotEqInt() public { - assertNotEq(-1, -1); - } - function testFailAssertNotEqIntWithMsg() public { - assertNotEq(-1, -1, "msg"); - } - - // --- assertNotEq (UInt) --- - - function testAssertNotEqUInt() public { - assertNotEq(uint(1), uint(2), "msg"); - assertNotEq(uint(1), uint(2)); - } - function testFailAssertNotEqUInt() public { - assertNotEq(uint(1), uint(1)); - } - function testFailAssertNotEqUIntWithMsg() public { - assertNotEq(uint(1), uint(1), "msg"); - } - - // --- assertNotEqDecimal (Int) --- - - function testAssertNotEqDecimalInt() public { - assertNotEqDecimal(-1, -2, 18, "msg"); - assertNotEqDecimal(-1, -2, 18); - } - function testFailAssertNotEqDecimalInt() public { - assertNotEqDecimal(-1, -1, 18); - } - function testFailAssertNotEqDecimalIntWithMsg() public { - assertNotEqDecimal(-1, -1, 18, "msg"); - } - - // --- assertNotEqDecimal (UInt) --- - - function testAssertNotEqDecimalUInt() public { - assertNotEqDecimal(uint(1), uint(2), 18, "msg"); - assertNotEqDecimal(uint(1), uint(2), 18); - } - function testFailAssertNotEqDecimalUInt() public { - assertNotEqDecimal(uint(1), uint(1), 18); - } - function testFailAssertNotEqDecimalUIntWithMsg() public { - assertNotEqDecimal(uint(1), uint(1), 18, "msg"); - } - - // --- assertGt (UInt) --- - - function testAssertGtUInt() public { - assertGt(uint(2), uint(1), "msg"); - assertGt(uint(3), uint(2)); - } - function testFailAssertGtUInt() public { - assertGt(uint(1), uint(2)); - } - function testFailAssertGtUIntWithMsg() public { - assertGt(uint(1), uint(2), "msg"); - } - - // --- assertGt (Int) --- - - function testAssertGtInt() public { - assertGt(-1, -2, "msg"); - assertGt(-1, -3); - } - function testFailAssertGtInt() public { - assertGt(-2, -1); - } - function testFailAssertGtIntWithMsg() public { - assertGt(-2, -1, "msg"); - } - - // --- assertGtDecimal (UInt) --- - - function testAssertGtDecimalUInt() public { - assertGtDecimal(uint(2), uint(1), 18, "msg"); - assertGtDecimal(uint(3), uint(2), 18); - } - function testFailAssertGtDecimalUInt() public { - assertGtDecimal(uint(1), uint(2), 18); - } - function testFailAssertGtDecimalUIntWithMsg() public { - assertGtDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertGtDecimal (Int) --- - - function testAssertGtDecimalInt() public { - assertGtDecimal(-1, -2, 18, "msg"); - assertGtDecimal(-1, -3, 18); - } - function testFailAssertGtDecimalInt() public { - assertGtDecimal(-2, -1, 18); - } - function testFailAssertGtDecimalIntWithMsg() public { - assertGtDecimal(-2, -1, 18, "msg"); - } - - // --- assertGe (UInt) --- - - function testAssertGeUInt() public { - assertGe(uint(2), uint(1), "msg"); - assertGe(uint(2), uint(2)); - } - function testFailAssertGeUInt() public { - assertGe(uint(1), uint(2)); - } - function testFailAssertGeUIntWithMsg() public { - assertGe(uint(1), uint(2), "msg"); - } - - // --- assertGe (Int) --- - - function testAssertGeInt() public { - assertGe(-1, -2, "msg"); - assertGe(-1, -1); - } - function testFailAssertGeInt() public { - assertGe(-2, -1); - } - function testFailAssertGeIntWithMsg() public { - assertGe(-2, -1, "msg"); - } - - // --- assertGeDecimal (UInt) --- - - function testAssertGeDecimalUInt() public { - assertGeDecimal(uint(2), uint(1), 18, "msg"); - assertGeDecimal(uint(2), uint(2), 18); - } - function testFailAssertGeDecimalUInt() public { - assertGeDecimal(uint(1), uint(2), 18); - } - function testFailAssertGeDecimalUIntWithMsg() public { - assertGeDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertGeDecimal (Int) --- - - function testAssertGeDecimalInt() public { - assertGeDecimal(-1, -2, 18, "msg"); - assertGeDecimal(-1, -2, 18); - } - function testFailAssertGeDecimalInt() public { - assertGeDecimal(-2, -1, 18); - } - function testFailAssertGeDecimalIntWithMsg() public { - assertGeDecimal(-2, -1, 18, "msg"); - } - - // --- assertLt (UInt) --- - - function testAssertLtUInt() public { - assertLt(uint(1), uint(2), "msg"); - assertLt(uint(1), uint(3)); - } - function testFailAssertLtUInt() public { - assertLt(uint(2), uint(2)); - } - function testFailAssertLtUIntWithMsg() public { - assertLt(uint(3), uint(2), "msg"); - } - - // --- assertLt (Int) --- - - function testAssertLtInt() public { - assertLt(-2, -1, "msg"); - assertLt(-1, 0); - } - function testFailAssertLtInt() public { - assertLt(-1, -2); - } - function testFailAssertLtIntWithMsg() public { - assertLt(-1, -1, "msg"); - } - - // --- assertLtDecimal (UInt) --- - - function testAssertLtDecimalUInt() public { - assertLtDecimal(uint(1), uint(2), 18, "msg"); - assertLtDecimal(uint(2), uint(3), 18); - } - function testFailAssertLtDecimalUInt() public { - assertLtDecimal(uint(1), uint(1), 18); - } - function testFailAssertLtDecimalUIntWithMsg() public { - assertLtDecimal(uint(2), uint(1), 18, "msg"); - } - - // --- assertLtDecimal (Int) --- - - function testAssertLtDecimalInt() public { - assertLtDecimal(-2, -1, 18, "msg"); - assertLtDecimal(-2, -1, 18); - } - function testFailAssertLtDecimalInt() public { - assertLtDecimal(-2, -2, 18); - } - function testFailAssertLtDecimalIntWithMsg() public { - assertLtDecimal(-1, -2, 18, "msg"); - } - - // --- assertLe (UInt) --- - - function testAssertLeUInt() public { - assertLe(uint(1), uint(2), "msg"); - assertLe(uint(1), uint(1)); - } - function testFailAssertLeUInt() public { - assertLe(uint(4), uint(2)); - } - function testFailAssertLeUIntWithMsg() public { - assertLe(uint(3), uint(2), "msg"); - } - - // --- assertLe (Int) --- - - function testAssertLeInt() public { - assertLe(-2, -1, "msg"); - assertLe(-1, -1); - } - function testFailAssertLeInt() public { - assertLe(-1, -2); - } - function testFailAssertLeIntWithMsg() public { - assertLe(-1, -3, "msg"); - } - - // --- assertLeDecimal (UInt) --- - - function testAssertLeDecimalUInt() public { - assertLeDecimal(uint(1), uint(2), 18, "msg"); - assertLeDecimal(uint(2), uint(2), 18); - } - function testFailAssertLeDecimalUInt() public { - assertLeDecimal(uint(1), uint(0), 18); - } - function testFailAssertLeDecimalUIntWithMsg() public { - assertLeDecimal(uint(1), uint(0), 18, "msg"); - } - - // --- assertLeDecimal (Int) --- - - function testAssertLeDecimalInt() public { - assertLeDecimal(-2, -1, 18, "msg"); - assertLeDecimal(-2, -2, 18); - } - function testFailAssertLeDecimalInt() public { - assertLeDecimal(-2, -3, 18); - } - function testFailAssertLeDecimalIntWithMsg() public { - assertLeDecimal(-1, -2, 18, "msg"); - } - - // --- assertNotEq (String) --- - - function testAssertNotEqString() public { - assertNotEq(new string(1), new string(2), "msg"); - assertNotEq(new string(1), new string(2)); - } - function testFailAssertNotEqString() public { - assertNotEq(new string(1), new string(1)); - } - function testFailAssertNotEqStringWithMsg() public { - assertNotEq(new string(1), new string(1), "msg"); - } - - // --- assertNotEq0 (Bytes) --- - - function testAssertNotEq0Bytes() public { - assertNotEq0(bytes("hi"), bytes("ho"), "msg"); - assertNotEq0(bytes("hi"), bytes("ho")); - } - function testFailAssertNotEq0Bytes() public { - assertNotEq0(bytes("hi"), bytes("hi")); - } - function testFailAssertNotEq0BytesWithMsg() public { - assertNotEq0(bytes("hi"), bytes("hi"), "msg"); - } - - // --- fail override --- - - // ensure that fail can be overridden - function fail() internal override { - super.fail(); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/package.json b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/package.json deleted file mode 100644 index f39bb39..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "forge-std", - "version": "1.5.6", - "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", - "homepage": "https://book.getfoundry.sh/forge/forge-std", - "bugs": "https://github.com/foundry-rs/forge-std/issues", - "license": "(Apache-2.0 OR MIT)", - "author": "Contributors to Forge Standard Library", - "files": [ - "src/**/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/foundry-rs/forge-std.git" - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Base.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Base.sol deleted file mode 100644 index 851ac0c..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Base.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {StdStorage} from "./StdStorage.sol"; -import {Vm, VmSafe} from "./Vm.sol"; - -abstract contract CommonBase { - // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. - address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); - // console.sol and console2.sol work by executing a staticcall to this address. - address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; - // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. - address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38. - address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256("foundry default caller")))); - // Address of the test contract, deployed by the DEFAULT_SENDER. - address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; - // Deterministic deployment address of the Multicall3 contract. - address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; - // The order of the secp256k1 curve. - uint256 internal constant SECP256K1_ORDER = - 115792089237316195423570985008687907852837564279074904382605163141518161494337; - - uint256 internal constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - Vm internal constant vm = Vm(VM_ADDRESS); - StdStorage internal stdstore; -} - -abstract contract TestBase is CommonBase {} - -abstract contract ScriptBase is CommonBase { - VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Script.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Script.sol deleted file mode 100644 index bffccad..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Script.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -// 💬 ABOUT -// Standard Library's default Script. - -// 🧩 MODULES -import {ScriptBase} from "./Base.sol"; -import {console} from "./console.sol"; -import {console2} from "./console2.sol"; -import {StdChains} from "./StdChains.sol"; -import {StdCheatsSafe} from "./StdCheats.sol"; -import {stdJson} from "./StdJson.sol"; -import {stdMath} from "./StdMath.sol"; -import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {VmSafe} from "./Vm.sol"; - -// 📦 BOILERPLATE -import {ScriptBase} from "./Base.sol"; - -// ⭐️ SCRIPT -abstract contract Script is StdChains, StdCheatsSafe, StdUtils, ScriptBase { - // Note: IS_SCRIPT() must return true. - bool public IS_SCRIPT = true; -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdAssertions.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdAssertions.sol deleted file mode 100644 index 2778b3a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdAssertions.sol +++ /dev/null @@ -1,376 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {DSTest} from "ds-test/test.sol"; -import {stdMath} from "./StdMath.sol"; - -abstract contract StdAssertions is DSTest { - event log_array(uint256[] val); - event log_array(int256[] val); - event log_array(address[] val); - event log_named_array(string key, uint256[] val); - event log_named_array(string key, int256[] val); - event log_named_array(string key, address[] val); - - function fail(string memory err) internal virtual { - emit log_named_string("Error", err); - fail(); - } - - function assertFalse(bool data) internal virtual { - assertTrue(!data); - } - - function assertFalse(bool data, string memory err) internal virtual { - assertTrue(!data, err); - } - - function assertEq(bool a, bool b) internal virtual { - if (a != b) { - emit log("Error: a == b not satisfied [bool]"); - emit log_named_string(" Left", a ? "true" : "false"); - emit log_named_string(" Right", b ? "true" : "false"); - fail(); - } - } - - function assertEq(bool a, bool b, string memory err) internal virtual { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes memory a, bytes memory b) internal virtual { - assertEq0(a, b); - } - - function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual { - assertEq0(a, b, err); - } - - function assertEq(uint256[] memory a, uint256[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [uint[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(int256[] memory a, int256[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [int[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(address[] memory a, address[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [address[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - // Legacy helper - function assertEqUint(uint256 a, uint256 b) internal virtual { - assertEq(uint256(a), uint256(b)); - } - - function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbs(a, b, maxDelta); - } - } - - function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); - emit log_named_decimal_uint(" Delta", delta, decimals); - fail(); - } - } - - function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err) - internal - virtual - { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - } - - function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbs(a, b, maxDelta); - } - } - - function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); - emit log_named_decimal_uint(" Delta", delta, decimals); - fail(); - } - } - - function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err) - internal - virtual - { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - } - - function assertApproxEqRel( - uint256 a, - uint256 b, - uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% - ) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); - emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); - fail(); - } - } - - function assertApproxEqRel( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRel(a, b, maxPercentDelta); - } - } - - function assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); - emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); - fail(); - } - } - - function assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - } - - function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); - emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); - fail(); - } - } - - function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRel(a, b, maxPercentDelta); - } - } - - function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); - emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); - fail(); - } - } - - function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err) - internal - virtual - { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - } - - function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { - assertEqCall(target, callDataA, target, callDataB, true); - } - - function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) - internal - virtual - { - assertEqCall(targetA, callDataA, targetB, callDataB, true); - } - - function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) - internal - virtual - { - assertEqCall(target, callDataA, target, callDataB, strictRevertData); - } - - function assertEqCall( - address targetA, - bytes memory callDataA, - address targetB, - bytes memory callDataB, - bool strictRevertData - ) internal virtual { - (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); - (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); - - if (successA && successB) { - assertEq(returnDataA, returnDataB, "Call return data does not match"); - } - - if (!successA && !successB && strictRevertData) { - assertEq(returnDataA, returnDataB, "Call revert data does not match"); - } - - if (!successA && successB) { - emit log("Error: Calls were not equal"); - emit log_named_bytes(" Left call revert data", returnDataA); - emit log_named_bytes(" Right call return data", returnDataB); - fail(); - } - - if (successA && !successB) { - emit log("Error: Calls were not equal"); - emit log_named_bytes(" Left call return data", returnDataA); - emit log_named_bytes(" Right call revert data", returnDataB); - fail(); - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdChains.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdChains.sol deleted file mode 100644 index f97637f..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdChains.sol +++ /dev/null @@ -1,231 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {VmSafe} from "./Vm.sol"; - -/** - * StdChains provides information about EVM compatible chains that can be used in scripts/tests. - * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are - * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of - * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the - * alias used in this contract, which can be found as the first argument to the - * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. - * - * There are two main ways to use this contract: - * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or - * `setChain(string memory chainAlias, Chain memory chain)` - * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. - * - * The first time either of those are used, chains are initialized with the default set of RPC URLs. - * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in - * `defaultRpcUrls`. - * - * The `setChain` function is straightforward, and it simply saves off the given chain data. - * - * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say - * we want to retrieve the RPC URL for `mainnet`: - * - If you have specified data with `setChain`, it will return that. - * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it - * is valid (e.g. a URL is specified, or an environment variable is given and exists). - * - If neither of the above conditions is met, the default data is returned. - * - * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. - */ -abstract contract StdChains { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - bool private stdChainsInitialized; - - struct ChainData { - string name; - uint256 chainId; - string rpcUrl; - } - - struct Chain { - // The chain name. - string name; - // The chain's Chain ID. - uint256 chainId; - // The chain's alias. (i.e. what gets specified in `foundry.toml`). - string chainAlias; - // A default RPC endpoint for this chain. - // NOTE: This default RPC URL is included for convenience to facilitate quick tests and - // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy - // usage as you will be throttled and this is a disservice to others who need this endpoint. - string rpcUrl; - } - - // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. - mapping(string => Chain) private chains; - // Maps from the chain's alias to it's default RPC URL. - mapping(string => string) private defaultRpcUrls; - // Maps from a chain ID to it's alias. - mapping(uint256 => string) private idToAlias; - - bool private fallbackToDefaultRpcUrls = true; - - // The RPC URL will be fetched from config or defaultRpcUrls if possible. - function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { - require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); - - initializeStdChains(); - chain = chains[chainAlias]; - require( - chain.chainId != 0, - string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) - ); - - chain = getChainWithUpdatedRpcUrl(chainAlias, chain); - } - - function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { - require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); - initializeStdChains(); - string memory chainAlias = idToAlias[chainId]; - - chain = chains[chainAlias]; - - require( - chain.chainId != 0, - string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) - ); - - chain = getChainWithUpdatedRpcUrl(chainAlias, chain); - } - - // set chain info, with priority to argument's rpcUrl field. - function setChain(string memory chainAlias, ChainData memory chain) internal virtual { - require( - bytes(chainAlias).length != 0, - "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." - ); - - require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); - - initializeStdChains(); - string memory foundAlias = idToAlias[chain.chainId]; - - require( - bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), - string( - abi.encodePacked( - "StdChains setChain(string,ChainData): Chain ID ", - vm.toString(chain.chainId), - " already used by \"", - foundAlias, - "\"." - ) - ) - ); - - uint256 oldChainId = chains[chainAlias].chainId; - delete idToAlias[oldChainId]; - - chains[chainAlias] = - Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); - idToAlias[chain.chainId] = chainAlias; - } - - // set chain info, with priority to argument's rpcUrl field. - function setChain(string memory chainAlias, Chain memory chain) internal virtual { - setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); - } - - function _toUpper(string memory str) private pure returns (string memory) { - bytes memory strb = bytes(str); - bytes memory copy = new bytes(strb.length); - for (uint256 i = 0; i < strb.length; i++) { - bytes1 b = strb[i]; - if (b >= 0x61 && b <= 0x7A) { - copy[i] = bytes1(uint8(b) - 32); - } else { - copy[i] = b; - } - } - return string(copy); - } - - // lookup rpcUrl, in descending order of priority: - // current -> config (foundry.toml) -> environment variable -> default - function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) { - if (bytes(chain.rpcUrl).length == 0) { - try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { - chain.rpcUrl = configRpcUrl; - } catch (bytes memory err) { - string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); - if (fallbackToDefaultRpcUrls) { - chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); - } else { - chain.rpcUrl = vm.envString(envName); - } - // distinguish 'not found' from 'cannot read' - bytes memory notFoundError = - abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); - if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, err), mload(err)) - } - } - } - } - return chain; - } - - function setFallbackToDefaultRpcUrls(bool useDefault) internal { - fallbackToDefaultRpcUrls = useDefault; - } - - function initializeStdChains() private { - if (stdChainsInitialized) return; - - stdChainsInitialized = true; - - // If adding an RPC here, make sure to test the default RPC URL in `testRpcs` - setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); - setChainWithDefaultRpcUrl( - "mainnet", ChainData("Mainnet", 1, "https://mainnet.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") - ); - setChainWithDefaultRpcUrl( - "goerli", ChainData("Goerli", 5, "https://goerli.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") - ); - setChainWithDefaultRpcUrl( - "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") - ); - setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); - setChainWithDefaultRpcUrl("optimism_goerli", ChainData("Optimism Goerli", 420, "https://goerli.optimism.io")); - setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl( - "arbitrum_one_goerli", ChainData("Arbitrum One Goerli", 421613, "https://goerli-rollup.arbitrum.io/rpc") - ); - setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); - setChainWithDefaultRpcUrl( - "polygon_mumbai", ChainData("Polygon Mumbai", 80001, "https://rpc-mumbai.maticvigil.com") - ); - setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); - setChainWithDefaultRpcUrl( - "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") - ); - setChainWithDefaultRpcUrl( - "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") - ); - setChainWithDefaultRpcUrl( - "bnb_smart_chain_testnet", - ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") - ); - setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); - } - - // set chain info, with priority to chainAlias' rpc url in foundry.toml - function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { - string memory rpcUrl = chain.rpcUrl; - defaultRpcUrls[chainAlias] = rpcUrl; - chain.rpcUrl = ""; - setChain(chainAlias, chain); - chain.rpcUrl = rpcUrl; // restore argument - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdCheats.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdCheats.sol deleted file mode 100644 index c1750c6..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdCheats.sol +++ /dev/null @@ -1,676 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {Vm} from "./Vm.sol"; -import {console2} from "./console2.sol"; - -abstract contract StdCheatsSafe { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - bool private gasMeteringOff; - - // Data structures to parse Transaction objects from the broadcast artifact - // that conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawTx1559 { - string[] arguments; - address contractAddress; - string contractName; - // json value name = function - string functionSig; - bytes32 hash; - // json value name = tx - RawTx1559Detail txDetail; - // json value name = type - string opcode; - } - - struct RawTx1559Detail { - AccessList[] accessList; - bytes data; - address from; - bytes gas; - bytes nonce; - address to; - bytes txType; - bytes value; - } - - struct Tx1559 { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - bytes32 hash; - Tx1559Detail txDetail; - string opcode; - } - - struct Tx1559Detail { - AccessList[] accessList; - bytes data; - address from; - uint256 gas; - uint256 nonce; - address to; - uint256 txType; - uint256 value; - } - - // Data structures to parse Transaction objects from the broadcast artifact - // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct TxLegacy { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - string hash; - string opcode; - TxDetailLegacy transaction; - } - - struct TxDetailLegacy { - AccessList[] accessList; - uint256 chainId; - bytes data; - address from; - uint256 gas; - uint256 gasPrice; - bytes32 hash; - uint256 nonce; - bytes1 opcode; - bytes32 r; - bytes32 s; - uint256 txType; - address to; - uint8 v; - uint256 value; - } - - struct AccessList { - address accessAddress; - bytes32[] storageKeys; - } - - // Data structures to parse Receipt objects from the broadcast artifact. - // The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawReceipt { - bytes32 blockHash; - bytes blockNumber; - address contractAddress; - bytes cumulativeGasUsed; - bytes effectiveGasPrice; - address from; - bytes gasUsed; - RawReceiptLog[] logs; - bytes logsBloom; - bytes status; - address to; - bytes32 transactionHash; - bytes transactionIndex; - } - - struct Receipt { - bytes32 blockHash; - uint256 blockNumber; - address contractAddress; - uint256 cumulativeGasUsed; - uint256 effectiveGasPrice; - address from; - uint256 gasUsed; - ReceiptLog[] logs; - bytes logsBloom; - uint256 status; - address to; - bytes32 transactionHash; - uint256 transactionIndex; - } - - // Data structures to parse the entire broadcast artifact, assuming the - // transactions conform to EIP1559. - - struct EIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - Receipt[] receipts; - uint256 timestamp; - Tx1559[] transactions; - TxReturn[] txReturns; - } - - struct RawEIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - RawReceipt[] receipts; - TxReturn[] txReturns; - uint256 timestamp; - RawTx1559[] transactions; - } - - struct RawReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - bytes blockNumber; - bytes data; - bytes logIndex; - bool removed; - bytes32[] topics; - bytes32 transactionHash; - bytes transactionIndex; - bytes transactionLogIndex; - } - - struct ReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - uint256 blockNumber; - bytes data; - uint256 logIndex; - bytes32[] topics; - uint256 transactionIndex; - uint256 transactionLogIndex; - bool removed; - } - - struct TxReturn { - string internalType; - string value; - } - - struct Account { - address addr; - uint256 key; - } - - // Checks that `addr` is not blacklisted by token contracts that have a blacklist. - function assumeNoBlacklisted(address token, address addr) internal virtual { - // Nothing to check if `token` is not a contract. - uint256 tokenCodeSize; - assembly { - tokenCodeSize := extcodesize(token) - } - require(tokenCodeSize > 0, "StdCheats assumeNoBlacklisted(address,address): Token address is not a contract."); - - bool success; - bytes memory returnData; - - // 4-byte selector for `isBlacklisted(address)`, used by USDC. - (success, returnData) = token.staticcall(abi.encodeWithSelector(0xfe575a87, addr)); - vm.assume(!success || abi.decode(returnData, (bool)) == false); - - // 4-byte selector for `isBlackListed(address)`, used by USDT. - (success, returnData) = token.staticcall(abi.encodeWithSelector(0xe47d6060, addr)); - vm.assume(!success || abi.decode(returnData, (bool)) == false); - } - - function assumeNoPrecompiles(address addr) internal virtual { - // Assembly required since `block.chainid` was introduced in 0.8.0. - uint256 chainId; - assembly { - chainId := chainid() - } - assumeNoPrecompiles(addr, chainId); - } - - function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual { - // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific - // address), but the same rationale for excluding them applies so we include those too. - - // These should be present on all EVM-compatible chains. - vm.assume(addr < address(0x1) || addr > address(0x9)); - - // forgefmt: disable-start - if (chainId == 10 || chainId == 420) { - // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 - vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); - } else if (chainId == 42161 || chainId == 421613) { - // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains - vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); - } else if (chainId == 43114 || chainId == 43113) { - // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 - vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); - vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); - vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); - } - // forgefmt: disable-end - } - - function readEIP1559ScriptArtifact(string memory path) - internal - view - virtual - returns (EIP1559ScriptArtifact memory) - { - string memory data = vm.readFile(path); - bytes memory parsedData = vm.parseJson(data); - RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); - EIP1559ScriptArtifact memory artifact; - artifact.libraries = rawArtifact.libraries; - artifact.path = rawArtifact.path; - artifact.timestamp = rawArtifact.timestamp; - artifact.pending = rawArtifact.pending; - artifact.txReturns = rawArtifact.txReturns; - artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); - artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); - return artifact; - } - - function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { - Tx1559[] memory txs = new Tx1559[](rawTxs.length); - for (uint256 i; i < rawTxs.length; i++) { - txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); - } - return txs; - } - - function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { - Tx1559 memory transaction; - transaction.arguments = rawTx.arguments; - transaction.contractName = rawTx.contractName; - transaction.functionSig = rawTx.functionSig; - transaction.hash = rawTx.hash; - transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); - transaction.opcode = rawTx.opcode; - return transaction; - } - - function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) - internal - pure - virtual - returns (Tx1559Detail memory) - { - Tx1559Detail memory txDetail; - txDetail.data = rawDetail.data; - txDetail.from = rawDetail.from; - txDetail.to = rawDetail.to; - txDetail.nonce = _bytesToUint(rawDetail.nonce); - txDetail.txType = _bytesToUint(rawDetail.txType); - txDetail.value = _bytesToUint(rawDetail.value); - txDetail.gas = _bytesToUint(rawDetail.gas); - txDetail.accessList = rawDetail.accessList; - return txDetail; - } - - function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); - RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); - return rawToConvertedEIPTx1559s(rawTxs); - } - - function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); - return rawToConvertedEIPTx1559(rawTx); - } - - // Analogous to readTransactions, but for receipts. - function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); - RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); - return rawToConvertedReceipts(rawReceipts); - } - - function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); - return rawToConvertedReceipt(rawReceipt); - } - - function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { - Receipt[] memory receipts = new Receipt[](rawReceipts.length); - for (uint256 i; i < rawReceipts.length; i++) { - receipts[i] = rawToConvertedReceipt(rawReceipts[i]); - } - return receipts; - } - - function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { - Receipt memory receipt; - receipt.blockHash = rawReceipt.blockHash; - receipt.to = rawReceipt.to; - receipt.from = rawReceipt.from; - receipt.contractAddress = rawReceipt.contractAddress; - receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); - receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); - receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); - receipt.status = _bytesToUint(rawReceipt.status); - receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); - receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); - receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); - receipt.logsBloom = rawReceipt.logsBloom; - receipt.transactionHash = rawReceipt.transactionHash; - return receipt; - } - - function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) - internal - pure - virtual - returns (ReceiptLog[] memory) - { - ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); - for (uint256 i; i < rawLogs.length; i++) { - logs[i].logAddress = rawLogs[i].logAddress; - logs[i].blockHash = rawLogs[i].blockHash; - logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); - logs[i].data = rawLogs[i].data; - logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); - logs[i].topics = rawLogs[i].topics; - logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); - logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); - logs[i].removed = rawLogs[i].removed; - } - return logs; - } - - // Deploy a contract by fetching the contract bytecode from - // the artifacts directory - // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` - function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); - } - - function deployCode(string memory what) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); - } - - /// @dev deploy contract with value on construction - function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); - } - - function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); - } - - // creates a labeled address and the corresponding private key - function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { - privateKey = uint256(keccak256(abi.encodePacked(name))); - addr = vm.addr(privateKey); - vm.label(addr, name); - } - - // creates a labeled address - function makeAddr(string memory name) internal virtual returns (address addr) { - (addr,) = makeAddrAndKey(name); - } - - // Destroys an account immediately, sending the balance to beneficiary. - // Destroying means: balance will be zero, code will be empty, and nonce will be 0 - // This is similar to selfdestruct but not identical: selfdestruct destroys code and nonce - // only after tx ends, this will run immediately. - function destroyAccount(address who, address beneficiary) internal virtual { - uint256 currBalance = who.balance; - vm.etch(who, abi.encode()); - vm.deal(who, 0); - vm.resetNonce(who); - - uint256 beneficiaryBalance = beneficiary.balance; - vm.deal(beneficiary, currBalance + beneficiaryBalance); - } - - // creates a struct containing both a labeled address and the corresponding private key - function makeAccount(string memory name) internal virtual returns (Account memory account) { - (account.addr, account.key) = makeAddrAndKey(name); - } - - function deriveRememberKey(string memory mnemonic, uint32 index) - internal - virtual - returns (address who, uint256 privateKey) - { - privateKey = vm.deriveKey(mnemonic, index); - who = vm.rememberKey(privateKey); - } - - function _bytesToUint(bytes memory b) private pure returns (uint256) { - require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); - return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); - } - - function isFork() internal view virtual returns (bool status) { - try vm.activeFork() { - status = true; - } catch (bytes memory) {} - } - - modifier skipWhenForking() { - if (!isFork()) { - _; - } - } - - modifier skipWhenNotForking() { - if (isFork()) { - _; - } - } - - modifier noGasMetering() { - vm.pauseGasMetering(); - // To prevent turning gas monitoring back on with nested functions that use this modifier, - // we check if gasMetering started in the off position. If it did, we don't want to turn - // it back on until we exit the top level function that used the modifier - // - // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. - // funcA will have `gasStartedOff` as false, funcB will have it as true, - // so we only turn metering back on at the end of the funcA - bool gasStartedOff = gasMeteringOff; - gasMeteringOff = true; - - _; - - // if gas metering was on when this modifier was called, turn it back on at the end - if (!gasStartedOff) { - gasMeteringOff = false; - vm.resumeGasMetering(); - } - } - - // a cheat for fuzzing addresses that are payable only - // see https://github.com/foundry-rs/foundry/issues/3631 - function assumePayable(address addr) internal virtual { - (bool success,) = payable(addr).call{value: 0}(""); - vm.assume(success); - } -} - -// Wrappers around cheatcodes to avoid footguns -abstract contract StdCheats is StdCheatsSafe { - using stdStorage for StdStorage; - - StdStorage private stdstore; - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - // Skip forward or rewind time by the specified number of seconds - function skip(uint256 time) internal virtual { - vm.warp(block.timestamp + time); - } - - function rewind(uint256 time) internal virtual { - vm.warp(block.timestamp - time); - } - - // Setup a prank from an address that has some ether - function hoax(address msgSender) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.prank(msgSender); - } - - function hoax(address msgSender, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.prank(msgSender); - } - - function hoax(address msgSender, address origin) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.prank(msgSender, origin); - } - - function hoax(address msgSender, address origin, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.prank(msgSender, origin); - } - - // Start perpetual prank from an address that has some ether - function startHoax(address msgSender) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.startPrank(msgSender); - } - - function startHoax(address msgSender, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.startPrank(msgSender); - } - - // Start perpetual prank from an address that has some ether - // tx.origin is set to the origin parameter - function startHoax(address msgSender, address origin) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.startPrank(msgSender, origin); - } - - function startHoax(address msgSender, address origin, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.startPrank(msgSender, origin); - } - - function changePrank(address msgSender) internal virtual { - vm.stopPrank(); - vm.startPrank(msgSender); - } - - function changePrank(address msgSender, address txOrigin) internal virtual { - vm.stopPrank(); - vm.startPrank(msgSender, txOrigin); - } - - // The same as Vm's `deal` - // Use the alternative signature for ERC20 tokens - function deal(address to, uint256 give) internal virtual { - vm.deal(to, give); - } - - // Set the balance of an account for any ERC20 token - // Use the alternative signature to update `totalSupply` - function deal(address token, address to, uint256 give) internal virtual { - deal(token, to, give, false); - } - - // Set the balance of an account for any ERC1155 token - // Use the alternative signature to update `totalSupply` - function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { - dealERC1155(token, to, id, give, false); - } - - function deal(address token, address to, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0x18160ddd)); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0x18160ddd).checked_write(totSup); - } - } - - function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x00fdd58e, to, id)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0xbd85b039, id)); - require( - totSupData.length != 0, - "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." - ); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); - } - } - - function dealERC721(address token, address to, uint256 id) internal virtual { - // check if token id is already minted and the actual owner. - (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); - require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); - - // get owner current balance - (, bytes memory fromBalData) = - token.staticcall(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); - uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); - - // get new user current balance - (, bytes memory toBalData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); - uint256 toPrevBal = abi.decode(toBalData, (uint256)); - - // update balances - stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); - - // update owner - stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdError.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdError.sol deleted file mode 100644 index a302191..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdError.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test -pragma solidity >=0.6.2 <0.9.0; - -library stdError { - bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); - bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); - bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); - bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); - bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); - bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); - bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); - bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); - bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdInvariant.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdInvariant.sol deleted file mode 100644 index efa1129..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdInvariant.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -contract StdInvariant { - struct FuzzSelector { - address addr; - bytes4[] selectors; - } - - address[] private _excludedContracts; - address[] private _excludedSenders; - address[] private _targetedContracts; - address[] private _targetedSenders; - - string[] private _excludedArtifacts; - string[] private _targetedArtifacts; - - FuzzSelector[] private _targetedArtifactSelectors; - FuzzSelector[] private _targetedSelectors; - - // Functions for users: - // These are intended to be called in tests. - - function excludeContract(address newExcludedContract_) internal { - _excludedContracts.push(newExcludedContract_); - } - - function excludeSender(address newExcludedSender_) internal { - _excludedSenders.push(newExcludedSender_); - } - - function excludeArtifact(string memory newExcludedArtifact_) internal { - _excludedArtifacts.push(newExcludedArtifact_); - } - - function targetArtifact(string memory newTargetedArtifact_) internal { - _targetedArtifacts.push(newTargetedArtifact_); - } - - function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal { - _targetedArtifactSelectors.push(newTargetedArtifactSelector_); - } - - function targetContract(address newTargetedContract_) internal { - _targetedContracts.push(newTargetedContract_); - } - - function targetSelector(FuzzSelector memory newTargetedSelector_) internal { - _targetedSelectors.push(newTargetedSelector_); - } - - function targetSender(address newTargetedSender_) internal { - _targetedSenders.push(newTargetedSender_); - } - - // Functions for forge: - // These are called by forge to run invariant tests and don't need to be called in tests. - - function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { - excludedArtifacts_ = _excludedArtifacts; - } - - function excludeContracts() public view returns (address[] memory excludedContracts_) { - excludedContracts_ = _excludedContracts; - } - - function excludeSenders() public view returns (address[] memory excludedSenders_) { - excludedSenders_ = _excludedSenders; - } - - function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { - targetedArtifacts_ = _targetedArtifacts; - } - - function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) { - targetedArtifactSelectors_ = _targetedArtifactSelectors; - } - - function targetContracts() public view returns (address[] memory targetedContracts_) { - targetedContracts_ = _targetedContracts; - } - - function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { - targetedSelectors_ = _targetedSelectors; - } - - function targetSenders() public view returns (address[] memory targetedSenders_) { - targetedSenders_ = _targetedSenders; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdJson.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdJson.sol deleted file mode 100644 index 014e6b1..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdJson.sol +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.0 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {VmSafe} from "./Vm.sol"; - -// Helpers for parsing and writing JSON files -// To parse: -// ``` -// using stdJson for string; -// string memory json = vm.readFile("some_peth"); -// json.parseUint(""); -// ``` -// To write: -// ``` -// using stdJson for string; -// string memory json = "deploymentArtifact"; -// Contract contract = new Contract(); -// json.serialize("contractAddress", address(contract)); -// json = json.serialize("deploymentTimes", uint(1)); -// // store the stringified JSON to the 'json' variable we have been using as a key -// // as we won't need it any longer -// string memory json2 = "finalArtifact"; -// string memory final = json2.serialize("depArtifact", json); -// final.write(""); -// ``` - -library stdJson { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { - return vm.parseJson(json, key); - } - - function readUint(string memory json, string memory key) internal returns (uint256) { - return vm.parseJsonUint(json, key); - } - - function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) { - return vm.parseJsonUintArray(json, key); - } - - function readInt(string memory json, string memory key) internal returns (int256) { - return vm.parseJsonInt(json, key); - } - - function readIntArray(string memory json, string memory key) internal returns (int256[] memory) { - return vm.parseJsonIntArray(json, key); - } - - function readBytes32(string memory json, string memory key) internal returns (bytes32) { - return vm.parseJsonBytes32(json, key); - } - - function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) { - return vm.parseJsonBytes32Array(json, key); - } - - function readString(string memory json, string memory key) internal returns (string memory) { - return vm.parseJsonString(json, key); - } - - function readStringArray(string memory json, string memory key) internal returns (string[] memory) { - return vm.parseJsonStringArray(json, key); - } - - function readAddress(string memory json, string memory key) internal returns (address) { - return vm.parseJsonAddress(json, key); - } - - function readAddressArray(string memory json, string memory key) internal returns (address[] memory) { - return vm.parseJsonAddressArray(json, key); - } - - function readBool(string memory json, string memory key) internal returns (bool) { - return vm.parseJsonBool(json, key); - } - - function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) { - return vm.parseJsonBoolArray(json, key); - } - - function readBytes(string memory json, string memory key) internal returns (bytes memory) { - return vm.parseJsonBytes(json, key); - } - - function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) { - return vm.parseJsonBytesArray(json, key); - } - - function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bool[] memory value) - internal - returns (string memory) - { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256[] memory value) - internal - returns (string memory) - { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256[] memory value) - internal - returns (string memory) - { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address[] memory value) - internal - returns (string memory) - { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string[] memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function write(string memory jsonKey, string memory path) internal { - vm.writeJson(jsonKey, path); - } - - function write(string memory jsonKey, string memory path, string memory valueKey) internal { - vm.writeJson(jsonKey, path, valueKey); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdMath.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdMath.sol deleted file mode 100644 index 459523b..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdMath.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -library stdMath { - int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; - - function abs(int256 a) internal pure returns (uint256) { - // Required or it will fail when `a = type(int256).min` - if (a == INT256_MIN) { - return 57896044618658097711785492504343953926634992332820282019728792003956564819968; - } - - return uint256(a > 0 ? a : -a); - } - - function delta(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? a - b : b - a; - } - - function delta(int256 a, int256 b) internal pure returns (uint256) { - // a and b are of the same sign - // this works thanks to two's complement, the left-most bit is the sign bit - if ((a ^ b) > -1) { - return delta(abs(a), abs(b)); - } - - // a and b are of opposite signs - return abs(a) + abs(b); - } - - function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - - return absDelta * 1e18 / b; - } - - function percentDelta(int256 a, int256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - uint256 absB = abs(b); - - return absDelta * 1e18 / absB; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdStorage.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdStorage.sol deleted file mode 100644 index 73a5ceb..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdStorage.sol +++ /dev/null @@ -1,327 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {Vm} from "./Vm.sol"; - -struct StdStorage { - mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; - mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds; - bytes32[] _keys; - bytes4 _sig; - uint256 _depth; - address _target; - bytes32 _set; -} - -library stdStorageSafe { - event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); - event WARNING_UninitedSlot(address who, uint256 slot); - - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return bytes4(keccak256(bytes(sigStr))); - } - - /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against - // slot complexity: - // if flat, will be bytes32(uint256(uint)); - // if map, will be keccak256(abi.encode(key, uint(slot))); - // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); - // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); - function find(StdStorage storage self) internal returns (uint256) { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - // calldata to test against - if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - vm.record(); - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - (bytes32[] memory reads,) = vm.accesses(address(who)); - if (reads.length == 1) { - bytes32 curr = vm.load(who, reads[0]); - if (curr == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[0])); - } - if (fdat != curr) { - require( - false, - "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." - ); - } - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - } else if (reads.length > 1) { - for (uint256 i = 0; i < reads.length; i++) { - bytes32 prev = vm.load(who, reads[i]); - if (prev == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[i])); - } - // store - vm.store(who, reads[i], bytes32(hex"1337")); - bool success; - bytes memory rdat; - { - (success, rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - if (success && fdat == bytes32(hex"1337")) { - // we found which of the slots is the actual one - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - vm.store(who, reads[i], prev); - break; - } - vm.store(who, reads[i], prev); - } - } else { - revert("stdStorage find(StdStorage): No storage use detected for target."); - } - - require( - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], - "stdStorage find(StdStorage): Slot(s) not found." - ); - - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - self._target = _target; - return self; - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - self._sig = _sig; - return self; - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - self._sig = sigs(_sig); - return self; - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - self._keys.push(bytes32(uint256(uint160(who)))); - return self; - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - self._keys.push(bytes32(amt)); - return self; - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - self._keys.push(key); - return self; - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - self._depth = _depth; - return self; - } - - function read(StdStorage storage self) private returns (bytes memory) { - address t = self._target; - uint256 s = find(self); - return abi.encode(vm.load(t, bytes32(s))); - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return abi.decode(read(self), (bytes32)); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - int256 v = read_int(self); - if (v == 0) return false; - if (v == 1) return true; - revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - } - - function read_address(StdStorage storage self) internal returns (address) { - return abi.decode(read(self), (address)); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return abi.decode(read(self), (uint256)); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return abi.decode(read(self), (int256)); - } - - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} - -library stdStorage { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return stdStorageSafe.sigs(sigStr); - } - - function find(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.find(self); - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - return stdStorageSafe.target(self, _target); - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, who); - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, amt); - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, key); - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - return stdStorageSafe.depth(self, _depth); - } - - function checked_write(StdStorage storage self, address who) internal { - checked_write(self, bytes32(uint256(uint160(who)))); - } - - function checked_write(StdStorage storage self, uint256 amt) internal { - checked_write(self, bytes32(amt)); - } - - function checked_write(StdStorage storage self, bool write) internal { - bytes32 t; - /// @solidity memory-safe-assembly - assembly { - t := write - } - checked_write(self, t); - } - - function checked_write(StdStorage storage self, bytes32 set) internal { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - find(self); - } - bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]); - - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - bytes32 curr = vm.load(who, slot); - - if (fdat != curr) { - require( - false, - "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." - ); - } - vm.store(who, slot, set); - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return stdStorageSafe.read_bytes32(self); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - return stdStorageSafe.read_bool(self); - } - - function read_address(StdStorage storage self) internal returns (address) { - return stdStorageSafe.read_address(self); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.read_uint(self); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return stdStorageSafe.read_int(self); - } - - // Private function so needs to be copied over - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - // Private function so needs to be copied over - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdStyle.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdStyle.sol deleted file mode 100644 index 46f4e81..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdStyle.sol +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -import {Vm} from "./Vm.sol"; - -library StdStyle { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - string constant RED = "\u001b[91m"; - string constant GREEN = "\u001b[92m"; - string constant YELLOW = "\u001b[93m"; - string constant BLUE = "\u001b[94m"; - string constant MAGENTA = "\u001b[95m"; - string constant CYAN = "\u001b[96m"; - string constant BOLD = "\u001b[1m"; - string constant DIM = "\u001b[2m"; - string constant ITALIC = "\u001b[3m"; - string constant UNDERLINE = "\u001b[4m"; - string constant INVERSE = "\u001b[7m"; - string constant RESET = "\u001b[0m"; - - function styleConcat(string memory style, string memory self) private pure returns (string memory) { - return string(abi.encodePacked(style, self, RESET)); - } - - function red(string memory self) internal pure returns (string memory) { - return styleConcat(RED, self); - } - - function red(uint256 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(int256 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(address self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(bool self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function redBytes(bytes memory self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function redBytes32(bytes32 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function green(string memory self) internal pure returns (string memory) { - return styleConcat(GREEN, self); - } - - function green(uint256 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(int256 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(address self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(bool self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function greenBytes(bytes memory self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function greenBytes32(bytes32 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function yellow(string memory self) internal pure returns (string memory) { - return styleConcat(YELLOW, self); - } - - function yellow(uint256 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(int256 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(address self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(bool self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellowBytes(bytes memory self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellowBytes32(bytes32 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function blue(string memory self) internal pure returns (string memory) { - return styleConcat(BLUE, self); - } - - function blue(uint256 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(int256 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(address self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(bool self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blueBytes(bytes memory self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blueBytes32(bytes32 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function magenta(string memory self) internal pure returns (string memory) { - return styleConcat(MAGENTA, self); - } - - function magenta(uint256 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(int256 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(address self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(bool self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magentaBytes(bytes memory self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magentaBytes32(bytes32 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function cyan(string memory self) internal pure returns (string memory) { - return styleConcat(CYAN, self); - } - - function cyan(uint256 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(int256 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(address self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(bool self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyanBytes(bytes memory self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyanBytes32(bytes32 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function bold(string memory self) internal pure returns (string memory) { - return styleConcat(BOLD, self); - } - - function bold(uint256 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(int256 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(address self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(bool self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function boldBytes(bytes memory self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function boldBytes32(bytes32 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function dim(string memory self) internal pure returns (string memory) { - return styleConcat(DIM, self); - } - - function dim(uint256 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(int256 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(address self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(bool self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dimBytes(bytes memory self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dimBytes32(bytes32 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function italic(string memory self) internal pure returns (string memory) { - return styleConcat(ITALIC, self); - } - - function italic(uint256 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(int256 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(address self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(bool self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italicBytes(bytes memory self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italicBytes32(bytes32 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function underline(string memory self) internal pure returns (string memory) { - return styleConcat(UNDERLINE, self); - } - - function underline(uint256 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(int256 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(address self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(bool self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underlineBytes(bytes memory self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underlineBytes32(bytes32 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function inverse(string memory self) internal pure returns (string memory) { - return styleConcat(INVERSE, self); - } - - function inverse(uint256 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(int256 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(address self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(bool self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverseBytes(bytes memory self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverseBytes32(bytes32 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdUtils.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdUtils.sol deleted file mode 100644 index d67025c..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/StdUtils.sol +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {IMulticall3} from "./interfaces/IMulticall3.sol"; -import {VmSafe} from "./Vm.sol"; - -abstract contract StdUtils { - /*////////////////////////////////////////////////////////////////////////// - CONSTANTS - //////////////////////////////////////////////////////////////////////////*/ - - IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; - uint256 private constant INT256_MIN_ABS = - 57896044618658097711785492504343953926634992332820282019728792003956564819968; - uint256 private constant SECP256K1_ORDER = - 115792089237316195423570985008687907852837564279074904382605163141518161494337; - uint256 private constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. - address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - - /*////////////////////////////////////////////////////////////////////////// - INTERNAL FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { - require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); - // If x is between min and max, return x directly. This is to ensure that dictionary values - // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 - if (x >= min && x <= max) return x; - - uint256 size = max - min + 1; - - // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. - // This helps ensure coverage of the min/max values. - if (x <= 3 && size > x) return min + x; - if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); - - // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. - if (x > max) { - uint256 diff = x - max; - uint256 rem = diff % size; - if (rem == 0) return max; - result = min + rem - 1; - } else if (x < min) { - uint256 diff = min - x; - uint256 rem = diff % size; - if (rem == 0) return min; - result = max - rem + 1; - } - } - - function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) { - result = _bound(x, min, max); - console2_log("Bound Result", result); - } - - function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { - require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); - - // Shifting all int256 values to uint256 to use _bound function. The range of two types are: - // int256 : -(2**255) ~ (2**255 - 1) - // uint256: 0 ~ (2**256 - 1) - // So, add 2**255, INT256_MIN_ABS to the integer values. - // - // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. - // So, use `~uint256(x) + 1` instead. - uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); - uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); - uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); - - uint256 y = _bound(_x, _min, _max); - - // To move it back to int256 value, subtract INT256_MIN_ABS at here. - result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); - } - - function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) { - result = _bound(x, min, max); - console2_log("Bound result", vm.toString(result)); - } - - function boundPrivateKey(uint256 privateKey) internal view virtual returns (uint256 result) { - result = _bound(privateKey, 1, SECP256K1_ORDER - 1); - } - - function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { - require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); - return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); - } - - /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce - /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol) - function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { - // forgefmt: disable-start - // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0. - // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it. - if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))); - if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))); - - // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length. - if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))); - if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))); - if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)))); - // forgefmt: disable-end - - // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp - // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) - // We assume nobody can have a nonce large enough to require more than 32 bytes. - return addressFromLast20Bytes( - keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) - ); - } - - function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) - internal - pure - virtual - returns (address) - { - return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash))); - } - - /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { - return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY); - } - - /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments - /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode - function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { - return hashInitCode(creationCode, ""); - } - - /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 - /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode - /// @param args the ABI-encoded arguments to the constructor of C - function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(creationCode, args)); - } - - // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. - function getTokenBalances(address token, address[] memory addresses) - internal - virtual - returns (uint256[] memory balances) - { - uint256 tokenCodeSize; - assembly { - tokenCodeSize := extcodesize(token) - } - require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); - - // ABI encode the aggregate call to Multicall3. - uint256 length = addresses.length; - IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); - for (uint256 i = 0; i < length; ++i) { - // 0x70a08231 = bytes4("balanceOf(address)")) - calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); - } - - // Make the aggregate call. - (, bytes[] memory returnData) = multicall.aggregate(calls); - - // ABI decode the return data and return the balances. - balances = new uint256[](length); - for (uint256 i = 0; i < length; ++i) { - balances[i] = abi.decode(returnData[i], (uint256)); - } - } - - /*////////////////////////////////////////////////////////////////////////// - PRIVATE FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { - return address(uint160(uint256(bytesValue))); - } - - // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. - - function console2_log(string memory p0, uint256 p1) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - status; - } - - function console2_log(string memory p0, string memory p1) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,string)", p0, p1)); - status; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Test.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Test.sol deleted file mode 100644 index 9ff5cb8..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Test.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -// 💬 ABOUT -// Standard Library's default Test - -// 🧩 MODULES -import {console} from "./console.sol"; -import {console2} from "./console2.sol"; -import {StdAssertions} from "./StdAssertions.sol"; -import {StdChains} from "./StdChains.sol"; -import {StdCheats} from "./StdCheats.sol"; -import {stdError} from "./StdError.sol"; -import {StdInvariant} from "./StdInvariant.sol"; -import {stdJson} from "./StdJson.sol"; -import {stdMath} from "./StdMath.sol"; -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {Vm} from "./Vm.sol"; -import {StdStyle} from "./StdStyle.sol"; - -// 📦 BOILERPLATE -import {TestBase} from "./Base.sol"; -import {DSTest} from "ds-test/test.sol"; - -// ⭐️ TEST -abstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase { -// Note: IS_TEST() must return true. -// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76. -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Vm.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Vm.sol deleted file mode 100644 index f919e6d..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/Vm.sol +++ /dev/null @@ -1,502 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -// Cheatcodes are marked as view/pure/none using the following rules: -// 0. A call's observable behaviour includes its return value, logs, reverts and state writes, -// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc), -// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`, -// 3. Otherwise you're `pure`. - -interface VmSafe { - struct Log { - bytes32[] topics; - bytes data; - address emitter; - } - - struct Rpc { - string key; - string url; - } - - struct DirEntry { - string errorMessage; - string path; - uint64 depth; - bool isDir; - bool isSymlink; - } - - struct FsMetadata { - bool isDir; - bool isSymlink; - uint256 length; - bool readOnly; - uint256 modified; - uint256 accessed; - uint256 created; - } - - // Loads a storage slot from an address - function load(address target, bytes32 slot) external view returns (bytes32 data); - // Signs data - function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - // Gets the address for a given private key - function addr(uint256 privateKey) external pure returns (address keyAddr); - // Gets the nonce of an account - function getNonce(address account) external view returns (uint64 nonce); - // Performs a foreign function call via the terminal - function ffi(string[] calldata commandInput) external returns (bytes memory result); - // Sets environment variables - function setEnv(string calldata name, string calldata value) external; - // Reads environment variables, (name) => (value) - function envBool(string calldata name) external view returns (bool value); - function envUint(string calldata name) external view returns (uint256 value); - function envInt(string calldata name) external view returns (int256 value); - function envAddress(string calldata name) external view returns (address value); - function envBytes32(string calldata name) external view returns (bytes32 value); - function envString(string calldata name) external view returns (string memory value); - function envBytes(string calldata name) external view returns (bytes memory value); - // Reads environment variables as arrays - function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); - function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); - function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); - function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); - function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); - function envString(string calldata name, string calldata delim) external view returns (string[] memory value); - function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); - // Read environment variables with default value - function envOr(string calldata name, bool defaultValue) external returns (bool value); - function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value); - function envOr(string calldata name, int256 defaultValue) external returns (int256 value); - function envOr(string calldata name, address defaultValue) external returns (address value); - function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value); - function envOr(string calldata name, string calldata defaultValue) external returns (string memory value); - function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value); - // Read environment variables as arrays with default value - function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) - external - returns (bool[] memory value); - function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) - external - returns (uint256[] memory value); - function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) - external - returns (int256[] memory value); - function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) - external - returns (address[] memory value); - function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) - external - returns (bytes32[] memory value); - function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) - external - returns (string[] memory value); - function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) - external - returns (bytes[] memory value); - // Records all storage reads and writes - function record() external; - // Gets all accessed reads and write slot from a recording session, for a given address - function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); - // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file - function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); - // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file - function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); - // Labels an address in call traces - function label(address account, string calldata newLabel) external; - // Gets the label for the specified address - function getLabel(address account) external returns (string memory label); - // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain - function broadcast() external; - // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain - function broadcast(address signer) external; - // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain - function broadcast(uint256 privateKey) external; - // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain - function startBroadcast() external; - // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain - function startBroadcast(address signer) external; - // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain - function startBroadcast(uint256 privateKey) external; - // Stops collecting onchain transactions - function stopBroadcast() external; - - // Get the path of the current project root. - function projectRoot() external view returns (string memory path); - // Reads the entire content of file to string. `path` is relative to the project root. - function readFile(string calldata path) external view returns (string memory data); - // Reads the entire content of file as binary. `path` is relative to the project root. - function readFileBinary(string calldata path) external view returns (bytes memory data); - // Reads next line of file to string. - function readLine(string calldata path) external view returns (string memory line); - // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. - // `path` is relative to the project root. - function writeFile(string calldata path, string calldata data) external; - // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. - // `path` is relative to the project root. - function writeFileBinary(string calldata path, bytes calldata data) external; - // Writes line to file, creating a file if it does not exist. - // `path` is relative to the project root. - function writeLine(string calldata path, string calldata data) external; - // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. - // `path` is relative to the project root. - function closeFile(string calldata path) external; - // Removes a file from the filesystem. - // This cheatcode will revert in the following situations, but is not limited to just these cases: - // - `path` points to a directory. - // - The file doesn't exist. - // - The user lacks permissions to remove the file. - // `path` is relative to the project root. - function removeFile(string calldata path) external; - // Creates a new, empty directory at the provided path. - // This cheatcode will revert in the following situations, but is not limited to just these cases: - // - User lacks permissions to modify `path`. - // - A parent of the given path doesn't exist and `recursive` is false. - // - `path` already exists and `recursive` is false. - // `path` is relative to the project root. - function createDir(string calldata path, bool recursive) external; - // Removes a directory at the provided path. - // This cheatcode will revert in the following situations, but is not limited to just these cases: - // - `path` doesn't exist. - // - `path` isn't a directory. - // - User lacks permissions to modify `path`. - // - The directory is not empty and `recursive` is false. - // `path` is relative to the project root. - function removeDir(string calldata path, bool recursive) external; - // Reads the directory at the given path recursively, up to `max_depth`. - // `max_depth` defaults to 1, meaning only the direct children of the given directory will be returned. - // Follows symbolic links if `follow_links` is true. - function readDir(string calldata path) external view returns (DirEntry[] memory entries); - function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); - function readDir(string calldata path, uint64 maxDepth, bool followLinks) - external - view - returns (DirEntry[] memory entries); - // Reads a symbolic link, returning the path that the link points to. - // This cheatcode will revert in the following situations, but is not limited to just these cases: - // - `path` is not a symbolic link. - // - `path` does not exist. - function readLink(string calldata linkPath) external view returns (string memory targetPath); - // Given a path, query the file system to get information about a file, directory, etc. - function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); - - // Convert values to a string - function toString(address value) external pure returns (string memory stringifiedValue); - function toString(bytes calldata value) external pure returns (string memory stringifiedValue); - function toString(bytes32 value) external pure returns (string memory stringifiedValue); - function toString(bool value) external pure returns (string memory stringifiedValue); - function toString(uint256 value) external pure returns (string memory stringifiedValue); - function toString(int256 value) external pure returns (string memory stringifiedValue); - // Convert values from a string - function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); - function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); - function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); - function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); - function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); - function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); - // Record all the transaction logs - function recordLogs() external; - // Gets all the recorded logs - function getRecordedLogs() external returns (Log[] memory logs); - // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index} - function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); - // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index} - function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) - external - pure - returns (uint256 privateKey); - // Adds a private key to the local forge wallet and returns the address - function rememberKey(uint256 privateKey) external returns (address keyAddr); - // - // parseJson - // - // ---- - // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects - // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in - // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that - // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded - // as tuples, with the attributes in the order in which they are defined. - // For example: json = { 'a': 1, 'b': 0xa4tb......3xs} - // a: uint256 - // b: address - // To decode that json, we need to define a struct or a tuple as follows: - // struct json = { uint256 a; address b; } - // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to - // decode the tuple in that order, and thus fail. - // ---- - // Given a string of JSON, return it as ABI-encoded - function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); - function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); - - // The following parseJson cheatcodes will do type coercion, for the type that they indicate. - // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12' - // and hex numbers '0xEF'. - // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not - // a JSON object. - function parseJsonUint(string calldata, string calldata) external returns (uint256); - function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory); - function parseJsonInt(string calldata, string calldata) external returns (int256); - function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory); - function parseJsonBool(string calldata, string calldata) external returns (bool); - function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory); - function parseJsonAddress(string calldata, string calldata) external returns (address); - function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory); - function parseJsonString(string calldata, string calldata) external returns (string memory); - function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory); - function parseJsonBytes(string calldata, string calldata) external returns (bytes memory); - function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory); - function parseJsonBytes32(string calldata, string calldata) external returns (bytes32); - function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory); - - // Serialize a key and value to a JSON object stored in-memory that can be later written to a file - // It returns the stringified version of the specific JSON file up to that moment. - function serializeBool(string calldata objectKey, string calldata valueKey, bool value) - external - returns (string memory json); - function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) - external - returns (string memory json); - function serializeAddress(string calldata objectKey, string calldata valueKey, address value) - external - returns (string memory json); - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) - external - returns (string memory json); - function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) - external - returns (string memory json); - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) - external - returns (string memory json); - - function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) - external - returns (string memory json); - function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) - external - returns (string memory json); - function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) - external - returns (string memory json); - function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) - external - returns (string memory json); - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) - external - returns (string memory json); - function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) - external - returns (string memory json); - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) - external - returns (string memory json); - - // - // writeJson - // - // ---- - // Write a serialized JSON object to a file. If the file exists, it will be overwritten. - // Let's assume we want to write the following JSON to a file: - // - // { "boolean": true, "number": 342, "object": { "title": "finally json serialization" } } - // - // ``` - // string memory json1 = "some key"; - // vm.serializeBool(json1, "boolean", true); - // vm.serializeBool(json1, "number", uint256(342)); - // json2 = "some other key"; - // string memory output = vm.serializeString(json2, "title", "finally json serialization"); - // string memory finalJson = vm.serialize(json1, "object", output); - // vm.writeJson(finalJson, "./output/example.json"); - // ``` - // The critical insight is that every invocation of serialization will return the stringified version of the JSON - // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version - // to serialize them as values to another JSON object. - // - // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..) - // will find the object in-memory that is keyed by "some key". - function writeJson(string calldata json, string calldata path) external; - // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = - // This is useful to replace a specific value of a JSON file, without having to parse the entire thing - function writeJson(string calldata json, string calldata path, string calldata valueKey) external; - // Returns the RPC url for the given alias - function rpcUrl(string calldata rpcAlias) external view returns (string memory json); - // Returns all rpc urls and their aliases `[alias, url][]` - function rpcUrls() external view returns (string[2][] memory urls); - // Returns all rpc urls and their aliases as structs. - function rpcUrlStructs() external view returns (Rpc[] memory urls); - // If the condition is false, discard this run's fuzz inputs and generate new ones. - function assume(bool condition) external pure; - // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. - function pauseGasMetering() external; - // Resumes gas metering (i.e. gas usage is counted again). Noop if already on. - function resumeGasMetering() external; - // Writes a breakpoint to jump to in the debugger - function breakpoint(string calldata char) external; - // Writes a conditional breakpoint to jump to in the debugger - function breakpoint(string calldata char, bool value) external; -} - -interface Vm is VmSafe { - // Sets block.timestamp - function warp(uint256 newTimestamp) external; - // Sets block.height - function roll(uint256 newHeight) external; - // Sets block.basefee - function fee(uint256 newBasefee) external; - // Sets block.difficulty - // Not available on EVM versions from Paris onwards. Use `prevrandao` instead. - // If used on unsupported EVM versions it will revert. - function difficulty(uint256 newDifficulty) external; - // Sets block.prevrandao - // Not available on EVM versions before Paris. Use `difficulty` instead. - // If used on unsupported EVM versions it will revert. - function prevrandao(bytes32 newPrevrandao) external; - // Sets block.chainid - function chainId(uint256 newChainId) external; - // Sets tx.gasprice - function txGasPrice(uint256 newGasPrice) external; - // Stores a value to an address' storage slot. - function store(address target, bytes32 slot, bytes32 value) external; - // Sets the nonce of an account; must be higher than the current nonce of the account - function setNonce(address account, uint64 newNonce) external; - // Sets the nonce of an account to an arbitrary value - function setNonceUnsafe(address account, uint64 newNonce) external; - // Resets the nonce of an account to 0 for EOAs and 1 for contract accounts - function resetNonce(address account) external; - // Sets the *next* call's msg.sender to be the input address - function prank(address msgSender) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called - function startPrank(address msgSender) external; - // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input - function prank(address msgSender, address txOrigin) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input - function startPrank(address msgSender, address txOrigin) external; - // Resets subsequent calls' msg.sender to be `address(this)` - function stopPrank() external; - // Sets an address' balance - function deal(address account, uint256 newBalance) external; - // Sets an address' code - function etch(address target, bytes calldata newRuntimeBytecode) external; - // Expects an error on next call - function expectRevert(bytes calldata revertData) external; - function expectRevert(bytes4 revertData) external; - function expectRevert() external; - - // Prepare an expected log with all four checks enabled. - // Call this function, then emit an event, then call a function. Internally after the call, we check if - // logs were emitted in the expected order with the expected topics and data. - // Second form also checks supplied address against emitting contract. - function expectEmit() external; - function expectEmit(address emitter) external; - - // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). - // Call this function, then emit an event, then call a function. Internally after the call, we check if - // logs were emitted in the expected order with the expected topics and data (as specified by the booleans). - // Second form also checks supplied address against emitting contract. - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) - external; - - // Mocks a call to an address, returning specified data. - // Calldata can either be strict or a partial match, e.g. if you only - // pass a Solidity selector to the expected calldata, then the entire Solidity - // function will be mocked. - function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; - // Mocks a call to an address with a specific msg.value, returning specified data. - // Calldata match takes precedence over msg.value in case of ambiguity. - function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; - // Reverts a call to an address with specified revert data. - function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; - // Reverts a call to an address with a specific msg.value, with specified revert data. - function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) - external; - // Clears all mocked calls - function clearMockedCalls() external; - // Expects a call to an address with the specified calldata. - // Calldata can either be a strict or a partial match - function expectCall(address callee, bytes calldata data) external; - // Expects given number of calls to an address with the specified calldata. - function expectCall(address callee, bytes calldata data, uint64 count) external; - // Expects a call to an address with the specified msg.value and calldata - function expectCall(address callee, uint256 msgValue, bytes calldata data) external; - // Expects given number of calls to an address with the specified msg.value and calldata - function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; - // Expect a call to an address with the specified msg.value, gas, and calldata. - function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; - // Expects given number of calls to an address with the specified msg.value, gas, and calldata. - function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; - // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas. - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; - // Expect given number of calls to an address with the specified msg.value and calldata, and a *minimum* amount of gas. - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) - external; - // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other - // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. - function expectSafeMemory(uint64 min, uint64 max) external; - // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. - // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges - // to the set. - function expectSafeMemoryCall(uint64 min, uint64 max) external; - // Sets block.coinbase - function coinbase(address newCoinbase) external; - // Snapshot the current state of the evm. - // Returns the id of the snapshot that was created. - // To revert a snapshot use `revertTo` - function snapshot() external returns (uint256 snapshotId); - // Revert the state of the EVM to a previous snapshot - // Takes the snapshot id to revert to. - // This deletes the snapshot and all snapshots taken after the given snapshot id. - function revertTo(uint256 snapshotId) external returns (bool success); - // Creates a new fork with the given endpoint and block and returns the identifier of the fork - function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); - // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork - function createFork(string calldata urlOrAlias) external returns (uint256 forkId); - // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction, - // and returns the identifier of the fork - function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); - // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); - // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before - // the transaction, returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); - // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); - // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. - function selectFork(uint256 forkId) external; - /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. - function activeFork() external view returns (uint256 forkId); - // Updates the currently active fork to given block number - // This is similar to `roll` but for the currently active fork - function rollFork(uint256 blockNumber) external; - // Updates the currently active fork to given transaction - // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block - function rollFork(bytes32 txHash) external; - // Updates the given fork to given block number - function rollFork(uint256 forkId, uint256 blockNumber) external; - // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block - function rollFork(uint256 forkId, bytes32 txHash) external; - // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup - // Meaning, changes made to the state of this account will be kept when switching forks - function makePersistent(address account) external; - function makePersistent(address account0, address account1) external; - function makePersistent(address account0, address account1, address account2) external; - function makePersistent(address[] calldata accounts) external; - // Revokes persistent status from the address, previously added via `makePersistent` - function revokePersistent(address account) external; - function revokePersistent(address[] calldata accounts) external; - // Returns true if the account is marked as persistent - function isPersistent(address account) external view returns (bool persistent); - // In forking mode, explicitly grant the given address cheatcode access - function allowCheatcodes(address account) external; - // Fetches the given transaction from the active fork and executes it on the current state - function transact(bytes32 txHash) external; - // Fetches the given transaction from the given fork and executes it on the current state - function transact(uint256 forkId, bytes32 txHash) external; -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/console.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/console.sol deleted file mode 100644 index ad57e53..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/console.sol +++ /dev/null @@ -1,1533 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -library console { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _sendLogPayload(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal view { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); - } - - function logUint(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function logString(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function log(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); - } - - function log(uint p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); - } - - function log(uint p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); - } - - function log(uint p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); - } - - function log(string memory p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); - } - - function log(bool p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); - } - - function log(address p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); - } - - function log(uint p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); - } - - function log(uint p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); - } - - function log(uint p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); - } - - function log(uint p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); - } - - function log(uint p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); - } - - function log(uint p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); - } - - function log(uint p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); - } - - function log(uint p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); - } - - function log(uint p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); - } - - function log(uint p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); - } - - function log(uint p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); - } - - function log(bool p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); - } - - function log(bool p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); - } - - function log(bool p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); - } - - function log(address p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); - } - - function log(address p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); - } - - function log(address p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/console2.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/console2.sol deleted file mode 100644 index c1e2cd7..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/console2.sol +++ /dev/null @@ -1,1558 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should -/// use `int256` and `uint256`. This modified version fixes that. This version is recommended -/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in -/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`. -/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178 -library console2 { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _castLogPayloadViewToPure( - function(bytes memory) internal view fnIn - ) internal pure returns (function(bytes memory) internal pure fnOut) { - assembly { - fnOut := fnIn - } - } - - function _sendLogPayload(bytes memory payload) internal pure { - _castLogPayloadViewToPure(_sendLogPayloadView)(payload); - } - - function _sendLogPayloadView(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal pure { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function logUint(uint256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function logString(string memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function log(int256 p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function log(string memory p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint256 p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); - } - - function log(uint256 p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); - } - - function log(uint256 p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); - } - - function log(uint256 p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); - } - - function log(string memory p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - } - - function log(string memory p0, int256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); - } - - function log(bool p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint256 p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); - } - - function log(address p0, string memory p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint256 p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint256 p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint256 p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal pure { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC1155.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC1155.sol deleted file mode 100644 index f7dd2b4..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC1155.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC165.sol"; - -/// @title ERC-1155 Multi Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-1155 -/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. -interface IERC1155 is IERC165 { - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_id` argument MUST be the token type being transferred. - /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferSingle( - address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value - ); - - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_ids` argument MUST be the list of tokens being transferred. - /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferBatch( - address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values - ); - - /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. - /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". - event URI(string _value, uint256 indexed _id); - - /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. - /// - MUST revert on any other error. - /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). - /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _id ID of the token type - /// @param _value Transfer amount - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` - function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; - - /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if length of `_ids` is not the same as length of `_values`. - /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. - /// - MUST revert on any other error. - /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). - /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). - /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _ids IDs of each token type (order and length must match _values array) - /// @param _values Transfer amounts per token type (order and length must match _ids array) - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` - function safeBatchTransferFrom( - address _from, - address _to, - uint256[] calldata _ids, - uint256[] calldata _values, - bytes calldata _data - ) external; - - /// @notice Get the balance of an account's tokens. - /// @param _owner The address of the token holder - /// @param _id ID of the token - /// @return The _owner's balance of the token type requested - function balanceOf(address _owner, uint256 _id) external view returns (uint256); - - /// @notice Get the balance of multiple account/token pairs - /// @param _owners The addresses of the token holders - /// @param _ids ID of the tokens - /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) - function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) - external - view - returns (uint256[] memory); - - /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. - /// @dev MUST emit the ApprovalForAll event on success. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Queries the approval status of an operator for a given owner. - /// @param _owner The owner of the tokens - /// @param _operator Address of authorized operator - /// @return True if the operator is approved, false if not - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC165.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC165.sol deleted file mode 100644 index 9af4bf8..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC165.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -interface IERC165 { - /// @notice Query if a contract implements an interface - /// @param interfaceID The interface identifier, as specified in ERC-165 - /// @dev Interface identification is specified in ERC-165. This function - /// uses less than 30,000 gas. - /// @return `true` if the contract implements `interfaceID` and - /// `interfaceID` is not 0xffffffff, `false` otherwise - function supportsInterface(bytes4 interfaceID) external view returns (bool); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC20.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC20.sol deleted file mode 100644 index ba40806..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC20.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -/// @dev Interface of the ERC20 standard as defined in the EIP. -/// @dev This includes the optional name, symbol, and decimals metadata. -interface IERC20 { - /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). - event Transfer(address indexed from, address indexed to, uint256 value); - - /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` - /// is the new allowance. - event Approval(address indexed owner, address indexed spender, uint256 value); - - /// @notice Returns the amount of tokens in existence. - function totalSupply() external view returns (uint256); - - /// @notice Returns the amount of tokens owned by `account`. - function balanceOf(address account) external view returns (uint256); - - /// @notice Moves `amount` tokens from the caller's account to `to`. - function transfer(address to, uint256 amount) external returns (bool); - - /// @notice Returns the remaining number of tokens that `spender` is allowed - /// to spend on behalf of `owner` - function allowance(address owner, address spender) external view returns (uint256); - - /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. - /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - function approve(address spender, uint256 amount) external returns (bool); - - /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. - /// `amount` is then deducted from the caller's allowance. - function transferFrom(address from, address to, uint256 amount) external returns (bool); - - /// @notice Returns the name of the token. - function name() external view returns (string memory); - - /// @notice Returns the symbol of the token. - function symbol() external view returns (string memory); - - /// @notice Returns the decimals places of the token. - function decimals() external view returns (uint8); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC4626.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC4626.sol deleted file mode 100644 index bfe3a11..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC4626.sol +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC20.sol"; - -/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in -/// https://eips.ethereum.org/EIPS/eip-4626 -interface IERC4626 is IERC20 { - event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares - ); - - /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. - /// @dev - /// - MUST be an ERC-20 token contract. - /// - MUST NOT revert. - function asset() external view returns (address assetTokenAddress); - - /// @notice Returns the total amount of the underlying asset that is “managed” by Vault. - /// @dev - /// - SHOULD include any compounding that occurs from yield. - /// - MUST be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT revert. - function totalAssets() external view returns (uint256 totalManagedAssets); - - /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToShares(uint256 assets) external view returns (uint256 shares); - - /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToAssets(uint256 shares) external view returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, - /// through a deposit call. - /// @dev - /// - MUST return a limited value if receiver is subject to some deposit limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. - /// - MUST NOT revert. - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit - /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called - /// in the same transaction. - /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the - /// deposit would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewDeposit(uint256 assets) external view returns (uint256 shares); - - /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// deposit execution, and are accounted for during deposit. - /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - - /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. - /// @dev - /// - MUST return a limited value if receiver is subject to some mint limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. - /// - MUST NOT revert. - function maxMint(address receiver) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call - /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the - /// same transaction. - /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint - /// would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by minting. - function previewMint(uint256 shares) external view returns (uint256 assets); - - /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint - /// execution, and are accounted for during mint. - /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function mint(uint256 shares, address receiver) external returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the - /// Vault, through a withdraw call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST NOT revert. - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw - /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if - /// called - /// in the same transaction. - /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though - /// the withdrawal would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - - /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// withdraw execution, and are accounted for during withdraw. - /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); - - /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, - /// through a redeem call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. - /// - MUST NOT revert. - function maxRedeem(address owner) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call - /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the - /// same transaction. - /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the - /// redemption would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. - function previewRedeem(uint256 shares) external view returns (uint256 assets); - - /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// redeem execution, and are accounted for during redeem. - /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC721.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC721.sol deleted file mode 100644 index 0a16f45..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IERC721.sol +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC165.sol"; - -/// @title ERC-721 Non-Fungible Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. -interface IERC721 is IERC165 { - /// @dev This emits when ownership of any NFT changes by any mechanism. - /// This event emits when NFTs are created (`from` == 0) and destroyed - /// (`to` == 0). Exception: during contract creation, any number of NFTs - /// may be created and assigned without emitting Transfer. At the time of - /// any transfer, the approved address for that NFT (if any) is reset to none. - event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); - - /// @dev This emits when the approved address for an NFT is changed or - /// reaffirmed. The zero address indicates there is no approved address. - /// When a Transfer event emits, this also indicates that the approved - /// address for that NFT (if any) is reset to none. - event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); - - /// @dev This emits when an operator is enabled or disabled for an owner. - /// The operator can manage all NFTs of the owner. - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @notice Count all NFTs assigned to an owner - /// @dev NFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. - /// @param _owner An address for whom to query the balance - /// @return The number of NFTs owned by `_owner`, possibly zero - function balanceOf(address _owner) external view returns (uint256); - - /// @notice Find the owner of an NFT - /// @dev NFTs assigned to zero address are considered invalid, and queries - /// about them do throw. - /// @param _tokenId The identifier for an NFT - /// @return The address of the owner of the NFT - function ownerOf(uint256 _tokenId) external view returns (address); - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. When transfer is complete, this function - /// checks if `_to` is a smart contract (code size > 0). If so, it calls - /// `onERC721Received` on `_to` and throws if the return value is not - /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - /// @param data Additional data with no specified format, sent in call to `_to` - function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev This works identically to the other function with an extra data parameter, - /// except this function just sets data to "". - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE - /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE - /// THEY MAY BE PERMANENTLY LOST - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function transferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Change or reaffirm the approved address for an NFT - /// @dev The zero address indicates there is no approved address. - /// Throws unless `msg.sender` is the current NFT owner, or an authorized - /// operator of the current owner. - /// @param _approved The new approved NFT controller - /// @param _tokenId The NFT to approve - function approve(address _approved, uint256 _tokenId) external payable; - - /// @notice Enable or disable approval for a third party ("operator") to manage - /// all of `msg.sender`'s assets - /// @dev Emits the ApprovalForAll event. The contract MUST allow - /// multiple operators per owner. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Get the approved address for a single NFT - /// @dev Throws if `_tokenId` is not a valid NFT. - /// @param _tokenId The NFT to find the approved address for - /// @return The approved address for this NFT, or the zero address if there is none - function getApproved(uint256 _tokenId) external view returns (address); - - /// @notice Query if an address is an authorized operator for another address - /// @param _owner The address that owns the NFTs - /// @param _operator The address that acts on behalf of the owner - /// @return True if `_operator` is an approved operator for `_owner`, false otherwise - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} - -/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. -interface IERC721TokenReceiver { - /// @notice Handle the receipt of an NFT - /// @dev The ERC721 smart contract calls this function on the recipient - /// after a `transfer`. This function MAY throw to revert and reject the - /// transfer. Return of other than the magic value MUST result in the - /// transaction being reverted. - /// Note: the contract address is always the message sender. - /// @param _operator The address which called `safeTransferFrom` function - /// @param _from The address which previously owned the token - /// @param _tokenId The NFT identifier which is being transferred - /// @param _data Additional data with no specified format - /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - /// unless throwing - function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) - external - returns (bytes4); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. -interface IERC721Metadata is IERC721 { - /// @notice A descriptive name for a collection of NFTs in this contract - function name() external view returns (string memory _name); - - /// @notice An abbreviated name for NFTs in this contract - function symbol() external view returns (string memory _symbol); - - /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. - /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC - /// 3986. The URI may point to a JSON file that conforms to the "ERC721 - /// Metadata JSON Schema". - function tokenURI(uint256 _tokenId) external view returns (string memory); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x780e9d63. -interface IERC721Enumerable is IERC721 { - /// @notice Count NFTs tracked by this contract - /// @return A count of valid NFTs tracked by this contract, where each one of - /// them has an assigned and queryable owner not equal to the zero address - function totalSupply() external view returns (uint256); - - /// @notice Enumerate valid NFTs - /// @dev Throws if `_index` >= `totalSupply()`. - /// @param _index A counter less than `totalSupply()` - /// @return The token identifier for the `_index`th NFT, - /// (sort order not specified) - function tokenByIndex(uint256 _index) external view returns (uint256); - - /// @notice Enumerate NFTs assigned to an owner - /// @dev Throws if `_index` >= `balanceOf(_owner)` or if - /// `_owner` is the zero address, representing invalid NFTs. - /// @param _owner An address where we are interested in NFTs owned by them - /// @param _index A counter less than `balanceOf(_owner)` - /// @return The token identifier for the `_index`th NFT assigned to `_owner`, - /// (sort order not specified) - function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IMulticall3.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IMulticall3.sol deleted file mode 100644 index 0d031b7..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/interfaces/IMulticall3.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -interface IMulticall3 { - struct Call { - address target; - bytes callData; - } - - struct Call3 { - address target; - bool allowFailure; - bytes callData; - } - - struct Call3Value { - address target; - bool allowFailure; - uint256 value; - bytes callData; - } - - struct Result { - bool success; - bytes returnData; - } - - function aggregate(Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes[] memory returnData); - - function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); - - function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); - - function blockAndAggregate(Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); - - function getBasefee() external view returns (uint256 basefee); - - function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); - - function getBlockNumber() external view returns (uint256 blockNumber); - - function getChainId() external view returns (uint256 chainid); - - function getCurrentBlockCoinbase() external view returns (address coinbase); - - function getCurrentBlockDifficulty() external view returns (uint256 difficulty); - - function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); - - function getCurrentBlockTimestamp() external view returns (uint256 timestamp); - - function getEthBalance(address addr) external view returns (uint256 balance); - - function getLastBlockHash() external view returns (bytes32 blockHash); - - function tryAggregate(bool requireSuccess, Call[] calldata calls) - external - payable - returns (Result[] memory returnData); - - function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/safeconsole.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/safeconsole.sol deleted file mode 100644 index 5714d09..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/src/safeconsole.sol +++ /dev/null @@ -1,13248 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -/// @author philogy -/// @dev Code generated automatically by script. -library safeconsole { - uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67; - - // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374) - // for the view-to-pure log trick. - function _sendLogPayload(uint256 offset, uint256 size) private pure { - function(uint256, uint256) internal view fnIn = _sendLogPayloadView; - function(uint256, uint256) internal pure pureSendLogPayload; - assembly { - pureSendLogPayload := fnIn - } - pureSendLogPayload(offset, size); - } - - function _sendLogPayloadView(uint256 offset, uint256 size) private view { - assembly { - pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0)) - } - } - - function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure { - function(uint256, uint256, uint256) internal view fnIn = _memcopyView; - function(uint256, uint256, uint256) internal pure pureMemcopy; - assembly { - pureMemcopy := fnIn - } - pureMemcopy(fromOffset, toOffset, length); - } - - function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view { - assembly { - pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length)) - } - } - - function logMemory(uint256 offset, uint256 length) internal pure { - if (offset >= 0x60) { - // Sufficient memory before slice to prepare call header. - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(sub(offset, 0x60)) - m1 := mload(sub(offset, 0x40)) - m2 := mload(sub(offset, 0x20)) - // Selector of `logBytes(bytes)`. - mstore(sub(offset, 0x60), 0xe17bf956) - mstore(sub(offset, 0x40), 0x20) - mstore(sub(offset, 0x20), length) - } - _sendLogPayload(offset - 0x44, length + 0x44); - assembly { - mstore(sub(offset, 0x60), m0) - mstore(sub(offset, 0x40), m1) - mstore(sub(offset, 0x20), m2) - } - } else { - // Insufficient space, so copy slice forward, add header and reverse. - bytes32 m0; - bytes32 m1; - bytes32 m2; - uint256 endOffset = offset + length; - assembly { - m0 := mload(add(endOffset, 0x00)) - m1 := mload(add(endOffset, 0x20)) - m2 := mload(add(endOffset, 0x40)) - } - _memcopy(offset, offset + 0x60, length); - assembly { - // Selector of `logBytes(bytes)`. - mstore(add(offset, 0x00), 0xe17bf956) - mstore(add(offset, 0x20), 0x20) - mstore(add(offset, 0x40), length) - } - _sendLogPayload(offset + 0x1c, length + 0x44); - _memcopy(offset + 0x60, offset, length); - assembly { - mstore(add(endOffset, 0x00), m0) - mstore(add(endOffset, 0x20), m1) - mstore(add(endOffset, 0x40), m2) - } - } - } - - function log(address p0) internal pure { - bytes32 m0; - bytes32 m1; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(address)`. - mstore(0x00, 0x2c2ecbc2) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(bool p0) internal pure { - bytes32 m0; - bytes32 m1; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(bool)`. - mstore(0x00, 0x32458eed) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(uint256 p0) internal pure { - bytes32 m0; - bytes32 m1; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - // Selector of `log(uint256)`. - mstore(0x00, 0xf82c50f1) - mstore(0x20, p0) - } - _sendLogPayload(0x1c, 0x24); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - } - } - - function log(bytes32 p0) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(string)`. - mstore(0x00, 0x41304fac) - mstore(0x20, 0x20) - writeString(0x40, p0) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,address)`. - mstore(0x00, 0xdaf0d4aa) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,bool)`. - mstore(0x00, 0x75b605d3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(address,uint256)`. - mstore(0x00, 0x8309e8a8) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(address p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,string)`. - mstore(0x00, 0x759f86bb) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,address)`. - mstore(0x00, 0x853c4849) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,bool)`. - mstore(0x00, 0x2a110e83) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(bool,uint256)`. - mstore(0x00, 0x399174d3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(bool p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,string)`. - mstore(0x00, 0x8feac525) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,address)`. - mstore(0x00, 0x69276c86) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,bool)`. - mstore(0x00, 0x1c9d7eb3) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - // Selector of `log(uint256,uint256)`. - mstore(0x00, 0xf666715a) - mstore(0x20, p0) - mstore(0x40, p1) - } - _sendLogPayload(0x1c, 0x44); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - } - } - - function log(uint256 p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,string)`. - mstore(0x00, 0x643fd0df) - mstore(0x20, p0) - mstore(0x40, 0x40) - writeString(0x60, p1) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, address p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,address)`. - mstore(0x00, 0x319af333) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, bool p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,bool)`. - mstore(0x00, 0xc3b55635) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, uint256 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(string,uint256)`. - mstore(0x00, 0xb60e72cc) - mstore(0x20, 0x40) - mstore(0x40, p1) - writeString(0x60, p0) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bytes32 p0, bytes32 p1) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,string)`. - mstore(0x00, 0x4b5c4277) - mstore(0x20, 0x40) - mstore(0x40, 0x80) - writeString(0x60, p0) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,address)`. - mstore(0x00, 0x018c84c2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,bool)`. - mstore(0x00, 0xf2a66286) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,address,uint256)`. - mstore(0x00, 0x17fe6185) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,address,string)`. - mstore(0x00, 0x007150be) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,address)`. - mstore(0x00, 0xf11699ed) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,bool)`. - mstore(0x00, 0xeb830c92) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,bool,uint256)`. - mstore(0x00, 0x9c4f99fb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,bool,string)`. - mstore(0x00, 0x212255cc) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,address)`. - mstore(0x00, 0x7bc0d848) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,bool)`. - mstore(0x00, 0x678209a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(address,uint256,uint256)`. - mstore(0x00, 0xb69bcaf6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(address p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,uint256,string)`. - mstore(0x00, 0xa1f2e8aa) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,address)`. - mstore(0x00, 0xf08744e8) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,bool)`. - mstore(0x00, 0xcf020fb1) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(address,string,uint256)`. - mstore(0x00, 0x67dd6ff1) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(address p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(address,string,string)`. - mstore(0x00, 0xfb772265) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bool p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,address)`. - mstore(0x00, 0xd2763667) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,bool)`. - mstore(0x00, 0x18c9c746) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,address,uint256)`. - mstore(0x00, 0x5f7b9afb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,address,string)`. - mstore(0x00, 0xde9a9270) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,address)`. - mstore(0x00, 0x1078f68d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,bool)`. - mstore(0x00, 0x50709698) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,bool,uint256)`. - mstore(0x00, 0x12f21602) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,bool,string)`. - mstore(0x00, 0x2555fa46) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,address)`. - mstore(0x00, 0x088ef9d2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,bool)`. - mstore(0x00, 0xe8defba9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(bool,uint256,uint256)`. - mstore(0x00, 0x37103367) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(bool p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,uint256,string)`. - mstore(0x00, 0xc3fc3970) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,address)`. - mstore(0x00, 0x9591b953) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,bool)`. - mstore(0x00, 0xdbb4c247) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(bool,string,uint256)`. - mstore(0x00, 0x1093ee11) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(bool,string,string)`. - mstore(0x00, 0xb076847f) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(uint256 p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,address)`. - mstore(0x00, 0xbcfd9be0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,bool)`. - mstore(0x00, 0x9b6ec042) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,address,uint256)`. - mstore(0x00, 0x5a9b5ed5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,address,string)`. - mstore(0x00, 0x63cb41f9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,address)`. - mstore(0x00, 0x35085f7b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,bool)`. - mstore(0x00, 0x20718650) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,bool,uint256)`. - mstore(0x00, 0x20098014) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,bool,string)`. - mstore(0x00, 0x85775021) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,address)`. - mstore(0x00, 0x5c96b331) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,bool)`. - mstore(0x00, 0x4766da72) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - // Selector of `log(uint256,uint256,uint256)`. - mstore(0x00, 0xd1ed7a3c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - } - _sendLogPayload(0x1c, 0x64); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,uint256,string)`. - mstore(0x00, 0x71d04af2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x60) - writeString(0x80, p2) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,address)`. - mstore(0x00, 0x7afac959) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,bool)`. - mstore(0x00, 0x4ceda75a) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(uint256,string,uint256)`. - mstore(0x00, 0x37aa7d4c) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, p2) - writeString(0x80, p1) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(uint256,string,string)`. - mstore(0x00, 0xb115611f) - mstore(0x20, p0) - mstore(0x40, 0x60) - mstore(0x60, 0xa0) - writeString(0x80, p1) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, address p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,address)`. - mstore(0x00, 0xfcec75e0) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,bool)`. - mstore(0x00, 0xc91d5ed4) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,address,uint256)`. - mstore(0x00, 0x0d26b925) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, address p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,address,string)`. - mstore(0x00, 0xe0e9ad4f) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bool p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,address)`. - mstore(0x00, 0x932bbb38) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,bool)`. - mstore(0x00, 0x850b7ad6) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,bool,uint256)`. - mstore(0x00, 0xc95958d6) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,bool,string)`. - mstore(0x00, 0xe298f47d) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, uint256 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,address)`. - mstore(0x00, 0x1c7ec448) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,bool)`. - mstore(0x00, 0xca7733b1) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - // Selector of `log(string,uint256,uint256)`. - mstore(0x00, 0xca47c4eb) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, p2) - writeString(0x80, p0) - } - _sendLogPayload(0x1c, 0xa4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,uint256,string)`. - mstore(0x00, 0x5970e089) - mstore(0x20, 0x60) - mstore(0x40, p1) - mstore(0x60, 0xa0) - writeString(0x80, p0) - writeString(0xc0, p2) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, address p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,address)`. - mstore(0x00, 0x95ed0195) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,bool)`. - mstore(0x00, 0xb0e0f9b5) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - // Selector of `log(string,string,uint256)`. - mstore(0x00, 0x5821efa1) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, p2) - writeString(0x80, p0) - writeString(0xc0, p1) - } - _sendLogPayload(0x1c, 0xe4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - // Selector of `log(string,string,string)`. - mstore(0x00, 0x2ced7cef) - mstore(0x20, 0x60) - mstore(0x40, 0xa0) - mstore(0x60, 0xe0) - writeString(0x80, p0) - writeString(0xc0, p1) - writeString(0x100, p2) - } - _sendLogPayload(0x1c, 0x124); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - } - } - - function log(address p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,address)`. - mstore(0x00, 0x665bf134) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,bool)`. - mstore(0x00, 0x0e378994) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,address,uint256)`. - mstore(0x00, 0x94250d77) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,address,string)`. - mstore(0x00, 0xf808da20) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,address)`. - mstore(0x00, 0x9f1bc36e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,bool)`. - mstore(0x00, 0x2cd4134a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,bool,uint256)`. - mstore(0x00, 0x3971e78c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,bool,string)`. - mstore(0x00, 0xaa6540c8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,address)`. - mstore(0x00, 0x8da6def5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,bool)`. - mstore(0x00, 0x9b4254e2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,address,uint256,uint256)`. - mstore(0x00, 0xbe553481) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,uint256,string)`. - mstore(0x00, 0xfdb4f990) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,address)`. - mstore(0x00, 0x8f736d16) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,bool)`. - mstore(0x00, 0x6f1a594e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,address,string,uint256)`. - mstore(0x00, 0xef1cefe7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,address,string,string)`. - mstore(0x00, 0x21bdaf25) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,address)`. - mstore(0x00, 0x660375dd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,bool)`. - mstore(0x00, 0xa6f50b0f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,address,uint256)`. - mstore(0x00, 0xa75c59de) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,address,string)`. - mstore(0x00, 0x2dd778e6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,address)`. - mstore(0x00, 0xcf394485) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,bool)`. - mstore(0x00, 0xcac43479) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,bool,uint256)`. - mstore(0x00, 0x8c4e5de6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,bool,string)`. - mstore(0x00, 0xdfc4a2e8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,address)`. - mstore(0x00, 0xccf790a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,bool)`. - mstore(0x00, 0xc4643e20) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,bool,uint256,uint256)`. - mstore(0x00, 0x386ff5f4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,uint256,string)`. - mstore(0x00, 0x0aa6cfad) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,address)`. - mstore(0x00, 0x19fd4956) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,bool)`. - mstore(0x00, 0x50ad461d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,bool,string,uint256)`. - mstore(0x00, 0x80e6a20b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,bool,string,string)`. - mstore(0x00, 0x475c5c33) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,address)`. - mstore(0x00, 0x478d1c62) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,bool)`. - mstore(0x00, 0xa1bcc9b3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,address,uint256)`. - mstore(0x00, 0x100f650e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,address,string)`. - mstore(0x00, 0x1da986ea) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,address)`. - mstore(0x00, 0xa31bfdcc) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,bool)`. - mstore(0x00, 0x3bf5e537) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,bool,uint256)`. - mstore(0x00, 0x22f6b999) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,bool,string)`. - mstore(0x00, 0xc5ad85f9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,address)`. - mstore(0x00, 0x20e3984d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,bool)`. - mstore(0x00, 0x66f1bc67) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(address,uint256,uint256,uint256)`. - mstore(0x00, 0x34f0e636) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(address p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,uint256,string)`. - mstore(0x00, 0x4a28c017) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,address)`. - mstore(0x00, 0x5c430d47) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,bool)`. - mstore(0x00, 0xcf18105c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,uint256,string,uint256)`. - mstore(0x00, 0xbf01f891) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,uint256,string,string)`. - mstore(0x00, 0x88a8c406) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,address)`. - mstore(0x00, 0x0d36fa20) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,bool)`. - mstore(0x00, 0x0df12b76) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,address,uint256)`. - mstore(0x00, 0x457fe3cf) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,address,string)`. - mstore(0x00, 0xf7e36245) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,address)`. - mstore(0x00, 0x205871c2) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,bool)`. - mstore(0x00, 0x5f1d5c9f) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,bool,uint256)`. - mstore(0x00, 0x515e38b6) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,bool,string)`. - mstore(0x00, 0xbc0b61fe) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,address)`. - mstore(0x00, 0x63183678) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,bool)`. - mstore(0x00, 0x0ef7e050) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(address,string,uint256,uint256)`. - mstore(0x00, 0x1dc8e1b8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(address p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,uint256,string)`. - mstore(0x00, 0x448830a8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,address)`. - mstore(0x00, 0xa04e2f87) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,bool)`. - mstore(0x00, 0x35a5071f) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(address,string,string,uint256)`. - mstore(0x00, 0x159f8927) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(address p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(address,string,string,string)`. - mstore(0x00, 0x5d02c50b) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bool p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,address)`. - mstore(0x00, 0x1d14d001) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,bool)`. - mstore(0x00, 0x46600be0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,address,uint256)`. - mstore(0x00, 0x0c66d1be) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,address,string)`. - mstore(0x00, 0xd812a167) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,address)`. - mstore(0x00, 0x1c41a336) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,bool)`. - mstore(0x00, 0x6a9c478b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,bool,uint256)`. - mstore(0x00, 0x07831502) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,bool,string)`. - mstore(0x00, 0x4a66cb34) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,address)`. - mstore(0x00, 0x136b05dd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,bool)`. - mstore(0x00, 0xd6019f1c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,address,uint256,uint256)`. - mstore(0x00, 0x7bf181a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,uint256,string)`. - mstore(0x00, 0x51f09ff8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,address)`. - mstore(0x00, 0x6f7c603e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,bool)`. - mstore(0x00, 0xe2bfd60b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,address,string,uint256)`. - mstore(0x00, 0xc21f64c7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,address,string,string)`. - mstore(0x00, 0xa73c1db6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,address)`. - mstore(0x00, 0xf4880ea4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,bool)`. - mstore(0x00, 0xc0a302d8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,address,uint256)`. - mstore(0x00, 0x4c123d57) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,address,string)`. - mstore(0x00, 0xa0a47963) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,address)`. - mstore(0x00, 0x8c329b1a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,bool)`. - mstore(0x00, 0x3b2a5ce0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,bool,uint256)`. - mstore(0x00, 0x6d7045c1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,bool,string)`. - mstore(0x00, 0x2ae408d4) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,address)`. - mstore(0x00, 0x54a7a9a0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,bool)`. - mstore(0x00, 0x619e4d0e) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,bool,uint256,uint256)`. - mstore(0x00, 0x0bb00eab) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,uint256,string)`. - mstore(0x00, 0x7dd4d0e0) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,address)`. - mstore(0x00, 0xf9ad2b89) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,bool)`. - mstore(0x00, 0xb857163a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,bool,string,uint256)`. - mstore(0x00, 0xe3a9ca2f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,bool,string,string)`. - mstore(0x00, 0x6d1e8751) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,address)`. - mstore(0x00, 0x26f560a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,bool)`. - mstore(0x00, 0xb4c314ff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,address,uint256)`. - mstore(0x00, 0x1537dc87) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,address,string)`. - mstore(0x00, 0x1bb3b09a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,address)`. - mstore(0x00, 0x9acd3616) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,bool)`. - mstore(0x00, 0xceb5f4d7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,bool,uint256)`. - mstore(0x00, 0x7f9bbca2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,bool,string)`. - mstore(0x00, 0x9143dbb1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,address)`. - mstore(0x00, 0x00dd87b9) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,bool)`. - mstore(0x00, 0xbe984353) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(bool,uint256,uint256,uint256)`. - mstore(0x00, 0x374bb4b2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(bool p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,uint256,string)`. - mstore(0x00, 0x8e69fb5d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,address)`. - mstore(0x00, 0xfedd1fff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,bool)`. - mstore(0x00, 0xe5e70b2b) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,uint256,string,uint256)`. - mstore(0x00, 0x6a1199e2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,uint256,string,string)`. - mstore(0x00, 0xf5bc2249) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,address)`. - mstore(0x00, 0x2b2b18dc) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,bool)`. - mstore(0x00, 0x6dd434ca) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,address,uint256)`. - mstore(0x00, 0xa5cada94) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,address,string)`. - mstore(0x00, 0x12d6c788) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,address)`. - mstore(0x00, 0x538e06ab) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,bool)`. - mstore(0x00, 0xdc5e935b) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,bool,uint256)`. - mstore(0x00, 0x1606a393) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,bool,string)`. - mstore(0x00, 0x483d0416) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,address)`. - mstore(0x00, 0x1596a1ce) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,bool)`. - mstore(0x00, 0x6b0e5d53) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(bool,string,uint256,uint256)`. - mstore(0x00, 0x28863fcb) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bool p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,uint256,string)`. - mstore(0x00, 0x1ad96de6) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,address)`. - mstore(0x00, 0x97d394d8) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,bool)`. - mstore(0x00, 0x1e4b87e5) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(bool,string,string,uint256)`. - mstore(0x00, 0x7be0c3eb) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bool p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(bool,string,string,string)`. - mstore(0x00, 0x1762e32a) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(uint256 p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,address)`. - mstore(0x00, 0x2488b414) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,bool)`. - mstore(0x00, 0x091ffaf5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,address,uint256)`. - mstore(0x00, 0x736efbb6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,address,string)`. - mstore(0x00, 0x031c6f73) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,address)`. - mstore(0x00, 0xef72c513) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,bool)`. - mstore(0x00, 0xe351140f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,bool,uint256)`. - mstore(0x00, 0x5abd992a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,bool,string)`. - mstore(0x00, 0x90fb06aa) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,address)`. - mstore(0x00, 0x15c127b5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,bool)`. - mstore(0x00, 0x5f743a7c) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,address,uint256,uint256)`. - mstore(0x00, 0x0c9cd9c1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,uint256,string)`. - mstore(0x00, 0xddb06521) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,address)`. - mstore(0x00, 0x9cba8fff) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,bool)`. - mstore(0x00, 0xcc32ab07) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,address,string,uint256)`. - mstore(0x00, 0x46826b5d) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,address,string,string)`. - mstore(0x00, 0x3e128ca3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,address)`. - mstore(0x00, 0xa1ef4cbb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,bool)`. - mstore(0x00, 0x454d54a5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,address,uint256)`. - mstore(0x00, 0x078287f5) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,address,string)`. - mstore(0x00, 0xade052c7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,address)`. - mstore(0x00, 0x69640b59) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,bool)`. - mstore(0x00, 0xb6f577a1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,bool,uint256)`. - mstore(0x00, 0x7464ce23) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,bool,string)`. - mstore(0x00, 0xdddb9561) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,address)`. - mstore(0x00, 0x88cb6041) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,bool)`. - mstore(0x00, 0x91a02e2a) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,bool,uint256,uint256)`. - mstore(0x00, 0xc6acc7a8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,uint256,string)`. - mstore(0x00, 0xde03e774) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,address)`. - mstore(0x00, 0xef529018) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,bool)`. - mstore(0x00, 0xeb928d7f) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,bool,string,uint256)`. - mstore(0x00, 0x2c1d0746) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,bool,string,string)`. - mstore(0x00, 0x68c8b8bd) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,address)`. - mstore(0x00, 0x56a5d1b1) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,bool)`. - mstore(0x00, 0x15cac476) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,address,uint256)`. - mstore(0x00, 0x88f6e4b2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,address,string)`. - mstore(0x00, 0x6cde40b8) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,address)`. - mstore(0x00, 0x9a816a83) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,bool)`. - mstore(0x00, 0xab085ae6) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,bool,uint256)`. - mstore(0x00, 0xeb7f6fd2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,bool,string)`. - mstore(0x00, 0xa5b4fc99) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,address)`. - mstore(0x00, 0xfa8185af) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,bool)`. - mstore(0x00, 0xc598d185) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - assembly { - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - // Selector of `log(uint256,uint256,uint256,uint256)`. - mstore(0x00, 0x193fb800) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - } - _sendLogPayload(0x1c, 0x84); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - } - } - - function log(uint256 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,uint256,string)`. - mstore(0x00, 0x59cfcbe3) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0x80) - writeString(0xa0, p3) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,address)`. - mstore(0x00, 0x42d21db7) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,bool)`. - mstore(0x00, 0x7af6ab25) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,uint256,string,uint256)`. - mstore(0x00, 0x5da297eb) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, p3) - writeString(0xa0, p2) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,uint256,string,string)`. - mstore(0x00, 0x27d8afd2) - mstore(0x20, p0) - mstore(0x40, p1) - mstore(0x60, 0x80) - mstore(0x80, 0xc0) - writeString(0xa0, p2) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,address)`. - mstore(0x00, 0x6168ed61) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,bool)`. - mstore(0x00, 0x90c30a56) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,address,uint256)`. - mstore(0x00, 0xe8d3018d) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,address,string)`. - mstore(0x00, 0x9c3adfa1) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,address)`. - mstore(0x00, 0xae2ec581) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,bool)`. - mstore(0x00, 0xba535d9c) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,bool,uint256)`. - mstore(0x00, 0xcf009880) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,bool,string)`. - mstore(0x00, 0xd2d423cd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,address)`. - mstore(0x00, 0x3b2279b4) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,bool)`. - mstore(0x00, 0x691a8f74) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(uint256,string,uint256,uint256)`. - mstore(0x00, 0x82c25b74) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p1) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(uint256 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,uint256,string)`. - mstore(0x00, 0xb7b914ca) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p1) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,address)`. - mstore(0x00, 0xd583c602) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,bool)`. - mstore(0x00, 0xb3a6b6bd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(uint256,string,string,uint256)`. - mstore(0x00, 0xb028c9bd) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p1) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(uint256 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(uint256,string,string,string)`. - mstore(0x00, 0x21ad0683) - mstore(0x20, p0) - mstore(0x40, 0x80) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p1) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, address p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,address)`. - mstore(0x00, 0xed8f28f6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,bool)`. - mstore(0x00, 0xb59dbd60) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,address,uint256)`. - mstore(0x00, 0x8ef3f399) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,address,string)`. - mstore(0x00, 0x800a1c67) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,address)`. - mstore(0x00, 0x223603bd) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,bool)`. - mstore(0x00, 0x79884c2b) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,bool,uint256)`. - mstore(0x00, 0x3e9f866a) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,bool,string)`. - mstore(0x00, 0x0454c079) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,address)`. - mstore(0x00, 0x63fb8bc5) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,bool)`. - mstore(0x00, 0xfc4845f0) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,address,uint256,uint256)`. - mstore(0x00, 0xf8f51b1e) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, address p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,uint256,string)`. - mstore(0x00, 0x5a477632) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,address)`. - mstore(0x00, 0xaabc9a31) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,bool)`. - mstore(0x00, 0x5f15d28c) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,address,string,uint256)`. - mstore(0x00, 0x91d1112e) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, address p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,address,string,string)`. - mstore(0x00, 0x245986f2) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bool p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,address)`. - mstore(0x00, 0x33e9dd1d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,bool)`. - mstore(0x00, 0x958c28c6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,address,uint256)`. - mstore(0x00, 0x5d08bb05) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,address,string)`. - mstore(0x00, 0x2d8e33a4) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,address)`. - mstore(0x00, 0x7190a529) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,bool)`. - mstore(0x00, 0x895af8c5) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,bool,uint256)`. - mstore(0x00, 0x8e3f78a9) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,bool,string)`. - mstore(0x00, 0x9d22d5dd) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,address)`. - mstore(0x00, 0x935e09bf) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,bool)`. - mstore(0x00, 0x8af7cf8a) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,bool,uint256,uint256)`. - mstore(0x00, 0x64b5bb67) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, bool p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,uint256,string)`. - mstore(0x00, 0x742d6ee7) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,address)`. - mstore(0x00, 0xe0625b29) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,bool)`. - mstore(0x00, 0x3f8a701d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,bool,string,uint256)`. - mstore(0x00, 0x24f91465) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,bool,string,string)`. - mstore(0x00, 0xa826caeb) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, uint256 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,address)`. - mstore(0x00, 0x5ea2b7ae) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,bool)`. - mstore(0x00, 0x82112a42) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,address,uint256)`. - mstore(0x00, 0x4f04fdc6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,address,string)`. - mstore(0x00, 0x9ffb2f93) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,address)`. - mstore(0x00, 0xe0e95b98) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,bool)`. - mstore(0x00, 0x354c36d6) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,bool,uint256)`. - mstore(0x00, 0xe41b6f6f) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,bool,string)`. - mstore(0x00, 0xabf73a98) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,address)`. - mstore(0x00, 0xe21de278) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,bool)`. - mstore(0x00, 0x7626db92) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - // Selector of `log(string,uint256,uint256,uint256)`. - mstore(0x00, 0xa7a87853) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - } - _sendLogPayload(0x1c, 0xc4); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - } - } - - function log(bytes32 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,uint256,string)`. - mstore(0x00, 0x854b3496) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, p2) - mstore(0x80, 0xc0) - writeString(0xa0, p0) - writeString(0xe0, p3) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,address)`. - mstore(0x00, 0x7c4632a4) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,bool)`. - mstore(0x00, 0x7d24491d) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,uint256,string,uint256)`. - mstore(0x00, 0xc67ea9d1) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p2) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,uint256,string,string)`. - mstore(0x00, 0x5ab84e1f) - mstore(0x20, 0x80) - mstore(0x40, p1) - mstore(0x60, 0xc0) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p2) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,address)`. - mstore(0x00, 0x439c7bef) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,bool)`. - mstore(0x00, 0x5ccd4e37) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,address,uint256)`. - mstore(0x00, 0x7cc3c607) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, address p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,address,string)`. - mstore(0x00, 0xeb1bff80) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,address)`. - mstore(0x00, 0xc371c7db) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,bool)`. - mstore(0x00, 0x40785869) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,bool,uint256)`. - mstore(0x00, 0xd6aefad2) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,bool,string)`. - mstore(0x00, 0x5e84b0ea) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,address)`. - mstore(0x00, 0x1023f7b2) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,bool)`. - mstore(0x00, 0xc3a8a654) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - // Selector of `log(string,string,uint256,uint256)`. - mstore(0x00, 0xf45d7d2c) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - } - _sendLogPayload(0x1c, 0x104); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - } - } - - function log(bytes32 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,uint256,string)`. - mstore(0x00, 0x5d1a971a) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, p2) - mstore(0x80, 0x100) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p3) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, address p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,address)`. - mstore(0x00, 0x6d572f44) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,bool)`. - mstore(0x00, 0x2c1754ed) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - // Selector of `log(string,string,string,uint256)`. - mstore(0x00, 0x8eafb02b) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, p3) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - } - _sendLogPayload(0x1c, 0x144); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - } - } - - function log(bytes32 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { - bytes32 m0; - bytes32 m1; - bytes32 m2; - bytes32 m3; - bytes32 m4; - bytes32 m5; - bytes32 m6; - bytes32 m7; - bytes32 m8; - bytes32 m9; - bytes32 m10; - bytes32 m11; - bytes32 m12; - assembly { - function writeString(pos, w) { - let length := 0 - for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } - mstore(pos, length) - let shift := sub(256, shl(3, length)) - mstore(add(pos, 0x20), shl(shift, shr(shift, w))) - } - m0 := mload(0x00) - m1 := mload(0x20) - m2 := mload(0x40) - m3 := mload(0x60) - m4 := mload(0x80) - m5 := mload(0xa0) - m6 := mload(0xc0) - m7 := mload(0xe0) - m8 := mload(0x100) - m9 := mload(0x120) - m10 := mload(0x140) - m11 := mload(0x160) - m12 := mload(0x180) - // Selector of `log(string,string,string,string)`. - mstore(0x00, 0xde68f20a) - mstore(0x20, 0x80) - mstore(0x40, 0xc0) - mstore(0x60, 0x100) - mstore(0x80, 0x140) - writeString(0xa0, p0) - writeString(0xe0, p1) - writeString(0x120, p2) - writeString(0x160, p3) - } - _sendLogPayload(0x1c, 0x184); - assembly { - mstore(0x00, m0) - mstore(0x20, m1) - mstore(0x40, m2) - mstore(0x60, m3) - mstore(0x80, m4) - mstore(0xa0, m5) - mstore(0xc0, m6) - mstore(0xe0, m7) - mstore(0x100, m8) - mstore(0x120, m9) - mstore(0x140, m10) - mstore(0x160, m11) - mstore(0x180, m12) - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdAssertions.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdAssertions.t.sol deleted file mode 100644 index fcc346b..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdAssertions.t.sol +++ /dev/null @@ -1,999 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdAssertionsTest is Test { - string constant CUSTOM_ERROR = "guh!"; - - bool constant EXPECT_PASS = false; - bool constant EXPECT_FAIL = true; - - bool constant SHOULD_REVERT = true; - bool constant SHOULD_RETURN = false; - - bool constant STRICT_REVERT_DATA = true; - bool constant NON_STRICT_REVERT_DATA = false; - - TestTest t = new TestTest(); - - /*////////////////////////////////////////////////////////////////////////// - FAIL(STRING) - //////////////////////////////////////////////////////////////////////////*/ - - function testShouldFail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._fail(CUSTOM_ERROR); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_FALSE - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertFalse_Pass() external { - t._assertFalse(false, EXPECT_PASS); - } - - function testAssertFalse_Fail() external { - vm.expectEmit(false, false, false, true); - emit log("Error: Assertion Failed"); - t._assertFalse(true, EXPECT_FAIL); - } - - function testAssertFalse_Err_Pass() external { - t._assertFalse(false, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertFalse_Err_Fail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertFalse(true, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(BOOL) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_Bool_Pass(bool a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testAssertEq_Bool_Fail(bool a, bool b) external { - vm.assume(a != b); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [bool]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_BoolErr_Pass(bool a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertEq_BoolErr_Fail(bool a, bool b) external { - vm.assume(a != b); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(BYTES) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_Bytes_Pass(bytes calldata a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testAssertEq_Bytes_Fail(bytes calldata a, bytes calldata b) external { - vm.assume(keccak256(a) != keccak256(b)); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [bytes]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_BytesErr_Pass(bytes calldata a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertEq_BytesErr_Fail(bytes calldata a, bytes calldata b) external { - vm.assume(keccak256(a) != keccak256(b)); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(ARRAY) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_UintArr_Pass(uint256 e0, uint256 e1, uint256 e2) public { - uint256[] memory a = new uint256[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - uint256[] memory b = new uint256[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_IntArr_Pass(int256 e0, int256 e1, int256 e2) public { - int256[] memory a = new int256[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - int256[] memory b = new int256[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_AddressArr_Pass(address e0, address e1, address e2) public { - address[] memory a = new address[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - address[] memory b = new address[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_UintArr_FailEl(uint256 e1) public { - vm.assume(e1 != 0); - uint256[] memory a = new uint256[](3); - uint256[] memory b = new uint256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_IntArr_FailEl(int256 e1) public { - vm.assume(e1 != 0); - int256[] memory a = new int256[](3); - int256[] memory b = new int256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_AddressArr_FailEl(address e1) public { - vm.assume(e1 != address(0)); - address[] memory a = new address[](3); - address[] memory b = new address[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_UintArrErr_FailEl(uint256 e1) public { - vm.assume(e1 != 0); - uint256[] memory a = new uint256[](3); - uint256[] memory b = new uint256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_IntArrErr_FailEl(int256 e1) public { - vm.assume(e1 != 0); - int256[] memory a = new int256[](3); - int256[] memory b = new int256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_AddressArrErr_FailEl(address e1) public { - vm.assume(e1 != address(0)); - address[] memory a = new address[](3); - address[] memory b = new address[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_UintArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - uint256[] memory a = new uint256[](lenA); - uint256[] memory b = new uint256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_IntArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - int256[] memory a = new int256[](lenA); - int256[] memory b = new int256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_AddressArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - address[] memory a = new address[](lenA); - address[] memory b = new address[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_UintArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - uint256[] memory a = new uint256[](lenA); - uint256[] memory b = new uint256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_IntArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - int256[] memory a = new int256[](lenA); - int256[] memory b = new int256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_AddressArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - address[] memory a = new address[](lenA); - address[] memory b = new address[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEqUint() public { - assertEqUint(uint8(1), uint128(1)); - assertEqUint(uint64(2), uint64(2)); - } - - function testFailAssertEqUint() public { - assertEqUint(uint64(1), uint96(2)); - assertEqUint(uint160(3), uint160(4)); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbs_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testAssertApproxEqAbs_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); - } - - function testAssertApproxEqAbs_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbs_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS_DECIMAL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbsDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqAbsDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbs_Int_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testAssertApproxEqAbs_Int_Fail(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); - } - - function testAssertApproxEqAbs_IntErr_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbs_IntErr_Fail(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS_DECIMAL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbsDecimal_Int_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_Int_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqAbsDecimal_IntErr_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_IntErr_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRel_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); - } - - function testAssertApproxEqRel_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); - } - - function testAssertApproxEqRel_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRel_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL_DECIMAL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRelDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqRelDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRel_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); - } - - function testAssertApproxEqRel_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); - } - - function testAssertApproxEqRel_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRel_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL_DECIMAL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRelDecimal_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqRelDecimal_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ_CALL - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEqCall_Return_Pass( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnData, - bool strictRevertData - ) external { - address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); - - t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_PASS); - } - - function testAssertEqCall_Return_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData - ) external { - vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); - - address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); - - vm.expectEmit(true, true, true, true); - emit log_named_string("Error", "Call return data does not match"); - t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); - } - - function testAssertEqCall_Revert_Pass( - bytes memory callDataA, - bytes memory callDataB, - bytes memory revertDataA, - bytes memory revertDataB - ) external { - address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); - address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); - - t._assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA, EXPECT_PASS); - } - - function testAssertEqCall_Revert_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory revertDataA, - bytes memory revertDataB - ) external { - vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); - - address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); - address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); - - vm.expectEmit(true, true, true, true); - emit log_named_string("Error", "Call revert data does not match"); - t._assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA, EXPECT_FAIL); - } - - function testAssertEqCall_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData - ) external { - address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); - - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Left call return data", returnDataA); - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Right call revert data", returnDataB); - t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); - - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Left call revert data", returnDataB); - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Right call return data", returnDataA); - t._assertEqCall(targetB, callDataB, targetA, callDataA, strictRevertData, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_NOT_EQ(BYTES) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertNotEq_Bytes_Pass(bytes32 a, bytes32 b) external { - vm.assume(a != b); - t._assertNotEq(a, b, EXPECT_PASS); - } - - function testAssertNotEq_Bytes_Fail(bytes32 a) external { - vm.expectEmit(false, false, false, true); - emit log("Error: a != b not satisfied [bytes32]"); - t._assertNotEq(a, a, EXPECT_FAIL); - } - - function testAssertNotEq_BytesErr_Pass(bytes32 a, bytes32 b) external { - vm.assume(a != b); - t._assertNotEq(a, b, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAsserNottEq_BytesErr_Fail(bytes32 a) external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertNotEq(a, a, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_NOT_EQ(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertNotEqUint() public { - assertNotEq(uint8(1), uint128(2)); - assertNotEq(uint64(3), uint64(4)); - } - - function testFailAssertNotEqUint() public { - assertNotEq(uint64(1), uint96(1)); - assertNotEq(uint160(2), uint160(2)); - } -} - -contract TestTest is Test { - modifier expectFailure(bool expectFail) { - bool preState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); - _; - bool postState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); - - if (preState == true) { - return; - } - - if (expectFail) { - require(postState == true, "expected failure not triggered"); - - // unwind the expected failure - vm.store(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x00))); - } else { - require(postState == false, "unexpected failure was triggered"); - } - } - - function _fail(string memory err) external expectFailure(true) { - fail(err); - } - - function _assertFalse(bool data, bool expectFail) external expectFailure(expectFail) { - assertFalse(data); - } - - function _assertFalse(bool data, string memory err, bool expectFail) external expectFailure(expectFail) { - assertFalse(data, err); - } - - function _assertEq(bool a, bool b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(bool a, bool b, string memory err, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b, err); - } - - function _assertEq(bytes memory a, bytes memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(bytes memory a, bytes memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(uint256[] memory a, uint256[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(int256[] memory a, int256[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(address[] memory a, address[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(uint256[] memory a, uint256[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(int256[] memory a, int256[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(address[] memory a, address[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertNotEq(bytes32 a, bytes32 b, bool expectFail) external expectFailure(expectFail) { - assertNotEq32(a, b); - } - - function _assertNotEq(bytes32 a, bytes32 b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertNotEq32(a, b, err); - } - - function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta); - } - - function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta, err); - } - - function _assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - - function _assertApproxEqAbsDecimal( - uint256 a, - uint256 b, - uint256 maxDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); - } - - function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta); - } - - function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta, err); - } - - function _assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - - function _assertApproxEqAbsDecimal( - int256 a, - int256 b, - uint256 maxDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); - } - - function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta); - } - - function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta, err); - } - - function _assertApproxEqRelDecimal(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - - function _assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); - } - - function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta); - } - - function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta, err); - } - - function _assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - - function _assertApproxEqRelDecimal( - int256 a, - int256 b, - uint256 maxPercentDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); - } - - function _assertEqCall( - address targetA, - bytes memory callDataA, - address targetB, - bytes memory callDataB, - bool strictRevertData, - bool expectFail - ) external expectFailure(expectFail) { - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } -} - -contract TestMockCall { - bytes returnData; - bool shouldRevert; - - constructor(bytes memory returnData_, bool shouldRevert_) { - returnData = returnData_; - shouldRevert = shouldRevert_; - } - - fallback() external payable { - bytes memory returnData_ = returnData; - - if (shouldRevert) { - assembly { - revert(add(returnData_, 0x20), mload(returnData_)) - } - } else { - assembly { - return(add(returnData_, 0x20), mload(returnData_)) - } - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdChains.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdChains.t.sol deleted file mode 100644 index f0ede99..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdChains.t.sol +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdChainsTest is Test { - function testChainRpcInitialization() public { - // RPCs specified in `foundry.toml` should be updated. - assertEq(getChain(1).rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); - assertEq(getChain("optimism_goerli").rpcUrl, "https://goerli.optimism.io/"); - assertEq(getChain("arbitrum_one_goerli").rpcUrl, "https://goerli-rollup.arbitrum.io/rpc/"); - - // Environment variables should be the next fallback - assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); - vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); - assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); - vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); - - // Cannot override RPCs defined in `foundry.toml` - vm.setEnv("MAINNET_RPC_URL", "myoverride2"); - assertEq(getChain("mainnet").rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); - - // Other RPCs should remain unchanged. - assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); - assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); - } - - function testRpc(string memory rpcAlias) internal { - string memory rpcUrl = getChain(rpcAlias).rpcUrl; - vm.createSelectFork(rpcUrl); - } - - // Ensure we can connect to the default RPC URL for each chain. - // function testRpcs() public { - // testRpc("mainnet"); - // testRpc("goerli"); - // testRpc("sepolia"); - // testRpc("optimism"); - // testRpc("optimism_goerli"); - // testRpc("arbitrum_one"); - // testRpc("arbitrum_one_goerli"); - // testRpc("arbitrum_nova"); - // testRpc("polygon"); - // testRpc("polygon_mumbai"); - // testRpc("avalanche"); - // testRpc("avalanche_fuji"); - // testRpc("bnb_smart_chain"); - // testRpc("bnb_smart_chain_testnet"); - // testRpc("gnosis_chain"); - // } - - function testChainNoDefault() public { - vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); - getChain("does_not_exist"); - } - - function testSetChainFirstFails() public { - vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); - setChain("anvil2", ChainData("Anvil", 31337, "URL")); - } - - function testChainBubbleUp() public { - setChain("needs_undefined_env_var", ChainData("", 123456789, "")); - vm.expectRevert( - "Failed to resolve env var `UNDEFINED_RPC_URL_PLACEHOLDER` in `${UNDEFINED_RPC_URL_PLACEHOLDER}`: environment variable not found" - ); - getChain("needs_undefined_env_var"); - } - - function testCannotSetChain_ChainIdExists() public { - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - - vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); - - setChain("another_custom_chain", ChainData("", 123456789, "")); - } - - function testSetChain() public { - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - Chain memory customChain = getChain("custom_chain"); - assertEq(customChain.name, "Custom Chain"); - assertEq(customChain.chainId, 123456789); - assertEq(customChain.chainAlias, "custom_chain"); - assertEq(customChain.rpcUrl, "https://custom.chain/"); - Chain memory chainById = getChain(123456789); - assertEq(chainById.name, customChain.name); - assertEq(chainById.chainId, customChain.chainId); - assertEq(chainById.chainAlias, customChain.chainAlias); - assertEq(chainById.rpcUrl, customChain.rpcUrl); - customChain.name = "Another Custom Chain"; - customChain.chainId = 987654321; - setChain("another_custom_chain", customChain); - Chain memory anotherCustomChain = getChain("another_custom_chain"); - assertEq(anotherCustomChain.name, "Another Custom Chain"); - assertEq(anotherCustomChain.chainId, 987654321); - assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); - assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); - // Verify the first chain data was not overwritten - chainById = getChain(123456789); - assertEq(chainById.name, "Custom Chain"); - assertEq(chainById.chainId, 123456789); - } - - function testSetNoEmptyAlias() public { - vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); - setChain("", ChainData("", 123456789, "")); - } - - function testSetNoChainId0() public { - vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); - setChain("alias", ChainData("", 0, "")); - } - - function testGetNoChainId0() public { - vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); - getChain(0); - } - - function testGetNoEmptyAlias() public { - vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); - getChain(""); - } - - function testChainIdNotFound() public { - vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); - getChain("no_such_alias"); - } - - function testChainAliasNotFound() public { - vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); - getChain(321); - } - - function testSetChain_ExistingOne() public { - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - assertEq(getChain(123456789).chainId, 123456789); - - setChain("custom_chain", ChainData("Modified Chain", 999999999, "https://modified.chain/")); - vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); - getChain(123456789); - - Chain memory modifiedChain = getChain(999999999); - assertEq(modifiedChain.name, "Modified Chain"); - assertEq(modifiedChain.chainId, 999999999); - assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); - } - - function testDontUseDefaultRpcUrl() public { - // Should error if default RPCs flag is set to false. - setFallbackToDefaultRpcUrls(false); - vm.expectRevert( - "Failed to get environment variable `ANVIL_RPC_URL` as type `string`: environment variable not found" - ); - getChain(31337); - vm.expectRevert( - "Failed to get environment variable `SEPOLIA_RPC_URL` as type `string`: environment variable not found" - ); - getChain("sepolia"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdCheats.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdCheats.t.sol deleted file mode 100644 index 6f4d5bb..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdCheats.t.sol +++ /dev/null @@ -1,507 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdCheats.sol"; -import "../src/Test.sol"; -import "../src/StdJson.sol"; - -contract StdCheatsTest is Test { - Bar test; - - using stdJson for string; - - function setUp() public { - test = new Bar(); - } - - function testSkip() public { - vm.warp(100); - skip(25); - assertEq(block.timestamp, 125); - } - - function testRewind() public { - vm.warp(100); - rewind(25); - assertEq(block.timestamp, 75); - } - - function testHoax() public { - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - } - - function testHoaxOrigin() public { - hoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - } - - function testHoaxDifferentAddresses() public { - hoax(address(1337), address(7331)); - test.origin{value: 100}(address(1337), address(7331)); - } - - function testStartHoax() public { - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testStartHoaxOrigin() public { - startHoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - test.origin{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testChangePrankMsgSender() public { - vm.startPrank(address(1337)); - test.bar(address(1337)); - changePrank(address(0xdead)); - test.bar(address(0xdead)); - changePrank(address(1337)); - test.bar(address(1337)); - vm.stopPrank(); - } - - function testChangePrankMsgSenderAndTxOrigin() public { - vm.startPrank(address(1337), address(1338)); - test.origin(address(1337), address(1338)); - changePrank(address(0xdead), address(0xbeef)); - test.origin(address(0xdead), address(0xbeef)); - changePrank(address(1337), address(1338)); - test.origin(address(1337), address(1338)); - vm.stopPrank(); - } - - function testMakeAccountEquivalence() public { - Account memory account = makeAccount("1337"); - (address addr, uint256 key) = makeAddrAndKey("1337"); - assertEq(account.addr, addr); - assertEq(account.key, key); - } - - function testMakeAddrEquivalence() public { - (address addr,) = makeAddrAndKey("1337"); - assertEq(makeAddr("1337"), addr); - } - - function testMakeAddrSigning() public { - (address addr, uint256 key) = makeAddrAndKey("1337"); - bytes32 hash = keccak256("some_message"); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); - assertEq(ecrecover(hash, v, r, s), addr); - } - - function testDeal() public { - deal(address(this), 1 ether); - assertEq(address(this).balance, 1 ether); - } - - function testDealToken() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18); - assertEq(barToken.balanceOf(address(this)), 10000e18); - } - - function testDealTokenAdjustTotalSupply() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18, true); - assertEq(barToken.balanceOf(address(this)), 10000e18); - assertEq(barToken.totalSupply(), 20000e18); - deal(bar, address(this), 0, true); - assertEq(barToken.balanceOf(address(this)), 0); - assertEq(barToken.totalSupply(), 10000e18); - } - - function testDealERC1155Token() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, false); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - } - - function testDealERC1155TokenAdjustTotalSupply() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, true); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - assertEq(barToken.totalSupply(0), 20000e18); - dealERC1155(bar, address(this), 0, 0, true); - assertEq(barToken.balanceOf(address(this), 0), 0); - assertEq(barToken.totalSupply(0), 10000e18); - } - - function testDealERC721Token() public { - BarERC721 barToken = new BarERC721(); - address bar = address(barToken); - dealERC721(bar, address(2), 1); - assertEq(barToken.balanceOf(address(2)), 1); - assertEq(barToken.balanceOf(address(1)), 0); - dealERC721(bar, address(1), 2); - assertEq(barToken.balanceOf(address(1)), 1); - assertEq(barToken.balanceOf(bar), 1); - } - - function testDeployCode() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function testDestroyAccount() public { - // deploy something to destroy it - BarERC721 barToken = new BarERC721(); - address bar = address(barToken); - vm.setNonce(bar, 10); - deal(bar, 100); - - uint256 prevThisBalance = address(this).balance; - uint256 size; - assembly { - size := extcodesize(bar) - } - - assertGt(size, 0); - assertEq(bar.balance, 100); - assertEq(vm.getNonce(bar), 10); - - destroyAccount(bar, address(this)); - assembly { - size := extcodesize(bar) - } - assertEq(address(this).balance, prevThisBalance + 100); - assertEq(vm.getNonce(bar), 0); - assertEq(size, 0); - assertEq(bar.balance, 0); - } - - function testDeployCodeNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar"); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function testDeployCodeVal() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - function testDeployCodeValNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - // We need this so we can call "this.deployCode" rather than "deployCode" directly - function deployCodeHelper(string memory what) external { - deployCode(what); - } - - function testDeployCodeFail() public { - vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); - this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); - } - - function getCode(address who) internal view returns (bytes memory o_code) { - /// @solidity memory-safe-assembly - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(who) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(who, add(o_code, 0x20), 0, size) - } - } - - function testDeriveRememberKey() public { - string memory mnemonic = "test test test test test test test test test test test junk"; - - (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); - assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); - } - - function testBytesToUint() public { - assertEq(3, bytesToUint_test(hex"03")); - assertEq(2, bytesToUint_test(hex"02")); - assertEq(255, bytesToUint_test(hex"ff")); - assertEq(29625, bytesToUint_test(hex"73b9")); - } - - function testParseJsonTxDetail() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - string memory json = vm.readFile(path); - bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); - RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); - Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); - assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); - assertEq( - txDetail.data, - hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" - ); - assertEq(txDetail.nonce, 3); - assertEq(txDetail.txType, 2); - assertEq(txDetail.gas, 29625); - assertEq(txDetail.value, 0); - } - - function testReadEIP1559Transaction() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 0; - Tx1559 memory transaction = readTx1559(path, index); - transaction; - } - - function testReadEIP1559Transactions() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Tx1559[] memory transactions = readTx1559s(path); - transactions; - } - - function testReadReceipt() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 5; - Receipt memory receipt = readReceipt(path, index); - assertEq( - receipt.logsBloom, - hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" - ); - } - - function testReadReceipts() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Receipt[] memory receipts = readReceipts(path); - receipts; - } - - function testGasMeteringModifier() public { - uint256 gas_start_normal = gasleft(); - addInLoop(); - uint256 gas_used_normal = gas_start_normal - gasleft(); - - uint256 gas_start_single = gasleft(); - addInLoopNoGas(); - uint256 gas_used_single = gas_start_single - gasleft(); - - uint256 gas_start_double = gasleft(); - addInLoopNoGasNoGas(); - uint256 gas_used_double = gas_start_double - gasleft(); - - emit log_named_uint("Normal gas", gas_used_normal); - emit log_named_uint("Single modifier gas", gas_used_single); - emit log_named_uint("Double modifier gas", gas_used_double); - assertTrue(gas_used_double + gas_used_single < gas_used_normal); - } - - function addInLoop() internal pure returns (uint256) { - uint256 b; - for (uint256 i; i < 10000; i++) { - b += i; - } - return b; - } - - function addInLoopNoGas() internal noGasMetering returns (uint256) { - return addInLoop(); - } - - function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { - return addInLoopNoGas(); - } - - function bytesToUint_test(bytes memory b) private pure returns (uint256) { - uint256 number; - for (uint256 i = 0; i < b.length; i++) { - number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); - } - return number; - } - - function testAssumeNoPrecompiles(address addr) external { - assumeNoPrecompiles(addr, getChain("optimism_goerli").chainId); - assertTrue( - addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) - || addr > address(0x4200000000000000000000000000000000000800) - ); - } - - function testAssumePayable() external { - // all should revert since these addresses are not payable - - // VM address - vm.expectRevert(); - assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - // Console address - vm.expectRevert(); - assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); - - // Create2Deployer - vm.expectRevert(); - assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); - } - - function testAssumePayable(address addr) external { - assumePayable(addr); - assertTrue( - addr != 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D && addr != 0x000000000000000000636F6e736F6c652e6c6f67 - && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C - ); - } -} - -contract StdCheatsMock is StdCheats { - // We deploy a mock version so we can properly test expected reverts. - function assumeNoBlacklisted_(address token, address addr) external { - return assumeNoBlacklisted(token, addr); - } -} - -contract StdCheatsForkTest is Test { - address internal constant SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; - address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; - address internal constant USDC_BLACKLISTED_USER = 0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD; - address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; - address internal constant USDT_BLACKLISTED_USER = 0x8f8a8F4B54a2aAC7799d7bc81368aC27b852822A; - - // We deploy a mock version so we can properly test the revert. - StdCheatsMock private stdCheats = new StdCheatsMock(); - - function setUp() public { - // All tests of the `assumeNoBlacklisted` method are fork tests using live contracts. - vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); - } - - function testCannotAssumeNoBlacklisted_EOA() external { - address eoa = vm.addr({privateKey: 1}); - vm.expectRevert("StdCheats assumeNoBlacklisted(address,address): Token address is not a contract."); - assumeNoBlacklisted(eoa, address(0)); - } - - function testAssumeNoBlacklisted_TokenWithoutBlacklist(address addr) external { - assumeNoBlacklisted(SHIB, addr); - assertTrue(true); - } - - function testAssumeNoBlacklisted_USDC() external { - vm.expectRevert(); - stdCheats.assumeNoBlacklisted_(USDC, USDC_BLACKLISTED_USER); - } - - function testAssumeNoBlacklisted_USDC(address addr) external { - assumeNoBlacklisted(USDC, addr); - assertFalse(USDCLike(USDC).isBlacklisted(addr)); - } - - function testAssumeNoBlacklisted_USDT() external { - vm.expectRevert(); - stdCheats.assumeNoBlacklisted_(USDT, USDT_BLACKLISTED_USER); - } - - function testAssumeNoBlacklisted_USDT(address addr) external { - assumeNoBlacklisted(USDT, addr); - assertFalse(USDTLike(USDT).isBlackListed(addr)); - } -} - -contract Bar { - constructor() payable { - /// `DEAL` STDCHEAT - totalSupply = 10000e18; - balanceOf[address(this)] = totalSupply; - } - - /// `HOAX` and `CHANGEPRANK` STDCHEATS - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } - - function origin(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedSender, "!prank"); - } - - function origin(address expectedSender, address expectedOrigin) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedOrigin, "!prank"); - } - - /// `DEAL` STDCHEAT - mapping(address => uint256) public balanceOf; - uint256 public totalSupply; -} - -contract BarERC1155 { - constructor() payable { - /// `DEALERC1155` STDCHEAT - _totalSupply[0] = 10000e18; - _balances[0][address(this)] = _totalSupply[0]; - } - - function balanceOf(address account, uint256 id) public view virtual returns (uint256) { - return _balances[id][account]; - } - - function totalSupply(uint256 id) public view virtual returns (uint256) { - return _totalSupply[id]; - } - - /// `DEALERC1155` STDCHEAT - mapping(uint256 => mapping(address => uint256)) private _balances; - mapping(uint256 => uint256) private _totalSupply; -} - -contract BarERC721 { - constructor() payable { - /// `DEALERC721` STDCHEAT - _owners[1] = address(1); - _balances[address(1)] = 1; - _owners[2] = address(this); - _owners[3] = address(this); - _balances[address(this)] = 2; - } - - function balanceOf(address owner) public view virtual returns (uint256) { - return _balances[owner]; - } - - function ownerOf(uint256 tokenId) public view virtual returns (address) { - address owner = _owners[tokenId]; - return owner; - } - - mapping(uint256 => address) private _owners; - mapping(address => uint256) private _balances; -} - -interface USDCLike { - function isBlacklisted(address) external view returns (bool); -} - -interface USDTLike { - function isBlackListed(address) external view returns (bool); -} - -contract RevertingContract { - constructor() { - revert(); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdError.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdError.t.sol deleted file mode 100644 index ccd3efa..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdError.t.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import "../src/StdError.sol"; -import "../src/Test.sol"; - -contract StdErrorsTest is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectAssertion() public { - vm.expectRevert(stdError.assertionError); - test.assertionError(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } - - function testExpectDiv() public { - vm.expectRevert(stdError.divisionError); - test.divError(0); - } - - function testExpectMod() public { - vm.expectRevert(stdError.divisionError); - test.modError(0); - } - - function testExpectEnum() public { - vm.expectRevert(stdError.enumConversionError); - test.enumConversion(1); - } - - function testExpectEncodeStg() public { - vm.expectRevert(stdError.encodeStorageError); - test.encodeStgError(); - } - - function testExpectPop() public { - vm.expectRevert(stdError.popError); - test.pop(); - } - - function testExpectOOB() public { - vm.expectRevert(stdError.indexOOBError); - test.indexOOBError(1); - } - - function testExpectMem() public { - vm.expectRevert(stdError.memOverflowError); - test.mem(); - } - - function testExpectIntern() public { - vm.expectRevert(stdError.zeroVarError); - test.intern(); - } -} - -contract ErrorsTest { - enum T {T1} - - uint256[] public someArr; - bytes someBytes; - - function assertionError() public pure { - assert(false); - } - - function arithmeticError(uint256 a) public pure { - a -= 100; - } - - function divError(uint256 a) public pure { - 100 / a; - } - - function modError(uint256 a) public pure { - 100 % a; - } - - function enumConversion(uint256 a) public pure { - T(a); - } - - function encodeStgError() public { - /// @solidity memory-safe-assembly - assembly { - sstore(someBytes.slot, 1) - } - keccak256(someBytes); - } - - function pop() public { - someArr.pop(); - } - - function indexOOBError(uint256 a) public pure { - uint256[] memory t = new uint256[](0); - t[a]; - } - - function mem() public pure { - uint256 l = 2 ** 256 / 32; - new uint256[](l); - } - - function intern() public returns (uint256) { - function(uint256) internal returns (uint256) x; - x(2); - return 7; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdMath.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdMath.t.sol deleted file mode 100644 index 95037ea..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdMath.t.sol +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import "../src/StdMath.sol"; -import "../src/Test.sol"; - -contract StdMathTest is Test { - function testGetAbs() external { - assertEq(stdMath.abs(-50), 50); - assertEq(stdMath.abs(50), 50); - assertEq(stdMath.abs(-1337), 1337); - assertEq(stdMath.abs(0), 0); - - assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); - assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); - } - - function testGetAbs_Fuzz(int256 a) external { - uint256 manualAbs = getAbs(a); - - uint256 abs = stdMath.abs(a); - - assertEq(abs, manualAbs); - } - - function testGetDelta_Uint() external { - assertEq(stdMath.delta(uint256(0), uint256(0)), 0); - assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); - assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); - assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); - assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); - - assertEq(stdMath.delta(0, uint256(0)), 0); - assertEq(stdMath.delta(1337, uint256(0)), 1337); - assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); - assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); - assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); - - assertEq(stdMath.delta(1337, uint256(1337)), 0); - assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); - assertEq(stdMath.delta(5000, uint256(1250)), 3750); - } - - function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external { - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function testGetDelta_Int() external { - assertEq(stdMath.delta(int256(0), int256(0)), 0); - assertEq(stdMath.delta(int256(0), int256(1337)), 1337); - assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); - assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); - assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); - - assertEq(stdMath.delta(0, int256(0)), 0); - assertEq(stdMath.delta(1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); - assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); - assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); - - assertEq(stdMath.delta(-0, int256(0)), 0); - assertEq(stdMath.delta(-1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(int256(0), -0), 0); - assertEq(stdMath.delta(int256(0), -1337), 1337); - assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(1337, int256(1337)), 0); - assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); - assertEq(stdMath.delta(5000, int256(1250)), 3750); - } - - function testGetDelta_Int_Fuzz(int256 a, int256 b) external { - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function testGetPercentDelta_Uint() external { - assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); - assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); - assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); - assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMath.percentDelta(uint256(1), 0); - } - - function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external { - vm.assume(b != 0); - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / b; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - function testGetPercentDelta_Int() external { - assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); - assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, int256(1337)), 0); - assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); - assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); - - assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, int256(2500)), 0); - assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMath.percentDelta(int256(1), 0); - } - - function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external { - vm.assume(b != 0); - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / absB; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - /*////////////////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////////////////*/ - - function getAbs(int256 a) private pure returns (uint256) { - if (a < 0) { - return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); - } - - return uint256(a); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdStorage.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdStorage.t.sol deleted file mode 100644 index d4c563a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdStorage.t.sol +++ /dev/null @@ -1,283 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdStorage.sol"; -import "../src/Test.sol"; - -contract StdStorageTest is Test { - using stdStorage for StdStorage; - - StorageTest internal test; - - function setUp() public { - test = new StorageTest(); - } - - function testStorageHidden() public { - assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); - } - - function testStorageObvious() public { - assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); - } - - function testStorageCheckedWriteHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); - assertEq(uint256(test.hidden()), 100); - } - - function testStorageCheckedWriteObvious() public { - stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); - assertEq(test.exists(), 100); - } - - function testStorageMapStructA() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); - } - - function testStorageMapStructB() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); - } - - function testStorageDeepMap() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( - address(this) - ).find(); - assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); - } - - function testStorageCheckedWriteDeepMap() public { - stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) - .checked_write(100); - assertEq(100, test.deep_map(address(this), address(this))); - } - - function testStorageDeepMapStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(0).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), - bytes32(slot) - ); - } - - function testStorageDeepMapStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(1).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), - bytes32(slot) - ); - } - - function testStorageCheckedWriteDeepMapStructA() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(100, a); - assertEq(0, b); - } - - function testStorageCheckedWriteDeepMapStructB() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(0, a); - assertEq(100, b); - } - - function testStorageCheckedWriteMapStructA() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 100); - assertEq(b, 0); - } - - function testStorageCheckedWriteMapStructB() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 0); - assertEq(b, 100); - } - - function testStorageStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); - assertEq(uint256(7), slot); - } - - function testStorageStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); - assertEq(uint256(7) + 1, slot); - } - - function testStorageCheckedWriteStructA() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 100); - assertEq(b, 1337); - } - - function testStorageCheckedWriteStructB() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 1337); - assertEq(b, 100); - } - - function testStorageMapAddrFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); - assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); - } - - function testStorageMapUintFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); - assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); - } - - function testStorageCheckedWriteMapUint() public { - stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); - assertEq(100, test.map_uint(100)); - } - - function testStorageCheckedWriteMapAddr() public { - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); - assertEq(100, test.map_addr(address(this))); - } - - function testStorageCheckedWriteMapBool() public { - stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); - assertTrue(test.map_bool(address(this))); - } - - function testFailStorageCheckedWriteMapPacked() public { - // expect PackedSlot error but not external call so cant expectRevert - stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337))) - .checked_write(100); - } - - function testStorageCheckedWriteMapPackedSuccess() public { - uint256 full = test.map_packed(address(1337)); - // keep upper 128, set lower 128 to 1337 - full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; - stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( - full - ); - assertEq(1337, test.read_struct_lower(address(1337))); - } - - function testFailStorageConst() public { - // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); - stdstore.target(address(test)).sig("const()").find(); - } - - function testFailStorageNativePack() public { - stdstore.target(address(test)).sig(test.tA.selector).find(); - stdstore.target(address(test)).sig(test.tB.selector).find(); - - // these both would fail - stdstore.target(address(test)).sig(test.tC.selector).find(); - stdstore.target(address(test)).sig(test.tD.selector).find(); - } - - function testStorageReadBytes32() public { - bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); - assertEq(val, hex"1337"); - } - - function testStorageReadBool_False() public { - bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); - assertEq(val, false); - } - - function testStorageReadBool_True() public { - bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); - assertEq(val, true); - } - - function testStorageReadBool_Revert() public { - vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - this.readNonBoolValue(); - } - - function readNonBoolValue() public { - stdstore.target(address(test)).sig(test.tE.selector).read_bool(); - } - - function testStorageReadAddress() public { - address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); - assertEq(val, address(1337)); - } - - function testStorageReadUint() public { - uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); - assertEq(val, 1); - } - - function testStorageReadInt() public { - int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); - assertEq(val, type(int256).min); - } -} - -contract StorageTest { - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - mapping(uint256 => uint256) public map_uint; - mapping(address => uint256) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basic; - - uint248 public tA; - bool public tB; - - bool public tC = false; - uint248 public tD = 1; - - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - mapping(address => bool) public map_bool; - - bytes32 public tE = hex"1337"; - address public tF = address(1337); - int256 public tG = type(int256).min; - bool public tH = true; - - constructor() { - basic = UnpackedStruct({a: 1337, b: 1337}); - - uint256 two = (1 << 128) | 1; - map_packed[msg.sender] = two; - map_packed[address(uint160(1337))] = 1 << 128; - } - - function read_struct_upper(address who) public view returns (uint256) { - return map_packed[who] >> 128; - } - - function read_struct_lower(address who) public view returns (uint256) { - return map_packed[who] & ((1 << 128) - 1); - } - - function hidden() public view returns (bytes32 t) { - bytes32 slot = keccak256("my.random.var"); - /// @solidity memory-safe-assembly - assembly { - t := sload(slot) - } - } - - function const() public pure returns (bytes32 t) { - t = bytes32(hex"1337"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdStyle.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdStyle.t.sol deleted file mode 100644 index f6fffe7..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdStyle.t.sol +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdStyleTest is Test { - function testStyleColor() public pure { - console2.log(StdStyle.red("StdStyle.red String Test")); - console2.log(StdStyle.red(uint256(10e18))); - console2.log(StdStyle.red(int256(-10e18))); - console2.log(StdStyle.red(true)); - console2.log(StdStyle.red(address(0))); - console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); - console2.log(StdStyle.green("StdStyle.green String Test")); - console2.log(StdStyle.green(uint256(10e18))); - console2.log(StdStyle.green(int256(-10e18))); - console2.log(StdStyle.green(true)); - console2.log(StdStyle.green(address(0))); - console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); - console2.log(StdStyle.yellow("StdStyle.yellow String Test")); - console2.log(StdStyle.yellow(uint256(10e18))); - console2.log(StdStyle.yellow(int256(-10e18))); - console2.log(StdStyle.yellow(true)); - console2.log(StdStyle.yellow(address(0))); - console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); - console2.log(StdStyle.blue("StdStyle.blue String Test")); - console2.log(StdStyle.blue(uint256(10e18))); - console2.log(StdStyle.blue(int256(-10e18))); - console2.log(StdStyle.blue(true)); - console2.log(StdStyle.blue(address(0))); - console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); - console2.log(StdStyle.magenta("StdStyle.magenta String Test")); - console2.log(StdStyle.magenta(uint256(10e18))); - console2.log(StdStyle.magenta(int256(-10e18))); - console2.log(StdStyle.magenta(true)); - console2.log(StdStyle.magenta(address(0))); - console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); - console2.log(StdStyle.cyan("StdStyle.cyan String Test")); - console2.log(StdStyle.cyan(uint256(10e18))); - console2.log(StdStyle.cyan(int256(-10e18))); - console2.log(StdStyle.cyan(true)); - console2.log(StdStyle.cyan(address(0))); - console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); - } - - function testStyleFontWeight() public pure { - console2.log(StdStyle.bold("StdStyle.bold String Test")); - console2.log(StdStyle.bold(uint256(10e18))); - console2.log(StdStyle.bold(int256(-10e18))); - console2.log(StdStyle.bold(address(0))); - console2.log(StdStyle.bold(true)); - console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); - console2.log(StdStyle.dim("StdStyle.dim String Test")); - console2.log(StdStyle.dim(uint256(10e18))); - console2.log(StdStyle.dim(int256(-10e18))); - console2.log(StdStyle.dim(address(0))); - console2.log(StdStyle.dim(true)); - console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); - console2.log(StdStyle.italic("StdStyle.italic String Test")); - console2.log(StdStyle.italic(uint256(10e18))); - console2.log(StdStyle.italic(int256(-10e18))); - console2.log(StdStyle.italic(address(0))); - console2.log(StdStyle.italic(true)); - console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); - console2.log(StdStyle.underline("StdStyle.underline String Test")); - console2.log(StdStyle.underline(uint256(10e18))); - console2.log(StdStyle.underline(int256(-10e18))); - console2.log(StdStyle.underline(address(0))); - console2.log(StdStyle.underline(true)); - console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); - console2.log(StdStyle.inverse("StdStyle.inverse String Test")); - console2.log(StdStyle.inverse(uint256(10e18))); - console2.log(StdStyle.inverse(int256(-10e18))); - console2.log(StdStyle.inverse(address(0))); - console2.log(StdStyle.inverse(true)); - console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); - } - - function testStyleCombined() public pure { - console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); - console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); - console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); - console2.log(StdStyle.blue(StdStyle.underline(address(0)))); - console2.log(StdStyle.magenta(StdStyle.inverse(true))); - } - - function testStyleCustom() public pure { - console2.log(h1("Custom Style 1")); - console2.log(h2("Custom Style 2")); - } - - function h1(string memory a) private pure returns (string memory) { - return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); - } - - function h2(string memory a) private pure returns (string memory) { - return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdUtils.t.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdUtils.t.sol deleted file mode 100644 index e859124..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/StdUtils.t.sol +++ /dev/null @@ -1,312 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdUtilsMock is StdUtils { - // We deploy a mock version so we can properly test expected reverts. - function getTokenBalances_(address token, address[] memory addresses) - external - returns (uint256[] memory balances) - { - return getTokenBalances(token, addresses); - } -} - -contract StdUtilsTest is Test { - /*////////////////////////////////////////////////////////////////////////// - BOUND UINT - //////////////////////////////////////////////////////////////////////////*/ - - function testBound() public { - assertEq(bound(uint256(5), 0, 4), 0); - assertEq(bound(uint256(0), 69, 69), 69); - assertEq(bound(uint256(0), 68, 69), 68); - assertEq(bound(uint256(10), 150, 190), 174); - assertEq(bound(uint256(300), 2800, 3200), 3107); - assertEq(bound(uint256(9999), 1337, 6666), 4669); - } - - function testBound_WithinRange() public { - assertEq(bound(uint256(51), 50, 150), 51); - assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); - assertEq(bound(uint256(149), 50, 150), 149); - assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); - } - - function testBound_EdgeCoverage() public { - assertEq(bound(uint256(0), 50, 150), 50); - assertEq(bound(uint256(1), 50, 150), 51); - assertEq(bound(uint256(2), 50, 150), 52); - assertEq(bound(uint256(3), 50, 150), 53); - assertEq(bound(type(uint256).max, 50, 150), 150); - assertEq(bound(type(uint256).max - 1, 50, 150), 149); - assertEq(bound(type(uint256).max - 2, 50, 150), 148); - assertEq(bound(type(uint256).max - 3, 50, 150), 147); - } - - function testBound_DistributionIsEven(uint256 min, uint256 size) public { - size = size % 100 + 1; - min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); - uint256 max = min + size - 1; - uint256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + i, min, max); - assertEq(result, min + (i - 1) % size); - // x < min - result = bound(min - i, min, max); - assertEq(result, max - (i - 1) % size); - } - } - - function testBound(uint256 num, uint256 min, uint256 max) public { - if (min > max) (min, max) = (max, min); - - uint256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function testBoundUint256Max() public { - assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); - assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); - } - - function testCannotBoundMaxLessThanMin() public { - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - bound(uint256(5), 100, 10); - } - - function testCannotBoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - bound(num, min, max); - } - - /*////////////////////////////////////////////////////////////////////////// - BOUND INT - //////////////////////////////////////////////////////////////////////////*/ - - function testBoundInt() public { - assertEq(bound(-3, 0, 4), 2); - assertEq(bound(0, -69, -69), -69); - assertEq(bound(0, -69, -68), -68); - assertEq(bound(-10, 150, 190), 154); - assertEq(bound(-300, 2800, 3200), 2908); - assertEq(bound(9999, -1337, 6666), 1995); - } - - function testBoundInt_WithinRange() public { - assertEq(bound(51, -50, 150), 51); - assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); - assertEq(bound(149, -50, 150), 149); - assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); - } - - function testBoundInt_EdgeCoverage() public { - assertEq(bound(type(int256).min, -50, 150), -50); - assertEq(bound(type(int256).min + 1, -50, 150), -49); - assertEq(bound(type(int256).min + 2, -50, 150), -48); - assertEq(bound(type(int256).min + 3, -50, 150), -47); - assertEq(bound(type(int256).min, 10, 150), 10); - assertEq(bound(type(int256).min + 1, 10, 150), 11); - assertEq(bound(type(int256).min + 2, 10, 150), 12); - assertEq(bound(type(int256).min + 3, 10, 150), 13); - - assertEq(bound(type(int256).max, -50, 150), 150); - assertEq(bound(type(int256).max - 1, -50, 150), 149); - assertEq(bound(type(int256).max - 2, -50, 150), 148); - assertEq(bound(type(int256).max - 3, -50, 150), 147); - assertEq(bound(type(int256).max, -50, -10), -10); - assertEq(bound(type(int256).max - 1, -50, -10), -11); - assertEq(bound(type(int256).max - 2, -50, -10), -12); - assertEq(bound(type(int256).max - 3, -50, -10), -13); - } - - function testBoundInt_DistributionIsEven(int256 min, uint256 size) public { - size = size % 100 + 1; - min = bound(min, -int256(size / 2), int256(size - size / 2)); - int256 max = min + int256(size) - 1; - int256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + int256(i), min, max); - assertEq(result, min + int256((i - 1) % size)); - // x < min - result = bound(min - int256(i), min, max); - assertEq(result, max - int256((i - 1) % size)); - } - } - - function testBoundInt(int256 num, int256 min, int256 max) public { - if (min > max) (min, max) = (max, min); - - int256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function testBoundIntInt256Max() public { - assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); - assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); - } - - function testBoundIntInt256Min() public { - assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); - assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); - } - - function testCannotBoundIntMaxLessThanMin() public { - vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); - bound(-5, 100, 10); - } - - function testCannotBoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); - bound(num, min, max); - } - - /*////////////////////////////////////////////////////////////////////////// - BOUND PRIVATE KEY - //////////////////////////////////////////////////////////////////////////*/ - - function testBoundPrivateKey() public { - assertEq(boundPrivateKey(0), 1); - assertEq(boundPrivateKey(1), 1); - assertEq(boundPrivateKey(300), 300); - assertEq(boundPrivateKey(9999), 9999); - assertEq(boundPrivateKey(SECP256K1_ORDER - 1), SECP256K1_ORDER - 1); - assertEq(boundPrivateKey(SECP256K1_ORDER), 1); - assertEq(boundPrivateKey(SECP256K1_ORDER + 1), 2); - assertEq(boundPrivateKey(UINT256_MAX), UINT256_MAX & SECP256K1_ORDER - 1); // x&y is equivalent to x-x%y - } - - /*////////////////////////////////////////////////////////////////////////// - BYTES TO UINT - //////////////////////////////////////////////////////////////////////////*/ - - function testBytesToUint() external { - bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - bytes memory two = hex"02"; - bytes memory millionEther = hex"d3c21bcecceda1000000"; - - assertEq(bytesToUint(maxUint), type(uint256).max); - assertEq(bytesToUint(two), 2); - assertEq(bytesToUint(millionEther), 1_000_000 ether); - } - - function testCannotConvertGT32Bytes() external { - bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); - bytesToUint(thirty3Bytes); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function testComputeCreateAddress() external { - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - uint256 nonce = 14; - address createAddress = computeCreateAddress(deployer, nonce); - assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE2 ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function testComputeCreate2Address() external { - bytes32 salt = bytes32(uint256(31415)); - bytes32 initcodeHash = keccak256(abi.encode(0x6080)); - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - address create2Address = computeCreate2Address(salt, initcodeHash, deployer); - assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); - } - - function testComputeCreate2AddressWithDefaultDeployer() external { - bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; - bytes32 initcodeHash = hashInitCode(hex"6080", ""); - assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); - address create2Address = computeCreate2Address(salt, initcodeHash); - assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); - } -} - -contract StdUtilsForkTest is Test { - /*////////////////////////////////////////////////////////////////////////// - GET TOKEN BALANCES - //////////////////////////////////////////////////////////////////////////*/ - - address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; - address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; - address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; - address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; - - address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; - address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; - address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; - - function setUp() public { - // All tests of the `getTokenBalances` method are fork tests using live contracts. - vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); - } - - function testCannotGetTokenBalances_NonTokenContract() external { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, - // so the `balanceOf` call should revert. - address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); - address[] memory addresses = new address[](1); - addresses[0] = USDC_HOLDER_0; - - vm.expectRevert("Multicall3: call failed"); - stdUtils.getTokenBalances_(token, addresses); - } - - function testCannotGetTokenBalances_EOA() external { - address eoa = vm.addr({privateKey: 1}); - address[] memory addresses = new address[](1); - addresses[0] = USDC_HOLDER_0; - vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); - getTokenBalances(eoa, addresses); - } - - function testGetTokenBalances_Empty() external { - address[] memory addresses = new address[](0); - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances.length, 0); - } - - function testGetTokenBalances_USDC() external { - address[] memory addresses = new address[](2); - addresses[0] = USDC_HOLDER_0; - addresses[1] = USDC_HOLDER_1; - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances[0], 159_000_000_000_000); - assertEq(balances[1], 131_350_000_000_000); - } - - function testGetTokenBalances_SHIB() external { - address[] memory addresses = new address[](3); - addresses[0] = SHIB_HOLDER_0; - addresses[1] = SHIB_HOLDER_1; - addresses[2] = SHIB_HOLDER_2; - uint256[] memory balances = getTokenBalances(SHIB, addresses); - assertEq(balances[0], 3_323_256_285_484.42e18); - assertEq(balances[1], 1_271_702_771_149.99999928e18); - assertEq(balances[2], 606_357_106_247e18); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationScript.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationScript.sol deleted file mode 100644 index e205cff..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationScript.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Script.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationScript is Script {} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationScriptBase.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationScriptBase.sol deleted file mode 100644 index ce8e0e9..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationScriptBase.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Script.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationScriptBase is ScriptBase {} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationTest.sol deleted file mode 100644 index 9beeafe..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationTest.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Test.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationTest is Test {} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationTestBase.sol b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationTestBase.sol deleted file mode 100644 index e993535..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/compilation/CompilationTestBase.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Test.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationTestBase is TestBase {} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/fixtures/broadcast.log.json b/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/fixtures/broadcast.log.json deleted file mode 100644 index 0a0200b..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/lib/forge-std/test/fixtures/broadcast.log.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "transactions": [ - { - "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", - "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0x73b9", - "value": "0x0", - "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", - "nonce": "0x3", - "accessList": [] - } - }, - { - "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "inc():(uint256)", - "arguments": [], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0xdcb2", - "value": "0x0", - "data": "0x371303c0", - "nonce": "0x4", - "accessList": [] - } - }, - { - "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "function": "t(uint256):(uint256)", - "arguments": ["1"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "gas": "0x8599", - "value": "0x0", - "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", - "nonce": "0x5", - "accessList": [] - } - } - ], - "receipts": [ - { - "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", - "transactionIndex": "0x0", - "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", - "blockNumber": "0x1", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x13f3a", - "gasUsed": "0x13f3a", - "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", - "transactionIndex": "0x0", - "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", - "blockNumber": "0x2", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x45d80", - "gasUsed": "0x45d80", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", - "transactionIndex": "0x0", - "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", - "blockNumber": "0x3", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "cumulativeGasUsed": "0x45feb", - "gasUsed": "0x45feb", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "transactionIndex": "0x0", - "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", - "blockNumber": "0x4", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0x5905", - "gasUsed": "0x5905", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "transactionIndex": "0x0", - "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", - "blockNumber": "0x5", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0xa9c4", - "gasUsed": "0xa9c4", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x0", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "cumulativeGasUsed": "0x66c5", - "gasUsed": "0x66c5", - "contractAddress": null, - "logs": [ - { - "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "topics": [ - "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x1", - "logIndex": "0x0", - "transactionLogIndex": "0x0", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", - "transactionIndex": "0x0", - "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", - "blockNumber": "0x7", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x0000000000000000000000000000000000001337", - "cumulativeGasUsed": "0x5208", - "gasUsed": "0x5208", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - } - ], - "libraries": [ - "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" - ], - "pending": [], - "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", - "returns": {}, - "timestamp": 1655140035 -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/morpho-blue-whitepaper.pdf b/lib/morpho-blue-irm/lib/morpho-blue/morpho-blue-whitepaper.pdf deleted file mode 100644 index b9a5a73c91302b1f9de6a9be8f8c15251c2b197f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708090 zcmeFYV~{Ofx93~7ZQHhOW0!5)wr%dRZQE75Y`b>ZuDW}_&v|d3)7^2SKiud~XGN?v zV~!j-GV?z&V*Fx`HAxjj#Aq4mSfNOJp9{XAm^ld;2y=2qbcCoQ_B48z;S8y~jwlH$GbNu^&e0&7- z>VK4ABw+sY{Ud{bR-rpD|>jHadrMogTXoXm!N zJf<8ROzfy$hA>_RMur|V3@cdF#TdS*43IH|*&q)?bTJSQ0( zZ4NwvMqk6Xjy4+{Gacg_{Tp;+tdBz~Ht{e%8X9~Xw(xM595Zcxz!;#*4j$%j*8k(8 z|JU>XKTG-F^Z!=hzZLjz1^!!s|GyM~`d2CYH!8>(*qAu|DQHapls9>M6I($eXA3)9 z0w#uk+gzNj{{V#(0V6BxKVAw3W+t-#s=2C8Ci4G2O#j#X*Nf#JuYZcSuz|CIwVm02 zf(e$tasPe&|7|5#{#TGcc*4ZQ`TrJvCWe0z$^WQ^`ucxL;qK~iACR%N8G@-l5JOf- z0P2|WYhM9C5lkkoiXFrEcKN^=Yt(pa{}Z4%+~7T^A(sp+EDVe`C9j3DaAoO5*J`Ky zRk^L*W79czx0!U>HB7XIgXKodZ^{js9nh_|nqpp!^Oj;a$Eg{cYeQS~T~;IrW6U-b z?tmr&1nEFgH0B#-hA|Cq3$A{pS^C}6^~GVTf#O#k8B<~X!Gfn3IL>8KrxG6D51)C< zkh2)&jFP&pz_-!Ffch8acvDmT_*_7MpSIG<|7*$pLuUU&B|%$TJ7=fA^v3Yltn_F6 zM`R|3e^SEqhl>8O{{t<5s7Bb%*4f1N&si-0kq_BF3}hf=_m_13G8Wq(6k_LO`U^mR znCXuv0q1`(j*^L!or|N<-}i!n<6mLv|H_BE3DNhz0gKG8Qp~2z*Ph7o!MrwkT3JP%~9sRsCQzKx0Jw+ zU^YPSsW4d-{z3&6<+(CsqZ;8Ns?EN16@ToY#Zq8r?Bj>GHsaoLLMuGq6?@;b+Ku`_ zzEzMaX#3S=H$Qf@AQ24(_JHp~(Zgd|5dqlJj^Yrv*9%4u_5SL3ReY2Q%)EgPw6ql_V~`AX1hVzZ5%l z4-UGr)jA86C+zn~6&6_$xVttb*Zqzv!Ak%Ma9S0YT+^<$B;??qgF&yd)m@M(tZf=? zk43S-{4j^x*fu+SSS+xboAuHden8*EFoeY8q%i7wa33e0aBLkdq9@3e5Tb zpfyE~i$Em@yG(P#&#tY=FlC`SWSxWq%Bgy)D-f5?c+7vb1bI?dw#5tji2n{?b^oAP zy3I1u#N*Yd7LAUKckC|1F=cHhATxmyS#r5Yg6cE1?WITb0DP3V2E{~@9;8J6E#;vY z0$3WpQ6v^NF^eVaCH=e@u25a#6KmaYc+A2@i)(hGI$14AwuzU;0)KZ~u{S9bf=Q^t zK3BEYeCn=&O0obJq&e2an;EN0F1&fOc#gMqDhC9-g974bVWWzS*f&Rzi%3c(Vs0CQ2NG1L=N%PKDk!1v;Y9qhbw#ikoJj7+_v@mFo5J*8CbC z$OaiOAXIgZmN`bzVIxHe(go1#&pNVjx==Yw3Q4)vRw%H#vyNxeIlI(s{pdD*tz%QF znU*}~0Kt}2WB2Z|L`^)RC>t~p{^47Y$Ys*m(O}oh>hO)h6*=COP~lg$V8d8jGdHJ?M3T6W z`2AYcmQ7ZXw$03$~F2-w1c5=+-G_=s-r zge8Q}Xn~xaMiis(v?hcKOFy4R2tSz0PKZtAz@ilN9WLj2nEw2ni>>)`yWpv{*KmL6 zUe02F#xjIv(#nGtPgPg)krqO4zCZ;lmdAXTO@BnwE{IdX0F5W89a4#^A;y$l6epyE z!=_hK^E2C~mjONM7fLUM?u#dClamV!x~yP?u#u{PyWQc+yLcfZ2K^!^yzJKejw7MF zfR$jtgA^T&Vj6oxP@5XbvQ-%6K%LM|OoRAg9JE-VM|Rq?t+pTWrG~7*sS6XKlK}}Y z{lNwd2QR5u)bJyliO|T=oMzOM(*uu zK*GqZb)ti6(VaZG_$_@5FoGx9T zwolg0wgyM4sz-^z1vLdz5+Ky^_;lkr1O%10C13!6Aa4Q%K0vIk-x$<69_SeXH;^eN zKtn~szrzB6prBkuCsF!q%(-Prfbx&Qz;7S{UV?{TMTP_k0QezDp6G>1q;T>fT*Cwb zGP?j+Nq~L}^_BQL-wE|wUuw^7d{{y5)*XY~L_|c`f4hQ@aSACiSTO+QL%KExaTT~V zfeiwBN?2hmE}i2Oa*$kV>*Ndt2*AU`>(&)Q(<7NsPmjai__wbEI{&0oNajWXdQoK% zfWCnERK}zS#1`0rJH8XI32SnA1Srf0Xaaz13?KXz z`e57z`&hyTz^C8o9sE4{q(*?b-N3ZAiE(xYBJR?M(DH|cfdl1HTi$hfbUp&}M~v4C z)o+7Fx`cNHAKcZaZtB0D>IX34#09|6+0{F0|52zfS3}oD$M8~%6wo`6-&qyxPeFi- z`x8PPJy7qJazH`B%6X&P-%oBCFyKMpBWY7Mrc;w24IQ{<*~ z3hg%(0#JYe(Et%Z88g6d3mfncRNb9P$TzL=XX)sgzF(t|XCQTg=zxzwYXWohK=|l& z+$g(|jzMp)AEo{!O`ynTzqx(4@me=!LpEl;EJ0%S@&U=Vz5EF!#_nI9$C zkNKUe==7g5#tW|wd~b=QM=?zyL(PS@Yi@k*P2jip*J1_@A}H7tL0_yC1MThs2Yg9~ z;n7%uKMd~$k{#NiqVTeRZz@3=!~}m}G58W10APdwc_HS&5*HO)cM@uMYtlN7tLa84)Hxceu+-bP!c2g#KRYf;$@t5XmmP^XgTD%8}8-dxWs47#Z04|k;%*+3xtYYh7RrkMHettEQ(}>kAHug_Fq>8*?H84{ zv3ynDvREl)_Tr6XP{?m2f0!MbP6)eaAtUlF2=96iaI^xkUI;YXko zgQf%g`f~g3x<;7TK6D<}F9y)9p&y8eu-kKZ1Lgk3HPHzdPu_MFaCmw~7xFH;WaBwE zcbPtR*C2zzAtM8>*YBdvkUqsHcfba5U>=H7=%N*&jY}v+U(BVEUCwXC>l*Xzd5hff znsZs(_z%I7aK%uZc>c8akrjH|r*X&~0*?fuk@8(9tTa&dgAn7N65TD^ew|zAnT$R29q>s z1_@*diV9k=<(MFf5VW3NyX5?O7p1N8u1ZPxCQJ-Z0S!}>UixigE%|Cn4ys9y*)-7! z;$-~Z=aVZT;fJv7+C->@Tpg9t9pJ#}GoZM0RM z>xIvwUQZcM3eLhuJqJW-0ODA*g{Zg1hm6ZC!fP&H@z*E?*0;?*_)frlk2P(nZ%XmU zdm_rasmvDPkRiHqEK4MA`9PavkQEGXcKC%vBk;L zkRDY6ss9So#jY_q zwW!K(;%;*yM5$wtZkiFupFLtrRS$@7Xj5psZm99WC`Z|{`r3fA6M#MBV6P%Mm`*1E zf+ICI902HfFuGih--Jz4X#F%ir|9~IdST9!29OV*6R!&;4}_@7@8lOkwxrMn3vaqN zE6kc)a97QpkP#`2SoK!H9(#`Mu97RC^0jJbVA2P_o%dSOg~>-+FANvT`jb9yDGyn3 zZR`xJ4__A5$+KUlV^c9Z3e6(5lJ*YcKuOmJC1Z4VVk+Z^QZA8;epEMKX*4OnTg#Rm&KR|OWp^Y11(d>gjB7fZ@QqFINh^8Q)dNaxld^?{!Ap;s z5Wn#kqNm}PcbYIZZ4gte@-^%uQ5Iy#GA7+@8i*NLKU;k}IE!08z44(c z^J8vgzZ;!!`qUs8OI=i>xp5>8MW44Vl{;OAug_U;E*sTw*f5FHwDQ(oS~QsR&{(|& zgAYXPymwTTBtPMyMh#pl$f5~#vMP#|W^TSz2?uRF^NxAII@t0emSRp|j{Si4vzEp1 z%L*amHAqOd;kF+%1TX*CAC4h!SMt0aEj9w@*h4tbw|}G_Hz6{Br|(2jURKMx@@Zuc z(U|Ec7qpf)LqSjsHf8n+Dpr@noTMqfGRw?ZS|~Ge6U>oya- z!Cd&$4TiOXrUI9E{3njL@oW1ezFl9P5i-P@rHa55Oi^1&tR;Nj?3~*ZNbqvYS~T9K zUMa1Y|7^ITKiqx=WJJA}=yaGsIX%t%4!>@1O=(t#wWmVjJ;axBejj=@U zpXx)0CkiT4i$^$mi#7nZ9l+(b8qdn)5keEyoP9k$WHE#4kCHxn2w5UgOeG|}_KrPiU&FJ%5a zi=DM{`FGOvmwWCMF`skEAacc`$7amusggQ4x?tmWu6M1lNZp?)<|5sOYnk7 zrZF%PXA0jp2g$zNaM`yZ@;(dQ%G>}*i>cN_6NFI#$#=xB!<_LUQ{A^3@3u_7r7}La z+pmlJR6Cm?+{@IaT4C63V!9o%pHec%fxjp1I&j{Nd0afZ3!8fwQIh1SC9&{8OAs}I zCUH&#y5Ky4V+`4oJQOc|@hrB|YO9t{#$eg;dQ57*oZ}OS7Pi>q;-`Ke>S+bBLUqxN zbv&Qx*x$1IPqlP-sQ}^j9u{jCh!Kc{m9{V)_IuLQG3&R2nzw8BR)%a!-o2CrGcv_f zH;zsGfV9}I-fL1w#CImrHQSC0vDT?cGEpm57uKpq48AF{+g(>kq z9zu4b+QnK{Wl*1Qryj|!>iT2ANAj{SBBx4Vzei&yGNla(u2#NXEy)-TS^SIl{o$=V zc}sP=`B`O$u@G)9?{JQfm1FnunfwVa8f+=;wZbMzP;ZR!;mopYpF9KQmAW38YWfl4 zpqW%c#a8^etxLVl=t(g+qatSIp{&^g_`tc{*gc8ajK^Ecb7j_m<(Jx^$txZHECE^4 z8Es!s{f?0Zsizih*6FQu+zSJ;ahAiXOBZ`{*`>l$0|md{Z^au$kcjcM2nX&nTBAoo zHsC>s$&unftG1^K(ku8^*Llp0)D35Eg`UnDY1B^qD%wltAYZCXyA+v=Y+MPT3k}z? zxCc5e+!>R+M94-x-QcI~XWTX~xeVDcasub1dVK6uk*3SuI?K2O?;mu@t9I}$M;*o0 z_65CsY{7@~H_NtMk{z>rqv`Q&+Nc(R~S{FY^? zq`<&mnJ42tY`K~O`BlNkHT2qEj3j>b<7?Z6JT%dN%D5`@qtbI)0|>6(q+(a3dM|rK z2ck4h(iecWXlKg7U5v-9lrhs`jFbU}#Y}z{0Mp~S3yf#i(@K=hQU4D0@ga$)r0ES= z&81FykQMFZZD}CbPsQR8ukw@-aV0gwLi^AvR*gxCPKn9Q z2U+T$eJsO80$va3+iA@RogOLM7=RR_c|WIP_)=gSAC^aJfy$<#hm>8xn?o)3$5)3H zK^|l|Hu z)bn+?Fl5FjZJN5~zR)g`3g3e~3$G(Na{!BCNrh*;roKpA*x8DS;)caq3Dk~|+-Ff5 zA?N#dq_yU-&mE=UF$n0w91k#4lOZ&*5>>138KGLYkBAb)O`*oG@NbaZa(3>1mP$ZN zl*SE{S1G|_Pps6EcxmV@H{#pnwf)WsK5FVM3v6iEgp3zYN8UeZfz&~%jdP5etVq2iXm)~RgvX6|eQ7&j^wKMZ^CXaW0j=#sBilZGiBLY`Z0@8njmzhZyD z!p^Fyi%#Dr?Gh@^=p{lGWQ6TTD+D)=jWJ#{xIWf+5v?ah{Id6fVluipbngQi8uLBg z-G5BY8R^OvR(*O5K5NMQ@I($Y15HL=5f%@A7AcS0yC_j1x>ByH+|8?47ir_mumeNq zkbSY)QSxn_VO53O#7?9*OE61)Pr{S8ax%v7IPJwW$J8S%id_PxHkf?wGA*4H=kmxW#HXYOK@s~(HDCUM0~IJ<(@VulIC>`95bs79A1We&3_K$R1%ByoZ(SaQ@iR0I#8?-PNX>@f zrs!>Z>UQ6Z;m(mY3vY6N|3EHhq5>!D>rU-lzR-G2;k36O`JCmP6;CYfP*|u@50iaM z(s=`%#6uEZ^^Xoa-dcMy`&XQg&x;g1B4(i(S30eHRE<5E4tKAgW=TpMgF*Xp`&o}d zJV6ERNJjUwpQCUeymfi(I#*QiCBm*uFZa>ZZ4j2A$4o~3Cxuuzyjc!NPBboEH{wCA zI1%i%c8`_-fhX7Y2^#1RBOJBKvaufYI4COqKZgB{3LU0{vwzCVgp1!TX{IGMUJUhn zcp%JM7oP*eXq|`4I2OHd5*(Z%j)0UJOL=jS#yuFD2C{V7I0*IkcJnQwzQ1KcK$xlu z9#1?O`u)%u+vobNmqaa(qTI~Z*3&wwo$Gg&#?hYQZ5LHfM7<`Na#%g_iKP=XzBhP@ zIMXSQ=`*BXU3^X*UQ`&_alZJd9#R|k zB@qkCMBEWeBD&tuo^JhiH}o7o6jV2p?wUn13yPf;uAUy@TK}0-hk+8N5*_96>12gY zWSyqYN;SYYH4}S$@%&_tQ`BOI5sxzh62kW6$#dbxr;&@E*q6s&IeskPb-n^M%5fU+ z`pY*{HX|pIuxMqQ_5DmR!kpvFMS3;4c5P49UPmF*p=sw?^r;I`hSjLFm(@#WaOsqf&GunoR3^PKtnsMG7RW`v5XH%}99?#~ zU**-eN{+%CbF^jz^sZ~YZ!tZ=x?8^b+8_!nzh?y9;=QoSPp_)wrfo|&Q$thGUUnn_ zv2FT%ii1Ufr4wZht^8_3gv_&Oa@3n5r_UvGKOy+|T21&-E>!saB+w1&B1MYNrihSytM~$G`q>TZXG@NA z(;;nC&NPi~eS0=6V6XzPsWT1spY|&bVH#sjX!i`G4s}fS?g9B;A=71dxCfy} z?)69#-ujcj^=}sYiiFR_4-+P!^hpUC`D-i@xMKn%O^L3%D;F83;&48{^( zRwFgtqRd7o2nrSLIBZ4cHE}pF>BG&%#?H*7r$>=h?u8jWoJ%Ge^#)JBKlR9xN?||#PQ;jhl-9Vg^e-MhV9o``oK87Nv7n1B^7$d5yny zMGTKCUC=$RE5_T1r$sJ9tOFZ#2cg5a?seO2ZqT>qmh90WSh{353Juh5X*4P^5 z*vQr;jkKigi--!Ee$6f4tL>-QK}ZGP@Uz@|ueD3{j+a}VSs+%eE7XQZe=J1CzmTDE za0~f&8ORPM$%(-0`<8(KqT1w?Zn-my%i1a`2p$zZczdlO4@A3<2UO$krb6LRS)B(- z_xIEeFJ;fXTY^3|c;-PF$mR#B9ZX%f8+jKhH|`Iw+ezl~m5+3Svjd1vx%J<$F2^3EYxRUh|0gNQ+Y&wffEF>%KL4$%J_Z%pp+h`N& z$#%;FJtZu}w3&|XT@=UMx$^99JcZmjsN&hiH_;nO-dXDPOri0d%l;H{Zs(ZP*K<_N z%H5aA*_M-!phynkKQ!4q3OeCx)AiVuDp|_T7D-^OJRs_6tV?kQ9Nv&QeLBe#;82F4a$*DBZ7)VN%cOQiS)Ho!jp@J{b zUva;AY-dd)L1uYoZ#IeHYNw&9fJ7f70t3b_NAlg}T(9b}$}~(iE03^aYLoG_hjxUN zowbJf-gvhVGjfY}f_j~hX<4kujRMH4hA%y+9_ySV5$5)&i?PA8u0QaiAWaTk zLXYv|V1yfZjrkP2zJnL(c8&iWoe|7C+5}vCC`` z^_zQCYCO)Etvu%0@3kvdwiCXo=e$pfp<9OAo_7`m;@fnfcE~iT|}{&iJRb&hTHG z=1rgqIIC#1k;4AFH8I>QS63h_0R0x(B@S+GZV*>jcmx~)2qbOX!5}Lj?#8B9Q=9L8 zOI}N=Tiq>Hjn8XV_*hV?uxJiW;L7pQz^fr4Ij9r>@hVDYCjbBe*;N7r;7qVFCCyQ| zr}WHBF>GVwYwLhCH?;tgdsf&Fvx^3q=8oc-H)$Hv#E zKwuP@9O{AAdb7<<4Z&ya85+Ub-M`R5yW>-$phf&+rnk0omWH-7miot)f&(yjZ7&T$ z6~H-zvNr{e{dZu2lVvXi{ai;PWq@a!8eG2?YWDQ^_HFk;fVwa)s-^|>Ptsu2>o~_C zZyY%Ugmn?~fdB)(VbngD{V{J=wg6T&*1k*Lso&WXSYP6dk(rsny}}_^7qF}$>*`v7 z0ac7qG<0~h(*eo!?{@;oTxa0uU&(CAmR-q8=mGsyY=Pnt)q&HySYFhe`Efx_Kck_M<;K`6#W(f9}W4y|keJzoW%T-h9e0kyNW1$(x?T|d}`OwGX4wX)g)WCT-}^$-14^`;1- z_-`j~a;kU%-ulol>w*1y`Tf3`-4oK(7<-b>K834Yr zq}TRDn+O0t`LX=K55Y3Kz3adEsXybAzxe~cO<#L0KK!5)9hw{82W7v*zP}IH>RVgx zKd5&_8*Aw3-_#x5*MM%mLx1~!ZEBFlw>MXQetRD2$ml)^;8l|;BMnXGI{=3sGuKbJCXK6GK+Z4pdxd0LJ11Lr zyMf>J(q!tp-;XDoARc@S#=~N}Uxs0*gt6$oMmKvk$K<;4hGsff4h%TzIZ-+892m=x zN?1p3HgqAz{r9SP^b)Scn^nEZo%ppK?sWKG&bXxxzmG2_X@&f?3n9I4KXxwF7uhz8 z$XjHvsIv9W$=sYc_bgfqaEE#T+0I-FylgYV`;3pma-l_;qY06-z?TCqbSxJab8iQdcSOktZlquON(>xr+;KN6_V?3 zFqO{n-k8fK8CowHsrX)L_gj$-T$+c?!JS-8&}A{)aQgaTyw7s*X-&9Mg^Q_Tp0V$pT*wcbSbdY~A2ub5&#iu9d*UrU4sRs!8 zK~2j_GOL(!sZ{s4T}eWbJA*dlfQ)^|4!_F-ncRJ59Q^!B7=(jzcfpGQ`2!BVEIZ9~ zo51^fp&lDduV@s^JpJmHwp!8VG~(*AZ_e$zaCXerN@$T$P)NR;amgypwJk>ogD2r6 zbXau^5YsC^)Rni%?ju~lV#l+1yqI&=(!PIVM{f*ok2>uAIijm6jA2tj`pSTRHNR<2 znd0zWAIZ>njiAyWqqqDz%?U;*8*2fiR(RU0QXd5@|M(Vl90#+o*2^MX*e!VTZ1p|| zm>xEzcr#MdXxr$pZUTUHm_jLQmD zfOLpXzSywoq)Tm+m4nL3>P(Zr?jHA-^MYx}I4I%86(?u;?#0PDkJl0v7<@-qj=Lrt zo}E$na2Kj4$=Br~J?3X|D=6Q_Qd->@@`Mf|ADh@$J2u=57@_tvx%_e3a}H zv9I|6*NS0OvwBUvTrL&omA(unoDHMb>d!}GM`Lp5fGbf2^Zs<3k`JX6g`lq^Ir0N5 zSr%_XXVhz7d%BD-bSg4+HZ6H8gs1P0iwX%7F=Ksiu> zkwq7^P%2Xof7gLH0%9qUs0RN2Tvym>W&@TJp}deXN=dCK<)o=sg;W3GAjAspkpzjS zxmB9@i7CRZFHMrbcDK+Z>);OCYSXx*u1yW0menn$b|r1l<=u@!Ej_QU+0}lSl*7U< zfc8`M!8z~{K)lk`t zgS#&Fs}|9az{idM989cp!6+GW_L!atOW7|>!!B(K!(R$*quLLWBwJMjv-|)_ha=Z! zRi^|?%-k|~<+e$7K7&}Ih2#t-C!CDM5}@-zFj@y%P^R}t7#7@ZGlWrc8+i4-Ep38z z#;>=bYNu;0h9_8J$PQkIiLRlc5Xe1~)ikjmhB*t^`6rL+hOj#F#o@0ue2Q06igM$o z93R*fZ4aH-A=a-Q28%Zw$6q(bTk#NCc*M@=NK?noD6jP!!$dd=8w?yQoF{kP$nRn0CQm+PaAIfR_} zvcfDyl^(LCzNpMX#>~JeCk(&jDpVk!RJ|k30=cBo6g(^qvKV?$q50CMvtl*|Lk4gU zEaR+dlmx_}69i&%F^X&ESzk5j!``KM=5~<6$!k-E+$o#r!sEXdro~UW;rFvI=4;ZW zs}45mFcPZk-NSi&VP$!F*EXnI7jJ!Z^`1<9%{!@XJJ=_i0cQ_+NYf=OEWpM;F=RC0 zvtV5#)Wvw((wr@VcY5q=ur`=13tHw^)G)g61y1(V^o-}OOVesN5!Lf|ozeWk86(m0 zYSCo#2hMp_W2Ly+spUsk*|U7gdCW|7+R+7JzcCoS5{L_yvE?=dv)T3)JD+U|2BEV9 zma!2{sWo)%_R0nulHV|<4lvIA$I<}}47=-_>K7*6h#DOUW4~!8DEk!m8=QL%C8cSS zB=_i?4Wu!-PxOd}0cQ_6G>kloc;AI6_Bn4}m5noz+bm#H66WnL#V zJ^$!9-Jn3xTz}wm@7Z!+QkFANIBBk4%od~EZEqPd%LwdPNQ^wN`_Q^1vyn*ADsVMq} z>Nao=Mk`whKETS|s{2J}NDOxR&N%>S8E)*le8a8;Qv&(sTHL0t*O{j3XDLozE&w$m zu02H(!`*vq2i$l7h7D}_+E(c@d=_>Zn@F^Z+Ms};5b?WC*)(LdzhFMTt&J90d}^S~ z&E*=V#v6e(_TzCP!hqYo{1=F5s}jg_ zP5x}EW#h6=6FyVj(g#ll&rRFWd}5S%$Go_~5Zq}lE{mJx1Kq1hY-ZD7HV?6@L0{8q z<|;C2d*IcQ1MJ8{C^t|=p83*K4`&>qLCGgpo41IJ?su$t8<~O2vov96fr!r%3R=p5 zEwS^Y#?H|~p9eQ32tIx|H)LPH+XtHpAT;wWY;A4A^3Wyyz}lXn_jg@Od02~VZ%&*L8BjM+^_3&|_taLl>} zFLzMs^^35?M|WL`hY>r@Wvmz zu`l_bIpZY?JV>o({=%{;F(2Qr;|Ze7{SFyaj;(KJvWPT4P8QsDs81{t9*RAtmum;~ z)#7lN*#_DgMun1t@fKdMB^nPb{j)4gIu&O(PWz!VI&0(@h__8#=W*ll+TFyj;q%=9 zjn5Za>$ttt<(<9gE+M5PW^AXb2I)aBst?qUF~#K#P#i$-TnQt0t)RD`*hI!QTGrjs zJX<**Cznm;-j`q}jAD$oAxRu|qoat$*~Hbhy*_lW&_N$h9jtzWLb9J8CWhx$6 z@4B9x-tokP?2Z+&@u%wyvANsTVu}uJiVKW32-uM!1J=X~Qi5_sK?TzFXft>n!3Wo) zG;ss|O(UoDxTH{`1MwUlSiE=-rph%9F&5h8)(YjH_}=XZnhBRZJ=ja zqvEH^sCA(eLV93nkM{Y*#>LB9(fQ2CHXJ7nRTOia;bV0C4khIwwqn&|B{7WAiXdO4 zn5|_28FSm67j5;F9@RmhZx8j+>1DdxF%h9+p@_tRIkLrb?KmwrKf!?ThQ+6&J+(*l zgwcR?flA>m5?&GAN?@QXs^y^Su40;OFQ%Pt4uo5y-j2;cX?qX;>4a5gKVuo1TFL|L zYqRB0Jr|SNyL(KK?7IyH*pURnBEe*5Jcu4qo-6tSuu9{p*||)Y2kK)|_MdLzJ8!s< z(MA|CoyKvL{)IOX2D`uVuI4fs;YVu!FE&;yL&*p^o(^kK9g)N$C*kqg=YE1IZN-7+ zoNZns=Ww(eRkZ-bPv@&3F`8NM6NP!B)t{|Hnw(_2G3gCI#HQG@qqU+s`nQ_j^#;AGgElc?w19&npGQ1fS>=r^Ruz|6 z9thSG*q5FGciUQOQv9eOyIeRbxns>j)18us>1QfN_RXqypAAof=1^DrFq@m{DajbE z)DVAP%CI!^qYj_lgfvZBNHAQl6;SBHD$iD7mTWN3)2EKz|#t2@K&W}h-T)GY| zj3NR9#7z10_ZXFK6tKBNfqD8&!i2uqov1P97v+9Cn<>e0{0I<9iT;FgD!bjoT-cjVqb@rCH1B|j!K zq(70dUGE%=Uae-@fd@)w2p--dE+PNm=C`41$gdRC=z8eKZq&%P44a_(nP}706~ids zrxrBZqeO431L9RegIc|NE1`#>eOSgI@=$|Gp}T4iLK{__>T*HLNLAUcnBn-I6&v?s zLvWbiV4uI#3MSv4ej+GVAjcIr6EJ7L_ml;xFNnHsP$hn}R5k?TaBV?4FKFO=#ka_j z+QJNL<#H-4Z`4S$`RSc-{~F({x_+SU`M5~f@$&cSoRP*v41#E_xk-3ee*u4-Ar@_@ z8m z*EOqr-$GyGzlQ)DUFvdF-ZJe=t$uHAER_-n+BP>3K(5_KI>q0qZxz-zo1?XjYSZy2 zWn#-i?^qJL+Mq%+U|CvjyNA(pC=U|$QkVgdclq`p%;%#v{UTQenvj?!OUZH^Wr0YnTy0&SIB+QqQAFwc#0f2$nZL0vRUj? z%H{~_6j9>)Oe!=t-z7OlxfQRxc^6jP@@qimwMv{$jFx%I8L${%6*HB-H@Vx*Fnf4& ze;zV~M&YC|-rOUpVW=rp9$ZocNe}4Ga3CBf?VcGrK{i^I%=`ag?3{u-i@I$eCmq|i z?WCiQZ9D1Mwr$(CZQHhO=O5qx9`31g>z;@6GHdOZ{jgT;+O_5!<2P_!iKkiiU{+fB z9PyF*XW*R_ZSfj)-lr(b`J3u7M-gpT@>QW8u4sM(V2|O{-*v#YEl;r{-)6AxwQkWxg?`t(jb;lJoQQms>cb zE9qP=B>R`l?lsXcE?O#yQAr*OwDA#Py&y}&c8j9&8fALtez9Ukf@MVh<%`1m^bn)h zWo1b0G~1jqdB5>Et(%wexpwh|ErA1X5rDJAyJW`DtT4C%Jd|E%J8I@9i(97Hn;GUv zSOr`B?#_jawy;+JI7@@#c8IKs(Wx-pYoe4ku>sgju6v)uZD|^UTl*#@U$UWEBcyXW zVX}!z%U|J6|H18D=TT9X)bN;aUdq3o_!zxRsjEf-)c5#gEn&e@*2;4xq;)xwPaJIn z9k^s2zwAj~Tep`@6F&dAcE)9vM%sU@|)eO92iOg%wiiHC8g} zDFkvrq~-7Z*VgM7@Lt)JY5->MQd&|fRx-+Q&NWv`oB*UU9TOAYE!SBa#?XbjwT$7@ zNz@q}ZV=^ntTxqwn;a=%4`vrf12mbl#oEe)D%$0@WyANSaUW^H-v#_PSATzqpn^vX zL5SvWK(I%Prp?DP4oISW_Si~1t1WT0;tz49B?V6RD%f-ij^A}9^vEvo{}o{X@K%;q z;gX6-cRb$vZAAcal#GSqUS3W6L%m9~(r|obRzq%SAdwH%>66#c&(<0qw_V<~+v}0` ze9x_t+1|>w`>4oF7=FUAkh3w9-Fq>|7ZgPemmX;9XpM)TCUdcs$Xr<`d(wqb);5yA z@cf3WWV)OlwoL6YHZ}@)RQL&d4ds}=*MIp<1H`>%=>cAp(}^Vj-qX4}tf5vO>aGb* zV)t`ab1+fH>kw)Jb8LW~ocUIz!@4@FNB24(Uz=l8)LZtnd8-%hbtCABVe9sP(c-+7=?i zEShjuu8U!)Mn`%%=_x{~A+R0}d$kB?@nS}> z)-%%XQBJkK8l&7jfzrKTw0)DyfN9o0$TL}g(USHSLTMtd9yE5 zD;iAd7=B_<1kj*)J4j339U-*cwZM+@74-JnejLd~{DiQPsVFB3GaAQufmn!-S%N84>AknovZKQMY=?DsH%Sah|UT?A?Q?t|tZV6;FG4>Ao z&`1C$hEB)O`a#Ff{Oqh7O%>EOhwQj&tq{K&Yk-O4noY*Bg;aPiVNGGYxS=M|-eEeA z4eVySLHACAY>e7-$E<|_^c{?h9#j>WE8ePd!oCaW$WmJL5s6EGsswU6H|Yls9q|L^ zb~QPECMkHs7i%RwZ#ypv6+|NeWFV7*!}WU~7RMmCV}iLx{HY$oM30qSbIPE5h7W`dHE7^sk5`l3*8#&9_v*+(1jt0>?#s7f9QxEnfxecOD^r1V!^wxH6Ca?NQV8nr7w zL)z+!A)yUG;esPt6xNiT{#Z2 zEbv(YmY?!^oF%1-C}N)uiKTXq(rO$Glv3c|iCs%^+K=1@zl=<2k3cIj-1!$1Ew~~A zE+KETa~s!R$ma5qDC-f8ZRt;Nd`;q84gPkuZq^3qNd(7RNCW8f^;DTHZ8Vi?@Uvn( zmw($rUw5ZhKCHvzy1euQl%?H{447PzAoP&Cvf9X_|G;yeeh1N^h8wC+sXE?VxNngj zRKG*H=~=zpmuk6!!Q5Ky8f;R~vua01xq(L;XDh3aX}t?2wqYWB7icKUCJUF44sNmE z3nzijVc96=*+(d`{|UrY#DVO(GD5lvaVXXbl!$a6{mnRD|0G(Y<7ToEAaK zYfF8y6I$n{lDn{MpoO#&Z;QeAn&KsRopfufvl8jU>BT_LAqSgEl{U78s(7-GA!GI0 zuNe#<5x-g8{=xTZa-v|C&U=C<8i>?N+D$Hp9fc585HGMOiEs>aiTvx)`J`lH!+UFS z<}+-Q3W;kYjktg#3nY&twO}h=Ff)yu9!{XCx;4!~9xj88ExH&=@NN}Y;9eq?Ua)Yn z6_B#&)p6P-^iEU1aN6wHn?H(P37%_F3->ci5%LH9-`?sF3()P454~IRKU#V3h>=$2 z9`+{1kbk6T>WcM|MvLs@adYl3q*$L1EEH{yY!_;zEIl8@DB<5BY?y}${itW{+@=II zHoisKXTF^sT;}xaaVKx6!$@gZqm%Cv<94A7sHRZ7QGruygIf3n$A8J^F?0D#NrKUN z59^Bkaf}!S6S0(U{ZJ7l$*R0e z5>Y0J$Sg0el|w665bc|$xG$P(v|-HWIG+eR>9znG5u_47+>$4waM1}5!P=u#QK%mC1gCp0@-4bNWERAL?2veJFTl}p10UIW<3h~J`+<1=Zd0+kAG}T{3aJk&NGgC4dzKSn|YO0x@l0eZ*qd%oGB+YWUxBJRLNIm-)zo5(yB`J6K z<;}hN5ck%hY7!k!=?yoxCj)GK#dZ@ts%F*=AAs%-#!Si-Ft`r&q32c*XL=(_0$$ca zkOE&O{k(l|XX?sW2bQ=Mvy{x}>WDWn&njqip6OyEdL9A@Dy?AUMykFu+WIBBf&C>B z&+`3e=klP{Gx5uhGE-OX+^XNIlzJyasudxizj7X`epxGWxG_x_*D8zDHl~&YVu7h{ zwwuj#{XrU0yVt9cIZr{*`)8Z8E$%vqC?YQ4IeXY7*M0{62AGw8grZxOfi|H>gOX7* z2<*?(g574H_|7H=HI*U8aF;O3dvolYwCa|>VT_B(YEc=Nl|lN#BqQN87~nZfG&P+*$t+sgRi0lLh*$pGsdTy&@Fsk#S5mwn1nha`ztmC}&5 zKbY*5c|?2{5vicde_KdH@Q%i{IR}InEkxR8zr*9J9HMDawC#!To^DYuz%%s-w!S{k zZP!LHs!lT*$r#z-ln{idgu-Y8;IEx~u$fjjo~}GV^f(ax^E%mo zewFACI=>^_&`SGI7oP(Q{YJsRLe5UVaQu?uf zdnGGnBFlS#JT)^hj!yP*z3pVRNcTL%^J67B)abdQY9uP*&!#h^$jP+>3U1<+wym9a zk(aHe=>N^W!QnK_d})D$wGN;9{wug*6opfR(S~gyA32eVs&JV67TP5VA?nP0hlngY$Wh5 zvFe^_1U3YCn|e8eY2MQLpGXOb-e^HEVTnu!oZMt9%)d^S35QtuO2-~{558ICE=e0U zrZJSMt()!*@FnI592A`yo}3_X@JZ&oND%^8UsvUBj3v8|W{S(r!DB|2NP z8!5uewmmv9G8v*9JRkzEB)#(6zw0MEs^8Jv;}1dje08#nOV?8KAMobkYAD@q%UroW zoF4|sp**ZDd#oepzxg0_2Qf+^hGgzqGePV2Z|MO6@k&~lb?L58u|Y~ZrFNN_jK`2p zMK|X7BKR<~4seQrrU&9O#Lgu5rV`ftzQ6kPEp>8=p-Cl~YFI=)4og#o5*z9aV4}?e z=HMS+*mrL{(M7@PH)}iDOSL~fAn4lf9Pw`K_^YFj3M<~KC&BbmC5TBwcPb^bzzrsm z>Ld_m8uTSH%kIwtp-j-s9Ut!71?t28HYmE7(F-Ol6k{GMJz$>t6}5M0fSNIIWhB+u0HUnuan9j0p0 z78pFsl;@;a_Hh-dcv` zl_6aYC3FgAu-7JqYJU zlbq4Aokk&6I1)m3S2m(8(A$KB)u2JX2W_(QPia;lCqj%lCY#!g1eFk z&2BehW2cnFt7U}`#U0Wr#xP!fq#KuX9ciAT4Z5xa)h*dz$cel`o<&qowC<1%tCgA+ zM)O+U4FK~Eb~)AZ5QwQ;m$ikf)xv=~4x53)hiGAjry5zcJp{-B&C4>19bQApc;b(b z5Q)BNM`XMwr%}y@iJ*fpEbZ!xtAmt5ThSqHLAlZ$G|t6G1I!PM$>Tg6?gv_?m1`Oj zIK5q8&N%e#Ry9zE#9CJSUxia2VSK5hQJq87jKl;P1)bjsJdST^Xb@hP=F}7A=LXIG z$~z&J1=$C2D1tDyy<(a#Gk!qKVgx38xD?Jwbsbiavd;>DrjsO=E9>p1U0@=wh%{4H zA8wJ24}WwB+Ah{t+Xjy%W=02{HB6T{18Q=q<@6sx?5!3)-=9G7TcO^+eAhCJ-9()! zIr0Ji6!fJdM|hHj!GW9TOBY z284xz0E|PH3f+{vLdpS28(l*4FH@RY0A9o#aQ9*CE@@RS!5MfEbZS1T`q-+fL-E+AF^AA!`sKPi8I~Eeb7KO?aMW)>rH{p@TkOH3z73%aT<4 z61$7}1}Tq5UrSL*lTpzr8GI%F0w|ztqD_RnlSx&0VF?X|RJ{n|M3MJCj187BYoX2| zD~KyKwc98zY?Ahoo&g0r#CCfAt07>zbO&&VqB3ayL(Klgu)%$GX#UjM+$Z(A`%btr zixV7F)p0r;*=&T6Sl*}_)j7utEK&DztykPrO<7oroQU)gThyJiQ(6`_Zt72$o_^|o z{C~cmM?l%#6}LM)EEhxmPDc?1T29YMD=_yH-?Ze0t= z&QfS@nZ?IPw2Y(Kd$aRP31AkO z#sYhrRDWXtRqfmD2DWQ({N~x(-RTAOC-TjrtE$SAok2$=U>ri%2Xz4hUNTNz-|pVl z07gf=+zmmGv6(aVg^`1)D-1qv?9ZK|18P9V28uid`Jtbko~2-Fc&owa`52V9!q5y~@!-R|~5z}C0C=>#>0vV_8eT^#@` z#(i%dX#~9xq|=Sz^}&FFyn(p^6Jh|3ZBE1-y1H2tn9dQ9o!Z_zf`9kS$ea32J0cPK z*1?^j(%%cO7WL;KO9p!)R;0cfyy1YK)$^9KUP z*99Vo1?v0hEiBXW`oRHAaEzmC=dbs9jD_B4sJWRHnUNmg&@BXW_$^#KrR`fY}XT|1LpQv&ctzntaBOjJlRf>R*Zs zE!p<*SRHuXtmN#wBC9U3TC_*5(z%U7E7}ZXJ8;i?w6^1nx?v0od;om*RU)w#Qp={D zx9vt&i# zolUhDYgR)aF{9T<8nUO42J;pUZu^n`;YKI-ly%3UCGi`pBg!c^{_c8H271#w2Z|g@ zG!%`wPv5S6`Uf`cQx8v;SC3+$%*pD=pp>DwG~90xTc?N}HHV*W;`spE@lo|G@)x9< zPsm}bM1pxUJ+yL68P|Xwz(y>MGl|qsn|5seD}+c>?3FI~8%h4B7u_bgN+@z?C58>* z={DWML6IPY4A#Kk)__5#uB)fcoJUT@Eb19TFf9m!7!V%SOrxD1I~g(oBh)3fDJrQu z)91UDcg?l!`$cxW5{8Xu7~k$9;2PkS{*3piHJ6rd2WX_8n9S5=)%C8-IXY^E_|VO~b=|ZFrX)+bdhY1Lg_?z3@$QFKXFH^^ zlu?p*e~C1=eXX}XqJ11^IuE>jEFY&ocRis#QnojH0TgaO3G1GVHXYW{6b(7r{g>S= zCw2*TF|0qIa-cRk1>Un!{^fEA(5P3h`>%83$&}gHC}`^pa8<9Ckf8tGW}jbLwbAUD zlmbe5Qh7DF!7g4@Yh#a9Z99(23a&pCoIY`K3xlsQIM&g0kWd?Nq3&Q!Hx~ z%RLVMmjygw+G@$Lx9W^3(NA#X_VJq*l$^sPwf^hgvg5{$!I4vQ+gc84XT0UzQA_pb zKA|;A)yreTJ=K@5+B%?3rjh!HM)jm*Sj

rBYB19ixdFGo)s^$umpUV6oTZE^vkd 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ⅅ=LO9A+`p*&6U^V`4^E*&A1qX9LGxuA&L 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
-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�e!T(ybx`Fg1`r=p)0F+e+69w7-u0I=Q5VlKDlr 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

-GM^10vS_ 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

h(6*o>0Eui!6zj`u<^#7#h@#nN7An=ZxoSE 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

S^k_2n;ugF#-ef+1CNw$6dtQx!;uaw@# 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 X5Qy>*45jsERwzV?RYF3?SeNx*o7cg! diff --git a/lib/morpho-blue-irm/lib/morpho-blue/package.json b/lib/morpho-blue-irm/lib/morpho-blue/package.json deleted file mode 100644 index 4c3d2c8..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "morpho-blue", - "description": "Morpho Blue Protocol", - "license": "BUSL-1.1", - "version": "1.0.0", - "scripts": { - "postinstall": "husky install && forge install", - "build:forge": "FOUNDRY_PROFILE=build forge build", - "build:hardhat": "npx hardhat compile", - "test:forge": "FOUNDRY_PROFILE=test forge test", - "test:forge:invariant": "FOUNDRY_MATCH_CONTRACT=InvariantTest yarn test:forge", - "test:forge:integration": "FOUNDRY_MATCH_CONTRACT=IntegrationTest yarn test:forge", - "test:hardhat": "npx hardhat test", - "lint": "yarn lint:forge && yarn lint:hardhat", - "lint:forge": "forge fmt --check", - "lint:hardhat": "prettier --check test/hardhat", - "lint:fix": "yarn lint:forge:fix && yarn lint:hardhat:fix", - "lint:forge:fix": "forge fmt", - "lint:hardhat:fix": "prettier --write test/hardhat", - "clean": "npx hardhat clean && forge clean" - }, - "dependencies": { - "ethers": "^6.7.1", - "ethers-maths": "^4.0.2", - "lodash": "^4.17.21" - }, - "devDependencies": { - "@commitlint/cli": "^17.7.1", - "@commitlint/config-conventional": "^17.7.0", - "@nomicfoundation/hardhat-chai-matchers": "^2.0.2", - "@nomicfoundation/hardhat-ethers": "^3.0.4", - "@nomicfoundation/hardhat-foundry": "^1.0.3", - "@nomicfoundation/hardhat-network-helpers": "^1.0.8", - "@trivago/prettier-plugin-sort-imports": "^4.2.0", - "@typechain/ethers-v6": "^0.5.0", - "@typechain/hardhat": "^9.0.0", - "@types/chai": "^4.3.5", - "@types/lodash": "^4.14.197", - "@types/mocha": "^10.0.1", - "@types/node": "^20.5.4", - "chai": "^4.3.8", - "dotenv": "^16.3.1", - "hardhat": "^2.17.1", - "hardhat-gas-reporter": "^1.0.9", - "hardhat-tracer": "^2.6.0", - "husky": "^8.0.3", - "lint-staged": "^14.0.1", - "prettier": "^3.0.2", - "solidity-coverage": "^0.8.4", - "ts-node": "^10.9.1", - "typechain": "^8.3.1", - "typescript": "^5.1.6" - }, - "lint-staged": { - "*.sol": "forge fmt", - "*.js": "yarn prettier", - "*.ts": "yarn prettier", - "*.json": "yarn prettier", - "*.yml": "yarn prettier" - }, - "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] - }, - "prettier": { - "printWidth": 120, - "plugins": [ - "@trivago/prettier-plugin-sort-imports" - ] - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/Morpho.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/Morpho.sol deleted file mode 100644 index 0f24d1a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/Morpho.sol +++ /dev/null @@ -1,525 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.19; - -import {Id, IMorpho, MarketParams, Position, Market, Authorization, Signature} from "./interfaces/IMorpho.sol"; -import { - IMorphoLiquidateCallback, - IMorphoRepayCallback, - IMorphoSupplyCallback, - IMorphoSupplyCollateralCallback, - IMorphoFlashLoanCallback -} from "./interfaces/IMorphoCallbacks.sol"; -import {IIrm} from "./interfaces/IIrm.sol"; -import {IERC20} from "./interfaces/IERC20.sol"; -import {IOracle} from "./interfaces/IOracle.sol"; - -import "./libraries/ConstantsLib.sol"; -import {UtilsLib} from "./libraries/UtilsLib.sol"; -import {EventsLib} from "./libraries/EventsLib.sol"; -import {ErrorsLib} from "./libraries/ErrorsLib.sol"; -import {MathLib, WAD} from "./libraries/MathLib.sol"; -import {SharesMathLib} from "./libraries/SharesMathLib.sol"; -import {MarketParamsLib} from "./libraries/MarketParamsLib.sol"; -import {SafeTransferLib} from "./libraries/SafeTransferLib.sol"; - -/// @title Morpho -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice The Morpho contract. -contract Morpho is IMorpho { - using MathLib for uint128; - using MathLib for uint256; - using UtilsLib for uint256; - using SharesMathLib for uint256; - using SafeTransferLib for IERC20; - using MarketParamsLib for MarketParams; - - /* IMMUTABLES */ - - /// @inheritdoc IMorpho - bytes32 public immutable DOMAIN_SEPARATOR; - - /* STORAGE */ - - /// @inheritdoc IMorpho - address public owner; - /// @inheritdoc IMorpho - address public feeRecipient; - /// @inheritdoc IMorpho - mapping(Id => mapping(address => Position)) public position; - /// @inheritdoc IMorpho - mapping(Id => Market) public market; - /// @inheritdoc IMorpho - mapping(address => bool) public isIrmEnabled; - /// @inheritdoc IMorpho - mapping(uint256 => bool) public isLltvEnabled; - /// @inheritdoc IMorpho - mapping(address => mapping(address => bool)) public isAuthorized; - /// @inheritdoc IMorpho - mapping(address => uint256) public nonce; - /// @inheritdoc IMorpho - mapping(Id => MarketParams) public idToMarketParams; - - /* CONSTRUCTOR */ - - /// @notice Constructs the contract. - /// @param newOwner The new owner of the contract. - constructor(address newOwner) { - require(newOwner != address(0), ErrorsLib.ZERO_ADDRESS); - - owner = newOwner; - DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, block.chainid, address(this))); - } - - /* MODIFIERS */ - - /// @dev Reverts if the caller is not the owner. - modifier onlyOwner() { - require(msg.sender == owner, ErrorsLib.NOT_OWNER); - _; - } - - /* ONLY OWNER FUNCTIONS */ - - /// @inheritdoc IMorpho - function setOwner(address newOwner) external onlyOwner { - require(newOwner != owner, ErrorsLib.ALREADY_SET); - - owner = newOwner; - - emit EventsLib.SetOwner(newOwner); - } - - /// @inheritdoc IMorpho - function enableIrm(address irm) external onlyOwner { - require(!isIrmEnabled[irm], ErrorsLib.ALREADY_SET); - - isIrmEnabled[irm] = true; - - emit EventsLib.EnableIrm(irm); - } - - /// @inheritdoc IMorpho - function enableLltv(uint256 lltv) external onlyOwner { - require(!isLltvEnabled[lltv], ErrorsLib.ALREADY_SET); - require(lltv < WAD, ErrorsLib.MAX_LLTV_EXCEEDED); - - isLltvEnabled[lltv] = true; - - emit EventsLib.EnableLltv(lltv); - } - - /// @inheritdoc IMorpho - function setFee(MarketParams memory marketParams, uint256 newFee) external onlyOwner { - Id id = marketParams.id(); - require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); - require(newFee != market[id].fee, ErrorsLib.ALREADY_SET); - require(newFee <= MAX_FEE, ErrorsLib.MAX_FEE_EXCEEDED); - - // Accrue interest using the previous fee set before changing it. - _accrueInterest(marketParams, id); - - // Safe "unchecked" cast. - market[id].fee = uint128(newFee); - - emit EventsLib.SetFee(id, newFee); - } - - /// @inheritdoc IMorpho - function setFeeRecipient(address newFeeRecipient) external onlyOwner { - require(newFeeRecipient != feeRecipient, ErrorsLib.ALREADY_SET); - - feeRecipient = newFeeRecipient; - - emit EventsLib.SetFeeRecipient(newFeeRecipient); - } - - /* MARKET CREATION */ - - /// @inheritdoc IMorpho - function createMarket(MarketParams memory marketParams) external { - Id id = marketParams.id(); - require(isIrmEnabled[marketParams.irm], ErrorsLib.IRM_NOT_ENABLED); - require(isLltvEnabled[marketParams.lltv], ErrorsLib.LLTV_NOT_ENABLED); - require(market[id].lastUpdate == 0, ErrorsLib.MARKET_ALREADY_CREATED); - - // Safe "unchecked" cast. - market[id].lastUpdate = uint128(block.timestamp); - idToMarketParams[id] = marketParams; - - emit EventsLib.CreateMarket(id, marketParams); - } - - /* SUPPLY MANAGEMENT */ - - /// @inheritdoc IMorpho - function supply( - MarketParams memory marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - bytes calldata data - ) external returns (uint256, uint256) { - Id id = marketParams.id(); - require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); - require(UtilsLib.exactlyOneZero(assets, shares), ErrorsLib.INCONSISTENT_INPUT); - require(onBehalf != address(0), ErrorsLib.ZERO_ADDRESS); - - _accrueInterest(marketParams, id); - - if (assets > 0) shares = assets.toSharesDown(market[id].totalSupplyAssets, market[id].totalSupplyShares); - else assets = shares.toAssetsUp(market[id].totalSupplyAssets, market[id].totalSupplyShares); - - position[id][onBehalf].supplyShares += shares; - market[id].totalSupplyShares += shares.toUint128(); - market[id].totalSupplyAssets += assets.toUint128(); - - emit EventsLib.Supply(id, msg.sender, onBehalf, assets, shares); - - if (data.length > 0) IMorphoSupplyCallback(msg.sender).onMorphoSupply(assets, data); - - IERC20(marketParams.loanToken).safeTransferFrom(msg.sender, address(this), assets); - - return (assets, shares); - } - - /// @inheritdoc IMorpho - function withdraw( - MarketParams memory marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - address receiver - ) external returns (uint256, uint256) { - Id id = marketParams.id(); - require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); - require(UtilsLib.exactlyOneZero(assets, shares), ErrorsLib.INCONSISTENT_INPUT); - // No need to verify that onBehalf != address(0) thanks to the authorization check. - require(receiver != address(0), ErrorsLib.ZERO_ADDRESS); - require(_isSenderAuthorized(onBehalf), ErrorsLib.UNAUTHORIZED); - - _accrueInterest(marketParams, id); - - if (assets > 0) shares = assets.toSharesUp(market[id].totalSupplyAssets, market[id].totalSupplyShares); - else assets = shares.toAssetsDown(market[id].totalSupplyAssets, market[id].totalSupplyShares); - - position[id][onBehalf].supplyShares -= shares; - market[id].totalSupplyShares -= shares.toUint128(); - market[id].totalSupplyAssets -= assets.toUint128(); - - require(market[id].totalBorrowAssets <= market[id].totalSupplyAssets, ErrorsLib.INSUFFICIENT_LIQUIDITY); - - emit EventsLib.Withdraw(id, msg.sender, onBehalf, receiver, assets, shares); - - IERC20(marketParams.loanToken).safeTransfer(receiver, assets); - - return (assets, shares); - } - - /* BORROW MANAGEMENT */ - - /// @inheritdoc IMorpho - function borrow( - MarketParams memory marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - address receiver - ) external returns (uint256, uint256) { - Id id = marketParams.id(); - require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); - require(UtilsLib.exactlyOneZero(assets, shares), ErrorsLib.INCONSISTENT_INPUT); - // No need to verify that onBehalf != address(0) thanks to the authorization check. - require(receiver != address(0), ErrorsLib.ZERO_ADDRESS); - require(_isSenderAuthorized(onBehalf), ErrorsLib.UNAUTHORIZED); - - _accrueInterest(marketParams, id); - - if (assets > 0) shares = assets.toSharesUp(market[id].totalBorrowAssets, market[id].totalBorrowShares); - else assets = shares.toAssetsDown(market[id].totalBorrowAssets, market[id].totalBorrowShares); - - position[id][onBehalf].borrowShares += shares.toUint128(); - market[id].totalBorrowShares += shares.toUint128(); - market[id].totalBorrowAssets += assets.toUint128(); - - require(_isHealthy(marketParams, id, onBehalf), ErrorsLib.INSUFFICIENT_COLLATERAL); - require(market[id].totalBorrowAssets <= market[id].totalSupplyAssets, ErrorsLib.INSUFFICIENT_LIQUIDITY); - - emit EventsLib.Borrow(id, msg.sender, onBehalf, receiver, assets, shares); - - IERC20(marketParams.loanToken).safeTransfer(receiver, assets); - - return (assets, shares); - } - - /// @inheritdoc IMorpho - function repay( - MarketParams memory marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - bytes calldata data - ) external returns (uint256, uint256) { - Id id = marketParams.id(); - require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); - require(UtilsLib.exactlyOneZero(assets, shares), ErrorsLib.INCONSISTENT_INPUT); - require(onBehalf != address(0), ErrorsLib.ZERO_ADDRESS); - - _accrueInterest(marketParams, id); - - if (assets > 0) shares = assets.toSharesDown(market[id].totalBorrowAssets, market[id].totalBorrowShares); - else assets = shares.toAssetsUp(market[id].totalBorrowAssets, market[id].totalBorrowShares); - - position[id][onBehalf].borrowShares -= shares.toUint128(); - market[id].totalBorrowShares -= shares.toUint128(); - market[id].totalBorrowAssets = UtilsLib.zeroFloorSub(market[id].totalBorrowAssets, assets).toUint128(); - - // `assets` may be greater than `totalBorrowAssets` by 1. - emit EventsLib.Repay(id, msg.sender, onBehalf, assets, shares); - - if (data.length > 0) IMorphoRepayCallback(msg.sender).onMorphoRepay(assets, data); - - IERC20(marketParams.loanToken).safeTransferFrom(msg.sender, address(this), assets); - - return (assets, shares); - } - - /* COLLATERAL MANAGEMENT */ - - /// @inheritdoc IMorpho - function supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes calldata data) - external - { - Id id = marketParams.id(); - require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); - require(assets != 0, ErrorsLib.ZERO_ASSETS); - require(onBehalf != address(0), ErrorsLib.ZERO_ADDRESS); - - // Don't accrue interest because it's not required and it saves gas. - - position[id][onBehalf].collateral += assets.toUint128(); - - emit EventsLib.SupplyCollateral(id, msg.sender, onBehalf, assets); - - if (data.length > 0) IMorphoSupplyCollateralCallback(msg.sender).onMorphoSupplyCollateral(assets, data); - - IERC20(marketParams.collateralToken).safeTransferFrom(msg.sender, address(this), assets); - } - - /// @inheritdoc IMorpho - function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver) - external - { - Id id = marketParams.id(); - require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); - require(assets != 0, ErrorsLib.ZERO_ASSETS); - // No need to verify that onBehalf != address(0) thanks to the authorization check. - require(receiver != address(0), ErrorsLib.ZERO_ADDRESS); - require(_isSenderAuthorized(onBehalf), ErrorsLib.UNAUTHORIZED); - - _accrueInterest(marketParams, id); - - position[id][onBehalf].collateral -= assets.toUint128(); - - require(_isHealthy(marketParams, id, onBehalf), ErrorsLib.INSUFFICIENT_COLLATERAL); - - emit EventsLib.WithdrawCollateral(id, msg.sender, onBehalf, receiver, assets); - - IERC20(marketParams.collateralToken).safeTransfer(receiver, assets); - } - - /* LIQUIDATION */ - - /// @inheritdoc IMorpho - function liquidate( - MarketParams memory marketParams, - address borrower, - uint256 seizedAssets, - uint256 repaidShares, - bytes calldata data - ) external returns (uint256, uint256) { - Id id = marketParams.id(); - require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); - require(UtilsLib.exactlyOneZero(seizedAssets, repaidShares), ErrorsLib.INCONSISTENT_INPUT); - - _accrueInterest(marketParams, id); - - uint256 collateralPrice = IOracle(marketParams.oracle).price(); - - require(!_isHealthy(marketParams, id, borrower, collateralPrice), ErrorsLib.HEALTHY_POSITION); - - uint256 repaidAssets; - { - // The liquidation incentive factor is min(maxLiquidationIncentiveFactor, 1/(1 - cursor*(1 - lltv))). - uint256 liquidationIncentiveFactor = UtilsLib.min( - MAX_LIQUIDATION_INCENTIVE_FACTOR, - WAD.wDivDown(WAD - LIQUIDATION_CURSOR.wMulDown(WAD - marketParams.lltv)) - ); - - if (seizedAssets > 0) { - repaidAssets = - seizedAssets.mulDivUp(collateralPrice, ORACLE_PRICE_SCALE).wDivUp(liquidationIncentiveFactor); - repaidShares = repaidAssets.toSharesDown(market[id].totalBorrowAssets, market[id].totalBorrowShares); - } else { - repaidAssets = repaidShares.toAssetsUp(market[id].totalBorrowAssets, market[id].totalBorrowShares); - seizedAssets = - repaidAssets.wMulDown(liquidationIncentiveFactor).mulDivDown(ORACLE_PRICE_SCALE, collateralPrice); - } - } - - position[id][borrower].borrowShares -= repaidShares.toUint128(); - market[id].totalBorrowShares -= repaidShares.toUint128(); - market[id].totalBorrowAssets = UtilsLib.zeroFloorSub(market[id].totalBorrowAssets, repaidAssets).toUint128(); - - position[id][borrower].collateral -= seizedAssets.toUint128(); - - // Realize the bad debt if needed. Note that it saves ~3k gas to do it. - uint256 badDebtShares; - if (position[id][borrower].collateral == 0) { - badDebtShares = position[id][borrower].borrowShares; - uint256 badDebt = badDebtShares.toAssetsUp(market[id].totalBorrowAssets, market[id].totalBorrowShares); - market[id].totalSupplyAssets -= badDebt.toUint128(); - market[id].totalBorrowAssets -= badDebt.toUint128(); - market[id].totalBorrowShares -= badDebtShares.toUint128(); - position[id][borrower].borrowShares = 0; - } - - IERC20(marketParams.collateralToken).safeTransfer(msg.sender, seizedAssets); - - // `repaidAssets` may be greater than `totalBorrowAssets` by 1. - emit EventsLib.Liquidate(id, msg.sender, borrower, repaidAssets, repaidShares, seizedAssets, badDebtShares); - - if (data.length > 0) IMorphoLiquidateCallback(msg.sender).onMorphoLiquidate(repaidAssets, data); - - IERC20(marketParams.loanToken).safeTransferFrom(msg.sender, address(this), repaidAssets); - - return (seizedAssets, repaidAssets); - } - - /* FLASH LOANS */ - - /// @inheritdoc IMorpho - function flashLoan(address token, uint256 assets, bytes calldata data) external { - IERC20(token).safeTransfer(msg.sender, assets); - - emit EventsLib.FlashLoan(msg.sender, token, assets); - - IMorphoFlashLoanCallback(msg.sender).onMorphoFlashLoan(assets, data); - - IERC20(token).safeTransferFrom(msg.sender, address(this), assets); - } - - /* AUTHORIZATION */ - - /// @inheritdoc IMorpho - function setAuthorization(address authorized, bool newIsAuthorized) external { - isAuthorized[msg.sender][authorized] = newIsAuthorized; - - emit EventsLib.SetAuthorization(msg.sender, msg.sender, authorized, newIsAuthorized); - } - - /// @inheritdoc IMorpho - function setAuthorizationWithSig(Authorization memory authorization, Signature calldata signature) external { - require(block.timestamp < authorization.deadline, ErrorsLib.SIGNATURE_EXPIRED); - require(authorization.nonce == nonce[authorization.authorizer]++, ErrorsLib.INVALID_NONCE); - - bytes32 hashStruct = keccak256(abi.encode(AUTHORIZATION_TYPEHASH, authorization)); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hashStruct)); - address signatory = ecrecover(digest, signature.v, signature.r, signature.s); - - require(signatory != address(0) && authorization.authorizer == signatory, ErrorsLib.INVALID_SIGNATURE); - - emit EventsLib.IncrementNonce(msg.sender, authorization.authorizer, authorization.nonce); - - isAuthorized[authorization.authorizer][authorization.authorized] = authorization.isAuthorized; - - emit EventsLib.SetAuthorization( - msg.sender, authorization.authorizer, authorization.authorized, authorization.isAuthorized - ); - } - - /// @dev Returns whether the sender is authorized to manage `onBehalf`'s positions. - function _isSenderAuthorized(address onBehalf) internal view returns (bool) { - return msg.sender == onBehalf || isAuthorized[onBehalf][msg.sender]; - } - - /* INTEREST MANAGEMENT */ - - /// @dev Accrues interest for the given market `marketParams`. - /// @dev Assumes that the inputs `marketParams` and `id` match. - function _accrueInterest(MarketParams memory marketParams, Id id) internal { - uint256 elapsed = block.timestamp - market[id].lastUpdate; - - if (elapsed == 0) return; - - if (market[id].totalBorrowAssets != 0) { - uint256 borrowRate = IIrm(marketParams.irm).borrowRate(marketParams, market[id]); - uint256 interest = market[id].totalBorrowAssets.wMulDown(borrowRate.wTaylorCompounded(elapsed)); - market[id].totalBorrowAssets += interest.toUint128(); - market[id].totalSupplyAssets += interest.toUint128(); - - uint256 feeShares; - if (market[id].fee != 0) { - uint256 feeAmount = interest.wMulDown(market[id].fee); - // The fee amount is subtracted from the total supply in this calculation to compensate for the fact - // that total supply is already increased by the full interest (including the fee amount). - feeShares = - feeAmount.toSharesDown(market[id].totalSupplyAssets - feeAmount, market[id].totalSupplyShares); - position[id][feeRecipient].supplyShares += feeShares; - market[id].totalSupplyShares += feeShares.toUint128(); - } - - emit EventsLib.AccrueInterest(id, borrowRate, interest, feeShares); - } - - // Safe "unchecked" cast. - market[id].lastUpdate = uint128(block.timestamp); - } - - /* HEALTH CHECK */ - - /// @dev Returns whether the position of `borrower` in the given market `marketParams` is healthy. - /// @dev Assumes that the inputs `marketParams` and `id` match. - function _isHealthy(MarketParams memory marketParams, Id id, address borrower) internal view returns (bool) { - if (position[id][borrower].borrowShares == 0) return true; - - uint256 collateralPrice = IOracle(marketParams.oracle).price(); - - return _isHealthy(marketParams, id, borrower, collateralPrice); - } - - /// @dev Returns whether the position of `borrower` in the given market `marketParams` with the given - /// `collateralPrice` is healthy. - /// @dev Assumes that the inputs `marketParams` and `id` match. - /// @dev Rounds in favor of the protocol, so one might not be able to borrow exactly `maxBorrow` but one unit less. - function _isHealthy(MarketParams memory marketParams, Id id, address borrower, uint256 collateralPrice) - internal - view - returns (bool) - { - uint256 borrowed = uint256(position[id][borrower].borrowShares).toAssetsUp( - market[id].totalBorrowAssets, market[id].totalBorrowShares - ); - uint256 maxBorrow = uint256(position[id][borrower].collateral).mulDivDown(collateralPrice, ORACLE_PRICE_SCALE) - .wMulDown(marketParams.lltv); - - return maxBorrow >= borrowed; - } - - /* STORAGE VIEW */ - - /// @inheritdoc IMorpho - function extSloads(bytes32[] calldata slots) external view returns (bytes32[] memory res) { - uint256 nSlots = slots.length; - - res = new bytes32[](nSlots); - - for (uint256 i; i < nSlots;) { - bytes32 slot = slots[i++]; - - assembly ("memory-safe") { - mstore(add(res, mul(i, 32)), sload(slot)) - } - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IERC20.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IERC20.sol deleted file mode 100644 index 4d16188..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IERC20.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title IERC20 -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @dev Empty because we only call library functions. It prevents calling transfer (transferFrom) instead of -/// safeTransfer (safeTransferFrom). -interface IERC20 {} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IIrm.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IIrm.sol deleted file mode 100644 index 2615e3a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IIrm.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -import {MarketParams, Market} from "./IMorpho.sol"; - -/// @title IIrm -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Interface that Interest Rate Models (IRMs) used by Morpho must implement. -interface IIrm { - /// @notice Returns the borrow rate of the market `marketParams`. - /// @param marketParams The MarketParams struct of the market. - /// @param market The Market struct of the market. - function borrowRate(MarketParams memory marketParams, Market memory market) external returns (uint256); - - /// @notice Returns the borrow rate of the market `marketParams` without modifying any storage. - /// @param marketParams The MarketParams struct of the market. - /// @param market The Market struct of the market. - function borrowRateView(MarketParams memory marketParams, Market memory market) external view returns (uint256); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IMorpho.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IMorpho.sol deleted file mode 100644 index 02aa4e2..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IMorpho.sol +++ /dev/null @@ -1,300 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -type Id is bytes32; - -struct MarketParams { - address loanToken; - address collateralToken; - address oracle; - address irm; - uint256 lltv; -} - -/// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest -/// accrual. -struct Position { - uint256 supplyShares; - uint128 borrowShares; - uint128 collateral; -} - -/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual. -/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual. -/// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last -/// interest accrual. -struct Market { - uint128 totalSupplyAssets; - uint128 totalSupplyShares; - uint128 totalBorrowAssets; - uint128 totalBorrowShares; - uint128 lastUpdate; - uint128 fee; -} - -struct Authorization { - address authorizer; - address authorized; - bool isAuthorized; - uint256 nonce; - uint256 deadline; -} - -struct Signature { - uint8 v; - bytes32 r; - bytes32 s; -} - -/// @title IMorpho -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Interface of Morpho. -interface IMorpho { - /// @notice The EIP-712 domain separator. - /// @dev Warning: In case of a hardfork, every EIP-712 signed message based on this domain separator can be reused - /// on the forked chain because the domain separator would be the same. - function DOMAIN_SEPARATOR() external view returns (bytes32); - - /// @notice The owner of the contract. - /// @dev It has the power to change the owner. - /// @dev It has the power to set fees on markets and set the fee recipient. - /// @dev It has the power to enable but not disable IRMs and LLTVs. - function owner() external view returns (address); - - /// @notice The fee recipient of all markets. - /// @dev The recipient receives the fees of a given market through a supply position on that market. - function feeRecipient() external view returns (address); - - /// @notice The state of the position of `user` on the market corresponding to `id`. - function position(Id id, address user) - external - view - returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral); - - /// @notice The state of the market corresponding to `id`. - function market(Id id) - external - view - returns ( - uint128 totalSupplyAssets, - uint128 totalSupplyShares, - uint128 totalBorrowAssets, - uint128 totalBorrowShares, - uint128 lastUpdate, - uint128 fee - ); - - /// @notice Whether the `irm` is enabled. - function isIrmEnabled(address irm) external view returns (bool); - - /// @notice Whether the `lltv` is enabled. - function isLltvEnabled(uint256 lltv) external view returns (bool); - - /// @notice Whether `authorized` is authorized to modify `authorizer`'s positions. - /// @dev Anyone is authorized to modify their own positions, regardless of this variable. - function isAuthorized(address authorizer, address authorized) external view returns (bool); - - /// @notice The `authorizer`'s current nonce. Used to prevent replay attacks with EIP-712 signatures. - function nonce(address authorizer) external view returns (uint256); - - /// @notice The market params corresponding to `id`. - /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer - /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`. - function idToMarketParams(Id id) - external - view - returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv); - - /// @notice Sets `newOwner` as owner of the contract. - /// @dev Warning: No two-step transfer ownership. - /// @dev Warning: The owner can be set to the zero address. - function setOwner(address newOwner) external; - - /// @notice Enables `irm` as a possible IRM for market creation. - /// @dev Warning: It is not possible to disable an IRM. - function enableIrm(address irm) external; - - /// @notice Enables `lltv` as a possible LLTV for market creation. - /// @dev Warning: It is not possible to disable a LLTV. - function enableLltv(uint256 lltv) external; - - /// @notice Sets the `newFee` for the given market `marketParams`. - /// @dev Warning: The recipient can be the zero address. - function setFee(MarketParams memory marketParams, uint256 newFee) external; - - /// @notice Sets `newFeeRecipient` as recipient of the fee. - /// @dev Warning: The fee recipient can be set to the zero address. - /// @dev Warning: The fee to be accrued on each market won't belong to the old fee recipient after calling this - /// function. - function setFeeRecipient(address newFeeRecipient) external; - - /// @notice Creates the market `marketParams`. - /// @dev Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees - /// Morpho behaves as expected: - /// - The token should be ERC-20 compliant, except that it can omit return values on `transfer` and `transferFrom`. - /// - The token balance of Morpho should only decrease on `transfer` and `transferFrom`. In particular, tokens with - /// burn functions are not supported. - /// - The token should not re-enter Morpho on `transfer` nor `transferFrom`. - /// - The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount - /// on `transfer` and `transferFrom`. In particular, tokens with fees on transfer are not supported. - /// - The IRM should not re-enter Morpho. - /// @dev Here is a list of properties on the market's dependencies that could break Morpho's liveness properties: - /// - The token can revert on `transfer` and `transferFrom` for a reason other than an approval or balance issue. - /// - A very high amount of assets (~1e35) supplied or borrowed can make the computation of `toSharesUp` and - /// `toSharesDown` overflow. - /// - The IRM can revert on `borrowRate`. - /// - A very high borrow rate returned by the IRM can make the computation of `interest` in `_accrueInterest` - /// overflow. - /// - The oracle can revert on `price`. Note that this can be used to prevent `borrow`, `withdrawCollateral` and - /// `liquidate` from being used under certain market conditions. - /// - A very high price returned by the oracle can make the computation of `maxBorrow` in `_isHealthy` overflow, or - /// the computation of `assetsRepaid` in `liquidate` overflow. - function createMarket(MarketParams memory marketParams) external; - - /// @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's - /// `onMorphoSupply` function with the given `data`. - /// @dev Either `assets` or `shares` should be zero. Most usecases should rely on `assets` as an input so the caller - /// is guaranteed to have `assets` tokens pulled from their balance, but the possibility to mint a specific amount - /// of shares is given for full compatibility and precision. - /// @dev Supplying a large amount can revert for overflow. - /// @param marketParams The market to supply assets to. - /// @param assets The amount of assets to supply. - /// @param shares The amount of shares to mint. - /// @param onBehalf The address that will own the increased supply position. - /// @param data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed. - /// @return assetsSupplied The amount of assets supplied. - /// @return sharesSupplied The amount of shares minted. - function supply( - MarketParams memory marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - bytes memory data - ) external returns (uint256 assetsSupplied, uint256 sharesSupplied); - - /// @notice Withdraws `assets` or `shares` on behalf of `onBehalf` to `receiver`. - /// @dev Either `assets` or `shares` should be zero. To withdraw max, pass the `shares`'s balance of `onBehalf`. - /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions. - /// @dev Withdrawing an amount corresponding to more shares than supplied will revert for underflow. - /// @param marketParams The market to withdraw assets from. - /// @param assets The amount of assets to withdraw. - /// @param shares The amount of shares to burn. - /// @param onBehalf The address of the owner of the supply position. - /// @param receiver The address that will receive the withdrawn assets. - /// @return assetsWithdrawn The amount of assets withdrawn. - /// @return sharesWithdrawn The amount of shares burned. - function withdraw( - MarketParams memory marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - address receiver - ) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn); - - /// @notice Borrows `assets` or `shares` on behalf of `onBehalf` to `receiver`. - /// @dev Either `assets` or `shares` should be zero. Most usecases should rely on `assets` as an input so the caller - /// is guaranteed to borrow `assets` of tokens, but the possibility to mint a specific amount of shares is given for - /// full compatibility and precision. - /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions. - /// @dev Borrowing a large amount can revert for overflow. - /// @param marketParams The market to borrow assets from. - /// @param assets The amount of assets to borrow. - /// @param shares The amount of shares to mint. - /// @param onBehalf The address that will own the increased borrow position. - /// @param receiver The address that will receive the borrowed assets. - /// @return assetsBorrowed The amount of assets borrowed. - /// @return sharesBorrowed The amount of shares minted. - function borrow( - MarketParams memory marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - address receiver - ) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed); - - /// @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's - /// `onMorphoReplay` function with the given `data`. - /// @dev Either `assets` or `shares` should be zero. To repay max, pass the `shares`'s balance of `onBehalf`. - /// @dev Repaying an amount corresponding to more shares than borrowed will revert for underflow. - /// @param marketParams The market to repay assets to. - /// @param assets The amount of assets to repay. - /// @param shares The amount of shares to burn. - /// @param onBehalf The address of the owner of the debt position. - /// @param data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed. - /// @return assetsRepaid The amount of assets repaid. - /// @return sharesRepaid The amount of shares burned. - function repay( - MarketParams memory marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - bytes memory data - ) external returns (uint256 assetsRepaid, uint256 sharesRepaid); - - /// @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's - /// `onMorphoSupplyCollateral` function with the given `data`. - /// @dev Interest are not accrued since it's not required and it saves gas. - /// @dev Supplying a large amount can revert for overflow. - /// @param marketParams The market to supply collateral to. - /// @param assets The amount of collateral to supply. - /// @param onBehalf The address that will own the increased collateral position. - /// @param data Arbitrary data to pass to the `onMorphoSupplyCollateral` callback. Pass empty data if not needed. - function supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes memory data) - external; - - /// @notice Withdraws `assets` of collateral on behalf of `onBehalf` to `receiver`. - /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions. - /// @dev Withdrawing an amount corresponding to more collateral than supplied will revert for underflow. - /// @param marketParams The market to withdraw collateral from. - /// @param assets The amount of collateral to withdraw. - /// @param onBehalf The address of the owner of the collateral position. - /// @param receiver The address that will receive the collateral assets. - function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver) - external; - - /// @notice Liquidates the given `repaidShares` of debt asset or seize the given `seizedAssets` of collateral on the - /// given market `marketParams` of the given `borrower`'s position, optionally calling back the caller's - /// `onMorphoLiquidate` function with the given `data`. - /// @dev Either `seizedAssets` or `repaidShares` should be zero. - /// @dev Seizing more than the collateral balance will underflow and revert without any error message. - /// @dev Repaying more than the borrow balance will underflow and revert without any error message. - /// @param marketParams The market of the position. - /// @param borrower The owner of the position. - /// @param seizedAssets The amount of collateral to seize. - /// @param repaidShares The amount of shares to repay. - /// @param data Arbitrary data to pass to the `onMorphoLiquidate` callback. Pass empty data if not needed. - /// @return The amount of assets seized. - /// @return The amount of assets repaid. - function liquidate( - MarketParams memory marketParams, - address borrower, - uint256 seizedAssets, - uint256 repaidShares, - bytes memory data - ) external returns (uint256, uint256); - - /// @notice Executes a flash loan. - /// @dev Flash loans have access to the whole balance of the contract (the liquidity and deposited collateral of all - /// markets combined, plus donations). - /// @param token The token to flash loan. - /// @param assets The amount of assets to flash loan. - /// @param data Arbitrary data to pass to the `onMorphoFlashLoan` callback. - function flashLoan(address token, uint256 assets, bytes calldata data) external; - - /// @notice Sets the authorization for `authorized` to manage `msg.sender`'s positions. - /// @param authorized The authorized address. - /// @param newIsAuthorized The new authorization status. - function setAuthorization(address authorized, bool newIsAuthorized) external; - - /// @notice Sets the authorization for `authorization.authorized` to manage `authorization.authorizer`'s positions. - /// @dev Warning: Reverts if the signature has already been submitted. - /// @dev The signature is malleable, but it has no impact on the security here. - /// @dev The nonce is passed as argument to be able to revert with a different error message. - /// @param authorization The `Authorization` struct. - /// @param signature The signature. - function setAuthorizationWithSig(Authorization calldata authorization, Signature calldata signature) external; - - /// @notice Returns the data stored on the different `slots`. - function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol deleted file mode 100644 index b4c7898..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IMorphoCallbacks.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title IMorphoLiquidateCallback -/// @notice Interface that liquidators willing to use `liquidate`'s callback must implement. -interface IMorphoLiquidateCallback { - /// @notice Callback called when a liquidation occurs. - /// @dev The callback is called only if data is not empty. - /// @param repaidAssets The amount of repaid assets. - /// @param data Arbitrary data passed to the `liquidate` function. - function onMorphoLiquidate(uint256 repaidAssets, bytes calldata data) external; -} - -/// @title IMorphoRepayCallback -/// @notice Interface that users willing to use `repay`'s callback must implement. -interface IMorphoRepayCallback { - /// @notice Callback called when a repayment occurs. - /// @dev The callback is called only if data is not empty. - /// @param assets The amount of repaid assets. - /// @param data Arbitrary data passed to the `repay` function. - function onMorphoRepay(uint256 assets, bytes calldata data) external; -} - -/// @title IMorphoSupplyCallback -/// @notice Interface that users willing to use `supply`'s callback must implement. -interface IMorphoSupplyCallback { - /// @notice Callback called when a supply occurs. - /// @dev The callback is called only if data is not empty. - /// @param assets The amount of supplied assets. - /// @param data Arbitrary data passed to the `supply` function. - function onMorphoSupply(uint256 assets, bytes calldata data) external; -} - -/// @title IMorphoSupplyCollateralCallback -/// @notice Interface that users willing to use `supplyCollateral`'s callback must implement. -interface IMorphoSupplyCollateralCallback { - /// @notice Callback called when a supply of collateral occurs. - /// @dev The callback is called only if data is not empty. - /// @param assets The amount of supplied collateral. - /// @param data Arbitrary data passed to the `supplyCollateral` function. - function onMorphoSupplyCollateral(uint256 assets, bytes calldata data) external; -} - -/// @title IMorphoFlashLoanCallback -/// @notice Interface that users willing to use `flashLoan`'s callback must implement. -interface IMorphoFlashLoanCallback { - /// @notice Callback called when a flash loan occurs. - /// @dev The callback is called only if data is not empty. - /// @param assets The amount of assets that was flash loaned. - /// @param data Arbitrary data passed to the `flashLoan` function. - function onMorphoFlashLoan(uint256 assets, bytes calldata data) external; -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IOracle.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IOracle.sol deleted file mode 100644 index 576230b..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/IOracle.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity >=0.5.0; - -/// @title IOracle -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Interface that oracles used by Morpho must implement. -interface IOracle { - /// @notice Returns the price of 1 asset of collateral token quoted in 1 asset of loan token, scaled by 1e36. - /// @dev It corresponds to the price of 10**(collateral token decimals) assets of collateral token quoted in - /// 10**(loan token decimals) assets of loan token with `36 + loan token decimals - collateral token decimals` - /// decimals of precision. - function price() external view returns (uint256); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/LICENSE b/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/LICENSE deleted file mode 100644 index aec4e2a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/interfaces/LICENSE +++ /dev/null @@ -1,389 +0,0 @@ -This software is available under your choice of the GNU General Public -License, version 2 or later, or the Business Source License, as set -forth below. - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - -Business Source License 1.1 - -License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. -"Business Source License" is a trademark of MariaDB Corporation Ab. - ------------------------------------------------------------------------------ - -Parameters - -Licensor: Morpho Association - -Licensed Work: Morpho Blue Core - The Licensed Work is (c) 2023 Morpho Association - -Additional Use Grant: Any uses listed and defined at - morpho-blue-core-license-grants.morpho.eth - -Change Date: The earlier of (i) 2026-01-01, or (ii) a date specified - at morpho-blue-core-license-date.morpho.eth, or (iii) - upon the activation of the setFee function of the - Licensed Work’s applicable protocol smart contracts - deployed for production use. - -Change License: GNU General Public License v2.0 or later - ------------------------------------------------------------------------------ - -Terms - -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited -production use. - -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. - -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND -TITLE. - -MariaDB hereby grants you permission to use this License’s text to license -your works, and to refer to it using the trademark "Business Source License", -as long as you comply with the Covenants of Licensor below. - ------------------------------------------------------------------------------ - -Covenants of Licensor - -In consideration of the right to use this License’s text and the "Business -Source License" name and trademark, Licensor covenants to MariaDB, and to all -other recipients of the licensed work to be provided by Licensor: - -1. To specify as the Change License the GPL Version 2.0 or any later version, - or a license that is compatible with GPL Version 2.0 or a later version, - where "compatible" means that software provided under the Change License can - be included in a program with software provided under GPL Version 2.0 or a - later version. Licensor may specify additional Change Licenses without - limitation. - -2. To either: (a) specify an additional grant of rights to use that does not - impose any additional restriction on the right granted in this License, as - the Additional Use Grant; or (b) insert the text "None". - -3. To specify a Change Date. - -4. Not to modify this License in any other way. - ------------------------------------------------------------------------------ - -Notice - -The Business Source License (this document, or the "License") is not an Open -Source license. However, the Licensed Work will eventually be made available -under an Open Source License, as stated in this License. diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/ConstantsLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/ConstantsLib.sol deleted file mode 100644 index c4e49fe..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/ConstantsLib.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -/// @dev The maximum fee a market can have (25%). -uint256 constant MAX_FEE = 0.25e18; - -/// @dev Oracle price scale. -uint256 constant ORACLE_PRICE_SCALE = 1e36; - -/// @dev Liquidation cursor. -uint256 constant LIQUIDATION_CURSOR = 0.3e18; - -/// @dev Max liquidation incentive factor. -uint256 constant MAX_LIQUIDATION_INCENTIVE_FACTOR = 1.15e18; - -/// @dev The EIP-712 typeHash for EIP712Domain. -bytes32 constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(uint256 chainId,address verifyingContract)"); - -/// @dev The EIP-712 typeHash for Authorization. -bytes32 constant AUTHORIZATION_TYPEHASH = - keccak256("Authorization(address authorizer,address authorized,bool isAuthorized,uint256 nonce,uint256 deadline)"); diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/ErrorsLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/ErrorsLib.sol deleted file mode 100644 index 893a6b3..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/ErrorsLib.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -/// @title ErrorsLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Library exposing error messages. -library ErrorsLib { - /// @notice Thrown when the caller is not the owner. - string internal constant NOT_OWNER = "not owner"; - - /// @notice Thrown when the LLTV to enable exceeds the maximum LLTV. - string internal constant MAX_LLTV_EXCEEDED = "max LLTV exceeded"; - - /// @notice Thrown when the fee to set exceeds the maximum fee. - string internal constant MAX_FEE_EXCEEDED = "max fee exceeded"; - - /// @notice Thrown when the value is already set. - string internal constant ALREADY_SET = "already set"; - - /// @notice Thrown when the IRM is not enabled at market creation. - string internal constant IRM_NOT_ENABLED = "IRM not enabled"; - - /// @notice Thrown when the LLTV is not enabled at market creation. - string internal constant LLTV_NOT_ENABLED = "LLTV not enabled"; - - /// @notice Thrown when the market is already created. - string internal constant MARKET_ALREADY_CREATED = "market already created"; - - /// @notice Thrown when the market is not created. - string internal constant MARKET_NOT_CREATED = "market not created"; - - /// @notice Thrown when not exactly one of the input amount is zero. - string internal constant INCONSISTENT_INPUT = "inconsistent input"; - - /// @notice Thrown when zero assets is passed as input. - string internal constant ZERO_ASSETS = "zero assets"; - - /// @notice Thrown when a zero address is passed as input. - string internal constant ZERO_ADDRESS = "zero address"; - - /// @notice Thrown when the caller is not authorized to conduct an action. - string internal constant UNAUTHORIZED = "unauthorized"; - - /// @notice Thrown when the collateral is insufficient to `borrow` or `withdrawCollateral`. - string internal constant INSUFFICIENT_COLLATERAL = "insufficient collateral"; - - /// @notice Thrown when the liquidity is insufficient to `withdraw` or `borrow`. - string internal constant INSUFFICIENT_LIQUIDITY = "insufficient liquidity"; - - /// @notice Thrown when the position to liquidate is healthy. - string internal constant HEALTHY_POSITION = "position is healthy"; - - /// @notice Thrown when the authorization signature is invalid. - string internal constant INVALID_SIGNATURE = "invalid signature"; - - /// @notice Thrown when the authorization signature is expired. - string internal constant SIGNATURE_EXPIRED = "signature expired"; - - /// @notice Thrown when the nonce is invalid. - string internal constant INVALID_NONCE = "invalid nonce"; - - /// @notice Thrown when a token transfer reverted. - string internal constant TRANSFER_REVERTED = "transfer reverted"; - - /// @notice Thrown when a token transfer returned false. - string internal constant TRANSFER_RETURNED_FALSE = "transfer returned false"; - - /// @notice Thrown when a token transferFrom reverted. - string internal constant TRANSFER_FROM_REVERTED = "transferFrom reverted"; - - /// @notice Thrown when a token transferFrom returned false - string internal constant TRANSFER_FROM_RETURNED_FALSE = "transferFrom returned false"; - - /// @notice Thrown when the maximum uint128 is exceeded. - string internal constant MAX_UINT128_EXCEEDED = "max uint128 exceeded"; -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/EventsLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/EventsLib.sol deleted file mode 100644 index 825ea17..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/EventsLib.sol +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {Id, MarketParams} from "../interfaces/IMorpho.sol"; - -/// @title EventsLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Library exposing events. -library EventsLib { - /// @notice Emitted when setting a new owner. - /// @param newOwner The new owner of the contract. - event SetOwner(address indexed newOwner); - - /// @notice Emitted when setting a new fee. - /// @param id The market id. - /// @param newFee The new fee. - event SetFee(Id indexed id, uint256 newFee); - - /// @notice Emitted when setting a new fee recipient. - /// @param newFeeRecipient The new fee recipient. - event SetFeeRecipient(address indexed newFeeRecipient); - - /// @notice Emitted when enabling an IRM. - /// @param irm The IRM that was enabled. - event EnableIrm(address indexed irm); - - /// @notice Emitted when enabling an LLTV. - /// @param lltv The LLTV that was enabled. - event EnableLltv(uint256 lltv); - - /// @notice Emitted when creating a market. - /// @param id The market id. - /// @param marketParams The market that was created. - event CreateMarket(Id indexed id, MarketParams marketParams); - - /// @notice Emitted on supply of assets. - /// @param id The market id. - /// @param caller The caller. - /// @param onBehalf The address that received the supply. - /// @param assets The amount of assets supplied. - /// @param shares The amount of shares minted. - event Supply(Id indexed id, address indexed caller, address indexed onBehalf, uint256 assets, uint256 shares); - - /// @notice Emitted on withdrawal of assets. - /// @param id The market id. - /// @param caller The caller. - /// @param onBehalf The address from which the assets were withdrawn. - /// @param receiver The address that received the withdrawn assets. - /// @param assets The amount of assets withdrawn. - /// @param shares The amount of shares burned. - event Withdraw( - Id indexed id, - address caller, - address indexed onBehalf, - address indexed receiver, - uint256 assets, - uint256 shares - ); - - /// @notice Emitted on borrow of assets. - /// @param id The market id. - /// @param caller The caller. - /// @param onBehalf The address from which the assets were borrowed. - /// @param receiver The address that received the borrowed assets. - /// @param assets The amount of assets borrowed. - /// @param shares The amount of shares minted. - event Borrow( - Id indexed id, - address caller, - address indexed onBehalf, - address indexed receiver, - uint256 assets, - uint256 shares - ); - - /// @notice Emitted on repayment of assets. - /// @param id The market id. - /// @param caller The caller. - /// @param onBehalf The address for which the assets were repaid. - /// @param assets The amount of assets repaid. May be 1 over the corresponding market's `totalBorrowAssets`. - /// @param shares The amount of shares burned. - event Repay(Id indexed id, address indexed caller, address indexed onBehalf, uint256 assets, uint256 shares); - - /// @notice Emitted on supply of collateral. - /// @param id The market id. - /// @param caller The caller. - /// @param onBehalf The address that received the collateral. - /// @param assets The amount of collateral supplied. - event SupplyCollateral(Id indexed id, address indexed caller, address indexed onBehalf, uint256 assets); - - /// @notice Emitted on withdrawal of collateral. - /// @param id The market id. - /// @param caller The caller. - /// @param onBehalf The address from which the collateral was withdrawn. - /// @param receiver The address that received the withdrawn collateral. - /// @param assets The amount of collateral withdrawn. - event WithdrawCollateral( - Id indexed id, address caller, address indexed onBehalf, address indexed receiver, uint256 assets - ); - - /// @notice Emitted on liquidation of a position. - /// @param id The market id. - /// @param caller The caller. - /// @param borrower The borrower of the position. - /// @param repaidAssets The amount of assets repaid. May be 1 over the corresponding market's `totalBorrowAssets`. - /// @param repaidShares The amount of shares burned. - /// @param seizedAssets The amount of collateral seized. - /// @param badDebtShares The amount of shares minted as bad debt. - event Liquidate( - Id indexed id, - address indexed caller, - address indexed borrower, - uint256 repaidAssets, - uint256 repaidShares, - uint256 seizedAssets, - uint256 badDebtShares - ); - - /// @notice Emitted on flash loan. - /// @param caller The caller. - /// @param token The token that was flash loaned. - /// @param assets The amount that was flash loaned. - event FlashLoan(address indexed caller, address indexed token, uint256 assets); - - /// @notice Emitted when setting an authorization. - /// @param caller The caller. - /// @param authorizer The authorizer address. - /// @param authorized The authorized address. - /// @param newIsAuthorized The new authorization status. - event SetAuthorization( - address indexed caller, address indexed authorizer, address indexed authorized, bool newIsAuthorized - ); - - /// @notice Emitted when setting an authorization with a signature. - /// @param caller The caller. - /// @param authorizer The authorizer address. - /// @param usedNonce The nonce that was used. - event IncrementNonce(address indexed caller, address indexed authorizer, uint256 usedNonce); - - /// @notice Emitted when accruing interest. - /// @param id The market id. - /// @param prevBorrowRate The previous borrow rate. - /// @param interest The amount of interest accrued. - /// @param feeShares The amount of shares minted as fee. - event AccrueInterest(Id indexed id, uint256 prevBorrowRate, uint256 interest, uint256 feeShares); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/LICENSE b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/LICENSE deleted file mode 100644 index aec4e2a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/LICENSE +++ /dev/null @@ -1,389 +0,0 @@ -This software is available under your choice of the GNU General Public -License, version 2 or later, or the Business Source License, as set -forth below. - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - -Business Source License 1.1 - -License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. -"Business Source License" is a trademark of MariaDB Corporation Ab. - ------------------------------------------------------------------------------ - -Parameters - -Licensor: Morpho Association - -Licensed Work: Morpho Blue Core - The Licensed Work is (c) 2023 Morpho Association - -Additional Use Grant: Any uses listed and defined at - morpho-blue-core-license-grants.morpho.eth - -Change Date: The earlier of (i) 2026-01-01, or (ii) a date specified - at morpho-blue-core-license-date.morpho.eth, or (iii) - upon the activation of the setFee function of the - Licensed Work’s applicable protocol smart contracts - deployed for production use. - -Change License: GNU General Public License v2.0 or later - ------------------------------------------------------------------------------ - -Terms - -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited -production use. - -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. - -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND -TITLE. - -MariaDB hereby grants you permission to use this License’s text to license -your works, and to refer to it using the trademark "Business Source License", -as long as you comply with the Covenants of Licensor below. - ------------------------------------------------------------------------------ - -Covenants of Licensor - -In consideration of the right to use this License’s text and the "Business -Source License" name and trademark, Licensor covenants to MariaDB, and to all -other recipients of the licensed work to be provided by Licensor: - -1. To specify as the Change License the GPL Version 2.0 or any later version, - or a license that is compatible with GPL Version 2.0 or a later version, - where "compatible" means that software provided under the Change License can - be included in a program with software provided under GPL Version 2.0 or a - later version. Licensor may specify additional Change Licenses without - limitation. - -2. To either: (a) specify an additional grant of rights to use that does not - impose any additional restriction on the right granted in this License, as - the Additional Use Grant; or (b) insert the text "None". - -3. To specify a Change Date. - -4. Not to modify this License in any other way. - ------------------------------------------------------------------------------ - -Notice - -The Business Source License (this document, or the "License") is not an Open -Source license. However, the Licensed Work will eventually be made available -under an Open Source License, as stated in this License. diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/MarketParamsLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/MarketParamsLib.sol deleted file mode 100644 index 456b0e1..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/MarketParamsLib.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {Id, MarketParams} from "../interfaces/IMorpho.sol"; - -/// @title MarketParamsLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Library to convert a market to its id. -library MarketParamsLib { - /// @notice The length of the data used to compute the id of a market. - /// @dev The length is 5 * 32 because `MarketParams` has 5 variables of 32 bytes each. - uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32; - - /// @notice Returns the id of the market `marketParams`. - function id(MarketParams memory marketParams) internal pure returns (Id marketParamsId) { - assembly ("memory-safe") { - marketParamsId := keccak256(marketParams, MARKET_PARAMS_BYTES_LENGTH) - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/MathLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/MathLib.sol deleted file mode 100644 index 2ec6330..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/MathLib.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -uint256 constant WAD = 1e18; - -/// @title MathLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Library to manage fixed-point arithmetic. -library MathLib { - /// @dev (x * y) / WAD rounded down. - function wMulDown(uint256 x, uint256 y) internal pure returns (uint256) { - return mulDivDown(x, y, WAD); - } - - /// @dev (x * WAD) / y rounded down. - function wDivDown(uint256 x, uint256 y) internal pure returns (uint256) { - return mulDivDown(x, WAD, y); - } - - /// @dev (x * WAD) / y rounded up. - function wDivUp(uint256 x, uint256 y) internal pure returns (uint256) { - return mulDivUp(x, WAD, y); - } - - /// @dev (x * y) / d rounded down. - function mulDivDown(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) { - return (x * y) / d; - } - - /// @dev (x * y) / d rounded up. - function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) { - return (x * y + (d - 1)) / d; - } - - /// @dev The sum of the first three non-zero terms of a Taylor expansion of e^(nx) - 1, to approximate a continuous - /// compound interest rate. - function wTaylorCompounded(uint256 x, uint256 n) internal pure returns (uint256) { - uint256 firstTerm = x * n; - uint256 secondTerm = mulDivDown(firstTerm, firstTerm, 2 * WAD); - uint256 thirdTerm = mulDivDown(secondTerm, firstTerm, 3 * WAD); - - return firstTerm + secondTerm + thirdTerm; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/SafeTransferLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/SafeTransferLib.sol deleted file mode 100644 index d31a791..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/SafeTransferLib.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {IERC20} from "../interfaces/IERC20.sol"; - -import {ErrorsLib} from "../libraries/ErrorsLib.sol"; - -interface IERC20Internal { - function transfer(address to, uint256 value) external returns (bool); - function transferFrom(address from, address to, uint256 value) external returns (bool); -} - -/// @title SafeTransferLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Library to manage transfers of tokens, even if calls to the transfer or transferFrom functions are not -/// returning a boolean. -/// @dev It is the responsibility of the market creator to make sure that the address of the token has non-zero code. -library SafeTransferLib { - /// @dev Warning: It does not revert on `token` with no code. - function safeTransfer(IERC20 token, address to, uint256 value) internal { - (bool success, bytes memory returndata) = - address(token).call(abi.encodeCall(IERC20Internal.transfer, (to, value))); - require(success, ErrorsLib.TRANSFER_REVERTED); - require(returndata.length == 0 || abi.decode(returndata, (bool)), ErrorsLib.TRANSFER_RETURNED_FALSE); - } - - /// @dev Warning: It does not revert on `token` with no code. - function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { - (bool success, bytes memory returndata) = - address(token).call(abi.encodeCall(IERC20Internal.transferFrom, (from, to, value))); - require(success, ErrorsLib.TRANSFER_FROM_REVERTED); - require(returndata.length == 0 || abi.decode(returndata, (bool)), ErrorsLib.TRANSFER_FROM_RETURNED_FALSE); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/SharesMathLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/SharesMathLib.sol deleted file mode 100644 index 5147606..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/SharesMathLib.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {MathLib} from "./MathLib.sol"; - -/// @title SharesMathLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Shares management library. -/// @dev This implementation mitigates share price manipulations, using OpenZeppelin's method of virtual shares: -/// https://docs.openzeppelin.com/contracts/4.x/erc4626#inflation-attack. -library SharesMathLib { - using MathLib for uint256; - - /// @dev The number of virtual shares has been chosen low enough to prevent overflows, and high enough to ensure - /// high precision computations. - uint256 internal constant VIRTUAL_SHARES = 1e6; - - /// @dev A number of virtual assets of 1 enforces a conversion rate between shares and assets when a market is - /// empty. - uint256 internal constant VIRTUAL_ASSETS = 1; - - /// @dev Calculates the value of `assets` quoted in shares, rounding down. - function toSharesDown(uint256 assets, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) { - return assets.mulDivDown(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS); - } - - /// @dev Calculates the value of `shares` quoted in assets, rounding down. - function toAssetsDown(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) { - return shares.mulDivDown(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES); - } - - /// @dev Calculates the value of `assets` quoted in shares, rounding up. - function toSharesUp(uint256 assets, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) { - return assets.mulDivUp(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS); - } - - /// @dev Calculates the value of `shares` quoted in assets, rounding up. - function toAssetsUp(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) { - return shares.mulDivUp(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/UtilsLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/UtilsLib.sol deleted file mode 100644 index 066043d..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/UtilsLib.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {ErrorsLib} from "../libraries/ErrorsLib.sol"; - -/// @title UtilsLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Library exposing helpers. -/// @dev Inspired by https://github.com/morpho-org/morpho-utils. -library UtilsLib { - /// @dev Returns true if there is exactly one zero among `x` and `y`. - function exactlyOneZero(uint256 x, uint256 y) internal pure returns (bool z) { - assembly { - z := xor(iszero(x), iszero(y)) - } - } - - /// @dev Returns the min of `x` and `y`. - function min(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { - z := xor(x, mul(xor(x, y), lt(y, x))) - } - } - - /// @dev Returns `x` safely cast to uint128. - function toUint128(uint256 x) internal pure returns (uint128) { - require(x <= type(uint128).max, ErrorsLib.MAX_UINT128_EXCEEDED); - return uint128(x); - } - - /// @dev Returns max(x - y, 0). - function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { - z := mul(gt(x, y), sub(x, y)) - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol deleted file mode 100644 index 9f9fbd6..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoBalancesLib.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {Id, MarketParams, Market, IMorpho} from "../../interfaces/IMorpho.sol"; -import {IIrm} from "../../interfaces/IIrm.sol"; - -import {MathLib} from "../MathLib.sol"; -import {UtilsLib} from "../UtilsLib.sol"; -import {MorphoLib} from "./MorphoLib.sol"; -import {SharesMathLib} from "../SharesMathLib.sol"; -import {MarketParamsLib} from "../MarketParamsLib.sol"; - -interface IMorphoMarketStruct { - function market(Id id) external view returns (Market memory); -} - -/// @title MorphoBalancesLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Helper library exposing getters with the expected value after interest accrual. -/// @dev This library is not used in Morpho itself and is intended to be used by integrators. -/// @dev The getter to retrieve the expected total borrow shares is not exposed because interest accrual does not apply -/// to it. The value can be queried directly on Morpho using `totalBorrowShares`. -library MorphoBalancesLib { - using MathLib for uint256; - using MathLib for uint128; - using UtilsLib for uint256; - using MorphoLib for IMorpho; - using SharesMathLib for uint256; - using MarketParamsLib for MarketParams; - - /// @notice Returns the expected market balances of a market after having accrued interest. - /// @return The expected total supply assets. - /// @return The expected total supply shares. - /// @return The expected total borrow assets. - /// @return The expected total borrow shares. - function expectedMarketBalances(IMorpho morpho, MarketParams memory marketParams) - internal - view - returns (uint256, uint256, uint256, uint256) - { - Id id = marketParams.id(); - - Market memory market = IMorphoMarketStruct(address(morpho)).market(id); - - uint256 elapsed = block.timestamp - market.lastUpdate; - - if (elapsed != 0 && market.totalBorrowAssets != 0) { - uint256 borrowRate = IIrm(marketParams.irm).borrowRateView(marketParams, market); - uint256 interest = market.totalBorrowAssets.wMulDown(borrowRate.wTaylorCompounded(elapsed)); - market.totalBorrowAssets += interest.toUint128(); - market.totalSupplyAssets += interest.toUint128(); - - if (market.fee != 0) { - uint256 feeAmount = interest.wMulDown(market.fee); - // The fee amount is subtracted from the total supply in this calculation to compensate for the fact - // that total supply is already updated. - uint256 feeShares = - feeAmount.toSharesDown(market.totalSupplyAssets - feeAmount, market.totalSupplyShares); - market.totalSupplyShares += feeShares.toUint128(); - } - } - - return (market.totalSupplyAssets, market.totalSupplyShares, market.totalBorrowAssets, market.totalBorrowShares); - } - - /// @notice Returns the expected total supply assets of a market after having accrued interest. - function expectedTotalSupply(IMorpho morpho, MarketParams memory marketParams) - internal - view - returns (uint256 totalSupplyAssets) - { - (totalSupplyAssets,,,) = expectedMarketBalances(morpho, marketParams); - } - - /// @notice Returns the expected total borrow assets of a market after having accrued interest. - function expectedTotalBorrow(IMorpho morpho, MarketParams memory marketParams) - internal - view - returns (uint256 totalBorrowAssets) - { - (,, totalBorrowAssets,) = expectedMarketBalances(morpho, marketParams); - } - - /// @notice Returns the expected total supply shares of a market after having accrued interest. - function expectedTotalSupplyShares(IMorpho morpho, MarketParams memory marketParams) - internal - view - returns (uint256 totalSupplyShares) - { - (, totalSupplyShares,,) = expectedMarketBalances(morpho, marketParams); - } - - /// @notice Returns the expected supply balance of a user on a market after having accrued interest. - /// @dev Warning: Wrong for `feeRecipient` because their supply shares increase is not taken into account. - function expectedSupplyBalance(IMorpho morpho, MarketParams memory marketParams, address user) - internal - view - returns (uint256) - { - Id id = marketParams.id(); - uint256 supplyShares = morpho.supplyShares(id, user); - (uint256 totalSupplyAssets, uint256 totalSupplyShares,,) = expectedMarketBalances(morpho, marketParams); - - return supplyShares.toAssetsDown(totalSupplyAssets, totalSupplyShares); - } - - /// @notice Returns the expected borrow balance of a user on a market after having accrued interest. - function expectedBorrowBalance(IMorpho morpho, MarketParams memory marketParams, address user) - internal - view - returns (uint256) - { - Id id = marketParams.id(); - uint256 borrowShares = morpho.borrowShares(id, user); - (,, uint256 totalBorrowAssets, uint256 totalBorrowShares) = expectedMarketBalances(morpho, marketParams); - - return borrowShares.toAssetsUp(totalBorrowAssets, totalBorrowShares); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoLib.sol deleted file mode 100644 index de82e6d..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoLib.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {IMorpho, Id} from "../../interfaces/IMorpho.sol"; -import {MorphoStorageLib} from "./MorphoStorageLib.sol"; - -/// @title MorphoLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Helper library to access Morpho storage variables. -library MorphoLib { - function supplyShares(IMorpho morpho, Id id, address user) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.positionSupplySharesSlot(id, user)); - return uint256(morpho.extSloads(slot)[0]); - } - - function borrowShares(IMorpho morpho, Id id, address user) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.positionBorrowSharesAndCollateralSlot(id, user)); - return uint128(uint256(morpho.extSloads(slot)[0])); - } - - function collateral(IMorpho morpho, Id id, address user) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.positionBorrowSharesAndCollateralSlot(id, user)); - return uint256(morpho.extSloads(slot)[0] >> 128); - } - - function totalSupplyAssets(IMorpho morpho, Id id) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.marketTotalSupplyAssetsAndSharesSlot(id)); - return uint128(uint256(morpho.extSloads(slot)[0])); - } - - function totalSupplyShares(IMorpho morpho, Id id) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.marketTotalSupplyAssetsAndSharesSlot(id)); - return uint256(morpho.extSloads(slot)[0] >> 128); - } - - function totalBorrowAssets(IMorpho morpho, Id id) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.marketTotalBorrowAssetsAndSharesSlot(id)); - return uint128(uint256(morpho.extSloads(slot)[0])); - } - - function totalBorrowShares(IMorpho morpho, Id id) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.marketTotalBorrowAssetsAndSharesSlot(id)); - return uint256(morpho.extSloads(slot)[0] >> 128); - } - - function lastUpdate(IMorpho morpho, Id id) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.marketLastUpdateAndFeeSlot(id)); - return uint128(uint256(morpho.extSloads(slot)[0])); - } - - function fee(IMorpho morpho, Id id) internal view returns (uint256) { - bytes32[] memory slot = _array(MorphoStorageLib.marketLastUpdateAndFeeSlot(id)); - return uint256(morpho.extSloads(slot)[0] >> 128); - } - - function _array(bytes32 x) private pure returns (bytes32[] memory) { - bytes32[] memory res = new bytes32[](1); - res[0] = x; - return res; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoStorageLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoStorageLib.sol deleted file mode 100644 index 07e3900..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/libraries/periphery/MorphoStorageLib.sol +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {Id} from "../../interfaces/IMorpho.sol"; - -/// @title MorphoStorageLib -/// @author Morpho Labs -/// @custom:contact security@morpho.org -/// @notice Helper library exposing getters to access Morpho storage variables' slot. -/// @dev This library is not used in Morpho itself and is intended to be used by integrators. -library MorphoStorageLib { - /* SLOTS */ - - uint256 internal constant OWNER_SLOT = 0; - uint256 internal constant FEE_RECIPIENT_SLOT = 1; - uint256 internal constant POSITION_SLOT = 2; - uint256 internal constant MARKET_SLOT = 3; - uint256 internal constant IS_IRM_ENABLED_SLOT = 4; - uint256 internal constant IS_LLTV_ENABLED_SLOT = 5; - uint256 internal constant IS_AUTHORIZED_SLOT = 6; - uint256 internal constant NONCE_SLOT = 7; - uint256 internal constant ID_TO_MARKET_PARAMS_SLOT = 8; - - /* SLOT OFFSETS */ - - uint256 internal constant LOAN_TOKEN_OFFSET = 0; - uint256 internal constant COLLATERAL_TOKEN_OFFSET = 1; - uint256 internal constant ORACLE_OFFSET = 2; - uint256 internal constant IRM_OFFSET = 3; - uint256 internal constant LLTV_OFFSET = 4; - - uint256 internal constant SUPPLY_SHARES_OFFSET = 0; - uint256 internal constant BORROW_SHARES_AND_COLLATERAL_OFFSET = 1; - - uint256 internal constant TOTAL_SUPPLY_ASSETS_AND_SHARES_OFFSET = 0; - uint256 internal constant TOTAL_BORROW_ASSETS_AND_SHARES_OFFSET = 1; - uint256 internal constant LAST_UPDATE_AND_FEE_OFFSET = 2; - - /* GETTERS */ - - function ownerSlot() internal pure returns (bytes32) { - return bytes32(OWNER_SLOT); - } - - function feeRecipientSlot() internal pure returns (bytes32) { - return bytes32(FEE_RECIPIENT_SLOT); - } - - function positionSupplySharesSlot(Id id, address user) internal pure returns (bytes32) { - return bytes32( - uint256(keccak256(abi.encode(user, keccak256(abi.encode(id, POSITION_SLOT))))) + SUPPLY_SHARES_OFFSET - ); - } - - function positionBorrowSharesAndCollateralSlot(Id id, address user) internal pure returns (bytes32) { - return bytes32( - uint256(keccak256(abi.encode(user, keccak256(abi.encode(id, POSITION_SLOT))))) - + BORROW_SHARES_AND_COLLATERAL_OFFSET - ); - } - - function marketTotalSupplyAssetsAndSharesSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, MARKET_SLOT))) + TOTAL_SUPPLY_ASSETS_AND_SHARES_OFFSET); - } - - function marketTotalBorrowAssetsAndSharesSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, MARKET_SLOT))) + TOTAL_BORROW_ASSETS_AND_SHARES_OFFSET); - } - - function marketLastUpdateAndFeeSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, MARKET_SLOT))) + LAST_UPDATE_AND_FEE_OFFSET); - } - - function isIrmEnabledSlot(address irm) internal pure returns (bytes32) { - return keccak256(abi.encode(irm, IS_IRM_ENABLED_SLOT)); - } - - function isLltvEnabledSlot(uint256 lltv) internal pure returns (bytes32) { - return keccak256(abi.encode(lltv, IS_LLTV_ENABLED_SLOT)); - } - - function isAuthorizedSlot(address authorizer, address authorizee) internal pure returns (bytes32) { - return keccak256(abi.encode(authorizee, keccak256(abi.encode(authorizer, IS_AUTHORIZED_SLOT)))); - } - - function nonceSlot(address authorizer) internal pure returns (bytes32) { - return keccak256(abi.encode(authorizer, NONCE_SLOT)); - } - - function idToLoanTokenSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + LOAN_TOKEN_OFFSET); - } - - function idToCollateralTokenSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + COLLATERAL_TOKEN_OFFSET); - } - - function idToOracleSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + ORACLE_OFFSET); - } - - function idToIrmSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + IRM_OFFSET); - } - - function idToLltvSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_PARAMS_SLOT))) + LLTV_OFFSET); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/ERC20Mock.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/ERC20Mock.sol deleted file mode 100644 index 871fd97..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/ERC20Mock.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {IERC20} from "./interfaces/IERC20.sol"; - -contract ERC20Mock is IERC20 { - uint256 public totalSupply; - - mapping(address account => uint256) public balanceOf; - mapping(address account => mapping(address spender => uint256)) public allowance; - - function setBalance(address account, uint256 amount) public virtual { - if (amount > balanceOf[account]) totalSupply += amount - balanceOf[account]; - else totalSupply -= balanceOf[account] - amount; - - balanceOf[account] = amount; - } - - function approve(address spender, uint256 amount) public virtual returns (bool) { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - - return true; - } - - function transfer(address to, uint256 amount) public virtual returns (bool) { - require(balanceOf[msg.sender] >= amount, "insufficient balance"); - - balanceOf[msg.sender] -= amount; - balanceOf[to] += amount; - - emit Transfer(msg.sender, to, amount); - - return true; - } - - function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) { - require(allowance[from][msg.sender] >= amount, "insufficient allowance"); - - allowance[from][msg.sender] -= amount; - - require(balanceOf[from] >= amount, "insufficient balance"); - - balanceOf[from] -= amount; - balanceOf[to] += amount; - - emit Transfer(from, to, amount); - - return true; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/FlashBorrowerMock.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/FlashBorrowerMock.sol deleted file mode 100644 index be0783c..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/FlashBorrowerMock.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {IERC20} from "./interfaces/IERC20.sol"; -import {IMorpho} from "../interfaces/IMorpho.sol"; -import {IMorphoFlashLoanCallback} from "../interfaces/IMorphoCallbacks.sol"; - -contract FlashBorrowerMock is IMorphoFlashLoanCallback { - IMorpho private immutable MORPHO; - - constructor(IMorpho newMorpho) { - MORPHO = newMorpho; - } - - function flashLoan(address token, uint256 assets, bytes calldata data) external { - MORPHO.flashLoan(token, assets, data); - } - - function onMorphoFlashLoan(uint256 assets, bytes calldata data) external { - require(msg.sender == address(MORPHO)); - address token = abi.decode(data, (address)); - IERC20(token).approve(address(MORPHO), assets); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/IrmMock.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/IrmMock.sol deleted file mode 100644 index e721977..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/IrmMock.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {IIrm} from "../interfaces/IIrm.sol"; -import {MarketParams, Market} from "../interfaces/IMorpho.sol"; - -import {MathLib} from "../libraries/MathLib.sol"; - -contract IrmMock is IIrm { - using MathLib for uint128; - - function borrowRateView(MarketParams memory, Market memory market) public pure returns (uint256) { - uint256 utilization = market.totalBorrowAssets.wDivDown(market.totalSupplyAssets); - - // Divide by the number of seconds in a year. - // This is a very simple model where x% utilization corresponds to x% APR. - return utilization / 365 days; - } - - function borrowRate(MarketParams memory marketParams, Market memory market) external pure returns (uint256) { - return borrowRateView(marketParams, market); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/LICENSE b/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/LICENSE deleted file mode 100644 index aec4e2a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/LICENSE +++ /dev/null @@ -1,389 +0,0 @@ -This software is available under your choice of the GNU General Public -License, version 2 or later, or the Business Source License, as set -forth below. - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - -Business Source License 1.1 - -License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. -"Business Source License" is a trademark of MariaDB Corporation Ab. - ------------------------------------------------------------------------------ - -Parameters - -Licensor: Morpho Association - -Licensed Work: Morpho Blue Core - The Licensed Work is (c) 2023 Morpho Association - -Additional Use Grant: Any uses listed and defined at - morpho-blue-core-license-grants.morpho.eth - -Change Date: The earlier of (i) 2026-01-01, or (ii) a date specified - at morpho-blue-core-license-date.morpho.eth, or (iii) - upon the activation of the setFee function of the - Licensed Work’s applicable protocol smart contracts - deployed for production use. - -Change License: GNU General Public License v2.0 or later - ------------------------------------------------------------------------------ - -Terms - -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited -production use. - -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. - -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND -TITLE. - -MariaDB hereby grants you permission to use this License’s text to license -your works, and to refer to it using the trademark "Business Source License", -as long as you comply with the Covenants of Licensor below. - ------------------------------------------------------------------------------ - -Covenants of Licensor - -In consideration of the right to use this License’s text and the "Business -Source License" name and trademark, Licensor covenants to MariaDB, and to all -other recipients of the licensed work to be provided by Licensor: - -1. To specify as the Change License the GPL Version 2.0 or any later version, - or a license that is compatible with GPL Version 2.0 or a later version, - where "compatible" means that software provided under the Change License can - be included in a program with software provided under GPL Version 2.0 or a - later version. Licensor may specify additional Change Licenses without - limitation. - -2. To either: (a) specify an additional grant of rights to use that does not - impose any additional restriction on the right granted in this License, as - the Additional Use Grant; or (b) insert the text "None". - -3. To specify a Change Date. - -4. Not to modify this License in any other way. - ------------------------------------------------------------------------------ - -Notice - -The Business Source License (this document, or the "License") is not an Open -Source license. However, the Licensed Work will eventually be made available -under an Open Source License, as stated in this License. diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/OracleMock.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/OracleMock.sol deleted file mode 100644 index fb0b062..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/OracleMock.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {IOracle} from "../interfaces/IOracle.sol"; - -contract OracleMock is IOracle { - uint256 public price; - - function setPrice(uint256 newPrice) external { - price = newPrice; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/interfaces/IERC20.sol b/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/interfaces/IERC20.sol deleted file mode 100644 index cf17ab2..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/src/mocks/interfaces/IERC20.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -interface IERC20 { - /* EVENTS */ - - event Transfer(address indexed from, address indexed to, uint256 value); - - event Approval(address indexed owner, address indexed spender, uint256 value); - - /* FUNCTIONS */ - - function totalSupply() external view returns (uint256); - - function balanceOf(address account) external view returns (uint256); - - function transfer(address to, uint256 value) external returns (bool); - - function allowance(address owner, address spender) external view returns (uint256); - - function approve(address spender, uint256 value) external returns (bool); - - function transferFrom(address from, address to, uint256 value) external returns (bool); -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/LICENSE b/lib/morpho-blue-irm/lib/morpho-blue/test/LICENSE deleted file mode 100644 index aec4e2a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/LICENSE +++ /dev/null @@ -1,389 +0,0 @@ -This software is available under your choice of the GNU General Public -License, version 2 or later, or the Business Source License, as set -forth below. - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - -Business Source License 1.1 - -License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. -"Business Source License" is a trademark of MariaDB Corporation Ab. - ------------------------------------------------------------------------------ - -Parameters - -Licensor: Morpho Association - -Licensed Work: Morpho Blue Core - The Licensed Work is (c) 2023 Morpho Association - -Additional Use Grant: Any uses listed and defined at - morpho-blue-core-license-grants.morpho.eth - -Change Date: The earlier of (i) 2026-01-01, or (ii) a date specified - at morpho-blue-core-license-date.morpho.eth, or (iii) - upon the activation of the setFee function of the - Licensed Work’s applicable protocol smart contracts - deployed for production use. - -Change License: GNU General Public License v2.0 or later - ------------------------------------------------------------------------------ - -Terms - -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited -production use. - -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. - -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND -TITLE. - -MariaDB hereby grants you permission to use this License’s text to license -your works, and to refer to it using the trademark "Business Source License", -as long as you comply with the Covenants of Licensor below. - ------------------------------------------------------------------------------ - -Covenants of Licensor - -In consideration of the right to use this License’s text and the "Business -Source License" name and trademark, Licensor covenants to MariaDB, and to all -other recipients of the licensed work to be provided by Licensor: - -1. To specify as the Change License the GPL Version 2.0 or any later version, - or a license that is compatible with GPL Version 2.0 or a later version, - where "compatible" means that software provided under the Change License can - be included in a program with software provided under GPL Version 2.0 or a - later version. Licensor may specify additional Change Licenses without - limitation. - -2. To either: (a) specify an additional grant of rights to use that does not - impose any additional restriction on the right granted in this License, as - the Additional Use Grant; or (b) insert the text "None". - -3. To specify a Change Date. - -4. Not to modify this License in any other way. - ------------------------------------------------------------------------------ - -Notice - -The Business Source License (this document, or the "License") is not an Open -Source license. However, the Licensed Work will eventually be made available -under an Open Source License, as stated in this License. diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/BaseTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/BaseTest.sol deleted file mode 100644 index 3a59787..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/BaseTest.sol +++ /dev/null @@ -1,409 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../../lib/forge-std/src/Test.sol"; -import "../../lib/forge-std/src/console.sol"; - -import "../../src/interfaces/IMorphoCallbacks.sol"; -import {IrmMock} from "../../src/mocks/IrmMock.sol"; -import {ERC20Mock} from "../../src/mocks/ERC20Mock.sol"; -import {OracleMock} from "../../src/mocks/OracleMock.sol"; - -import "../../src/Morpho.sol"; -import {Math} from "./helpers/Math.sol"; -import {SigUtils} from "./helpers/SigUtils.sol"; -import {ArrayLib} from "./helpers/ArrayLib.sol"; -import {MorphoLib} from "../../src/libraries/periphery/MorphoLib.sol"; -import {MorphoBalancesLib} from "../../src/libraries/periphery/MorphoBalancesLib.sol"; - -contract BaseTest is Test { - using Math for uint256; - using MathLib for uint256; - using SharesMathLib for uint256; - using ArrayLib for address[]; - using MorphoLib for IMorpho; - using MorphoBalancesLib for IMorpho; - using MarketParamsLib for MarketParams; - - uint256 internal constant BLOCK_TIME = 1; - uint256 internal constant HIGH_COLLATERAL_AMOUNT = 1e35; - uint256 internal constant MIN_TEST_AMOUNT = 100; - uint256 internal constant MAX_TEST_AMOUNT = 1e28; - uint256 internal constant MIN_TEST_SHARES = MIN_TEST_AMOUNT * SharesMathLib.VIRTUAL_SHARES; - uint256 internal constant MAX_TEST_SHARES = MAX_TEST_AMOUNT * SharesMathLib.VIRTUAL_SHARES; - uint256 internal constant MIN_TEST_LLTV = 0.01 ether; - uint256 internal constant MAX_TEST_LLTV = 0.99 ether; - uint256 internal constant DEFAULT_TEST_LLTV = 0.8 ether; - uint256 internal constant MIN_COLLATERAL_PRICE = 1e10; - uint256 internal constant MAX_COLLATERAL_PRICE = 1e40; - uint256 internal constant MAX_COLLATERAL_ASSETS = type(uint128).max; - - address internal SUPPLIER; - address internal BORROWER; - address internal REPAYER; - address internal ONBEHALF; - address internal RECEIVER; - address internal LIQUIDATOR; - address internal OWNER; - address internal FEE_RECIPIENT; - - IMorpho internal morpho; - ERC20Mock internal loanToken; - ERC20Mock internal collateralToken; - OracleMock internal oracle; - IrmMock internal irm; - - MarketParams internal marketParams; - Id internal id; - - function setUp() public virtual { - SUPPLIER = makeAddr("Supplier"); - BORROWER = makeAddr("Borrower"); - REPAYER = makeAddr("Repayer"); - ONBEHALF = makeAddr("OnBehalf"); - RECEIVER = makeAddr("Receiver"); - LIQUIDATOR = makeAddr("Liquidator"); - OWNER = makeAddr("Owner"); - FEE_RECIPIENT = makeAddr("FeeRecipient"); - - morpho = new Morpho(OWNER); - - loanToken = new ERC20Mock(); - vm.label(address(loanToken), "LoanToken"); - - collateralToken = new ERC20Mock(); - vm.label(address(collateralToken), "CollateralToken"); - - oracle = new OracleMock(); - - oracle.setPrice(ORACLE_PRICE_SCALE); - - irm = new IrmMock(); - - vm.startPrank(OWNER); - morpho.enableIrm(address(irm)); - morpho.setFeeRecipient(FEE_RECIPIENT); - vm.stopPrank(); - - loanToken.approve(address(morpho), type(uint256).max); - collateralToken.approve(address(morpho), type(uint256).max); - - vm.startPrank(SUPPLIER); - loanToken.approve(address(morpho), type(uint256).max); - collateralToken.approve(address(morpho), type(uint256).max); - - changePrank(BORROWER); - loanToken.approve(address(morpho), type(uint256).max); - collateralToken.approve(address(morpho), type(uint256).max); - - changePrank(REPAYER); - loanToken.approve(address(morpho), type(uint256).max); - collateralToken.approve(address(morpho), type(uint256).max); - - changePrank(LIQUIDATOR); - loanToken.approve(address(morpho), type(uint256).max); - collateralToken.approve(address(morpho), type(uint256).max); - - changePrank(ONBEHALF); - loanToken.approve(address(morpho), type(uint256).max); - collateralToken.approve(address(morpho), type(uint256).max); - morpho.setAuthorization(BORROWER, true); - vm.stopPrank(); - - _setLltv(DEFAULT_TEST_LLTV); - } - - function _setLltv(uint256 lltv) internal { - marketParams = MarketParams(address(loanToken), address(collateralToken), address(oracle), address(irm), lltv); - id = marketParams.id(); - - vm.startPrank(OWNER); - if (!morpho.isLltvEnabled(lltv)) morpho.enableLltv(lltv); - if (morpho.lastUpdate(marketParams.id()) == 0) morpho.createMarket(marketParams); - vm.stopPrank(); - - _forward(1); - } - - /// @dev Rolls & warps the given number of blocks forward the blockchain. - function _forward(uint256 blocks) internal { - vm.roll(block.number + blocks); - vm.warp(block.timestamp + blocks * BLOCK_TIME); // Block speed should depend on test network. - } - - /// @dev Bounds the fuzzing input to a realistic number of blocks. - function _boundBlocks(uint256 blocks) internal view returns (uint256) { - return bound(blocks, 1, type(uint32).max); - } - - /// @dev Bounds the fuzzing input to a non-zero address. - /// @dev This function should be used in place of `vm.assume` in invariant test handler functions: - /// https://github.com/foundry-rs/foundry/issues/4190. - function _boundAddressNotZero(address input) internal view virtual returns (address) { - return address(uint160(bound(uint256(uint160(input)), 1, type(uint160).max))); - } - - function _supply(uint256 amount) internal { - loanToken.setBalance(address(this), amount); - morpho.supply(marketParams, amount, 0, address(this), hex""); - } - - function _supplyCollateralForBorrower(address borrower) internal { - collateralToken.setBalance(borrower, HIGH_COLLATERAL_AMOUNT); - vm.startPrank(borrower); - collateralToken.approve(address(morpho), type(uint256).max); - morpho.supplyCollateral(marketParams, HIGH_COLLATERAL_AMOUNT, borrower, hex""); - vm.stopPrank(); - } - - function _boundHealthyPosition(uint256 amountCollateral, uint256 amountBorrowed, uint256 priceCollateral) - internal - view - returns (uint256, uint256, uint256) - { - priceCollateral = bound(priceCollateral, MIN_COLLATERAL_PRICE, MAX_COLLATERAL_PRICE); - amountBorrowed = bound(amountBorrowed, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT); - - uint256 minCollateral = amountBorrowed.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, priceCollateral); - - if (minCollateral <= MAX_COLLATERAL_ASSETS) { - amountCollateral = bound(amountCollateral, minCollateral, MAX_COLLATERAL_ASSETS); - } else { - amountCollateral = MAX_COLLATERAL_ASSETS; - amountBorrowed = Math.min( - amountBorrowed.wMulDown(marketParams.lltv).mulDivDown(priceCollateral, ORACLE_PRICE_SCALE), - MAX_TEST_AMOUNT - ); - } - - vm.assume(amountBorrowed > 0); - vm.assume(amountCollateral < type(uint256).max / priceCollateral); - return (amountCollateral, amountBorrowed, priceCollateral); - } - - function _boundUnhealthyPosition(uint256 amountCollateral, uint256 amountBorrowed, uint256 priceCollateral) - internal - view - returns (uint256, uint256, uint256) - { - priceCollateral = bound(priceCollateral, MIN_COLLATERAL_PRICE, MAX_COLLATERAL_PRICE); - amountBorrowed = bound(amountBorrowed, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT); - - uint256 maxCollateral = - amountBorrowed.wDivDown(marketParams.lltv).mulDivDown(ORACLE_PRICE_SCALE, priceCollateral); - amountCollateral = bound(amountBorrowed, 0, Math.min(maxCollateral, MAX_COLLATERAL_ASSETS)); - - vm.assume(amountCollateral > 0); - return (amountCollateral, amountBorrowed, priceCollateral); - } - - function _boundTestLltv(uint256 lltv) internal view returns (uint256) { - return bound(lltv, MIN_TEST_LLTV, MAX_TEST_LLTV); - } - - function _boundSupplyCollateralAssets(MarketParams memory _marketParams, address onBehalf, uint256 assets) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 collateral = morpho.collateral(_id, onBehalf); - - return bound(assets, 0, MAX_TEST_AMOUNT.zeroFloorSub(collateral)); - } - - function _boundWithdrawCollateralAssets(MarketParams memory _marketParams, address onBehalf, uint256 assets) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 collateral = morpho.collateral(_id, onBehalf); - uint256 collateralPrice = IOracle(_marketParams.oracle).price(); - uint256 borrowed = morpho.expectedBorrowBalance(_marketParams, onBehalf); - - return bound( - assets, - 0, - collateral.zeroFloorSub(borrowed.wDivUp(_marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice)) - ); - } - - function _boundSupplyAssets(MarketParams memory _marketParams, address onBehalf, uint256 assets) - internal - view - returns (uint256) - { - uint256 supplyBalance = morpho.expectedSupplyBalance(_marketParams, onBehalf); - - return bound(assets, 0, MAX_TEST_AMOUNT.zeroFloorSub(supplyBalance)); - } - - function _boundSupplyShares(MarketParams memory _marketParams, address onBehalf, uint256 assets) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 supplyShares = morpho.supplyShares(_id, onBehalf); - - return bound( - assets, - 0, - MAX_TEST_AMOUNT.toSharesDown(morpho.totalSupplyAssets(_id), morpho.totalSupplyShares(_id)).zeroFloorSub( - supplyShares - ) - ); - } - - function _boundWithdrawAssets(MarketParams memory _marketParams, address onBehalf, uint256 assets) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 supplyBalance = morpho.expectedSupplyBalance(_marketParams, onBehalf); - uint256 liquidity = morpho.totalSupplyAssets(_id) - morpho.totalBorrowAssets(_id); - - return bound(assets, 0, MAX_TEST_AMOUNT.min(supplyBalance).min(liquidity)); - } - - function _boundWithdrawShares(MarketParams memory _marketParams, address onBehalf, uint256 shares) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 supplyShares = morpho.supplyShares(_id, onBehalf); - uint256 totalSupplyAssets = morpho.totalSupplyAssets(_id); - - uint256 liquidity = totalSupplyAssets - morpho.totalBorrowAssets(_id); - uint256 liquidityShares = liquidity.toSharesDown(totalSupplyAssets, morpho.totalSupplyShares(_id)); - - return bound(shares, 0, supplyShares.min(liquidityShares)); - } - - function _boundBorrowAssets(MarketParams memory _marketParams, address onBehalf, uint256 assets) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 maxBorrow = _maxBorrow(_marketParams, onBehalf); - uint256 borrowed = morpho.expectedBorrowBalance(_marketParams, onBehalf); - uint256 liquidity = morpho.totalSupplyAssets(_id) - morpho.totalBorrowAssets(_id); - - return bound(assets, 0, MAX_TEST_AMOUNT.min(maxBorrow - borrowed).min(liquidity)); - } - - function _boundRepayAssets(MarketParams memory _marketParams, address onBehalf, uint256 assets) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - (,, uint256 totalBorrowAssets, uint256 totalBorrowShares) = morpho.expectedMarketBalances(_marketParams); - uint256 maxRepayAssets = morpho.borrowShares(_id, onBehalf).toAssetsDown(totalBorrowAssets, totalBorrowShares); - - return bound(assets, 0, maxRepayAssets); - } - - function _boundRepayShares(MarketParams memory _marketParams, address onBehalf, uint256 shares) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 borrowShares = morpho.borrowShares(_id, onBehalf); - - return bound(shares, 0, borrowShares); - } - - function _boundLiquidateSeizedAssets(MarketParams memory _marketParams, address borrower, uint256 seizedAssets) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 collateral = morpho.collateral(_id, borrower); - uint256 collateralPrice = IOracle(_marketParams.oracle).price(); - uint256 maxRepaidAssets = morpho.expectedBorrowBalance(_marketParams, borrower); - uint256 maxSeizedAssets = maxRepaidAssets.wMulDown(_liquidationIncentiveFactor(_marketParams.lltv)).mulDivDown( - ORACLE_PRICE_SCALE, collateralPrice - ); - - return bound(seizedAssets, 0, Math.min(collateral, maxSeizedAssets)); - } - - function _boundLiquidateRepaidShares(MarketParams memory _marketParams, address borrower, uint256 repaidShares) - internal - view - returns (uint256) - { - Id _id = _marketParams.id(); - - uint256 borrowShares = morpho.borrowShares(_id, borrower); - uint256 collateralPrice = IOracle(_marketParams.oracle).price(); - uint256 maxRepaidAssets = morpho.collateral(_id, borrower).mulDivUp(collateralPrice, ORACLE_PRICE_SCALE).wDivUp( - _liquidationIncentiveFactor(_marketParams.lltv) - ); - (,, uint256 totalBorrowAssets, uint256 totalBorrowShares) = morpho.expectedMarketBalances(marketParams); - uint256 maxRepaidShares = maxRepaidAssets.toSharesDown(totalBorrowAssets, totalBorrowShares); - - return bound(repaidShares, 0, Math.min(borrowShares, maxRepaidShares)); - } - - function _maxBorrow(MarketParams memory _marketParams, address user) internal view returns (uint256) { - Id _id = _marketParams.id(); - - uint256 collateralPrice = IOracle(_marketParams.oracle).price(); - - return morpho.collateral(_id, user).mulDivDown(collateralPrice, ORACLE_PRICE_SCALE).wMulDown(_marketParams.lltv); - } - - function _isHealthy(MarketParams memory _marketParams, address user) internal view returns (bool) { - uint256 maxBorrow = _maxBorrow(_marketParams, user); - uint256 borrowed = morpho.expectedBorrowBalance(_marketParams, user); - - return maxBorrow >= borrowed; - } - - function _liquidationIncentiveFactor(uint256 lltv) internal pure returns (uint256) { - return Math.min(MAX_LIQUIDATION_INCENTIVE_FACTOR, WAD.wDivDown(WAD - LIQUIDATION_CURSOR.wMulDown(WAD - lltv))); - } - - function _boundValidLltv(uint256 lltv) internal view returns (uint256) { - return bound(lltv, 0, WAD - 1); - } - - function _accrueInterest(MarketParams memory market) internal { - collateralToken.setBalance(address(this), 1); - morpho.supplyCollateral(market, 1, address(this), hex""); - morpho.withdrawCollateral(market, 1, address(this), address(10)); - } - - function neq(MarketParams memory a, MarketParams memory b) internal pure returns (bool) { - return (Id.unwrap(a.id()) != Id.unwrap(b.id())); - } - - function _randomCandidate(address[] memory candidates, uint256 seed) internal pure returns (address) { - if (candidates.length == 0) return address(0); - - return candidates[seed % candidates.length]; - } - - function _randomNonZero(address[] memory users, uint256 seed) internal pure returns (address) { - users = users.removeAll(address(0)); - - return _randomCandidate(users, seed); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/InvariantTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/InvariantTest.sol deleted file mode 100644 index d1e0d68..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/InvariantTest.sol +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "./BaseTest.sol"; - -contract InvariantTest is BaseTest { - using MathLib for uint256; - using SharesMathLib for uint256; - using MorphoLib for IMorpho; - using MorphoBalancesLib for IMorpho; - using MarketParamsLib for MarketParams; - - bytes4[] internal selectors; - - function setUp() public virtual override { - super.setUp(); - - _targetSenders(); - - _weightSelector(this.mine.selector, 100); - - targetContract(address(this)); - targetSelector(FuzzSelector({addr: address(this), selectors: selectors})); - } - - modifier logCall(string memory name) { - console2.log(msg.sender, "->", name); - - _; - } - - function _targetSenders() internal virtual { - _targetSender(makeAddr("Sender1")); - _targetSender(makeAddr("Sender2")); - _targetSender(makeAddr("Sender3")); - _targetSender(makeAddr("Sender4")); - _targetSender(makeAddr("Sender5")); - _targetSender(makeAddr("Sender6")); - _targetSender(makeAddr("Sender7")); - _targetSender(makeAddr("Sender8")); - } - - function _targetSender(address sender) internal { - targetSender(sender); - - vm.startPrank(sender); - loanToken.approve(address(morpho), type(uint256).max); - collateralToken.approve(address(morpho), type(uint256).max); - vm.stopPrank(); - } - - function _weightSelector(bytes4 selector, uint256 weight) internal { - for (uint256 i; i < weight; ++i) { - selectors.push(selector); - } - } - - /* HANDLERS */ - - function mine(uint256 blocks) external { - blocks = bound(blocks, 1, 50_400); - - _forward(blocks); - } - - /* UTILS */ - - function _randomSupplier(address[] memory users, MarketParams memory _marketParams, uint256 seed) - internal - view - returns (address) - { - Id _id = _marketParams.id(); - address[] memory candidates = new address[](users.length); - - for (uint256 i; i < users.length; ++i) { - address user = users[i]; - - if (morpho.supplyShares(_id, user) != 0) { - candidates[i] = user; - } - } - - return _randomNonZero(candidates, seed); - } - - function _randomBorrower(address[] memory users, MarketParams memory _marketParams, uint256 seed) - internal - view - returns (address) - { - Id _id = _marketParams.id(); - address[] memory candidates = new address[](users.length); - - for (uint256 i; i < users.length; ++i) { - address user = users[i]; - - if (morpho.borrowShares(_id, user) != 0) { - candidates[i] = user; - } - } - - return _randomNonZero(candidates, seed); - } - - function _randomHealthyCollateralSupplier(address[] memory users, MarketParams memory _marketParams, uint256 seed) - internal - view - returns (address) - { - Id _id = _marketParams.id(); - address[] memory candidates = new address[](users.length); - - for (uint256 i; i < users.length; ++i) { - address user = users[i]; - - if (morpho.collateral(_id, user) != 0 && _isHealthy(_marketParams, user)) { - candidates[i] = user; - } - } - - return _randomNonZero(candidates, seed); - } - - function _randomUnhealthyBorrower(address[] memory users, MarketParams memory _marketParams, uint256 seed) - internal - view - returns (address randomSenderToLiquidate) - { - address[] memory candidates = new address[](users.length); - - for (uint256 i; i < users.length; ++i) { - address user = users[i]; - - if (!_isHealthy(_marketParams, user)) { - candidates[i] = user; - } - } - - return _randomNonZero(candidates, seed); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/MarketParamsLibTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/MarketParamsLibTest.sol deleted file mode 100644 index ad52b39..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/MarketParamsLibTest.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../../lib/forge-std/src/Test.sol"; - -import {MarketParamsLib, MarketParams, Id} from "../../src/libraries/MarketParamsLib.sol"; - -contract MarketParamsLibTest is Test { - using MarketParamsLib for MarketParams; - - function testMarketParamsId(MarketParams memory marketParamsFuzz) public { - assertEq(Id.unwrap(marketParamsFuzz.id()), keccak256(abi.encode(marketParamsFuzz))); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/ArrayLib.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/ArrayLib.sol deleted file mode 100644 index ba590c7..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/ArrayLib.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -library ArrayLib { - function removeAll(address[] memory inputs, address removed) internal pure returns (address[] memory result) { - result = new address[](inputs.length); - - uint256 nbAddresses; - for (uint256 i; i < inputs.length; ++i) { - address input = inputs[i]; - - if (input != removed) { - result[nbAddresses] = input; - ++nbAddresses; - } - } - - assembly { - mstore(result, nbAddresses) - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/Math.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/Math.sol deleted file mode 100644 index ef6e90b..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/Math.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -library Math { - function max(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? a : b; - } - - function min(uint256 a, uint256 b) internal pure returns (uint256) { - return a < b ? a : b; - } - - function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256) { - return x <= y ? 0 : x - y; - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/SigUtils.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/SigUtils.sol deleted file mode 100644 index 9a60b52..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/SigUtils.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {AUTHORIZATION_TYPEHASH} from "../../../src/libraries/ConstantsLib.sol"; - -import {Authorization} from "../../../src/interfaces/IMorpho.sol"; - -library SigUtils { - /// @dev Computes the hash of the EIP-712 encoded data. - function getTypedDataHash(bytes32 domainSeparator, Authorization memory authorization) - public - pure - returns (bytes32) - { - return keccak256(abi.encodePacked("\x19\x01", domainSeparator, hashStruct(authorization))); - } - - function hashStruct(Authorization memory authorization) internal pure returns (bytes32) { - return keccak256( - abi.encode( - AUTHORIZATION_TYPEHASH, - authorization.authorizer, - authorization.authorized, - authorization.isAuthorized, - authorization.nonce, - authorization.deadline - ) - ); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/WadMath.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/WadMath.sol deleted file mode 100644 index 24744b3..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/helpers/WadMath.sol +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.0; - -/** - * @title Fixed point arithmetic library - * @author Alberto Cuesta Cañada, Jacob Eliosoff, Alex Roan - * @notice This library is imported for testing purposes only. It is not used in production. - * Code is cut from https://raw.githubusercontent.com/usmfum/USM/master/contracts/WadMath.sol - */ -library WadMath { - uint256 public constant WAD = 1e18; - uint256 public constant FLOOR_LOG_2_WAD_SCALED = 158961593653514369813532673448321674075; // log2(1e18) * 2**121 - uint256 public constant CEIL_LOG_2_E_SCALED_OVER_WAD = 3835341275459348170; // log2(e) * 2**121 / 1e18 - - function wadDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - z = x * WAD + y; // 101 (1.01) / 1000 (10) -> (101 * 100 + 1000 - 1) / 1000 -> 11 (0.11 = 0.101 rounded up). - unchecked { - z -= 1; - } // Can do unchecked subtraction since division in next line will catch y = 0 case anyway - z /= y; - } - - function wadExpUp(uint256 y) internal pure returns (uint256 z) { - uint256 exponent = FLOOR_LOG_2_WAD_SCALED - CEIL_LOG_2_E_SCALED_OVER_WAD * y; - require(exponent <= type(uint128).max, "exponent overflow"); - uint256 wadOneOverExpY = pow_2(uint128(exponent)); - z = wadDivUp(WAD, wadOneOverExpY); - } - - /** - * Calculate 2 raised into given power. - * - * @param x power to raise 2 into, multiplied by 2^121 - * @return z 2 raised into given power - */ - function pow_2(uint128 x) internal pure returns (uint128 z) { - unchecked { - uint256 r = 0x80000000000000000000000000000000; - if (x & 0x1000000000000000000000000000000 > 0) r = r * 0xb504f333f9de6484597d89b3754abe9f >> 127; - if (x & 0x800000000000000000000000000000 > 0) r = r * 0x9837f0518db8a96f46ad23182e42f6f6 >> 127; - if (x & 0x400000000000000000000000000000 > 0) r = r * 0x8b95c1e3ea8bd6e6fbe4628758a53c90 >> 127; - if (x & 0x200000000000000000000000000000 > 0) r = r * 0x85aac367cc487b14c5c95b8c2154c1b2 >> 127; - if (x & 0x100000000000000000000000000000 > 0) r = r * 0x82cd8698ac2ba1d73e2a475b46520bff >> 127; - if (x & 0x80000000000000000000000000000 > 0) r = r * 0x8164d1f3bc0307737be56527bd14def4 >> 127; - if (x & 0x40000000000000000000000000000 > 0) r = r * 0x80b1ed4fd999ab6c25335719b6e6fd20 >> 127; - if (x & 0x20000000000000000000000000000 > 0) r = r * 0x8058d7d2d5e5f6b094d589f608ee4aa2 >> 127; - if (x & 0x10000000000000000000000000000 > 0) r = r * 0x802c6436d0e04f50ff8ce94a6797b3ce >> 127; - if (x & 0x8000000000000000000000000000 > 0) r = r * 0x8016302f174676283690dfe44d11d008 >> 127; - if (x & 0x4000000000000000000000000000 > 0) r = r * 0x800b179c82028fd0945e54e2ae18f2f0 >> 127; - if (x & 0x2000000000000000000000000000 > 0) r = r * 0x80058baf7fee3b5d1c718b38e549cb93 >> 127; - if (x & 0x1000000000000000000000000000 > 0) r = r * 0x8002c5d00fdcfcb6b6566a58c048be1f >> 127; - if (x & 0x800000000000000000000000000 > 0) r = r * 0x800162e61bed4a48e84c2e1a463473d9 >> 127; - if (x & 0x400000000000000000000000000 > 0) r = r * 0x8000b17292f702a3aa22beacca949013 >> 127; - if (x & 0x200000000000000000000000000 > 0) r = r * 0x800058b92abbae02030c5fa5256f41fe >> 127; - if (x & 0x100000000000000000000000000 > 0) r = r * 0x80002c5c8dade4d71776c0f4dbea67d6 >> 127; - if (x & 0x80000000000000000000000000 > 0) r = r * 0x8000162e44eaf636526be456600bdbe4 >> 127; - if (x & 0x40000000000000000000000000 > 0) r = r * 0x80000b1721fa7c188307016c1cd4e8b6 >> 127; - if (x & 0x20000000000000000000000000 > 0) r = r * 0x8000058b90de7e4cecfc487503488bb1 >> 127; - if (x & 0x10000000000000000000000000 > 0) r = r * 0x800002c5c8678f36cbfce50a6de60b14 >> 127; - if (x & 0x8000000000000000000000000 > 0) r = r * 0x80000162e431db9f80b2347b5d62e516 >> 127; - if (x & 0x4000000000000000000000000 > 0) r = r * 0x800000b1721872d0c7b08cf1e0114152 >> 127; - if (x & 0x2000000000000000000000000 > 0) r = r * 0x80000058b90c1aa8a5c3736cb77e8dff >> 127; - if (x & 0x1000000000000000000000000 > 0) r = r * 0x8000002c5c8605a4635f2efc2362d978 >> 127; - if (x & 0x800000000000000000000000 > 0) r = r * 0x800000162e4300e635cf4a109e3939bd >> 127; - if (x & 0x400000000000000000000000 > 0) r = r * 0x8000000b17217ff81bef9c551590cf83 >> 127; - if (x & 0x200000000000000000000000 > 0) r = r * 0x800000058b90bfdd4e39cd52c0cfa27c >> 127; - if (x & 0x100000000000000000000000 > 0) r = r * 0x80000002c5c85fe6f72d669e0e76e411 >> 127; - if (x & 0x80000000000000000000000 > 0) r = r * 0x8000000162e42ff18f9ad35186d0df28 >> 127; - if (x & 0x40000000000000000000000 > 0) r = r * 0x80000000b17217f84cce71aa0dcfffe7 >> 127; - if (x & 0x20000000000000000000000 > 0) r = r * 0x8000000058b90bfc07a77ad56ed22aaa >> 127; - if (x & 0x10000000000000000000000 > 0) r = r * 0x800000002c5c85fdfc23cdead40da8d6 >> 127; - if (x & 0x8000000000000000000000 > 0) r = r * 0x80000000162e42fefc25eb1571853a66 >> 127; - if (x & 0x4000000000000000000000 > 0) r = r * 0x800000000b17217f7d97f692baacded5 >> 127; - if (x & 0x2000000000000000000000 > 0) r = r * 0x80000000058b90bfbead3b8b5dd254d7 >> 127; - if (x & 0x1000000000000000000000 > 0) r = r * 0x8000000002c5c85fdf4eedd62f084e67 >> 127; - if (x & 0x800000000000000000000 > 0) r = r * 0x800000000162e42fefa58aef378bf586 >> 127; - if (x & 0x400000000000000000000 > 0) r = r * 0x8000000000b17217f7d24a78a3c7ef02 >> 127; - if (x & 0x200000000000000000000 > 0) r = r * 0x800000000058b90bfbe9067c93e474a6 >> 127; - if (x & 0x100000000000000000000 > 0) r = r * 0x80000000002c5c85fdf47b8e5a72599f >> 127; - if (x & 0x80000000000000000000 > 0) r = r * 0x8000000000162e42fefa3bdb315934a2 >> 127; - if (x & 0x40000000000000000000 > 0) r = r * 0x80000000000b17217f7d1d7299b49c46 >> 127; - if (x & 0x20000000000000000000 > 0) r = r * 0x8000000000058b90bfbe8e9a8d1c4ea0 >> 127; - if (x & 0x10000000000000000000 > 0) r = r * 0x800000000002c5c85fdf4745969ea76f >> 127; - if (x & 0x8000000000000000000 > 0) r = r * 0x80000000000162e42fefa3a0df5373bf >> 127; - if (x & 0x4000000000000000000 > 0) r = r * 0x800000000000b17217f7d1cff4aac1e1 >> 127; - if (x & 0x2000000000000000000 > 0) r = r * 0x80000000000058b90bfbe8e7db95a2f1 >> 127; - if (x & 0x1000000000000000000 > 0) r = r * 0x8000000000002c5c85fdf473e61ae1f8 >> 127; - if (x & 0x800000000000000000 > 0) r = r * 0x800000000000162e42fefa39f121751c >> 127; - if (x & 0x400000000000000000 > 0) r = r * 0x8000000000000b17217f7d1cf815bb96 >> 127; - if (x & 0x200000000000000000 > 0) r = r * 0x800000000000058b90bfbe8e7bec1e0d >> 127; - if (x & 0x100000000000000000 > 0) r = r * 0x80000000000002c5c85fdf473dee5f17 >> 127; - if (x & 0x80000000000000000 > 0) r = r * 0x8000000000000162e42fefa39ef5438f >> 127; - if (x & 0x40000000000000000 > 0) r = r * 0x80000000000000b17217f7d1cf7a26c8 >> 127; - if (x & 0x20000000000000000 > 0) r = r * 0x8000000000000058b90bfbe8e7bcf4a4 >> 127; - if (x & 0x10000000000000000 > 0) r = r * 0x800000000000002c5c85fdf473de72a2 >> 127; - if (x & 0x8000000000000000 > 0) r = r * 0x80000000000000162e42fefa39ef3765 >> 127; - if (x & 0x4000000000000000 > 0) r = r * 0x800000000000000b17217f7d1cf79b37 >> 127; - if (x & 0x2000000000000000 > 0) r = r * 0x80000000000000058b90bfbe8e7bcd7d >> 127; - if (x & 0x1000000000000000 > 0) r = r * 0x8000000000000002c5c85fdf473de6b6 >> 127; - if (x & 0x800000000000000 > 0) r = r * 0x800000000000000162e42fefa39ef359 >> 127; - if (x & 0x400000000000000 > 0) r = r * 0x8000000000000000b17217f7d1cf79ac >> 127; - if (x & 0x200000000000000 > 0) r = r * 0x800000000000000058b90bfbe8e7bcd6 >> 127; - if (x & 0x100000000000000 > 0) r = r * 0x80000000000000002c5c85fdf473de6a >> 127; - if (x & 0x80000000000000 > 0) r = r * 0x8000000000000000162e42fefa39ef35 >> 127; - if (x & 0x40000000000000 > 0) r = r * 0x80000000000000000b17217f7d1cf79a >> 127; - if (x & 0x20000000000000 > 0) r = r * 0x8000000000000000058b90bfbe8e7bcd >> 127; - if (x & 0x10000000000000 > 0) r = r * 0x800000000000000002c5c85fdf473de6 >> 127; - if (x & 0x8000000000000 > 0) r = r * 0x80000000000000000162e42fefa39ef3 >> 127; - if (x & 0x4000000000000 > 0) r = r * 0x800000000000000000b17217f7d1cf79 >> 127; - if (x & 0x2000000000000 > 0) r = r * 0x80000000000000000058b90bfbe8e7bc >> 127; - if (x & 0x1000000000000 > 0) r = r * 0x8000000000000000002c5c85fdf473de >> 127; - if (x & 0x800000000000 > 0) r = r * 0x800000000000000000162e42fefa39ef >> 127; - if (x & 0x400000000000 > 0) r = r * 0x8000000000000000000b17217f7d1cf7 >> 127; - if (x & 0x200000000000 > 0) r = r * 0x800000000000000000058b90bfbe8e7b >> 127; - if (x & 0x100000000000 > 0) r = r * 0x80000000000000000002c5c85fdf473d >> 127; - if (x & 0x80000000000 > 0) r = r * 0x8000000000000000000162e42fefa39e >> 127; - if (x & 0x40000000000 > 0) r = r * 0x80000000000000000000b17217f7d1cf >> 127; - if (x & 0x20000000000 > 0) r = r * 0x8000000000000000000058b90bfbe8e7 >> 127; - if (x & 0x10000000000 > 0) r = r * 0x800000000000000000002c5c85fdf473 >> 127; - if (x & 0x8000000000 > 0) r = r * 0x80000000000000000000162e42fefa39 >> 127; - if (x & 0x4000000000 > 0) r = r * 0x800000000000000000000b17217f7d1c >> 127; - if (x & 0x2000000000 > 0) r = r * 0x80000000000000000000058b90bfbe8e >> 127; - if (x & 0x1000000000 > 0) r = r * 0x8000000000000000000002c5c85fdf47 >> 127; - if (x & 0x800000000 > 0) r = r * 0x800000000000000000000162e42fefa3 >> 127; - if (x & 0x400000000 > 0) r = r * 0x8000000000000000000000b17217f7d1 >> 127; - if (x & 0x200000000 > 0) r = r * 0x800000000000000000000058b90bfbe8 >> 127; - if (x & 0x100000000 > 0) r = r * 0x80000000000000000000002c5c85fdf4 >> 127; - if (x & 0x80000000 > 0) r = r * 0x8000000000000000000000162e42fefa >> 127; - if (x & 0x40000000 > 0) r = r * 0x80000000000000000000000b17217f7d >> 127; - if (x & 0x20000000 > 0) r = r * 0x8000000000000000000000058b90bfbe >> 127; - if (x & 0x10000000 > 0) r = r * 0x800000000000000000000002c5c85fdf >> 127; - if (x & 0x8000000 > 0) r = r * 0x80000000000000000000000162e42fef >> 127; - if (x & 0x4000000 > 0) r = r * 0x800000000000000000000000b17217f7 >> 127; - if (x & 0x2000000 > 0) r = r * 0x80000000000000000000000058b90bfb >> 127; - if (x & 0x1000000 > 0) r = r * 0x8000000000000000000000002c5c85fd >> 127; - if (x & 0x800000 > 0) r = r * 0x800000000000000000000000162e42fe >> 127; - if (x & 0x400000 > 0) r = r * 0x8000000000000000000000000b17217f >> 127; - if (x & 0x200000 > 0) r = r * 0x800000000000000000000000058b90bf >> 127; - if (x & 0x100000 > 0) r = r * 0x80000000000000000000000002c5c85f >> 127; - if (x & 0x80000 > 0) r = r * 0x8000000000000000000000000162e42f >> 127; - if (x & 0x40000 > 0) r = r * 0x80000000000000000000000000b17217 >> 127; - if (x & 0x20000 > 0) r = r * 0x8000000000000000000000000058b90b >> 127; - if (x & 0x10000 > 0) r = r * 0x800000000000000000000000002c5c85 >> 127; - if (x & 0x8000 > 0) r = r * 0x80000000000000000000000000162e42 >> 127; - if (x & 0x4000 > 0) r = r * 0x800000000000000000000000000b1721 >> 127; - if (x & 0x2000 > 0) r = r * 0x80000000000000000000000000058b90 >> 127; - if (x & 0x1000 > 0) r = r * 0x8000000000000000000000000002c5c8 >> 127; - if (x & 0x800 > 0) r = r * 0x800000000000000000000000000162e4 >> 127; - if (x & 0x400 > 0) r = r * 0x8000000000000000000000000000b172 >> 127; - if (x & 0x200 > 0) r = r * 0x800000000000000000000000000058b9 >> 127; - if (x & 0x100 > 0) r = r * 0x80000000000000000000000000002c5c >> 127; - if (x & 0x80 > 0) r = r * 0x8000000000000000000000000000162e >> 127; - if (x & 0x40 > 0) r = r * 0x80000000000000000000000000000b17 >> 127; - if (x & 0x20 > 0) r = r * 0x8000000000000000000000000000058b >> 127; - if (x & 0x10 > 0) r = r * 0x800000000000000000000000000002c5 >> 127; - if (x & 0x8 > 0) r = r * 0x80000000000000000000000000000162 >> 127; - if (x & 0x4 > 0) r = r * 0x800000000000000000000000000000b1 >> 127; - if (x & 0x2 > 0) r = r * 0x80000000000000000000000000000058 >> 127; - if (x & 0x1 > 0) r = r * 0x8000000000000000000000000000002c >> 127; - - r >>= 127 - (x >> 121); - - z = uint128(r); - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/AccrueInterestIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/AccrueInterestIntegrationTest.sol deleted file mode 100644 index 25b9109..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/AccrueInterestIntegrationTest.sol +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract AccrueInterestIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - using SharesMathLib for uint256; - - function testAccrueInterestNoTimeElapsed(uint256 amountSupplied, uint256 amountBorrowed) public { - uint256 collateralPrice = oracle.price(); - uint256 amountCollateral; - (amountCollateral, amountBorrowed,) = _boundHealthyPosition(amountCollateral, amountBorrowed, collateralPrice); - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - - loanToken.setBalance(address(this), amountSupplied); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - uint256 totalBorrowBeforeAccrued = morpho.totalBorrowAssets(id); - uint256 totalSupplyBeforeAccrued = morpho.totalSupplyAssets(id); - uint256 totalSupplySharesBeforeAccrued = morpho.totalSupplyShares(id); - - _accrueInterest(marketParams); - - assertEq(morpho.totalBorrowAssets(id), totalBorrowBeforeAccrued, "total borrow"); - assertEq(morpho.totalSupplyAssets(id), totalSupplyBeforeAccrued, "total supply"); - assertEq(morpho.totalSupplyShares(id), totalSupplySharesBeforeAccrued, "total supply shares"); - assertEq(morpho.supplyShares(id, FEE_RECIPIENT), 0, "feeRecipient's supply shares"); - } - - function testAccrueInterestNoBorrow(uint256 amountSupplied, uint256 blocks) public { - amountSupplied = bound(amountSupplied, 2, MAX_TEST_AMOUNT); - blocks = _boundBlocks(blocks); - - loanToken.setBalance(address(this), amountSupplied); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - _forward(blocks); - - uint256 totalBorrowBeforeAccrued = morpho.totalBorrowAssets(id); - uint256 totalSupplyBeforeAccrued = morpho.totalSupplyAssets(id); - uint256 totalSupplySharesBeforeAccrued = morpho.totalSupplyShares(id); - - _accrueInterest(marketParams); - - assertEq(morpho.totalBorrowAssets(id), totalBorrowBeforeAccrued, "total borrow"); - assertEq(morpho.totalSupplyAssets(id), totalSupplyBeforeAccrued, "total supply"); - assertEq(morpho.totalSupplyShares(id), totalSupplySharesBeforeAccrued, "total supply shares"); - assertEq(morpho.supplyShares(id, FEE_RECIPIENT), 0, "feeRecipient's supply shares"); - assertEq(morpho.lastUpdate(id), block.timestamp, "last update"); - } - - function testAccrueInterestNoFee(uint256 amountSupplied, uint256 amountBorrowed, uint256 blocks) public { - uint256 collateralPrice = oracle.price(); - uint256 amountCollateral; - (amountCollateral, amountBorrowed,) = _boundHealthyPosition(amountCollateral, amountBorrowed, collateralPrice); - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - blocks = _boundBlocks(blocks); - - loanToken.setBalance(address(this), amountSupplied); - loanToken.setBalance(address(this), amountSupplied); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - _forward(blocks); - - uint256 borrowRate = (morpho.totalBorrowAssets(id).wDivDown(morpho.totalSupplyAssets(id))) / 365 days; - uint256 totalBorrowBeforeAccrued = morpho.totalBorrowAssets(id); - uint256 totalSupplyBeforeAccrued = morpho.totalSupplyAssets(id); - uint256 totalSupplySharesBeforeAccrued = morpho.totalSupplyShares(id); - uint256 expectedAccruedInterest = - totalBorrowBeforeAccrued.wMulDown(borrowRate.wTaylorCompounded(blocks * BLOCK_TIME)); - - collateralToken.setBalance(address(this), 1); - morpho.supplyCollateral(marketParams, 1, address(this), hex""); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.AccrueInterest(id, borrowRate, expectedAccruedInterest, 0); - // Accrues interest. - morpho.withdrawCollateral(marketParams, 1, address(this), address(this)); - - assertEq(morpho.totalBorrowAssets(id), totalBorrowBeforeAccrued + expectedAccruedInterest, "total borrow"); - assertEq(morpho.totalSupplyAssets(id), totalSupplyBeforeAccrued + expectedAccruedInterest, "total supply"); - assertEq(morpho.totalSupplyShares(id), totalSupplySharesBeforeAccrued, "total supply shares"); - assertEq(morpho.supplyShares(id, FEE_RECIPIENT), 0, "feeRecipient's supply shares"); - assertEq(morpho.lastUpdate(id), block.timestamp, "last update"); - } - - struct AccrueInterestWithFeesTestParams { - uint256 borrowRate; - uint256 totalBorrowBeforeAccrued; - uint256 totalSupplyBeforeAccrued; - uint256 totalSupplySharesBeforeAccrued; - uint256 expectedAccruedInterest; - uint256 feeAmount; - uint256 feeShares; - } - - function testAccrueInterestWithFees(uint256 amountSupplied, uint256 amountBorrowed, uint256 blocks, uint256 fee) - public - { - AccrueInterestWithFeesTestParams memory params; - - uint256 collateralPrice = oracle.price(); - uint256 amountCollateral; - (amountCollateral, amountBorrowed,) = _boundHealthyPosition(amountCollateral, amountBorrowed, collateralPrice); - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - blocks = _boundBlocks(blocks); - fee = bound(fee, 1, MAX_FEE); - - // Set fee parameters. - vm.startPrank(OWNER); - if (fee != morpho.fee(id)) morpho.setFee(marketParams, fee); - vm.stopPrank(); - - loanToken.setBalance(address(this), amountSupplied); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - _forward(blocks); - - params.borrowRate = (morpho.totalBorrowAssets(id).wDivDown(morpho.totalSupplyAssets(id))) / 365 days; - params.totalBorrowBeforeAccrued = morpho.totalBorrowAssets(id); - params.totalSupplyBeforeAccrued = morpho.totalSupplyAssets(id); - params.totalSupplySharesBeforeAccrued = morpho.totalSupplyShares(id); - params.expectedAccruedInterest = - params.totalBorrowBeforeAccrued.wMulDown(params.borrowRate.wTaylorCompounded(blocks * BLOCK_TIME)); - params.feeAmount = params.expectedAccruedInterest.wMulDown(fee); - params.feeShares = params.feeAmount.toSharesDown( - params.totalSupplyBeforeAccrued + params.expectedAccruedInterest - params.feeAmount, - params.totalSupplySharesBeforeAccrued - ); - - collateralToken.setBalance(address(this), 1); - morpho.supplyCollateral(marketParams, 1, address(this), hex""); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.AccrueInterest(id, params.borrowRate, params.expectedAccruedInterest, params.feeShares); - // Accrues interest. - morpho.withdrawCollateral(marketParams, 1, address(this), address(this)); - - assertEq( - morpho.totalSupplyAssets(id), - params.totalSupplyBeforeAccrued + params.expectedAccruedInterest, - "total supply" - ); - assertEq( - morpho.totalBorrowAssets(id), - params.totalBorrowBeforeAccrued + params.expectedAccruedInterest, - "total borrow" - ); - assertEq( - morpho.totalSupplyShares(id), - params.totalSupplySharesBeforeAccrued + params.feeShares, - "total supply shares" - ); - assertEq(morpho.supplyShares(id, FEE_RECIPIENT), params.feeShares, "feeRecipient's supply shares"); - assertEq(morpho.lastUpdate(id), block.timestamp, "last update"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/AuthorizationIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/AuthorizationIntegrationTest.sol deleted file mode 100644 index d8cb5b1..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/AuthorizationIntegrationTest.sol +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract AuthorizationIntegrationTest is BaseTest { - function testSetAuthorization(address addressFuzz) public { - vm.assume(addressFuzz != address(this)); - - morpho.setAuthorization(addressFuzz, true); - - assertTrue(morpho.isAuthorized(address(this), addressFuzz)); - - morpho.setAuthorization(addressFuzz, false); - - assertFalse(morpho.isAuthorized(address(this), addressFuzz)); - } - - function testSetAuthorizationWithSignatureDeadlineOutdated( - Authorization memory authorization, - uint256 privateKey, - uint256 blocks - ) public { - blocks = _boundBlocks(blocks); - authorization.deadline = block.timestamp; - - // Private key must be less than the secp256k1 curve order. - privateKey = bound(privateKey, 1, type(uint32).max); - authorization.nonce = 0; - authorization.authorizer = vm.addr(privateKey); - - Signature memory sig; - bytes32 digest = SigUtils.getTypedDataHash(morpho.DOMAIN_SEPARATOR(), authorization); - (sig.v, sig.r, sig.s) = vm.sign(privateKey, digest); - - _forward(blocks); - - vm.expectRevert(bytes(ErrorsLib.SIGNATURE_EXPIRED)); - morpho.setAuthorizationWithSig(authorization, sig); - } - - function testAuthorizationWithSigWrongPK(Authorization memory authorization, uint256 privateKey) public { - authorization.deadline = bound(authorization.deadline, block.timestamp + 1, type(uint256).max); - - // Private key must be less than the secp256k1 curve order. - privateKey = bound(privateKey, 1, type(uint32).max); - authorization.nonce = 0; - - Signature memory sig; - bytes32 digest = SigUtils.getTypedDataHash(morpho.DOMAIN_SEPARATOR(), authorization); - (sig.v, sig.r, sig.s) = vm.sign(privateKey, digest); - - vm.expectRevert(bytes(ErrorsLib.INVALID_SIGNATURE)); - morpho.setAuthorizationWithSig(authorization, sig); - } - - function testAuthorizationWithSigWrongNonce(Authorization memory authorization, uint256 privateKey) public { - authorization.deadline = bound(authorization.deadline, block.timestamp + 1, type(uint256).max); - authorization.nonce = bound(authorization.nonce, 1, type(uint256).max); - - // Private key must be less than the secp256k1 curve order. - privateKey = bound(privateKey, 1, type(uint32).max); - authorization.authorizer = vm.addr(privateKey); - - Signature memory sig; - bytes32 digest = SigUtils.getTypedDataHash(morpho.DOMAIN_SEPARATOR(), authorization); - (sig.v, sig.r, sig.s) = vm.sign(privateKey, digest); - - vm.expectRevert(bytes(ErrorsLib.INVALID_NONCE)); - morpho.setAuthorizationWithSig(authorization, sig); - } - - function testAuthorizationWithSig(Authorization memory authorization, uint256 privateKey) public { - authorization.deadline = bound(authorization.deadline, block.timestamp + 1, type(uint256).max); - - // Private key must be less than the secp256k1 curve order. - privateKey = bound(privateKey, 1, type(uint32).max); - authorization.nonce = 0; - authorization.authorizer = vm.addr(privateKey); - - Signature memory sig; - bytes32 digest = SigUtils.getTypedDataHash(morpho.DOMAIN_SEPARATOR(), authorization); - (sig.v, sig.r, sig.s) = vm.sign(privateKey, digest); - - morpho.setAuthorizationWithSig(authorization, sig); - - assertEq(morpho.isAuthorized(authorization.authorizer, authorization.authorized), authorization.isAuthorized); - assertEq(morpho.nonce(authorization.authorizer), 1); - } - - function testAuthorizationFailsWithReusedSig(Authorization memory authorization, uint256 privateKey) public { - authorization.deadline = bound(authorization.deadline, block.timestamp + 1, type(uint256).max); - - // Private key must be less than the secp256k1 curve order. - privateKey = bound(privateKey, 1, type(uint32).max); - authorization.nonce = 0; - authorization.authorizer = vm.addr(privateKey); - - Signature memory sig; - bytes32 digest = SigUtils.getTypedDataHash(morpho.DOMAIN_SEPARATOR(), authorization); - (sig.v, sig.r, sig.s) = vm.sign(privateKey, digest); - - morpho.setAuthorizationWithSig(authorization, sig); - - vm.expectRevert(bytes(ErrorsLib.INVALID_NONCE)); - morpho.setAuthorizationWithSig(authorization, sig); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/BorrowIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/BorrowIntegrationTest.sol deleted file mode 100644 index 1733c78..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/BorrowIntegrationTest.sol +++ /dev/null @@ -1,268 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract BorrowIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - using SharesMathLib for uint256; - - function testBorrowMarketNotCreated(MarketParams memory marketParamsFuzz, address borrowerFuzz, uint256 amount) - public - { - vm.assume(neq(marketParamsFuzz, marketParams)); - - vm.prank(borrowerFuzz); - vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); - morpho.borrow(marketParamsFuzz, amount, 0, borrowerFuzz, RECEIVER); - } - - function testBorrowZeroAmount(address borrowerFuzz) public { - vm.prank(borrowerFuzz); - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.borrow(marketParams, 0, 0, borrowerFuzz, RECEIVER); - } - - function testBorrowInconsistentInput(address borrowerFuzz, uint256 amount, uint256 shares) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - shares = bound(shares, 1, MAX_TEST_SHARES); - - vm.prank(borrowerFuzz); - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.borrow(marketParams, amount, shares, borrowerFuzz, RECEIVER); - } - - function testBorrowToZeroAddress(address borrowerFuzz, uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - _supply(amount); - - vm.prank(borrowerFuzz); - vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS)); - morpho.borrow(marketParams, amount, 0, borrowerFuzz, address(0)); - } - - function testBorrowUnauthorized(address supplier, address attacker, uint256 amount) public { - vm.assume(supplier != attacker && supplier != address(0)); - (uint256 amountCollateral, uint256 amountBorrowed,) = _boundHealthyPosition(amount, amount, ORACLE_PRICE_SCALE); - - _supply(amountBorrowed); - - collateralToken.setBalance(supplier, amountCollateral); - - vm.startPrank(supplier); - collateralToken.approve(address(morpho), amountCollateral); - morpho.supplyCollateral(marketParams, amountCollateral, supplier, hex""); - - changePrank(attacker); - vm.expectRevert(bytes(ErrorsLib.UNAUTHORIZED)); - morpho.borrow(marketParams, amountBorrowed, 0, supplier, RECEIVER); - } - - function testBorrowUnhealthyPosition( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundUnhealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - vm.expectRevert(bytes(ErrorsLib.INSUFFICIENT_COLLATERAL)); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - } - - function testBorrowUnsufficientLiquidity( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - vm.assume(amountBorrowed >= 2); - amountSupplied = bound(amountSupplied, 1, amountBorrowed - 1); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - vm.expectRevert(bytes(ErrorsLib.INSUFFICIENT_LIQUIDITY)); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - } - - function testBorrowAssets( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - - uint256 expectedBorrowShares = amountBorrowed.toSharesUp(0, 0); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Borrow(id, BORROWER, BORROWER, RECEIVER, amountBorrowed, expectedBorrowShares); - (uint256 returnAssets, uint256 returnShares) = - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, RECEIVER); - vm.stopPrank(); - - assertEq(returnAssets, amountBorrowed, "returned asset amount"); - assertEq(returnShares, expectedBorrowShares, "returned shares amount"); - assertEq(morpho.totalBorrowAssets(id), amountBorrowed, "total borrow"); - assertEq(morpho.borrowShares(id, BORROWER), expectedBorrowShares, "borrow shares"); - assertEq(morpho.borrowShares(id, BORROWER), expectedBorrowShares, "total borrow shares"); - assertEq(loanToken.balanceOf(RECEIVER), amountBorrowed, "borrower balance"); - assertEq(loanToken.balanceOf(address(morpho)), amountSupplied - amountBorrowed, "morpho balance"); - } - - function testBorrowShares( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 sharesBorrowed, - uint256 priceCollateral - ) public { - priceCollateral = bound(priceCollateral, MIN_COLLATERAL_PRICE, MAX_COLLATERAL_PRICE); - sharesBorrowed = bound(sharesBorrowed, MIN_TEST_SHARES, MAX_TEST_SHARES); - uint256 expectedAmountBorrowed = sharesBorrowed.toAssetsDown(0, 0); - uint256 expectedBorrowedValue = sharesBorrowed.toAssetsUp(expectedAmountBorrowed, sharesBorrowed); - uint256 minCollateral = - expectedBorrowedValue.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, priceCollateral); - vm.assume(minCollateral <= MAX_COLLATERAL_ASSETS); - amountCollateral = bound(amountCollateral, minCollateral, MAX_COLLATERAL_ASSETS); - vm.assume(amountCollateral <= type(uint256).max / priceCollateral); - - amountSupplied = bound(amountSupplied, expectedAmountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Borrow(id, BORROWER, BORROWER, RECEIVER, expectedAmountBorrowed, sharesBorrowed); - (uint256 returnAssets, uint256 returnShares) = - morpho.borrow(marketParams, 0, sharesBorrowed, BORROWER, RECEIVER); - vm.stopPrank(); - - assertEq(returnAssets, expectedAmountBorrowed, "returned asset amount"); - assertEq(returnShares, sharesBorrowed, "returned shares amount"); - assertEq(morpho.totalBorrowAssets(id), expectedAmountBorrowed, "total borrow"); - assertEq(morpho.borrowShares(id, BORROWER), sharesBorrowed, "borrow shares"); - assertEq(morpho.borrowShares(id, BORROWER), sharesBorrowed, "total borrow shares"); - assertEq(loanToken.balanceOf(RECEIVER), expectedAmountBorrowed, "borrower balance"); - assertEq(loanToken.balanceOf(address(morpho)), amountSupplied - expectedAmountBorrowed, "morpho balance"); - } - - function testBorrowAssetsOnBehalf( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - collateralToken.setBalance(ONBEHALF, amountCollateral); - - vm.startPrank(ONBEHALF); - collateralToken.approve(address(morpho), amountCollateral); - morpho.supplyCollateral(marketParams, amountCollateral, ONBEHALF, hex""); - morpho.setAuthorization(BORROWER, true); - vm.stopPrank(); - - uint256 expectedBorrowShares = amountBorrowed.toSharesUp(0, 0); - - vm.prank(BORROWER); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Borrow(id, BORROWER, ONBEHALF, RECEIVER, amountBorrowed, expectedBorrowShares); - (uint256 returnAssets, uint256 returnShares) = - morpho.borrow(marketParams, amountBorrowed, 0, ONBEHALF, RECEIVER); - - assertEq(returnAssets, amountBorrowed, "returned asset amount"); - assertEq(returnShares, expectedBorrowShares, "returned shares amount"); - assertEq(morpho.borrowShares(id, ONBEHALF), expectedBorrowShares, "borrow shares"); - assertEq(morpho.totalBorrowAssets(id), amountBorrowed, "total borrow"); - assertEq(morpho.totalBorrowShares(id), expectedBorrowShares, "total borrow shares"); - assertEq(loanToken.balanceOf(RECEIVER), amountBorrowed, "borrower balance"); - assertEq(loanToken.balanceOf(address(morpho)), amountSupplied - amountBorrowed, "morpho balance"); - } - - function testBorrowSharesOnBehalf( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 sharesBorrowed, - uint256 priceCollateral - ) public { - priceCollateral = bound(priceCollateral, MIN_COLLATERAL_PRICE, MAX_COLLATERAL_PRICE); - sharesBorrowed = bound(sharesBorrowed, MIN_TEST_SHARES, MAX_TEST_SHARES); - uint256 expectedAmountBorrowed = sharesBorrowed.toAssetsDown(0, 0); - uint256 expectedBorrowedValue = sharesBorrowed.toAssetsUp(expectedAmountBorrowed, sharesBorrowed); - uint256 minCollateral = - expectedBorrowedValue.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, priceCollateral); - vm.assume(minCollateral <= MAX_COLLATERAL_ASSETS); - amountCollateral = bound(amountCollateral, minCollateral, MAX_COLLATERAL_ASSETS); - vm.assume(amountCollateral <= type(uint256).max / priceCollateral); - - amountSupplied = bound(amountSupplied, expectedAmountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - collateralToken.setBalance(ONBEHALF, amountCollateral); - - vm.startPrank(ONBEHALF); - collateralToken.approve(address(morpho), amountCollateral); - morpho.supplyCollateral(marketParams, amountCollateral, ONBEHALF, hex""); - morpho.setAuthorization(BORROWER, true); - vm.stopPrank(); - - vm.prank(BORROWER); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Borrow(id, BORROWER, ONBEHALF, RECEIVER, expectedAmountBorrowed, sharesBorrowed); - (uint256 returnAssets, uint256 returnShares) = - morpho.borrow(marketParams, 0, sharesBorrowed, ONBEHALF, RECEIVER); - - assertEq(returnAssets, expectedAmountBorrowed, "returned asset amount"); - assertEq(returnShares, sharesBorrowed, "returned shares amount"); - assertEq(morpho.borrowShares(id, ONBEHALF), sharesBorrowed, "borrow shares"); - assertEq(morpho.totalBorrowAssets(id), expectedAmountBorrowed, "total borrow"); - assertEq(morpho.totalBorrowShares(id), sharesBorrowed, "total borrow shares"); - assertEq(loanToken.balanceOf(RECEIVER), expectedAmountBorrowed, "borrower balance"); - assertEq(loanToken.balanceOf(address(morpho)), amountSupplied - expectedAmountBorrowed, "morpho balance"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/CallbacksIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/CallbacksIntegrationTest.sol deleted file mode 100644 index 62578aa..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/CallbacksIntegrationTest.sol +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract CallbacksIntegrationTest is - BaseTest, - IMorphoLiquidateCallback, - IMorphoRepayCallback, - IMorphoSupplyCallback, - IMorphoSupplyCollateralCallback, - IMorphoFlashLoanCallback -{ - using MathLib for uint256; - using MorphoLib for IMorpho; - using MarketParamsLib for MarketParams; - - // Callback functions. - - function onMorphoSupply(uint256 amount, bytes memory data) external { - require(msg.sender == address(morpho)); - bytes4 selector; - (selector, data) = abi.decode(data, (bytes4, bytes)); - if (selector == this.testSupplyCallback.selector) { - loanToken.approve(address(morpho), amount); - } - } - - function onMorphoSupplyCollateral(uint256 amount, bytes memory data) external { - require(msg.sender == address(morpho)); - bytes4 selector; - (selector, data) = abi.decode(data, (bytes4, bytes)); - if (selector == this.testSupplyCollateralCallback.selector) { - collateralToken.approve(address(morpho), amount); - } else if (selector == this.testFlashActions.selector) { - uint256 toBorrow = abi.decode(data, (uint256)); - collateralToken.setBalance(address(this), amount); - morpho.borrow(marketParams, toBorrow, 0, address(this), address(this)); - } - } - - function onMorphoRepay(uint256 amount, bytes memory data) external { - require(msg.sender == address(morpho)); - bytes4 selector; - (selector, data) = abi.decode(data, (bytes4, bytes)); - if (selector == this.testRepayCallback.selector) { - loanToken.approve(address(morpho), amount); - } else if (selector == this.testFlashActions.selector) { - uint256 toWithdraw = abi.decode(data, (uint256)); - morpho.withdrawCollateral(marketParams, toWithdraw, address(this), address(this)); - } - } - - function onMorphoLiquidate(uint256 repaid, bytes memory data) external { - require(msg.sender == address(morpho)); - bytes4 selector; - (selector, data) = abi.decode(data, (bytes4, bytes)); - if (selector == this.testLiquidateCallback.selector) { - loanToken.approve(address(morpho), repaid); - } - } - - function onMorphoFlashLoan(uint256 amount, bytes memory data) external { - require(msg.sender == address(morpho)); - bytes4 selector; - (selector, data) = abi.decode(data, (bytes4, bytes)); - if (selector == this.testFlashLoan.selector) { - assertEq(loanToken.balanceOf(address(this)), amount); - loanToken.approve(address(morpho), amount); - } - } - - // Tests. - - function testFlashLoan(uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - loanToken.setBalance(address(this), amount); - morpho.supply(marketParams, amount, 0, address(this), hex""); - - morpho.flashLoan(address(loanToken), amount, abi.encode(this.testFlashLoan.selector, hex"")); - - assertEq(loanToken.balanceOf(address(morpho)), amount, "balanceOf"); - } - - function testFlashLoanShouldRevertIfNotReimbursed(uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - loanToken.setBalance(address(this), amount); - morpho.supply(marketParams, amount, 0, address(this), hex""); - - loanToken.approve(address(morpho), 0); - - vm.expectRevert(bytes(ErrorsLib.TRANSFER_FROM_REVERTED)); - morpho.flashLoan( - address(loanToken), amount, abi.encode(this.testFlashLoanShouldRevertIfNotReimbursed.selector, hex"") - ); - } - - function testSupplyCallback(uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - loanToken.setBalance(address(this), amount); - loanToken.approve(address(morpho), 0); - - vm.expectRevert(); - morpho.supply(marketParams, amount, 0, address(this), hex""); - morpho.supply(marketParams, amount, 0, address(this), abi.encode(this.testSupplyCallback.selector, hex"")); - } - - function testSupplyCollateralCallback(uint256 amount) public { - amount = bound(amount, 1, MAX_COLLATERAL_ASSETS); - - collateralToken.setBalance(address(this), amount); - collateralToken.approve(address(morpho), 0); - - vm.expectRevert(); - morpho.supplyCollateral(marketParams, amount, address(this), hex""); - morpho.supplyCollateral( - marketParams, amount, address(this), abi.encode(this.testSupplyCollateralCallback.selector, hex"") - ); - } - - function testRepayCallback(uint256 loanAmount) public { - loanAmount = bound(loanAmount, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT); - uint256 collateralAmount; - (collateralAmount, loanAmount,) = _boundHealthyPosition(0, loanAmount, oracle.price()); - - oracle.setPrice(ORACLE_PRICE_SCALE); - - loanToken.setBalance(address(this), loanAmount); - collateralToken.setBalance(address(this), collateralAmount); - - morpho.supply(marketParams, loanAmount, 0, address(this), hex""); - morpho.supplyCollateral(marketParams, collateralAmount, address(this), hex""); - morpho.borrow(marketParams, loanAmount, 0, address(this), address(this)); - - loanToken.approve(address(morpho), 0); - - vm.expectRevert(); - morpho.repay(marketParams, loanAmount, 0, address(this), hex""); - morpho.repay(marketParams, loanAmount, 0, address(this), abi.encode(this.testRepayCallback.selector, hex"")); - } - - function testLiquidateCallback(uint256 loanAmount) public { - loanAmount = bound(loanAmount, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT); - uint256 collateralAmount; - (collateralAmount, loanAmount,) = _boundHealthyPosition(0, loanAmount, oracle.price()); - - oracle.setPrice(ORACLE_PRICE_SCALE); - - loanToken.setBalance(address(this), loanAmount); - collateralToken.setBalance(address(this), collateralAmount); - - morpho.supply(marketParams, loanAmount, 0, address(this), hex""); - morpho.supplyCollateral(marketParams, collateralAmount, address(this), hex""); - morpho.borrow(marketParams, loanAmount, 0, address(this), address(this)); - - oracle.setPrice(0.99e18); - - loanToken.setBalance(address(this), loanAmount); - loanToken.approve(address(morpho), 0); - - vm.expectRevert(); - morpho.liquidate(marketParams, address(this), collateralAmount, 0, hex""); - morpho.liquidate( - marketParams, address(this), collateralAmount, 0, abi.encode(this.testLiquidateCallback.selector, hex"") - ); - } - - function testFlashActions(uint256 loanAmount) public { - loanAmount = bound(loanAmount, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT); - uint256 collateralAmount; - (collateralAmount, loanAmount,) = _boundHealthyPosition(0, loanAmount, oracle.price()); - - oracle.setPrice(ORACLE_PRICE_SCALE); - - loanToken.setBalance(address(this), loanAmount); - morpho.supply(marketParams, loanAmount, 0, address(this), hex""); - - morpho.supplyCollateral( - marketParams, - collateralAmount, - address(this), - abi.encode(this.testFlashActions.selector, abi.encode(loanAmount)) - ); - assertGt(morpho.borrowShares(marketParams.id(), address(this)), 0, "no borrow"); - - morpho.repay( - marketParams, - loanAmount, - 0, - address(this), - abi.encode(this.testFlashActions.selector, abi.encode(collateralAmount)) - ); - assertEq(morpho.collateral(marketParams.id(), address(this)), 0, "no withdraw collateral"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/CreateMarketIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/CreateMarketIntegrationTest.sol deleted file mode 100644 index f0f3182..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/CreateMarketIntegrationTest.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract CreateMarketIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - using MarketParamsLib for MarketParams; - - function testCreateMarketWithNotEnabledIrmAndNotEnabledLltv(MarketParams memory marketParamsFuzz) public { - vm.assume(marketParamsFuzz.irm != address(irm) && marketParamsFuzz.lltv != marketParams.lltv); - - vm.prank(OWNER); - vm.expectRevert(bytes(ErrorsLib.IRM_NOT_ENABLED)); - morpho.createMarket(marketParamsFuzz); - } - - function testCreateMarketWithNotEnabledIrmAndEnabledLltv(MarketParams memory marketParamsFuzz) public { - vm.assume(marketParamsFuzz.irm != address(irm)); - marketParamsFuzz.lltv = _boundValidLltv(marketParamsFuzz.lltv); - - vm.startPrank(OWNER); - if (marketParamsFuzz.lltv != marketParams.lltv) morpho.enableLltv(marketParamsFuzz.lltv); - - vm.expectRevert(bytes(ErrorsLib.IRM_NOT_ENABLED)); - morpho.createMarket(marketParamsFuzz); - vm.stopPrank(); - } - - function testCreateMarketWithEnabledIrmAndNotEnabledLltv(MarketParams memory marketParamsFuzz) public { - vm.assume(marketParamsFuzz.lltv != marketParams.lltv); - - vm.startPrank(OWNER); - if (marketParamsFuzz.irm != marketParams.irm) morpho.enableIrm(marketParamsFuzz.irm); - - vm.expectRevert(bytes(ErrorsLib.LLTV_NOT_ENABLED)); - morpho.createMarket(marketParamsFuzz); - vm.stopPrank(); - } - - function testCreateMarketWithEnabledIrmAndLltv(MarketParams memory marketParamsFuzz) public { - marketParamsFuzz.lltv = _boundValidLltv(marketParamsFuzz.lltv); - Id marketParamsFuzzId = marketParamsFuzz.id(); - - vm.startPrank(OWNER); - if (marketParamsFuzz.irm != marketParams.irm) morpho.enableIrm(marketParamsFuzz.irm); - if (marketParamsFuzz.lltv != marketParams.lltv) morpho.enableLltv(marketParamsFuzz.lltv); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.CreateMarket(marketParamsFuzz.id(), marketParamsFuzz); - morpho.createMarket(marketParamsFuzz); - vm.stopPrank(); - - assertEq(morpho.lastUpdate(marketParamsFuzzId), block.timestamp, "lastUpdate != block.timestamp"); - assertEq(morpho.totalSupplyAssets(marketParamsFuzzId), 0, "totalSupplyAssets != 0"); - assertEq(morpho.totalSupplyShares(marketParamsFuzzId), 0, "totalSupplyShares != 0"); - assertEq(morpho.totalBorrowAssets(marketParamsFuzzId), 0, "totalBorrowAssets != 0"); - assertEq(morpho.totalBorrowShares(marketParamsFuzzId), 0, "totalBorrowShares != 0"); - assertEq(morpho.fee(marketParamsFuzzId), 0, "fee != 0"); - } - - function testCreateMarketAlreadyCreated(MarketParams memory marketParamsFuzz) public { - marketParamsFuzz.lltv = _boundValidLltv(marketParamsFuzz.lltv); - - vm.startPrank(OWNER); - if (marketParamsFuzz.irm != marketParams.irm) morpho.enableIrm(marketParamsFuzz.irm); - if (marketParamsFuzz.lltv != marketParams.lltv) morpho.enableLltv(marketParamsFuzz.lltv); - morpho.createMarket(marketParamsFuzz); - - vm.expectRevert(bytes(ErrorsLib.MARKET_ALREADY_CREATED)); - morpho.createMarket(marketParamsFuzz); - vm.stopPrank(); - } - - function testIdToMarketParams(MarketParams memory marketParamsFuzz) public { - marketParamsFuzz.lltv = _boundValidLltv(marketParamsFuzz.lltv); - Id marketParamsFuzzId = marketParamsFuzz.id(); - - vm.startPrank(OWNER); - if (marketParamsFuzz.irm != marketParams.irm) morpho.enableIrm(marketParamsFuzz.irm); - if (marketParamsFuzz.lltv != marketParams.lltv) morpho.enableLltv(marketParamsFuzz.lltv); - - morpho.createMarket(marketParamsFuzz); - vm.stopPrank(); - - (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv) = - morpho.idToMarketParams(marketParamsFuzzId); - - assertEq(marketParamsFuzz.loanToken, loanToken, "loanToken != loanToken"); - assertEq(marketParamsFuzz.collateralToken, collateralToken, "collateralToken != collateralToken"); - assertEq(marketParamsFuzz.oracle, oracle, "oracle != oracle"); - assertEq(marketParamsFuzz.irm, irm, "irm != irm"); - assertEq(marketParamsFuzz.lltv, lltv, "lltv != lltv"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/ExtSloadIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/ExtSloadIntegrationTest.sol deleted file mode 100644 index bf3c0ff..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/ExtSloadIntegrationTest.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract ExtSloadIntegrationTest is BaseTest { - function testExtSloads(uint256 slot, bytes32 value0) public { - bytes32[] memory slots = new bytes32[](2); - slots[0] = bytes32(slot); - slots[1] = bytes32(slot / 2); - - bytes32 value1 = keccak256(abi.encode(value0)); - vm.store(address(morpho), slots[0], value0); - vm.store(address(morpho), slots[1], value1); - - bytes32[] memory values = morpho.extSloads(slots); - - assertEq(values.length, 2, "values.length"); - assertEq(values[0], slot > 0 ? value0 : value1, "value0"); - assertEq(values[1], value1, "value1"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/LiquidateIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/LiquidateIntegrationTest.sol deleted file mode 100644 index 81cd98a..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/LiquidateIntegrationTest.sol +++ /dev/null @@ -1,299 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract LiquidateIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - using SharesMathLib for uint256; - - function testLiquidateNotCreatedMarket(MarketParams memory marketParamsFuzz, uint256 lltv) public { - _setLltv(_boundTestLltv(lltv)); - vm.assume(neq(marketParamsFuzz, marketParams)); - - vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); - morpho.liquidate(marketParamsFuzz, address(this), 1, 0, hex""); - } - - function testLiquidateZeroAmount(uint256 lltv) public { - _setLltv(_boundTestLltv(lltv)); - vm.prank(BORROWER); - - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.liquidate(marketParams, address(this), 0, 0, hex""); - } - - function testLiquidateInconsistentInput(uint256 seized, uint256 sharesRepaid) public { - seized = bound(seized, 1, MAX_TEST_AMOUNT); - sharesRepaid = bound(sharesRepaid, 1, MAX_TEST_SHARES); - - vm.prank(BORROWER); - - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.liquidate(marketParams, address(this), seized, sharesRepaid, hex""); - } - - function testLiquidateHealthyPosition( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 amountSeized, - uint256 priceCollateral, - uint256 lltv - ) public { - _setLltv(_boundTestLltv(lltv)); - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - - amountSupplied = bound(amountSupplied, amountBorrowed, amountBorrowed + MAX_TEST_AMOUNT); - _supply(amountSupplied); - - amountSeized = bound(amountSeized, 1, amountCollateral); - - oracle.setPrice(priceCollateral); - - loanToken.setBalance(LIQUIDATOR, amountBorrowed); - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - vm.prank(LIQUIDATOR); - vm.expectRevert(bytes(ErrorsLib.HEALTHY_POSITION)); - morpho.liquidate(marketParams, BORROWER, amountSeized, 0, hex""); - } - - struct LiquidateTestParams { - uint256 amountCollateral; - uint256 amountSupplied; - uint256 amountBorrowed; - uint256 priceCollateral; - uint256 lltv; - } - - function testLiquidateSeizedInputNoBadDebtRealized(LiquidateTestParams memory params, uint256 amountSeized) - public - { - _setLltv(_boundTestLltv(params.lltv)); - (params.amountCollateral, params.amountBorrowed, params.priceCollateral) = - _boundUnhealthyPosition(params.amountCollateral, params.amountBorrowed, params.priceCollateral); - - vm.assume(params.amountCollateral > 1); - - params.amountSupplied = - bound(params.amountSupplied, params.amountBorrowed, params.amountBorrowed + MAX_TEST_AMOUNT); - _supply(params.amountSupplied); - - collateralToken.setBalance(BORROWER, params.amountCollateral); - - oracle.setPrice(type(uint256).max / params.amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, params.amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, params.amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - oracle.setPrice(params.priceCollateral); - - uint256 borrowShares = morpho.borrowShares(id, BORROWER); - uint256 liquidationIncentiveFactor = _liquidationIncentiveFactor(marketParams.lltv); - uint256 maxSeized = params.amountBorrowed.wMulDown(liquidationIncentiveFactor).mulDivDown( - ORACLE_PRICE_SCALE, params.priceCollateral - ); - vm.assume(maxSeized != 0); - - amountSeized = bound(amountSeized, 1, Math.min(maxSeized, params.amountCollateral - 1)); - - uint256 expectedRepaid = - amountSeized.mulDivUp(params.priceCollateral, ORACLE_PRICE_SCALE).wDivUp(liquidationIncentiveFactor); - uint256 expectedRepaidShares = - expectedRepaid.toSharesDown(morpho.totalBorrowAssets(id), morpho.totalBorrowShares(id)); - - loanToken.setBalance(LIQUIDATOR, params.amountBorrowed); - - vm.prank(LIQUIDATOR); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Liquidate(id, LIQUIDATOR, BORROWER, expectedRepaid, expectedRepaidShares, amountSeized, 0); - (uint256 returnSeized, uint256 returnRepaid) = morpho.liquidate(marketParams, BORROWER, amountSeized, 0, hex""); - - uint256 expectedCollateral = params.amountCollateral - amountSeized; - uint256 expectedBorrowed = params.amountBorrowed - expectedRepaid; - uint256 expectedBorrowShares = borrowShares - expectedRepaidShares; - - assertEq(returnSeized, amountSeized, "returned seized amount"); - assertEq(returnRepaid, expectedRepaid, "returned asset amount"); - assertEq(morpho.borrowShares(id, BORROWER), expectedBorrowShares, "borrow shares"); - assertEq(morpho.totalBorrowAssets(id), expectedBorrowed, "total borrow"); - assertEq(morpho.totalBorrowShares(id), expectedBorrowShares, "total borrow shares"); - assertEq(morpho.collateral(id, BORROWER), expectedCollateral, "collateral"); - assertEq(loanToken.balanceOf(BORROWER), params.amountBorrowed, "borrower balance"); - assertEq(loanToken.balanceOf(LIQUIDATOR), expectedBorrowed, "liquidator balance"); - assertEq(loanToken.balanceOf(address(morpho)), params.amountSupplied - expectedBorrowed, "morpho balance"); - assertEq(collateralToken.balanceOf(address(morpho)), expectedCollateral, "morpho collateral balance"); - assertEq(collateralToken.balanceOf(LIQUIDATOR), amountSeized, "liquidator collateral balance"); - } - - function testLiquidateSharesInputNoBadDebtRealized(LiquidateTestParams memory params, uint256 sharesRepaid) - public - { - _setLltv(_boundTestLltv(params.lltv)); - (params.amountCollateral, params.amountBorrowed, params.priceCollateral) = - _boundUnhealthyPosition(params.amountCollateral, params.amountBorrowed, params.priceCollateral); - - vm.assume(params.amountCollateral >= 1); - - params.amountSupplied = bound(params.amountSupplied, params.amountBorrowed, MAX_TEST_AMOUNT); - _supply(params.amountSupplied); - - collateralToken.setBalance(BORROWER, params.amountCollateral); - - oracle.setPrice(type(uint256).max / params.amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, params.amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, params.amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - oracle.setPrice(params.priceCollateral); - - uint256 borrowShares = morpho.borrowShares(id, BORROWER); - uint256 liquidationIncentiveFactor = _liquidationIncentiveFactor(marketParams.lltv); - uint256 maxSharesRepaid = (params.amountCollateral - 1).mulDivDown(params.priceCollateral, ORACLE_PRICE_SCALE) - .wDivDown(liquidationIncentiveFactor).toSharesDown(morpho.totalBorrowAssets(id), morpho.totalBorrowShares(id)); - vm.assume(maxSharesRepaid != 0); - - sharesRepaid = bound(sharesRepaid, 1, Math.min(borrowShares, maxSharesRepaid)); - - uint256 expectedRepaid = sharesRepaid.toAssetsUp(morpho.totalBorrowAssets(id), morpho.totalBorrowShares(id)); - uint256 expectedSeized = - expectedRepaid.wMulDown(liquidationIncentiveFactor).mulDivDown(ORACLE_PRICE_SCALE, params.priceCollateral); - - loanToken.setBalance(LIQUIDATOR, params.amountBorrowed); - - vm.prank(LIQUIDATOR); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Liquidate(id, LIQUIDATOR, BORROWER, expectedRepaid, sharesRepaid, expectedSeized, 0); - (uint256 returnSeized, uint256 returnRepaid) = morpho.liquidate(marketParams, BORROWER, 0, sharesRepaid, hex""); - - uint256 expectedCollateral = params.amountCollateral - expectedSeized; - uint256 expectedBorrowed = params.amountBorrowed - expectedRepaid; - uint256 expectedBorrowShares = borrowShares - sharesRepaid; - - assertEq(returnSeized, expectedSeized, "returned seized amount"); - assertEq(returnRepaid, expectedRepaid, "returned asset amount"); - assertEq(morpho.borrowShares(id, BORROWER), expectedBorrowShares, "borrow shares"); - assertEq(morpho.totalBorrowAssets(id), expectedBorrowed, "total borrow"); - assertEq(morpho.totalBorrowShares(id), expectedBorrowShares, "total borrow shares"); - assertEq(morpho.collateral(id, BORROWER), expectedCollateral, "collateral"); - assertEq(loanToken.balanceOf(BORROWER), params.amountBorrowed, "borrower balance"); - assertEq(loanToken.balanceOf(LIQUIDATOR), expectedBorrowed, "liquidator balance"); - assertEq(loanToken.balanceOf(address(morpho)), params.amountSupplied - expectedBorrowed, "morpho balance"); - assertEq(collateralToken.balanceOf(address(morpho)), expectedCollateral, "morpho collateral balance"); - assertEq(collateralToken.balanceOf(LIQUIDATOR), expectedSeized, "liquidator collateral balance"); - } - - struct LiquidateBadDebtTestParams { - uint256 liquidationIncentiveFactor; - uint256 expectedRepaid; - uint256 expectedRepaidShares; - uint256 borrowSharesBeforeLiquidation; - uint256 totalBorrowSharesBeforeLiquidation; - uint256 totalBorrowBeforeLiquidation; - uint256 totalSupplyBeforeLiquidation; - uint256 expectedBadDebt; - } - - function testLiquidateBadDebtRealized( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 priceCollateral, - uint256 lltv - ) public { - _setLltv(_boundTestLltv(lltv)); - LiquidateBadDebtTestParams memory params; - - (amountCollateral, amountBorrowed, priceCollateral) = - _boundUnhealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - - vm.assume(amountCollateral > 1); - - params.liquidationIncentiveFactor = _liquidationIncentiveFactor(marketParams.lltv); - params.expectedRepaid = - amountCollateral.mulDivUp(priceCollateral, ORACLE_PRICE_SCALE).wDivUp(params.liquidationIncentiveFactor); - - uint256 minBorrowed = Math.max(params.expectedRepaid, amountBorrowed); - amountBorrowed = bound(amountBorrowed, minBorrowed, Math.max(minBorrowed, MAX_TEST_AMOUNT)); - - amountSupplied = bound(amountSupplied, amountBorrowed, Math.max(amountBorrowed, MAX_TEST_AMOUNT)); - _supply(amountSupplied); - - loanToken.setBalance(LIQUIDATOR, amountBorrowed); - collateralToken.setBalance(BORROWER, amountCollateral); - - oracle.setPrice(type(uint256).max / amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - oracle.setPrice(priceCollateral); - - params.expectedRepaidShares = - params.expectedRepaid.toSharesDown(morpho.totalBorrowAssets(id), morpho.totalBorrowShares(id)); - params.borrowSharesBeforeLiquidation = morpho.borrowShares(id, BORROWER); - params.totalBorrowSharesBeforeLiquidation = morpho.totalBorrowShares(id); - params.totalBorrowBeforeLiquidation = morpho.totalBorrowAssets(id); - params.totalSupplyBeforeLiquidation = morpho.totalSupplyAssets(id); - params.expectedBadDebt = (params.borrowSharesBeforeLiquidation - params.expectedRepaidShares).toAssetsUp( - params.totalBorrowBeforeLiquidation - params.expectedRepaid, - params.totalBorrowSharesBeforeLiquidation - params.expectedRepaidShares - ); - - vm.prank(LIQUIDATOR); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Liquidate( - id, - LIQUIDATOR, - BORROWER, - params.expectedRepaid, - params.expectedRepaidShares, - amountCollateral, - params.expectedBadDebt * SharesMathLib.VIRTUAL_SHARES - ); - (uint256 returnSeized, uint256 returnRepaid) = - morpho.liquidate(marketParams, BORROWER, amountCollateral, 0, hex""); - - assertEq(returnSeized, amountCollateral, "returned seized amount"); - assertEq(returnRepaid, params.expectedRepaid, "returned asset amount"); - assertEq(morpho.collateral(id, BORROWER), 0, "collateral"); - assertEq(loanToken.balanceOf(BORROWER), amountBorrowed, "borrower balance"); - assertEq(loanToken.balanceOf(LIQUIDATOR), amountBorrowed - params.expectedRepaid, "liquidator balance"); - assertEq( - loanToken.balanceOf(address(morpho)), - amountSupplied - amountBorrowed + params.expectedRepaid, - "morpho balance" - ); - assertEq(collateralToken.balanceOf(address(morpho)), 0, "morpho collateral balance"); - assertEq(collateralToken.balanceOf(LIQUIDATOR), amountCollateral, "liquidator collateral balance"); - - // Bad debt realization. - assertEq(morpho.borrowShares(id, BORROWER), 0, "borrow shares"); - assertEq(morpho.totalBorrowShares(id), 0, "total borrow shares"); - assertEq( - morpho.totalBorrowAssets(id), - params.totalBorrowBeforeLiquidation - params.expectedRepaid - params.expectedBadDebt, - "total borrow" - ); - assertEq( - morpho.totalSupplyAssets(id), params.totalSupplyBeforeLiquidation - params.expectedBadDebt, "total supply" - ); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/OnlyOwnerIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/OnlyOwnerIntegrationTest.sol deleted file mode 100644 index aa2586f..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/OnlyOwnerIntegrationTest.sol +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract OnlyOwnerIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - - function testDeployWithAddressZero() public { - vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS)); - new Morpho(address(0)); - } - - function testSetOwnerWhenNotOwner(address addressFuzz) public { - vm.assume(addressFuzz != OWNER); - - vm.prank(addressFuzz); - vm.expectRevert(bytes(ErrorsLib.NOT_OWNER)); - morpho.setOwner(addressFuzz); - } - - function testSetOwnerAlreadySet() public { - vm.prank(OWNER); - vm.expectRevert(bytes(ErrorsLib.ALREADY_SET)); - morpho.setOwner(OWNER); - } - - function testSetOwner(address newOwner) public { - vm.assume(newOwner != OWNER); - - vm.prank(OWNER); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.SetOwner(newOwner); - morpho.setOwner(newOwner); - - assertEq(morpho.owner(), newOwner, "owner is not set"); - } - - function testEnableIrmWhenNotOwner(address addressFuzz, address irmFuzz) public { - vm.assume(addressFuzz != OWNER); - vm.assume(irmFuzz != address(irm)); - - vm.prank(addressFuzz); - vm.expectRevert(bytes(ErrorsLib.NOT_OWNER)); - morpho.enableIrm(irmFuzz); - } - - function testEnableIrmAlreadySet() public { - vm.prank(OWNER); - vm.expectRevert(bytes(ErrorsLib.ALREADY_SET)); - morpho.enableIrm(address(irm)); - } - - function testEnableIrm(address irmFuzz) public { - vm.assume(irmFuzz != address(irm)); - - vm.prank(OWNER); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.EnableIrm(irmFuzz); - morpho.enableIrm(irmFuzz); - - assertTrue(morpho.isIrmEnabled(irmFuzz), "IRM is not enabled"); - } - - function testEnableLltvWhenNotOwner(address addressFuzz, uint256 lltvFuzz) public { - vm.assume(addressFuzz != OWNER); - vm.assume(lltvFuzz != marketParams.lltv); - - vm.prank(addressFuzz); - vm.expectRevert(bytes(ErrorsLib.NOT_OWNER)); - morpho.enableLltv(lltvFuzz); - } - - function testEnableLltvAlreadySet() public { - vm.prank(OWNER); - vm.expectRevert(bytes(ErrorsLib.ALREADY_SET)); - morpho.enableLltv(marketParams.lltv); - } - - function testEnableTooHighLltv(uint256 lltv) public { - lltv = bound(lltv, WAD, type(uint256).max); - - vm.prank(OWNER); - vm.expectRevert(bytes(ErrorsLib.MAX_LLTV_EXCEEDED)); - morpho.enableLltv(lltv); - } - - function testEnableLltv(uint256 lltvFuzz) public { - lltvFuzz = _boundValidLltv(lltvFuzz); - vm.assume(lltvFuzz != marketParams.lltv); - - vm.prank(OWNER); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.EnableLltv(lltvFuzz); - morpho.enableLltv(lltvFuzz); - - assertTrue(morpho.isLltvEnabled(lltvFuzz), "LLTV is not enabled"); - } - - function testSetFeeWhenNotOwner(address addressFuzz, uint256 feeFuzz) public { - vm.assume(addressFuzz != OWNER); - - vm.prank(addressFuzz); - vm.expectRevert(bytes(ErrorsLib.NOT_OWNER)); - morpho.setFee(marketParams, feeFuzz); - } - - function testSetFeeWhenMarketNotCreated(MarketParams memory marketParamsFuzz, uint256 feeFuzz) public { - vm.assume(neq(marketParamsFuzz, marketParams)); - - vm.prank(OWNER); - vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); - morpho.setFee(marketParamsFuzz, feeFuzz); - } - - function testSetTooHighFee(uint256 feeFuzz) public { - feeFuzz = bound(feeFuzz, MAX_FEE + 1, type(uint256).max); - - vm.prank(OWNER); - vm.expectRevert(bytes(ErrorsLib.MAX_FEE_EXCEEDED)); - morpho.setFee(marketParams, feeFuzz); - } - - function testSetFee(uint256 feeFuzz) public { - feeFuzz = bound(feeFuzz, 1, MAX_FEE); - - vm.prank(OWNER); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.SetFee(id, feeFuzz); - morpho.setFee(marketParams, feeFuzz); - - assertEq(morpho.fee(id), feeFuzz); - } - - function testSetFeeRecipientWhenNotOwner(address addressFuzz) public { - vm.assume(addressFuzz != OWNER); - - vm.prank(addressFuzz); - vm.expectRevert(bytes(ErrorsLib.NOT_OWNER)); - morpho.setFeeRecipient(addressFuzz); - } - - function testSetFeeRecipient(address newFeeRecipient) public { - vm.assume(newFeeRecipient != morpho.feeRecipient()); - - vm.prank(OWNER); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.SetFeeRecipient(newFeeRecipient); - morpho.setFeeRecipient(newFeeRecipient); - - assertEq(morpho.feeRecipient(), newFeeRecipient); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/RepayIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/RepayIntegrationTest.sol deleted file mode 100644 index dffc67b..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/RepayIntegrationTest.sol +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract RepayIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - using SharesMathLib for uint256; - - function testRepayMarketNotCreated(MarketParams memory marketParamsFuzz) public { - vm.assume(neq(marketParamsFuzz, marketParams)); - - vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); - morpho.repay(marketParamsFuzz, 1, 0, address(this), hex""); - } - - function testRepayZeroAmount() public { - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.repay(marketParams, 0, 0, address(this), hex""); - } - - function testRepayInconsistentInput(uint256 amount, uint256 shares) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - shares = bound(shares, 1, MAX_TEST_SHARES); - - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.repay(marketParams, amount, shares, address(this), hex""); - } - - function testRepayOnBehalfZeroAddress(uint256 input, bool isAmount) public { - input = bound(input, 1, type(uint256).max); - vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS)); - morpho.repay(marketParams, isAmount ? input : 0, isAmount ? 0 : input, address(0), hex""); - } - - function testRepayAssets( - uint256 amountSupplied, - uint256 amountCollateral, - uint256 amountBorrowed, - uint256 amountRepaid, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - amountRepaid = bound(amountRepaid, 1, amountBorrowed); - uint256 expectedBorrowShares = amountBorrowed.toSharesUp(0, 0); - uint256 expectedRepaidShares = amountRepaid.toSharesDown(amountBorrowed, expectedBorrowShares); - - collateralToken.setBalance(ONBEHALF, amountCollateral); - loanToken.setBalance(REPAYER, amountRepaid); - - vm.startPrank(ONBEHALF); - morpho.supplyCollateral(marketParams, amountCollateral, ONBEHALF, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, ONBEHALF, RECEIVER); - vm.stopPrank(); - - vm.prank(REPAYER); - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Repay(id, REPAYER, ONBEHALF, amountRepaid, expectedRepaidShares); - (uint256 returnAssets, uint256 returnShares) = morpho.repay(marketParams, amountRepaid, 0, ONBEHALF, hex""); - - expectedBorrowShares -= expectedRepaidShares; - - assertEq(returnAssets, amountRepaid, "returned asset amount"); - assertEq(returnShares, expectedRepaidShares, "returned shares amount"); - assertEq(morpho.borrowShares(id, ONBEHALF), expectedBorrowShares, "borrow shares"); - assertEq(morpho.totalBorrowAssets(id), amountBorrowed - amountRepaid, "total borrow"); - assertEq(morpho.totalBorrowShares(id), expectedBorrowShares, "total borrow shares"); - assertEq(loanToken.balanceOf(RECEIVER), amountBorrowed, "RECEIVER balance"); - assertEq(loanToken.balanceOf(address(morpho)), amountSupplied - amountBorrowed + amountRepaid, "morpho balance"); - } - - function testRepayShares( - uint256 amountSupplied, - uint256 amountCollateral, - uint256 amountBorrowed, - uint256 sharesRepaid, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - uint256 expectedBorrowShares = amountBorrowed.toSharesUp(0, 0); - sharesRepaid = bound(sharesRepaid, 1, expectedBorrowShares); - uint256 expectedAmountRepaid = sharesRepaid.toAssetsUp(amountBorrowed, expectedBorrowShares); - - collateralToken.setBalance(ONBEHALF, amountCollateral); - loanToken.setBalance(REPAYER, expectedAmountRepaid); - - vm.startPrank(ONBEHALF); - morpho.supplyCollateral(marketParams, amountCollateral, ONBEHALF, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, ONBEHALF, RECEIVER); - vm.stopPrank(); - - vm.prank(REPAYER); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Repay(id, REPAYER, ONBEHALF, expectedAmountRepaid, sharesRepaid); - (uint256 returnAssets, uint256 returnShares) = morpho.repay(marketParams, 0, sharesRepaid, ONBEHALF, hex""); - - expectedBorrowShares -= sharesRepaid; - - assertEq(returnAssets, expectedAmountRepaid, "returned asset amount"); - assertEq(returnShares, sharesRepaid, "returned shares amount"); - assertEq(morpho.borrowShares(id, ONBEHALF), expectedBorrowShares, "borrow shares"); - assertEq(morpho.totalBorrowAssets(id), amountBorrowed - expectedAmountRepaid, "total borrow"); - assertEq(morpho.totalBorrowShares(id), expectedBorrowShares, "total borrow shares"); - assertEq(loanToken.balanceOf(RECEIVER), amountBorrowed, "RECEIVER balance"); - assertEq( - loanToken.balanceOf(address(morpho)), - amountSupplied - amountBorrowed + expectedAmountRepaid, - "morpho balance" - ); - } - - function testRepayMax(uint256 shares) public { - shares = bound(shares, MIN_TEST_SHARES, MAX_TEST_SHARES); - - uint256 assets = shares.toAssetsUp(0, 0); - - loanToken.setBalance(address(this), assets); - - morpho.supply(marketParams, 0, shares, SUPPLIER, hex""); - - collateralToken.setBalance(address(this), HIGH_COLLATERAL_AMOUNT); - - morpho.supplyCollateral(marketParams, HIGH_COLLATERAL_AMOUNT, BORROWER, hex""); - - vm.prank(BORROWER); - morpho.borrow(marketParams, 0, shares, BORROWER, RECEIVER); - - loanToken.setBalance(address(this), assets); - - morpho.repay(marketParams, 0, shares, BORROWER, hex""); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/SupplyCollateralIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/SupplyCollateralIntegrationTest.sol deleted file mode 100644 index 2994f97..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/SupplyCollateralIntegrationTest.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract SupplyCollateralIntegrationTest is BaseTest { - using MorphoLib for IMorpho; - - function testSupplyCollateralMarketNotCreated(MarketParams memory marketParamsFuzz, uint256 amount) public { - vm.assume(neq(marketParamsFuzz, marketParams)); - - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); - morpho.supplyCollateral(marketParamsFuzz, amount, SUPPLIER, hex""); - } - - function testSupplyCollateralZeroAmount(address SUPPLIER) public { - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.ZERO_ASSETS)); - morpho.supplyCollateral(marketParams, 0, SUPPLIER, hex""); - } - - function testSupplyCollateralOnBehalfZeroAddress(uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS)); - morpho.supplyCollateral(marketParams, amount, address(0), hex""); - } - - function testSupplyCollateral(uint256 amount) public { - amount = bound(amount, 1, MAX_COLLATERAL_ASSETS); - - collateralToken.setBalance(SUPPLIER, amount); - - vm.prank(SUPPLIER); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.SupplyCollateral(id, SUPPLIER, ONBEHALF, amount); - morpho.supplyCollateral(marketParams, amount, ONBEHALF, hex""); - - assertEq(morpho.collateral(id, ONBEHALF), amount, "collateral"); - assertEq(collateralToken.balanceOf(SUPPLIER), 0, "SUPPLIER balance"); - assertEq(collateralToken.balanceOf(address(morpho)), amount, "morpho balance"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/SupplyIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/SupplyIntegrationTest.sol deleted file mode 100644 index ceeca7e..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/SupplyIntegrationTest.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract SupplyIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - using SharesMathLib for uint256; - - function testSupplyMarketNotCreated(MarketParams memory marketParamsFuzz, uint256 amount) public { - vm.assume(neq(marketParamsFuzz, marketParams)); - - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); - morpho.supply(marketParamsFuzz, amount, 0, SUPPLIER, hex""); - } - - function testSupplyZeroAmount() public { - vm.assume(SUPPLIER != address(0)); - - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.supply(marketParams, 0, 0, SUPPLIER, hex""); - } - - function testSupplyOnBehalfZeroAddress(uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS)); - morpho.supply(marketParams, amount, 0, address(0), hex""); - } - - function testSupplyInconsistantInput(uint256 amount, uint256 shares) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - shares = bound(shares, 1, MAX_TEST_SHARES); - - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.supply(marketParams, amount, shares, address(0), hex""); - } - - function testSupplyAssets(uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - loanToken.setBalance(SUPPLIER, amount); - - uint256 expectedSupplyShares = amount.toSharesDown(0, 0); - - vm.prank(SUPPLIER); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Supply(id, SUPPLIER, ONBEHALF, amount, expectedSupplyShares); - (uint256 returnAssets, uint256 returnShares) = morpho.supply(marketParams, amount, 0, ONBEHALF, hex""); - - assertEq(returnAssets, amount, "returned asset amount"); - assertEq(returnShares, expectedSupplyShares, "returned shares amount"); - assertEq(morpho.supplyShares(id, ONBEHALF), expectedSupplyShares, "supply shares"); - assertEq(morpho.totalSupplyAssets(id), amount, "total supply"); - assertEq(morpho.totalSupplyShares(id), expectedSupplyShares, "total supply shares"); - assertEq(loanToken.balanceOf(SUPPLIER), 0, "SUPPLIER balance"); - assertEq(loanToken.balanceOf(address(morpho)), amount, "morpho balance"); - } - - function testSupplyShares(uint256 shares) public { - shares = bound(shares, 1, MAX_TEST_SHARES); - - uint256 expectedSuppliedAmount = shares.toAssetsUp(0, 0); - - loanToken.setBalance(SUPPLIER, expectedSuppliedAmount); - - vm.prank(SUPPLIER); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Supply(id, SUPPLIER, ONBEHALF, expectedSuppliedAmount, shares); - (uint256 returnAssets, uint256 returnShares) = morpho.supply(marketParams, 0, shares, ONBEHALF, hex""); - - assertEq(returnAssets, expectedSuppliedAmount, "returned asset amount"); - assertEq(returnShares, shares, "returned shares amount"); - assertEq(morpho.supplyShares(id, ONBEHALF), shares, "supply shares"); - assertEq(morpho.totalSupplyAssets(id), expectedSuppliedAmount, "total supply"); - assertEq(morpho.totalSupplyShares(id), shares, "total supply shares"); - assertEq(loanToken.balanceOf(SUPPLIER), 0, "SUPPLIER balance"); - assertEq(loanToken.balanceOf(address(morpho)), expectedSuppliedAmount, "morpho balance"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/WithdrawCollateralIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/WithdrawCollateralIntegrationTest.sol deleted file mode 100644 index 8a5b0ce..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/WithdrawCollateralIntegrationTest.sol +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract WithdrawCollateralIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - - function testWithdrawCollateralMarketNotCreated(MarketParams memory marketParamsFuzz) public { - vm.assume(neq(marketParamsFuzz, marketParams)); - - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); - morpho.withdrawCollateral(marketParamsFuzz, 1, SUPPLIER, RECEIVER); - } - - function testWithdrawCollateralZeroAmount(uint256 amount) public { - amount = bound(amount, 1, MAX_COLLATERAL_ASSETS); - - collateralToken.setBalance(SUPPLIER, amount); - - vm.startPrank(SUPPLIER); - collateralToken.approve(address(morpho), amount); - morpho.supplyCollateral(marketParams, amount, SUPPLIER, hex""); - - vm.expectRevert(bytes(ErrorsLib.ZERO_ASSETS)); - morpho.withdrawCollateral(marketParams, 0, SUPPLIER, RECEIVER); - vm.stopPrank(); - } - - function testWithdrawCollateralToZeroAddress(uint256 amount) public { - amount = bound(amount, 1, MAX_COLLATERAL_ASSETS); - - collateralToken.setBalance(SUPPLIER, amount); - - vm.startPrank(SUPPLIER); - morpho.supplyCollateral(marketParams, amount, SUPPLIER, hex""); - - vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS)); - morpho.withdrawCollateral(marketParams, amount, SUPPLIER, address(0)); - vm.stopPrank(); - } - - function testWithdrawCollateralUnauthorized(address attacker, uint256 amount) public { - vm.assume(attacker != SUPPLIER); - amount = bound(amount, 1, MAX_COLLATERAL_ASSETS); - - collateralToken.setBalance(SUPPLIER, amount); - - vm.prank(SUPPLIER); - morpho.supplyCollateral(marketParams, amount, SUPPLIER, hex""); - - vm.prank(attacker); - vm.expectRevert(bytes(ErrorsLib.UNAUTHORIZED)); - morpho.withdrawCollateral(marketParams, amount, SUPPLIER, RECEIVER); - } - - function testWithdrawCollateralUnhealthyPosition( - uint256 amountCollateral, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.expectRevert(bytes(ErrorsLib.INSUFFICIENT_COLLATERAL)); - morpho.withdrawCollateral(marketParams, amountCollateral, BORROWER, BORROWER); - vm.stopPrank(); - } - - function testWithdrawCollateral( - uint256 amountCollateral, - uint256 amountCollateralExcess, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - vm.assume(amountCollateral < MAX_COLLATERAL_ASSETS); - - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - amountCollateralExcess = bound( - amountCollateralExcess, - 1, - Math.min(MAX_COLLATERAL_ASSETS - amountCollateral, type(uint256).max / priceCollateral - amountCollateral) - ); - - oracle.setPrice(priceCollateral); - - collateralToken.setBalance(BORROWER, amountCollateral + amountCollateralExcess); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral + amountCollateralExcess, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.WithdrawCollateral(id, BORROWER, BORROWER, RECEIVER, amountCollateralExcess); - morpho.withdrawCollateral(marketParams, amountCollateralExcess, BORROWER, RECEIVER); - - vm.stopPrank(); - - assertEq(morpho.collateral(id, BORROWER), amountCollateral, "collateral balance"); - assertEq(collateralToken.balanceOf(RECEIVER), amountCollateralExcess, "lender balance"); - assertEq(collateralToken.balanceOf(address(morpho)), amountCollateral, "morpho balance"); - } - - function testWithdrawCollateralOnBehalf( - uint256 amountCollateral, - uint256 amountCollateralExcess, - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 priceCollateral - ) public { - (amountCollateral, amountBorrowed, priceCollateral) = - _boundHealthyPosition(amountCollateral, amountBorrowed, priceCollateral); - vm.assume(amountCollateral < MAX_COLLATERAL_ASSETS); - - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - _supply(amountSupplied); - - oracle.setPrice(priceCollateral); - - amountCollateralExcess = bound( - amountCollateralExcess, - 1, - Math.min(MAX_COLLATERAL_ASSETS - amountCollateral, type(uint256).max / priceCollateral - amountCollateral) - ); - - collateralToken.setBalance(ONBEHALF, amountCollateral + amountCollateralExcess); - - vm.startPrank(ONBEHALF); - morpho.supplyCollateral(marketParams, amountCollateral + amountCollateralExcess, ONBEHALF, hex""); - morpho.setAuthorization(BORROWER, true); - morpho.borrow(marketParams, amountBorrowed, 0, ONBEHALF, ONBEHALF); - vm.stopPrank(); - - vm.prank(BORROWER); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.WithdrawCollateral(id, BORROWER, ONBEHALF, RECEIVER, amountCollateralExcess); - morpho.withdrawCollateral(marketParams, amountCollateralExcess, ONBEHALF, RECEIVER); - - assertEq(morpho.collateral(id, ONBEHALF), amountCollateral, "collateral balance"); - assertEq(collateralToken.balanceOf(RECEIVER), amountCollateralExcess, "lender balance"); - assertEq(collateralToken.balanceOf(address(morpho)), amountCollateral, "morpho balance"); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/WithdrawIntegrationTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/WithdrawIntegrationTest.sol deleted file mode 100644 index b61b6b7..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/integration/WithdrawIntegrationTest.sol +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../BaseTest.sol"; - -contract WithdrawIntegrationTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - using SharesMathLib for uint256; - - function testWithdrawMarketNotCreated(MarketParams memory marketParamsParamsFuzz) public { - vm.assume(neq(marketParamsParamsFuzz, marketParams)); - - vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); - morpho.withdraw(marketParamsParamsFuzz, 1, 0, address(this), address(this)); - } - - function testWithdrawZeroAmount(uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - loanToken.setBalance(address(this), amount); - morpho.supply(marketParams, amount, 0, address(this), hex""); - - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.withdraw(marketParams, 0, 0, address(this), address(this)); - } - - function testWithdrawInconsistentInput(uint256 amount, uint256 shares) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - shares = bound(shares, 1, MAX_TEST_SHARES); - - loanToken.setBalance(address(this), amount); - morpho.supply(marketParams, amount, 0, address(this), hex""); - - vm.expectRevert(bytes(ErrorsLib.INCONSISTENT_INPUT)); - morpho.withdraw(marketParams, amount, shares, address(this), address(this)); - } - - function testWithdrawToZeroAddress(uint256 amount) public { - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - loanToken.setBalance(address(this), amount); - morpho.supply(marketParams, amount, 0, address(this), hex""); - - vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS)); - morpho.withdraw(marketParams, amount, 0, address(this), address(0)); - } - - function testWithdrawUnauthorized(address attacker, uint256 amount) public { - vm.assume(attacker != address(this)); - amount = bound(amount, 1, MAX_TEST_AMOUNT); - - loanToken.setBalance(address(this), amount); - morpho.supply(marketParams, amount, 0, address(this), hex""); - - vm.prank(attacker); - vm.expectRevert(bytes(ErrorsLib.UNAUTHORIZED)); - morpho.withdraw(marketParams, amount, 0, address(this), address(this)); - } - - function testWithdrawInsufficientLiquidity(uint256 amountSupplied, uint256 amountBorrowed) public { - uint256 amountCollateral; - (amountCollateral, amountBorrowed,) = _boundHealthyPosition(0, amountBorrowed, oracle.price()); - amountSupplied = bound(amountSupplied, amountBorrowed + 1, MAX_TEST_AMOUNT + 1); - - loanToken.setBalance(SUPPLIER, amountSupplied); - - vm.prank(SUPPLIER); - morpho.supply(marketParams, amountSupplied, 0, SUPPLIER, hex""); - - collateralToken.setBalance(BORROWER, amountCollateral); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, RECEIVER); - vm.stopPrank(); - - vm.prank(SUPPLIER); - vm.expectRevert(bytes(ErrorsLib.INSUFFICIENT_LIQUIDITY)); - morpho.withdraw(marketParams, amountSupplied, 0, SUPPLIER, RECEIVER); - } - - function testWithdrawAssets(uint256 amountSupplied, uint256 amountBorrowed, uint256 amountWithdrawn) public { - uint256 amountCollateral; - (amountCollateral, amountBorrowed,) = _boundHealthyPosition(0, amountBorrowed, oracle.price()); - vm.assume(amountBorrowed < MAX_TEST_AMOUNT); - amountSupplied = bound(amountSupplied, amountBorrowed + 1, MAX_TEST_AMOUNT); - amountWithdrawn = bound(amountWithdrawn, 1, amountSupplied - amountBorrowed); - - loanToken.setBalance(address(this), amountSupplied); - collateralToken.setBalance(BORROWER, amountCollateral); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - uint256 expectedSupplyShares = amountSupplied.toSharesDown(0, 0); - uint256 expectedWithdrawnShares = amountWithdrawn.toSharesUp(amountSupplied, expectedSupplyShares); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Withdraw(id, address(this), address(this), RECEIVER, amountWithdrawn, expectedWithdrawnShares); - (uint256 returnAssets, uint256 returnShares) = - morpho.withdraw(marketParams, amountWithdrawn, 0, address(this), RECEIVER); - - expectedSupplyShares -= expectedWithdrawnShares; - - assertEq(returnAssets, amountWithdrawn, "returned asset amount"); - assertEq(returnShares, expectedWithdrawnShares, "returned shares amount"); - assertEq(morpho.supplyShares(id, address(this)), expectedSupplyShares, "supply shares"); - assertEq(morpho.totalSupplyShares(id), expectedSupplyShares, "total supply shares"); - assertEq(morpho.totalSupplyAssets(id), amountSupplied - amountWithdrawn, "total supply"); - assertEq(loanToken.balanceOf(RECEIVER), amountWithdrawn, "RECEIVER balance"); - assertEq(loanToken.balanceOf(BORROWER), amountBorrowed, "borrower balance"); - assertEq( - loanToken.balanceOf(address(morpho)), amountSupplied - amountBorrowed - amountWithdrawn, "morpho balance" - ); - } - - function testWithdrawShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 sharesWithdrawn) public { - uint256 amountCollateral; - (amountCollateral, amountBorrowed,) = _boundHealthyPosition(0, amountBorrowed, oracle.price()); - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - - uint256 expectedSupplyShares = amountSupplied.toSharesDown(0, 0); - uint256 availableLiquidity = amountSupplied - amountBorrowed; - uint256 withdrawableShares = availableLiquidity.toSharesDown(amountSupplied, expectedSupplyShares); - vm.assume(withdrawableShares != 0); - - sharesWithdrawn = bound(sharesWithdrawn, 1, withdrawableShares); - uint256 expectedAmountWithdrawn = sharesWithdrawn.toAssetsDown(amountSupplied, expectedSupplyShares); - - loanToken.setBalance(address(this), amountSupplied); - collateralToken.setBalance(BORROWER, amountCollateral); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - vm.startPrank(BORROWER); - morpho.supplyCollateral(marketParams, amountCollateral, BORROWER, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Withdraw(id, address(this), address(this), RECEIVER, expectedAmountWithdrawn, sharesWithdrawn); - (uint256 returnAssets, uint256 returnShares) = - morpho.withdraw(marketParams, 0, sharesWithdrawn, address(this), RECEIVER); - - expectedSupplyShares -= sharesWithdrawn; - - assertEq(returnAssets, expectedAmountWithdrawn, "returned asset amount"); - assertEq(returnShares, sharesWithdrawn, "returned shares amount"); - assertEq(morpho.supplyShares(id, address(this)), expectedSupplyShares, "supply shares"); - assertEq(morpho.totalSupplyAssets(id), amountSupplied - expectedAmountWithdrawn, "total supply"); - assertEq(morpho.totalSupplyShares(id), expectedSupplyShares, "total supply shares"); - assertEq(loanToken.balanceOf(RECEIVER), expectedAmountWithdrawn, "RECEIVER balance"); - assertEq( - loanToken.balanceOf(address(morpho)), - amountSupplied - amountBorrowed - expectedAmountWithdrawn, - "morpho balance" - ); - } - - function testWithdrawAssetsOnBehalf(uint256 amountSupplied, uint256 amountBorrowed, uint256 amountWithdrawn) - public - { - uint256 amountCollateral; - (amountCollateral, amountBorrowed,) = _boundHealthyPosition(0, amountBorrowed, oracle.price()); - vm.assume(amountBorrowed < MAX_TEST_AMOUNT); - amountSupplied = bound(amountSupplied, amountBorrowed + 1, MAX_TEST_AMOUNT); - amountWithdrawn = bound(amountWithdrawn, 1, amountSupplied - amountBorrowed); - - loanToken.setBalance(ONBEHALF, amountSupplied); - collateralToken.setBalance(ONBEHALF, amountCollateral); - - vm.startPrank(ONBEHALF); - morpho.supplyCollateral(marketParams, amountCollateral, ONBEHALF, hex""); - morpho.supply(marketParams, amountSupplied, 0, ONBEHALF, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, ONBEHALF, ONBEHALF); - vm.stopPrank(); - - uint256 expectedSupplyShares = amountSupplied.toSharesDown(0, 0); - uint256 expectedWithdrawnShares = amountWithdrawn.toSharesUp(amountSupplied, expectedSupplyShares); - - uint256 receiverBalanceBefore = loanToken.balanceOf(RECEIVER); - - vm.startPrank(BORROWER); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Withdraw(id, BORROWER, ONBEHALF, RECEIVER, amountWithdrawn, expectedWithdrawnShares); - (uint256 returnAssets, uint256 returnShares) = - morpho.withdraw(marketParams, amountWithdrawn, 0, ONBEHALF, RECEIVER); - - expectedSupplyShares -= expectedWithdrawnShares; - - assertEq(returnAssets, amountWithdrawn, "returned asset amount"); - assertEq(returnShares, expectedWithdrawnShares, "returned shares amount"); - assertEq(morpho.supplyShares(id, ONBEHALF), expectedSupplyShares, "supply shares"); - assertEq(morpho.totalSupplyAssets(id), amountSupplied - amountWithdrawn, "total supply"); - assertEq(morpho.totalSupplyShares(id), expectedSupplyShares, "total supply shares"); - assertEq(loanToken.balanceOf(RECEIVER) - receiverBalanceBefore, amountWithdrawn, "RECEIVER balance"); - assertEq( - loanToken.balanceOf(address(morpho)), amountSupplied - amountBorrowed - amountWithdrawn, "morpho balance" - ); - } - - function testWithdrawSharesOnBehalf(uint256 amountSupplied, uint256 amountBorrowed, uint256 sharesWithdrawn) - public - { - uint256 amountCollateral; - (amountCollateral, amountBorrowed,) = _boundHealthyPosition(0, amountBorrowed, oracle.price()); - amountSupplied = bound(amountSupplied, amountBorrowed, MAX_TEST_AMOUNT); - - uint256 expectedSupplyShares = amountSupplied.toSharesDown(0, 0); - uint256 availableLiquidity = amountSupplied - amountBorrowed; - uint256 withdrawableShares = availableLiquidity.toSharesDown(amountSupplied, expectedSupplyShares); - vm.assume(withdrawableShares != 0); - - sharesWithdrawn = bound(sharesWithdrawn, 1, withdrawableShares); - uint256 expectedAmountWithdrawn = sharesWithdrawn.toAssetsDown(amountSupplied, expectedSupplyShares); - - loanToken.setBalance(ONBEHALF, amountSupplied); - collateralToken.setBalance(ONBEHALF, amountCollateral); - - vm.startPrank(ONBEHALF); - morpho.supplyCollateral(marketParams, amountCollateral, ONBEHALF, hex""); - morpho.supply(marketParams, amountSupplied, 0, ONBEHALF, hex""); - morpho.borrow(marketParams, amountBorrowed, 0, ONBEHALF, ONBEHALF); - vm.stopPrank(); - - uint256 receiverBalanceBefore = loanToken.balanceOf(RECEIVER); - - vm.startPrank(BORROWER); - - vm.expectEmit(true, true, true, true, address(morpho)); - emit EventsLib.Withdraw(id, BORROWER, ONBEHALF, RECEIVER, expectedAmountWithdrawn, sharesWithdrawn); - (uint256 returnAssets, uint256 returnShares) = - morpho.withdraw(marketParams, 0, sharesWithdrawn, ONBEHALF, RECEIVER); - - expectedSupplyShares -= sharesWithdrawn; - - assertEq(returnAssets, expectedAmountWithdrawn, "returned asset amount"); - assertEq(returnShares, sharesWithdrawn, "returned shares amount"); - assertEq(morpho.supplyShares(id, ONBEHALF), expectedSupplyShares, "supply shares"); - assertEq(morpho.totalSupplyAssets(id), amountSupplied - expectedAmountWithdrawn, "total supply"); - assertEq(morpho.totalSupplyShares(id), expectedSupplyShares, "total supply shares"); - assertEq(loanToken.balanceOf(RECEIVER) - receiverBalanceBefore, expectedAmountWithdrawn, "RECEIVER balance"); - assertEq( - loanToken.balanceOf(address(morpho)), - amountSupplied - amountBorrowed - expectedAmountWithdrawn, - "morpho balance" - ); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/invariant/MorphoInvariantTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/invariant/MorphoInvariantTest.sol deleted file mode 100644 index edb4234..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/invariant/MorphoInvariantTest.sol +++ /dev/null @@ -1,417 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../InvariantTest.sol"; - -contract MorphoInvariantTest is InvariantTest { - using MathLib for uint256; - using SharesMathLib for uint256; - using MorphoLib for IMorpho; - using MorphoBalancesLib for IMorpho; - using MarketParamsLib for MarketParams; - - uint256 internal immutable MIN_PRICE = ORACLE_PRICE_SCALE / 10; - uint256 internal immutable MAX_PRICE = ORACLE_PRICE_SCALE * 10; - - address internal immutable USER; - - MarketParams[] internal allMarketParams; - - constructor() { - USER = makeAddr("User"); - } - - function setUp() public virtual override { - _weightSelector(this.setPrice.selector, 10); - _weightSelector(this.setFeeNoRevert.selector, 5); - _weightSelector(this.supplyAssetsOnBehalfNoRevert.selector, 100); - _weightSelector(this.supplySharesOnBehalfNoRevert.selector, 100); - _weightSelector(this.withdrawAssetsOnBehalfNoRevert.selector, 50); - _weightSelector(this.borrowAssetsOnBehalfNoRevert.selector, 75); - _weightSelector(this.repayAssetsOnBehalfNoRevert.selector, 35); - _weightSelector(this.repaySharesOnBehalfNoRevert.selector, 35); - _weightSelector(this.supplyCollateralOnBehalfNoRevert.selector, 100); - _weightSelector(this.withdrawCollateralOnBehalfNoRevert.selector, 50); - _weightSelector(this.liquidateSeizedAssetsNoRevert.selector, 5); - _weightSelector(this.liquidateRepaidSharesNoRevert.selector, 5); - - super.setUp(); - - allMarketParams.push(marketParams); - - for (uint256 i = 2; i <= 6; ++i) { - MarketParams memory _marketParams = MarketParams({ - loanToken: address(loanToken), - collateralToken: address(collateralToken), - oracle: address(oracle), - irm: address(irm), - lltv: MAX_TEST_LLTV / i - }); - - vm.startPrank(OWNER); - morpho.enableLltv(_marketParams.lltv); - morpho.createMarket(_marketParams); - vm.stopPrank(); - - allMarketParams.push(_marketParams); - } - } - - function _targetSenders() internal virtual override { - _targetSender(USER); - } - - modifier authorized(address onBehalf) { - if (onBehalf != msg.sender) { - vm.prank(onBehalf); - morpho.setAuthorization(msg.sender, true); - } - - _; - - vm.prank(onBehalf); - morpho.setAuthorization(msg.sender, false); - } - - function _randomMarket(uint256 marketSeed) internal view returns (MarketParams memory _marketParams) { - return allMarketParams[marketSeed % allMarketParams.length]; - } - - function _supplyAssets(MarketParams memory _marketParams, uint256 assets, address onBehalf) - internal - logCall("supplyAssets") - { - loanToken.setBalance(msg.sender, assets); - - vm.prank(msg.sender); - morpho.supply(_marketParams, assets, 0, onBehalf, hex""); - } - - function _supplyShares(MarketParams memory _marketParams, uint256 shares, address onBehalf) - internal - logCall("supplyShares") - { - (uint256 totalSupplyAssets, uint256 totalSupplyShares,,) = morpho.expectedMarketBalances(_marketParams); - - loanToken.setBalance(msg.sender, shares.toAssetsUp(totalSupplyAssets, totalSupplyShares)); - - vm.prank(msg.sender); - morpho.supply(_marketParams, 0, shares, onBehalf, hex""); - } - - function _withdraw( - MarketParams memory _marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - address receiver - ) internal authorized(onBehalf) logCall("withdraw") { - vm.prank(msg.sender); - morpho.withdraw(_marketParams, assets, shares, onBehalf, receiver); - } - - function _borrow( - MarketParams memory _marketParams, - uint256 assets, - uint256 shares, - address onBehalf, - address receiver - ) internal authorized(onBehalf) logCall("borrow") { - vm.prank(msg.sender); - morpho.borrow(_marketParams, assets, shares, onBehalf, receiver); - } - - function _repayAssets(MarketParams memory _marketParams, uint256 assets, address onBehalf) - internal - logCall("repayAssets") - { - loanToken.setBalance(msg.sender, assets); - - vm.prank(msg.sender); - morpho.repay(_marketParams, assets, 0, onBehalf, hex""); - } - - function _repayShares(MarketParams memory _marketParams, uint256 shares, address onBehalf) - internal - logCall("repayShares") - { - (,, uint256 totalBorrowAssets, uint256 totalBorrowShares) = morpho.expectedMarketBalances(_marketParams); - - loanToken.setBalance(msg.sender, shares.toAssetsUp(totalBorrowAssets, totalBorrowShares)); - - vm.prank(msg.sender); - morpho.repay(_marketParams, 0, shares, onBehalf, hex""); - } - - function _supplyCollateral(MarketParams memory _marketParams, uint256 assets, address onBehalf) - internal - logCall("supplyCollateral") - { - collateralToken.setBalance(msg.sender, assets); - - vm.prank(msg.sender); - morpho.supplyCollateral(_marketParams, assets, onBehalf, hex""); - } - - function _withdrawCollateral(MarketParams memory _marketParams, uint256 assets, address onBehalf, address receiver) - internal - authorized(onBehalf) - logCall("withdrawCollateral") - { - vm.prank(msg.sender); - morpho.withdrawCollateral(_marketParams, assets, onBehalf, receiver); - } - - function _liquidateSeizedAssets(MarketParams memory _marketParams, address borrower, uint256 seizedAssets) - internal - logCall("liquidateSeizedAssets") - { - uint256 collateralPrice = oracle.price(); - uint256 repaidAssets = seizedAssets.mulDivUp(collateralPrice, ORACLE_PRICE_SCALE).wDivUp( - _liquidationIncentiveFactor(_marketParams.lltv) - ); - - loanToken.setBalance(msg.sender, repaidAssets); - - vm.prank(msg.sender); - morpho.liquidate(_marketParams, borrower, seizedAssets, 0, hex""); - } - - function _liquidateRepaidShares(MarketParams memory _marketParams, address borrower, uint256 repaidShares) - internal - logCall("liquidateRepaidShares") - { - (,, uint256 totalBorrowAssets, uint256 totalBorrowShares) = morpho.expectedMarketBalances(_marketParams); - - loanToken.setBalance(msg.sender, repaidShares.toAssetsUp(totalBorrowAssets, totalBorrowShares)); - - vm.prank(msg.sender); - morpho.liquidate(_marketParams, borrower, 0, repaidShares, hex""); - } - - /* HANDLERS */ - - function setPrice(uint256 price) external { - price = bound(price, MIN_PRICE, MAX_PRICE); - - oracle.setPrice(price); - } - - function setFeeNoRevert(uint256 marketSeed, uint256 newFee) external { - MarketParams memory _marketParams = _randomMarket(marketSeed); - Id _id = _marketParams.id(); - - newFee = bound(newFee, 0, MAX_FEE); - if (newFee == morpho.fee(_id)) return; - - vm.prank(OWNER); - morpho.setFee(_marketParams, newFee); - } - - function supplyAssetsOnBehalfNoRevert(uint256 marketSeed, uint256 assets, uint256 onBehalfSeed) external { - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address onBehalf = _randomCandidate(targetSenders(), onBehalfSeed); - - assets = _boundSupplyAssets(_marketParams, USER, assets); - if (assets == 0) return; - - _supplyAssets(_marketParams, assets, onBehalf); - } - - function supplySharesOnBehalfNoRevert(uint256 marketSeed, uint256 shares, uint256 onBehalfSeed) external { - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address onBehalf = _randomCandidate(targetSenders(), onBehalfSeed); - - shares = _boundSupplyShares(_marketParams, onBehalf, shares); - if (shares == 0) return; - - _supplyShares(_marketParams, shares, onBehalf); - } - - function withdrawAssetsOnBehalfNoRevert(uint256 marketSeed, uint256 assets, uint256 onBehalfSeed, address receiver) - external - { - receiver = _boundAddressNotZero(receiver); - - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address onBehalf = _randomSupplier(targetSenders(), _marketParams, onBehalfSeed); - if (onBehalf == address(0)) return; - - assets = _boundWithdrawAssets(_marketParams, onBehalf, assets); - if (assets == 0) return; - - _withdraw(_marketParams, assets, 0, onBehalf, receiver); - } - - function borrowAssetsOnBehalfNoRevert(uint256 marketSeed, uint256 assets, uint256 onBehalfSeed, address receiver) - external - { - receiver = _boundAddressNotZero(receiver); - - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address onBehalf = _randomHealthyCollateralSupplier(targetSenders(), _marketParams, onBehalfSeed); - if (onBehalf == address(0)) return; - - assets = _boundBorrowAssets(_marketParams, onBehalf, assets); - if (assets == 0) return; - - _borrow(_marketParams, assets, 0, onBehalf, receiver); - } - - function repayAssetsOnBehalfNoRevert(uint256 marketSeed, uint256 assets, uint256 onBehalfSeed) external { - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address onBehalf = _randomBorrower(targetSenders(), _marketParams, onBehalfSeed); - if (onBehalf == address(0)) return; - - assets = _boundRepayAssets(_marketParams, onBehalf, assets); - if (assets == 0) return; - - _repayAssets(_marketParams, assets, onBehalf); - } - - function repaySharesOnBehalfNoRevert(uint256 marketSeed, uint256 shares, uint256 onBehalfSeed) external { - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address onBehalf = _randomBorrower(targetSenders(), _marketParams, onBehalfSeed); - if (onBehalf == address(0)) return; - - shares = _boundRepayShares(_marketParams, onBehalf, shares); - if (shares == 0) return; - - _repayShares(_marketParams, shares, onBehalf); - } - - function supplyCollateralOnBehalfNoRevert(uint256 marketSeed, uint256 assets, uint256 onBehalfSeed) external { - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address onBehalf = _randomCandidate(targetSenders(), onBehalfSeed); - - assets = _boundSupplyCollateralAssets(_marketParams, onBehalf, assets); - if (assets == 0) return; - - _supplyCollateral(_marketParams, assets, onBehalf); - } - - function withdrawCollateralOnBehalfNoRevert( - uint256 marketSeed, - uint256 assets, - uint256 onBehalfSeed, - address receiver - ) external { - receiver = _boundAddressNotZero(receiver); - - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address onBehalf = _randomHealthyCollateralSupplier(targetSenders(), _marketParams, onBehalfSeed); - if (onBehalf == address(0)) return; - - assets = _boundWithdrawCollateralAssets(_marketParams, onBehalf, assets); - if (assets == 0) return; - - _withdrawCollateral(_marketParams, assets, onBehalf, receiver); - } - - function liquidateSeizedAssetsNoRevert(uint256 marketSeed, uint256 seizedAssets, uint256 onBehalfSeed) external { - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address borrower = _randomUnhealthyBorrower(targetSenders(), _marketParams, onBehalfSeed); - if (borrower == address(0)) return; - - seizedAssets = _boundLiquidateSeizedAssets(_marketParams, borrower, seizedAssets); - if (seizedAssets == 0) return; - - _liquidateSeizedAssets(_marketParams, borrower, seizedAssets); - } - - function liquidateRepaidSharesNoRevert(uint256 marketSeed, uint256 repaidShares, uint256 onBehalfSeed) external { - MarketParams memory _marketParams = _randomMarket(marketSeed); - - address borrower = _randomUnhealthyBorrower(targetSenders(), _marketParams, onBehalfSeed); - if (borrower == address(0)) return; - - repaidShares = _boundLiquidateRepaidShares(_marketParams, borrower, repaidShares); - if (repaidShares == 0) return; - - _liquidateRepaidShares(_marketParams, borrower, repaidShares); - } - - /* INVARIANTS */ - - function invariantSupplyShares() public { - address[] memory users = targetSenders(); - - for (uint256 i; i < allMarketParams.length; ++i) { - MarketParams memory _marketParams = allMarketParams[i]; - Id _id = _marketParams.id(); - - uint256 sumSupplyShares = morpho.supplyShares(_id, FEE_RECIPIENT); - for (uint256 j; j < users.length; ++j) { - sumSupplyShares += morpho.supplyShares(_id, users[j]); - } - - assertEq(sumSupplyShares, morpho.totalSupplyShares(_id), vm.toString(_marketParams.lltv)); - } - } - - function invariantBorrowShares() public { - address[] memory users = targetSenders(); - - for (uint256 i; i < allMarketParams.length; ++i) { - MarketParams memory _marketParams = allMarketParams[i]; - Id _id = _marketParams.id(); - - uint256 sumBorrowShares; - for (uint256 j; j < users.length; ++j) { - sumBorrowShares += morpho.borrowShares(_id, users[j]); - } - - assertEq(sumBorrowShares, morpho.totalBorrowShares(_id), vm.toString(_marketParams.lltv)); - } - } - - function invariantTotalSupplyGeTotalBorrow() public { - for (uint256 i; i < allMarketParams.length; ++i) { - MarketParams memory _marketParams = allMarketParams[i]; - Id _id = _marketParams.id(); - - assertGe(morpho.totalSupplyAssets(_id), morpho.totalBorrowAssets(_id)); - } - } - - function invariantMorphoBalance() public { - for (uint256 i; i < allMarketParams.length; ++i) { - MarketParams memory _marketParams = allMarketParams[i]; - Id _id = _marketParams.id(); - - assertGe( - loanToken.balanceOf(address(morpho)) + morpho.totalBorrowAssets(_id), morpho.totalSupplyAssets(_id) - ); - } - } - - function invariantBadDebt() public { - address[] memory users = targetSenders(); - - for (uint256 i; i < allMarketParams.length; ++i) { - MarketParams memory _marketParams = allMarketParams[i]; - Id _id = _marketParams.id(); - - for (uint256 j; j < users.length; ++j) { - address user = users[j]; - - if (morpho.collateral(_id, user) == 0) { - assertEq( - morpho.borrowShares(_id, user), - 0, - string.concat(vm.toString(_marketParams.lltv), ":", vm.toString(user)) - ); - } - } - } - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/MathLibTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/MathLibTest.sol deleted file mode 100644 index b6f3847..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/MathLibTest.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../../../lib/forge-std/src/Test.sol"; - -import "../../../src/libraries/MathLib.sol"; -import "../helpers/WadMath.sol"; - -contract MathLibTest is Test { - using MathLib for uint256; - - function testWTaylorCompounded(uint256 rate, uint256 timeElapsed) public { - // Assume rate is less than a ~500% APY. (~180% APR) - rate = bound(rate, 0, WAD / 20_000_000); - timeElapsed = bound(timeElapsed, 0, 365 days); - uint256 result = rate.wTaylorCompounded(timeElapsed) + WAD; - uint256 toCompare = WadMath.wadExpUp(rate * timeElapsed); - assertLe(result, toCompare, "rate should be less than the compounded rate"); - assertGe(result, WAD + timeElapsed * rate, "rate should be greater than the simple interest rate"); - assertLe((toCompare - result) * 100_00 / toCompare, 8_00, "The error should be less than or equal to 8%"); - } - - function testMulDivDown(uint256 x, uint256 y, uint256 denominator) public { - // Ignore cases where x * y overflows or denominator is 0. - unchecked { - if (denominator == 0 || (x != 0 && (x * y) / x != y)) return; - } - - assertEq(MathLib.mulDivDown(x, y, denominator), (x * y) / denominator); - } - - function testMulDivDownOverflow(uint256 x, uint256 y, uint256 denominator) public { - denominator = bound(denominator, 1, type(uint256).max); - // Overflow if - // x * y > type(uint256).max - // <=> y > 0 and x > type(uint256).max / y - // With - // type(uint256).max / y < type(uint256).max - // <=> y > 1 - y = bound(y, 2, type(uint256).max); - x = bound(x, type(uint256).max / y + 1, type(uint256).max); - - vm.expectRevert(); - MathLib.mulDivDown(x, y, denominator); - } - - function testMulDivDownZeroDenominator(uint256 x, uint256 y) public { - vm.expectRevert(); - MathLib.mulDivDown(x, y, 0); - } - - function testMulDivUp(uint256 x, uint256 y, uint256 denominator) public { - denominator = bound(denominator, 1, type(uint256).max - 1); - y = bound(y, 1, type(uint256).max); - x = bound(x, 0, (type(uint256).max - denominator - 1) / y); - - assertEq(MathLib.mulDivUp(x, y, denominator), x * y == 0 ? 0 : (x * y - 1) / denominator + 1); - } - - function testMulDivUpOverflow(uint256 x, uint256 y, uint256 denominator) public { - denominator = bound(denominator, 1, type(uint256).max); - // Overflow if - // x * y + denominator - 1 > type(uint256).max - // <=> x * y > type(uint256).max - denominator + 1 - // <=> y > 0 and x > (type(uint256).max - denominator + 1) / y - // With - // (type(uint256).max - denominator + 1) / y < type(uint256).max - // <=> y > (type(uint256).max - denominator + 1) / type(uint256).max - y = bound(y, (type(uint256).max - denominator + 1) / type(uint256).max + 1, type(uint256).max); - x = bound(x, (type(uint256).max - denominator + 1) / y + 1, type(uint256).max); - - vm.expectRevert(); - MathLib.mulDivUp(x, y, denominator); - } - - function testMulDivUpUnderverflow(uint256 x, uint256 y) public { - vm.assume(x > 0 && y > 0); - - vm.expectRevert(); - MathLib.mulDivUp(x, y, 0); - } - - function testMulDivUpZeroDenominator(uint256 x, uint256 y) public { - vm.expectRevert(); - MathLib.mulDivUp(x, y, 0); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/SafeTransferLibTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/SafeTransferLibTest.sol deleted file mode 100644 index de019de..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/SafeTransferLibTest.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../../../lib/forge-std/src/Test.sol"; - -import "../../../src/libraries/ErrorsLib.sol"; -import {IERC20, SafeTransferLib} from "../../../src/libraries/SafeTransferLib.sol"; - -/// @dev Token not returning any boolean on transfer and transferFrom. -contract ERC20WithoutBoolean { - mapping(address => uint256) public balanceOf; - - function transfer(address to, uint256 amount) public { - balanceOf[msg.sender] -= amount; - balanceOf[to] += amount; - } - - function transferFrom(address from, address to, uint256 amount) public { - // Skip allowance check. - balanceOf[from] -= amount; - balanceOf[to] += amount; - } - - function setBalance(address account, uint256 amount) public { - balanceOf[account] = amount; - } -} - -/// @dev Token returning false on transfer and transferFrom. -contract ERC20WithBooleanAlwaysFalse { - mapping(address => uint256) public balanceOf; - - function transfer(address to, uint256 amount) public returns (bool failure) { - balanceOf[msg.sender] -= amount; - balanceOf[to] += amount; - failure = false; // To silence warning. - } - - function transferFrom(address from, address to, uint256 amount) public returns (bool failure) { - // Skip allowance check. - balanceOf[from] -= amount; - balanceOf[to] += amount; - failure = false; // To silence warning. - } - - function setBalance(address account, uint256 amount) public { - balanceOf[account] = amount; - } -} - -contract SafeTransferLibTest is Test { - using SafeTransferLib for *; - - ERC20WithoutBoolean public tokenWithoutBoolean; - ERC20WithBooleanAlwaysFalse public tokenWithBooleanAlwaysFalse; - - function setUp() public { - tokenWithoutBoolean = new ERC20WithoutBoolean(); - tokenWithBooleanAlwaysFalse = new ERC20WithBooleanAlwaysFalse(); - } - - function testSafeTransfer(address to, uint256 amount) public { - tokenWithoutBoolean.setBalance(address(this), amount); - - this.safeTransfer(address(tokenWithoutBoolean), to, amount); - } - - function testSafeTransferFrom(address from, address to, uint256 amount) public { - tokenWithoutBoolean.setBalance(from, amount); - - this.safeTransferFrom(address(tokenWithoutBoolean), from, to, amount); - } - - function testSafeTransferWithBoolFalse(address to, uint256 amount) public { - tokenWithBooleanAlwaysFalse.setBalance(address(this), amount); - - vm.expectRevert(bytes(ErrorsLib.TRANSFER_RETURNED_FALSE)); - this.safeTransfer(address(tokenWithBooleanAlwaysFalse), to, amount); - } - - function testSafeTransferFromWithBoolFalse(address from, address to, uint256 amount) public { - tokenWithBooleanAlwaysFalse.setBalance(from, amount); - - vm.expectRevert(bytes(ErrorsLib.TRANSFER_FROM_RETURNED_FALSE)); - this.safeTransferFrom(address(tokenWithBooleanAlwaysFalse), from, to, amount); - } - - function safeTransfer(address token, address to, uint256 amount) external { - IERC20(token).safeTransfer(to, amount); - } - - function safeTransferFrom(address token, address from, address to, uint256 amount) external { - IERC20(token).safeTransferFrom(from, to, amount); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/UtilsLibTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/UtilsLibTest.sol deleted file mode 100644 index 5d3441b..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/UtilsLibTest.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../../../lib/forge-std/src/Test.sol"; - -import "../../../src/libraries/ErrorsLib.sol"; -import "../../../src/libraries/UtilsLib.sol"; - -contract UtilsLibTest is Test { - using UtilsLib for uint256; - - function testExactlyOneZero(uint256 x, uint256 y) public { - assertEq(UtilsLib.exactlyOneZero(x, y), (x > 0 && y == 0) || (x == 0 && y > 0)); - } - - function testMin(uint256 x, uint256 y) public { - assertEq(UtilsLib.min(x, y), x < y ? x : y); - } - - function testToUint128(uint256 x) public { - vm.assume(x <= type(uint128).max); - assertEq(uint256(x.toUint128()), x); - } - - function testToUint128Revert(uint256 x) public { - vm.assume(x > type(uint128).max); - vm.expectRevert(bytes(ErrorsLib.MAX_UINT128_EXCEEDED)); - x.toUint128(); - } - - function testZeroFloorSub(uint256 x, uint256 y) public { - assertEq(UtilsLib.zeroFloorSub(x, y), x < y ? 0 : x - y); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoBalancesLibTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoBalancesLibTest.sol deleted file mode 100644 index 516bb08..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoBalancesLibTest.sol +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import "../../BaseTest.sol"; - -contract MorphoBalancesLibTest is BaseTest { - using MathLib for uint256; - using SharesMathLib for uint256; - using MorphoLib for IMorpho; - using MorphoBalancesLib for IMorpho; - - function testVirtualAccrueInterest(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed, uint256 fee) - public - { - _generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee); - - ( - uint256 virtualTotalSupplyAssets, - uint256 virtualTotalSupplyShares, - uint256 virtualTotalBorrowAssets, - uint256 virtualTotalBorrowShares - ) = morpho.expectedMarketBalances(marketParams); - - _accrueInterest(marketParams); - - assertEq(virtualTotalSupplyAssets, morpho.totalSupplyAssets(id), "total supply assets"); - assertEq(virtualTotalBorrowAssets, morpho.totalBorrowAssets(id), "total borrow assets"); - assertEq(virtualTotalSupplyShares, morpho.totalSupplyShares(id), "total supply shares"); - assertEq(virtualTotalBorrowShares, morpho.totalBorrowShares(id), "total borrow shares"); - } - - function testExpectedTotalSupply(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed, uint256 fee) - public - { - _generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee); - - uint256 expectedTotalSupply = morpho.expectedTotalSupply(marketParams); - - _accrueInterest(marketParams); - - assertEq(expectedTotalSupply, morpho.totalSupplyAssets(id)); - } - - function testExpectedTotalBorrow(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed, uint256 fee) - public - { - _generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee); - - uint256 expectedTotalBorrow = morpho.expectedTotalBorrow(marketParams); - - _accrueInterest(marketParams); - - assertEq(expectedTotalBorrow, morpho.totalBorrowAssets(id)); - } - - function testExpectedTotalSupplyShares( - uint256 amountSupplied, - uint256 amountBorrowed, - uint256 timeElapsed, - uint256 fee - ) public { - _generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee); - - uint256 expectedTotalSupplyShares = morpho.expectedTotalSupplyShares(marketParams); - - _accrueInterest(marketParams); - - assertEq(expectedTotalSupplyShares, morpho.totalSupplyShares(id)); - } - - function testExpectedSupplyBalance(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed, uint256 fee) - internal - { - _generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee); - - uint256 expectedSupplyBalance = morpho.expectedSupplyBalance(marketParams, address(this)); - - _accrueInterest(marketParams); - - uint256 actualSupplyBalance = morpho.supplyShares(id, address(this)).toAssetsDown( - morpho.totalSupplyAssets(id), morpho.totalSupplyShares(id) - ); - - assertEq(expectedSupplyBalance, actualSupplyBalance); - } - - function testExpectedBorrowBalance(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed, uint256 fee) - internal - { - _generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee); - - uint256 expectedBorrowBalance = morpho.expectedBorrowBalance(marketParams, address(this)); - - _accrueInterest(marketParams); - - uint256 actualBorrowBalance = morpho.borrowShares(id, address(this)).toAssetsUp( - morpho.totalBorrowAssets(id), morpho.totalBorrowShares(id) - ); - - assertEq(expectedBorrowBalance, actualBorrowBalance); - } - - function _generatePendingInterest(uint256 amountSupplied, uint256 amountBorrowed, uint256 blocks, uint256 fee) - internal - { - amountSupplied = bound(amountSupplied, 0, MAX_TEST_AMOUNT); - amountBorrowed = bound(amountBorrowed, 0, amountSupplied); - blocks = _boundBlocks(blocks); - fee = bound(fee, 0, MAX_FEE); - - // Set fee parameters. - vm.startPrank(OWNER); - if (fee != morpho.fee(id)) morpho.setFee(marketParams, fee); - vm.stopPrank(); - - if (amountSupplied > 0) { - loanToken.setBalance(address(this), amountSupplied); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - if (amountBorrowed > 0) { - uint256 collateralPrice = oracle.price(); - collateralToken.setBalance( - BORROWER, amountBorrowed.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice) - ); - - vm.startPrank(BORROWER); - morpho.supplyCollateral( - marketParams, - amountBorrowed.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice), - BORROWER, - hex"" - ); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - } - } - - _forward(blocks); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoLibTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoLibTest.sol deleted file mode 100644 index 864bee1..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoLibTest.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {MorphoBalancesLib} from "../../../../src/libraries/periphery/MorphoBalancesLib.sol"; - -import "../../BaseTest.sol"; - -contract MorphoLibTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - - function _testMorphoLibCommon(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) - private - { - // Prepare storage layout with non empty values. - - amountSupplied = bound(amountSupplied, 2, MAX_TEST_AMOUNT); - amountBorrowed = bound(amountBorrowed, 1, amountSupplied); - timestamp = bound(timestamp, block.timestamp, type(uint32).max); - fee = bound(fee, 0, MAX_FEE); - - // Set fee parameters. - if (fee != morpho.fee(id)) { - vm.prank(OWNER); - morpho.setFee(marketParams, fee); - } - - // Set timestamp. - vm.warp(timestamp); - - loanToken.setBalance(address(this), amountSupplied); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - uint256 collateralPrice = IOracle(marketParams.oracle).price(); - collateralToken.setBalance( - BORROWER, amountBorrowed.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice) - ); - - vm.startPrank(BORROWER); - morpho.supplyCollateral( - marketParams, - amountBorrowed.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice), - BORROWER, - hex"" - ); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - } - - function testSupplyShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (uint256 expectedSupplyShares,,) = morpho.position(id, address(this)); - assertEq(morpho.supplyShares(id, address(this)), expectedSupplyShares); - } - - function testBorrowShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (, uint256 expectedBorrowShares,) = morpho.position(id, BORROWER); - assertEq(morpho.borrowShares(id, BORROWER), expectedBorrowShares); - } - - function testCollateral(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (,, uint256 expectedCollateral) = morpho.position(id, BORROWER); - assertEq(morpho.collateral(id, BORROWER), expectedCollateral); - } - - function testTotalSupplyAssets(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) - public - { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (uint256 expectedTotalSupplyAssets,,,,,) = morpho.market(id); - assertEq(morpho.totalSupplyAssets(id), expectedTotalSupplyAssets); - } - - function testTotalSupplyShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) - public - { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (, uint256 expectedTotalSupplyShares,,,,) = morpho.market(id); - assertEq(morpho.totalSupplyShares(id), expectedTotalSupplyShares); - } - - function testTotalBorrowAssets(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) - public - { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (,, uint256 expectedTotalBorrowAssets,,,) = morpho.market(id); - assertEq(morpho.totalBorrowAssets(id), expectedTotalBorrowAssets); - } - - function testTotalBorrowShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) - public - { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (,,, uint256 expectedTotalBorrowShares,,) = morpho.market(id); - assertEq(morpho.totalBorrowShares(id), expectedTotalBorrowShares); - } - - function testLastUpdate(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (,,,, uint256 expectedLastUpdate,) = morpho.market(id); - assertEq(morpho.lastUpdate(id), expectedLastUpdate); - } - - function testFee(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { - _testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); - - (,,,,, uint256 expectedFee) = morpho.market(id); - assertEq(morpho.fee(id), expectedFee); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoStorageLibTest.sol b/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoStorageLibTest.sol deleted file mode 100644 index 8f88f4d..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/forge/libraries/periphery/MorphoStorageLibTest.sol +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {MorphoStorageLib} from "../../../../src/libraries/periphery/MorphoStorageLib.sol"; -import {SigUtils} from "../../helpers/SigUtils.sol"; - -import "../../BaseTest.sol"; - -contract MorphoStorageLibTest is BaseTest { - using MathLib for uint256; - using MorphoLib for IMorpho; - using SharesMathLib for uint256; - - function testStorage(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed, uint256 fee) public { - // Prepare storage layout with non empty values. - - amountSupplied = bound(amountSupplied, 2, MAX_TEST_AMOUNT); - amountBorrowed = bound(amountBorrowed, 1, amountSupplied); - timeElapsed = uint32(bound(timeElapsed, 1, 1e8)); - fee = bound(fee, 1, MAX_FEE); - - // Set fee parameters. - vm.prank(OWNER); - morpho.setFee(marketParams, fee); - - loanToken.setBalance(address(this), amountSupplied); - morpho.supply(marketParams, amountSupplied, 0, address(this), hex""); - - uint256 collateralPrice = IOracle(marketParams.oracle).price(); - collateralToken.setBalance( - BORROWER, amountBorrowed.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice) - ); - - vm.startPrank(BORROWER); - morpho.supplyCollateral( - marketParams, - amountBorrowed.wDivUp(marketParams.lltv).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice), - BORROWER, - hex"" - ); - morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); - vm.stopPrank(); - - uint256 privateKey = 1; - address authorizer = vm.addr(privateKey); - Authorization memory authorization = Authorization({ - authorizer: authorizer, - authorized: BORROWER, - isAuthorized: true, - nonce: 0, - deadline: block.timestamp + type(uint32).max - }); - - Signature memory sig; - bytes32 digest = SigUtils.getTypedDataHash(morpho.DOMAIN_SEPARATOR(), authorization); - (sig.v, sig.r, sig.s) = vm.sign(privateKey, digest); - - morpho.setAuthorizationWithSig(authorization, sig); - - bytes32[] memory slots = new bytes32[](16); - slots[0] = MorphoStorageLib.ownerSlot(); - slots[1] = MorphoStorageLib.feeRecipientSlot(); - slots[2] = MorphoStorageLib.positionSupplySharesSlot(id, address(this)); - slots[3] = MorphoStorageLib.positionBorrowSharesAndCollateralSlot(id, BORROWER); - slots[4] = MorphoStorageLib.marketTotalSupplyAssetsAndSharesSlot(id); - slots[5] = MorphoStorageLib.marketTotalBorrowAssetsAndSharesSlot(id); - slots[6] = MorphoStorageLib.marketLastUpdateAndFeeSlot(id); - slots[7] = MorphoStorageLib.isIrmEnabledSlot(address(irm)); - slots[8] = MorphoStorageLib.isLltvEnabledSlot(marketParams.lltv); - slots[9] = MorphoStorageLib.isAuthorizedSlot(authorizer, BORROWER); - slots[10] = MorphoStorageLib.nonceSlot(authorizer); - slots[11] = MorphoStorageLib.idToLoanTokenSlot(id); - slots[12] = MorphoStorageLib.idToCollateralTokenSlot(id); - slots[13] = MorphoStorageLib.idToOracleSlot(id); - slots[14] = MorphoStorageLib.idToIrmSlot(id); - slots[15] = MorphoStorageLib.idToLltvSlot(id); - - bytes32[] memory values = morpho.extSloads(slots); - - assertEq(abi.decode(abi.encode(values[0]), (address)), morpho.owner()); - assertEq(abi.decode(abi.encode(values[1]), (address)), morpho.feeRecipient()); - assertEq(uint256(values[2]), morpho.supplyShares(id, address(this))); - assertEq(uint128(uint256(values[3])), morpho.borrowShares(id, BORROWER)); - assertEq(uint256(values[3] >> 128), morpho.collateral(id, BORROWER)); - assertEq(uint128(uint256(values[4])), morpho.totalSupplyAssets(id)); - assertEq(uint256(values[4] >> 128), morpho.totalSupplyShares(id)); - assertEq(uint128(uint256(values[5])), morpho.totalBorrowAssets(id)); - assertEq(uint256(values[5] >> 128), morpho.totalBorrowShares(id)); - assertEq(uint128(uint256(values[6])), morpho.lastUpdate(id)); - assertEq(uint256(values[6] >> 128), morpho.fee(id)); - assertEq(abi.decode(abi.encode(values[7]), (bool)), morpho.isIrmEnabled(address(irm))); - assertEq(abi.decode(abi.encode(values[8]), (bool)), morpho.isLltvEnabled(marketParams.lltv)); - assertEq(abi.decode(abi.encode(values[9]), (bool)), morpho.isAuthorized(authorizer, BORROWER)); - assertEq(uint256(values[10]), morpho.nonce(authorizer)); - - ( - address expectedloanToken, - address expectedCollateralToken, - address expectedOracle, - address expectedIrm, - uint256 expectedLltv - ) = morpho.idToMarketParams(id); - assertEq(abi.decode(abi.encode(values[11]), (address)), expectedloanToken); - assertEq(abi.decode(abi.encode(values[12]), (address)), expectedCollateralToken); - assertEq(abi.decode(abi.encode(values[13]), (address)), expectedOracle); - assertEq(abi.decode(abi.encode(values[14]), (address)), expectedIrm); - assertEq(uint256(values[15]), expectedLltv); - } -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/hardhat/Morpho.spec.ts b/lib/morpho-blue-irm/lib/morpho-blue/test/hardhat/Morpho.spec.ts deleted file mode 100644 index f43d020..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/hardhat/Morpho.spec.ts +++ /dev/null @@ -1,218 +0,0 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { setNextBlockTimestamp } from "@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time"; -import { expect } from "chai"; -import { AbiCoder, MaxUint256, keccak256, toBigInt } from "ethers"; -import hre from "hardhat"; -import { Morpho, OracleMock, ERC20Mock, IrmMock } from "types"; -import { MarketParamsStruct } from "types/src/Morpho"; -import { FlashBorrowerMock } from "types/src/mocks/FlashBorrowerMock"; - -const closePositions = false; -// Without the division it overflows. -const initBalance = MaxUint256 / 10000000000000000n; -const oraclePriceScale = 1000000000000000000000000000000000000n; - -let seed = 42; -const random = () => { - seed = (seed * 16807) % 2147483647; - - return (seed - 1) / 2147483646; -}; - -const identifier = (marketParams: MarketParamsStruct) => { - const encodedMarket = AbiCoder.defaultAbiCoder().encode( - ["address", "address", "address", "address", "uint256"], - Object.values(marketParams), - ); - - return Buffer.from(keccak256(encodedMarket).slice(2), "hex"); -}; - -const logProgress = (name: string, i: number, max: number) => { - if (i % 10 == 0) console.log("[" + name + "]", Math.floor((100 * i) / max), "%"); -}; - -const randomForwardTimestamp = async () => { - const block = await hre.ethers.provider.getBlock("latest"); - const elapsed = random() < 1 / 2 ? 0 : (1 + Math.floor(random() * 100)) * 12; // 50% of the time, don't go forward in time. - - await setNextBlockTimestamp(block!.timestamp + elapsed); -}; - -describe("Morpho", () => { - let admin: SignerWithAddress; - let liquidator: SignerWithAddress; - let suppliers: SignerWithAddress[]; - let borrowers: SignerWithAddress[]; - - let morpho: Morpho; - let loanToken: ERC20Mock; - let collateralToken: ERC20Mock; - let oracle: OracleMock; - let irm: IrmMock; - let flashBorrower: FlashBorrowerMock; - - let marketParams: MarketParamsStruct; - let id: Buffer; - - const updateMarket = (newMarket: Partial) => { - marketParams = { ...marketParams, ...newMarket }; - id = identifier(marketParams); - }; - - beforeEach(async () => { - const allSigners = await hre.ethers.getSigners(); - - const users = allSigners.slice(0, -2); - - [admin, liquidator] = allSigners.slice(-2); - suppliers = users.slice(0, users.length / 2); - borrowers = users.slice(users.length / 2); - - const ERC20MockFactory = await hre.ethers.getContractFactory("ERC20Mock", admin); - - loanToken = await ERC20MockFactory.deploy(); - collateralToken = await ERC20MockFactory.deploy(); - - const OracleMockFactory = await hre.ethers.getContractFactory("OracleMock", admin); - - oracle = await OracleMockFactory.deploy(); - - await oracle.setPrice(oraclePriceScale); - - const MorphoFactory = await hre.ethers.getContractFactory("Morpho", admin); - - morpho = await MorphoFactory.deploy(admin.address); - - const IrmMockFactory = await hre.ethers.getContractFactory("IrmMock", admin); - - irm = await IrmMockFactory.deploy(); - - updateMarket({ - loanToken: await loanToken.getAddress(), - collateralToken: await collateralToken.getAddress(), - oracle: await oracle.getAddress(), - irm: await irm.getAddress(), - lltv: BigInt.WAD / 2n + 1n, - }); - - await morpho.enableLltv(marketParams.lltv); - await morpho.enableIrm(marketParams.irm); - await morpho.createMarket(marketParams); - - const morphoAddress = await morpho.getAddress(); - - for (const user of users) { - await loanToken.setBalance(user.address, initBalance); - await loanToken.connect(user).approve(morphoAddress, MaxUint256); - await collateralToken.setBalance(user.address, initBalance); - await collateralToken.connect(user).approve(morphoAddress, MaxUint256); - } - - await loanToken.setBalance(admin.address, initBalance); - await loanToken.connect(admin).approve(morphoAddress, MaxUint256); - - await loanToken.setBalance(liquidator.address, initBalance); - await loanToken.connect(liquidator).approve(morphoAddress, MaxUint256); - - const FlashBorrowerFactory = await hre.ethers.getContractFactory("FlashBorrowerMock", admin); - - flashBorrower = await FlashBorrowerFactory.deploy(morphoAddress); - }); - - it("should simulate gas cost [main]", async () => { - for (let i = 0; i < suppliers.length; ++i) { - logProgress("main", i, suppliers.length); - - const supplier = suppliers[i]; - - let assets = BigInt.WAD * toBigInt(1 + Math.floor(random() * 100)); - - await randomForwardTimestamp(); - - await morpho.connect(supplier).supply(marketParams, assets, 0, supplier.address, "0x"); - - await randomForwardTimestamp(); - - await morpho.connect(supplier).withdraw(marketParams, assets / 2n, 0, supplier.address, supplier.address); - - const borrower = borrowers[i]; - - const market = await morpho.market(id); - const liquidity = market.totalSupplyAssets - market.totalBorrowAssets; - - assets = assets.min(liquidity / 2n); - - await randomForwardTimestamp(); - - await morpho.connect(borrower).supplyCollateral(marketParams, assets, borrower.address, "0x"); - - await randomForwardTimestamp(); - - await morpho.connect(borrower).borrow(marketParams, assets / 2n, 0, borrower.address, borrower.address); - - await randomForwardTimestamp(); - - await morpho.connect(borrower).repay(marketParams, assets / 4n, 0, borrower.address, "0x"); - - await randomForwardTimestamp(); - - await morpho.connect(borrower).withdrawCollateral(marketParams, assets / 8n, borrower.address, borrower.address); - } - }); - - it("should simulate gas cost [liquidations]", async () => { - for (let i = 0; i < suppliers.length; ++i) { - logProgress("liquidations", i, suppliers.length); - - const user = suppliers[i]; - const borrower = borrowers[i]; - - const lltv = (BigInt.WAD * toBigInt(i + 1)) / toBigInt(suppliers.length + 1); - const assets = BigInt.WAD * toBigInt(1 + Math.floor(random() * 100)); - const borrowedAmount = assets.wadMulDown(lltv - 1n); - - if (!(await morpho.isLltvEnabled(lltv))) { - await morpho.enableLltv(lltv); - await morpho.createMarket({ ...marketParams, lltv }); - } - - updateMarket({ lltv }); - - // We use 2 different users to borrow from a marketParams so that liquidations do not put the borrow storage back to 0 on that marketParams. - await morpho.connect(user).supply(marketParams, assets, 0, user.address, "0x"); - await morpho.connect(user).supplyCollateral(marketParams, assets, user.address, "0x"); - await morpho.connect(user).borrow(marketParams, borrowedAmount, 0, user.address, user.address); - - await morpho.connect(borrower).supply(marketParams, assets, 0, borrower.address, "0x"); - await morpho.connect(borrower).supplyCollateral(marketParams, assets, borrower.address, "0x"); - await morpho.connect(borrower).borrow(marketParams, borrowedAmount, 0, borrower.address, user.address); - - await oracle.setPrice(oraclePriceScale / 1000n); - - const seized = closePositions ? assets : assets / 2n; - - await morpho.connect(liquidator).liquidate(marketParams, borrower.address, seized, 0, "0x"); - - const remainingCollateral = (await morpho.position(id, borrower.address)).collateral; - - if (closePositions) - expect(remainingCollateral === 0n, "did not take the whole collateral when closing the position").to.be.true; - else expect(remainingCollateral !== 0n, "unexpectedly closed the position").to.be.true; - - await oracle.setPrice(oraclePriceScale); - } - }); - - it("should simuate gas cost [flashLoans]", async () => { - const user = borrowers[0]; - const assets = BigInt.WAD; - - await morpho.connect(user).supply(marketParams, assets, 0, user.address, "0x"); - - const loanAddress = await loanToken.getAddress(); - - const data = AbiCoder.defaultAbiCoder().encode(["address"], [loanAddress]); - await flashBorrower.flashLoan(loanAddress, assets / 2n, data); - }); -}); diff --git a/lib/morpho-blue-irm/lib/morpho-blue/test/morpho_tests.tree b/lib/morpho-blue-irm/lib/morpho-blue/test/morpho_tests.tree deleted file mode 100644 index dff911e..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/test/morpho_tests.tree +++ /dev/null @@ -1,288 +0,0 @@ -. -└── setOwner(address newOwner) external - ├── when msg.sender not owner - │ └── revert with NOT_OWNER - └── when msg.sender is owner - ├── it should set owner to newOwner - └── it should emit SetOwner(newOwner) -. -└── enableIrm(address irm) external - ├── when msg.sender not owner - │ └── revert with NOT_OWNER - └── when msg.sender is owner - ├── it should set isIrmEnabled[irm] to true - └── it should emit EnableIrm(irm) -. -└── enableLltv(uint256 lltv) external - ├── when msg.sender not owner - │ └── revert with NOT_OWNER - └── when msg.sender is owner - ├── when lltv >= WAD - │ └── revert with MAX_LLTV_EXCEEDED - └── when lltv < WAD - ├── it should set isLltvEnabled[lltv] to true - └── it should emit EnableLltv(lltv) -. -└── setFee(MarketParams memory marketParams, uint256 newFee) external - ├── when msg.sender not owner - │ └── revert with NOT_OWNER - └── when msg.sender is owner - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - ├── when newFee > MAX_FEE - │ └── revert with MAX_FEE_EXCEEDED - └── when newFee <= MAX_FEE - ├── it should accrue the interest - ├── it should set fee[marketParams.id] to newFee - └── it should emit SetFee(marketParams.id, newFee) -. -└── setFeeRecipient(address recipient) external - ├── when msg.sender not owner - │ └── revert with NOT_OWNER - └── when msg.sender is owner - ├── it should set feeRecipient to recipient - └── it should emit SetFeeRecipient(recipient) -. -└── createMarket(MarketParams memory marketParams) external - ├── when irm is not enabled - │ └── revert with IRM_NOT_ENABLED - └── when irm is enabled - ├── when marketParams.lltv is not enabled - │ └── revert with LLTV_NOT_ENABLED - └── when marketParams.lltv is enabled - ├── when market is already created - │ └── revert with MARKET_ALREADY_CREATED - └── when market is not already created - ├── it should set lastUpdate[marketParams.id] to block.timestamp - ├── it should set idToMarket[id] to marketParams - └── it should emit CreateMarket(marketParams.id, marketParams) -. -└── supply(MarketParams memory marketParams, uint256 assets, uint256 shares, address onBehalf, bytes calldata data) external - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - ├── when both assets and shares are null or both assets and shares are not null - │ └─ revert with INCONSISTENT_INPUT - └── when one of assets or shares is null and one of assets or shares is not null - ├── when onBehalf is the zero address - │ └── revert with ZERO_ADDRESS - └── when onBehalf is not the zero address - ├── it should accrue the interest - ├── when assets is not zero - │ └── it should set shares to assets.toSharesUp(totalSupplyAssets[marketParams.id], totalSupplyShares[marketParams.id]) - ├── when assets is zero - │ └── it should set assets to shares.toAssetsDown(totalSupplyAssets[id], totalSupplyShares[id]) - ├── it should add shares to supplyShares[marketParams.id][onBehalf] - ├── it should add shares to totalSupplyShares[marketParams.id] - ├── it should add assets to totalSupplyAssets[marketParams.id] - ├── it should emit Supply(marketParams.id, msg.sender, onBehalf, assets, shares) - ├── if data.length > 0 - │ └── it should call sender's onMorphoSupply callback - ├── it should transfer assets of the loan asset from the sender to Morpho - └── it should return the assets and the shares supplied -. -└── withdraw(MarketParams memory marketParams, uint256 assets, uint256 shares, address onBehalf, address receiver) external - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - ├── when both assets and shares are null or both assets and shares are not null - │ └─ revert with INCONSISTENT_INPUT - └── when one of assets or shares is null and one of assets or shares is not null - ├── when receiver is the zero address - │ └── revert with ZERO_ADDRESS - └── when receiver is not the zero address - ├── when not sender and not approved - │ └── revert with UNAUTHORIZED - └── when sender or approved - ├── it should accrue the interest - ├── when assets is not zero - │ └── it should set shares to assets.toSharesUp(totalSupplyAssets[marketParams.id], totalSupplyShares[marketParams.id]) - ├── when assets is zero - │ └── it should set assets to shares.toAssetsDown(totalSupplyAssets[id], totalSupplyShares[id]) - ├── it should remove shares from supplyShares[marketParams.id][onBehalf] - ├── it should remove shares from totalSupplyShares[marketParams.id] - ├── it should remove assets from totalSupplyAssets[marketParams.id] - ├── it should emit Withdraw(marketParams.id, msg.sender, onBehalf, receiver, assets, shares) - ├── it should transfer assets of the loan asset to the receiver - ├── when totalBorrowAssets[marketParams.id] > totalSupplyAssets[marketParams.id] - │ └── revert with INSUFFICIENT_LIQUIDITY - └── when totalBorrowAssets[marketParams.id] <= totalSupplyAssets[marketParams.id] - └── it should return the assets and the shares withdrawn -. -└── borrow(MarketParams memory marketParams, uint256 assets, uint256 shares, address onBehalf, address receiver) external - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - ├── when both assets and shares are null or both assets and shares are not null - │ └─ revert with INCONSISTENT_INPUT - └── when one of assets or shares is null and one of assets or shares is not null - ├── when receiver is the zero address - │ └── revert with ZERO_ADDRESS - └── when receiver is not the zero address - ├── when not sender and not approved - │ └── revert with UNAUTHORIZED - └── when sender or approved - ├── it should accrue the interest - ├── when assets is not zero - │ └── it should set shares to assets.toSharesUp(totalSupplyAssets[marketParams.id], totalSupplyShares[marketParams.id]) - ├── when assets is zero - │ └── it should set assets to shares.toAssetsDown(totalSupplyAssets[id], totalSupplyShares[id]) - ├── it should add shares to borrowShares[marketParams.id][onBehalf] - ├── it should add shares to totalBorrowShares[marketParams.id] - ├── it should add assets to totalBorrowAssets[marketParams.id] - ├── it should emit Borrow(marketParams.id, msg.sender, onBehalf, receiver, assets, shares) - ├── it should transfer assets of the loan asset to the receiver - ├── when position is not healthy - │ └── revert with INSUFFICIENT_COLLATERAL - └── when position is healthy - ├── when totalBorrowAssets[marketParams.id] > totalSupplyAssets[marketParams.id] - │ └── revert with INSUFFICIENT_LIQUIDITY - └── when totalBorrowAssets[marketParams.id] <= totalSupplyAssets[marketParams.id] - └── it should return the assets and the shares borrowed - -. -└── repay(MarketParams memory marketParams, uint256 assets, uint256 shares, address onBehalf, bytes calldata data) external - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - ├── when both assets and shares are null or both assets and shares are not null - │ └─ revert with INCONSISTENT_INPUT - └── when one of assets or shares is null and one of assets or shares is not null - ├── when onBehalf is the zero address - │ └── revert with ZERO_ADDRESS - └── when onBehalf is not the zero address - ├── it should accrue the interest - ├── when assets is not zero - │ └── it should set shares to assets.toSharesUp(totalSupplyAssets[marketParams.id], totalSupplyShares[marketParams.id]) - ├── when assets is zero - │ └── it should set assets to shares.toAssetsDown(totalSupplyAssets[id], totalSupplyShares[id]) - ├── it should remove shares from borrowShares[marketParams.id][onBehalf] - ├── it should remove shares from totalBorrowShares[marketParams.id] - ├── it should remove assets from totalBorrowAssets[marketParams.id] - ├── it should emit Repay(marketParams.id, msg.sender, onBehalf, assets, shares) - ├── if data.length > 0 - │ └── it should call sender's onMorphoRepay callback - ├── it should transfer assets of the loan asset from the sender to Morpho - └── it should return the assets and the shares repaid -. -└── supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes calldata data) external - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - ├── when the assets to supply is zero - │ └── revert with ZERO_ASSETS - └── when the assets to supply is not zero - ├── when onBehalf is the zero address - │ └── revert with ZERO_ADDRESS - └── when onBehalf is not the zero address - ├── it should add assets to collateral[marketParams.id][onBehalf] - ├── it should emit SupplyCollateral(marketParams.id, msg.sender, onBehalf, assets) - ├── if data.length > 0 - │ └── it should call sender's onMorphoSupplyCollateral callback - └── it should transfer assets of the collateral asset from the sender to Morpho -. -└── withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver) external - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - ├── when the assets to withdraw is zero - │ └── revert with ZERO_ASSETS - └── when the assets to withdraw is not zero - ├── when receiver is the zero address - │ └── revert with ZERO_ADDRESS - └── when receiver is not the zero address - ├── when not sender and not approved - │ └── revert with MANAGER_NOT_APPROVED - └── when sender or approved - ├── it should accrue the interest - ├── it should remove assets from collateral[marketParams.id][onBehalf] - ├── it should emit WithdrawCollateral(marketParams.id, msg.sender, onBehalf, receiver, assets) - ├── it should transfer assets of the collateral asset to the receiver - └── when position is not healthy - └── revert with INSUFFICIENT_COLLATERAL -. -└── liquidate(MarketParams memory marketParams, address borrower, uint256 seizedAssets, uint256 repaidShares, bytes calldata data) external - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - ├── when both seizedAssets and repaidShares are null or both seizedAssets and repaidShares are not null - │ └─ revert with INCONSISTENT_INPUT - └── when one of seizedAssets or repaidShares is null and one of seizedAssets or repaidShares is not null - ├── it should accrue the interest - ├── when position is healthy - │ └── revert with HEALTHY_POSITION - └── when the position is not healthy - ├── when seizedAssets is not zero - │ ├── it should compute assetsRepaid = seizedAssets.mulDivUp(collateralPrice, ORACLE_PRICE_SCALE).wDivUp(liquidationIncentiveFactor(marketParams.lltv)) - │ └── it should compute repaidShares = assetsRepaid.toSharesDown(totalBorrow[marketParams.id], totalBorrowShares[market.id]) - ├── when repaidShares is not zero - │ ├── it should compute assetsRepaid = repaidShares.toAssetsUp(totalBorrow[marketParams.id], totalBorrowShares[marketParams.id]) - │ └── it should compute seizedAssets = assetsRepaid.wMulDown(liquidationIncentiveFactor).mulDivDown(ORACLE_PRICE_SCALE, collateralPrice) - ├── it should remove repaidShares from totalBorrowShares[marketParams.id] - ├── it should remove assetsRepaid from totalBorrow[marketParams.id] - ├── it should remove repaidShares from collateral[marketParams.id][borrower] - ├── if after the liquidation the borrower's collateral is 0 - │ └── it should realize bad debt - │ ├── it should compute badDebt = borrowShares[marketParams.id][borrower].toAssetsUp(totalBorrow[marketParams.id], totalBorrowShares[marketParams.id]) - │ ├── it should remove badDebt from totalSupplyAssets[marketParams.id] - │ ├── it should remove badDebt from totalBorrowAssets[marketParams.id] - │ ├── it should remove borrowShares[marketParams.id][borrower] from totalBorrowShares[marketParams.id] - │ └── it should set borrowShares[marketParams.id][borrower] to 0 - ├── it should transfer repaidShares of collateral asset to the sender - ├── it should emit Liquidate(marketParams.id, msg.sender, borrower, assetsRepaid, repaidShares, seizedAssets, badDebtShares) - ├── if data.length > 0 - │ └── it should call sender's onMorphoLiquidate callback - └── it should transfer assetsRepaid of loan asset from the sender to Morpho -. -└── flashLoan(address token, uint256 assets, bytes calldata data) external - ├── it should transfer assets of token from Morpho to the sender - ├── it should call sender's onMorphoFlashLoan callback - ├── it should emit FlashLoan(msg.sender, token, assets) - └── it should transfer assets of token from the sender to Morpho -. -└── setAuthorizationWithSig(Authorization memory authorization, Signature calldata signature) external - ├── when block.timestamp >= authorization.deadline - │ └── revert with SIGNATURE_EXPIRED - └── when block.timestamp < deadline - ├── when authorization.nonce != nonce[authorization.authorizer] - │ └── revert with INVALID_NONCE - └── when authorization.nonce == nonce[authorization.authorizer] - ├── when the signature is invalid or not signed by authorization.authorizer - │ └── revert with INVALID_SIGNATURE - └── when the signature is valid and signed by authorization.authorizer - ├── it should increment authorization.authorizer's nonce - ├── it should emit IncrementNonce(msg.sender, authorization.authorizer, authorization.nonce) - ├── it should set isAuthorized[authorization.authorizer][authorization.authorized] to authorization.isAuthorized - └── it should emit SetAuthorization(msg.sender, authorization.authorizer, authorization.authorized, authorization.isAuthorized) -. -└── setAuthorization(address authorized, bool newIsAuthorized) external - ├── should set isApproved[msg.sender][authorized] to newIsAuthorized - └── it should emit SetAuthorization(msg.sender, msg.sender, authorized, newIsAuthorized) -. -└── accrueInterest(MarketParams memory marketParams) external - ├── when market is not created - │ └── revert with MARKET_NOT_CREATED - └── when market is created - └── it should accrue the interest -. -└── _accrueInterest(MarketParams memory marketParams, Id id) internal - └── when interest not already accrued in the block - ├── it should set lastUpdate to block.timestamp - └── when marketTotalBorrow is not 0 - ├── it should compute accruedInterest = marketTotalBorrow.wMulDown(borrowRate.wTaylorCompounded(elapsed)) - ├── it should add accruedInterest to totalBorrowAssets - ├── it should add accruedInterest to totalSupplyAssets - └── when fee[id] != 0 - │ ├── it should add accruedInterest.wMulDown(fee[id]) to feeAmount - │ ├── it should add feeAmount.mulDivDown(totalSupplyShares[id], totalSupplyAssets[id] - feeAmount) to supplyShares[id][feeRecipient] - │ └── it should add feeAmount.mulDivDown(totalSupplyShares[id], totalSupplyAssets[id] - feeAmount) to totalSupplyShares[id] - └── it should emit AccrueInterest(id, borrowRate, accruedInterest, feeShares) -. -└── _isHealthy(MarketParams memory marketParams, Id id, address user, uint256 collateralPrice) internal - ├── it should compute borrowed = borrowShares[id][user].toAssetsUp(totalBorrowAssets[id], totalBorrowShares[id]) - ├── it should compute maxBorrow = collateral[id][user].mulDivDown(collateralPrice, ORACLE_PRICE_SCALE).wMulDown(marketParams.lltv) - └── it should return maxBorrow >= borrowed -. -└── liquidationIncentiveFactor(uint256 lltv) internal - └── it should return min(MAX_LIQUIDATION_INCENTIVE_FACTOR, WAD.wDivDown(WAD - LIQUIDATION_CURSOR.wMulDown(WAD - lltv))) diff --git a/lib/morpho-blue-irm/lib/morpho-blue/tsconfig.json b/lib/morpho-blue-irm/lib/morpho-blue/tsconfig.json deleted file mode 100644 index b301bff..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "strict": true, - "esModuleInterop": true, - "rootDir": ".", - "baseUrl": ".", - "outDir": "dist", - "moduleResolution": "nodenext", - "resolveJsonModule": true, - "declaration": true - }, - "include": ["types", "test/hardhat"], - "files": ["./hardhat.config.ts"] -} diff --git a/lib/morpho-blue-irm/lib/morpho-blue/yarn.lock b/lib/morpho-blue-irm/lib/morpho-blue/yarn.lock deleted file mode 100644 index cf01a88..0000000 --- a/lib/morpho-blue-irm/lib/morpho-blue/yarn.lock +++ /dev/null @@ -1,6226 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@adraffy/ens-normalize@1.9.2": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz#60111a5d9db45b2e5cbb6231b0bb8d97e8659316" - integrity sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg== - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.5": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.10.tgz#1c20e612b768fefa75f6e90d6ecb86329247f0a3" - integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== - dependencies: - "@babel/highlight" "^7.22.10" - chalk "^2.4.2" - -"@babel/generator@7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.7.tgz#8da2599beb4a86194a3b24df6c085931d9ee45ad" - integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w== - dependencies: - "@babel/types" "^7.17.0" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/generator@^7.17.3": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" - integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== - dependencies: - "@babel/types" "^7.22.10" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/helper-environment-visitor@^7.16.7": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" - integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== - -"@babel/helper-function-name@^7.16.7": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" - integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== - dependencies: - "@babel/template" "^7.22.5" - "@babel/types" "^7.22.5" - -"@babel/helper-hoist-variables@^7.16.7": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-split-export-declaration@^7.16.7": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - -"@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" - integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== - -"@babel/highlight@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" - integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== - dependencies: - "@babel/helper-validator-identifier" "^7.22.5" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.17.3", "@babel/parser@^7.20.5", "@babel/parser@^7.22.5": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.11.tgz#becf8ee33aad2a35ed5607f521fe6e72a615f905" - integrity sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g== - -"@babel/template@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" - integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== - dependencies: - "@babel/code-frame" "^7.22.5" - "@babel/parser" "^7.22.5" - "@babel/types" "^7.22.5" - -"@babel/traverse@7.17.3": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" - integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.3" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.3" - "@babel/types" "^7.17.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" - integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" - -"@babel/types@^7.17.0", "@babel/types@^7.22.10", "@babel/types@^7.22.5": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.11.tgz#0e65a6a1d4d9cbaa892b2213f6159485fe632ea2" - integrity sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.5" - to-fast-properties "^2.0.0" - -"@chainsafe/as-sha256@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" - integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== - -"@chainsafe/persistent-merkle-tree@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" - integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/persistent-merkle-tree@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" - integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/ssz@^0.10.0": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" - integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.5.0" - -"@chainsafe/ssz@^0.9.2": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" - integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.4.2" - case "^1.6.3" - -"@commitlint/cli@^17.7.1": - version "17.7.1" - resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-17.7.1.tgz#f3ab35bd38d82fcd4ab03ec5a1e9db26d57fe1b0" - integrity sha512-BCm/AT06SNCQtvFv921iNhudOHuY16LswT0R3OeolVGLk8oP+Rk9TfQfgjH7QPMjhvp76bNqGFEcpKojxUNW1g== - dependencies: - "@commitlint/format" "^17.4.4" - "@commitlint/lint" "^17.7.0" - "@commitlint/load" "^17.7.1" - "@commitlint/read" "^17.5.1" - "@commitlint/types" "^17.4.4" - execa "^5.0.0" - lodash.isfunction "^3.0.9" - resolve-from "5.0.0" - resolve-global "1.0.0" - yargs "^17.0.0" - -"@commitlint/config-conventional@^17.7.0": - version "17.7.0" - resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-17.7.0.tgz#1bbf2bce7851db63c1a8aa8d924277ad4938247e" - integrity sha512-iicqh2o6et+9kWaqsQiEYZzfLbtoWv9uZl8kbI8EGfnc0HeGafQBF7AJ0ylN9D/2kj6txltsdyQs8+2fTMwWEw== - dependencies: - conventional-changelog-conventionalcommits "^6.1.0" - -"@commitlint/config-validator@^17.6.7": - version "17.6.7" - resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-17.6.7.tgz#c664d42a1ecf5040a3bb0843845150f55734df41" - integrity sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ== - dependencies: - "@commitlint/types" "^17.4.4" - ajv "^8.11.0" - -"@commitlint/ensure@^17.6.7": - version "17.6.7" - resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-17.6.7.tgz#77a77a0c05e6a1c34589f59e82e6cb937101fc4b" - integrity sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw== - dependencies: - "@commitlint/types" "^17.4.4" - lodash.camelcase "^4.3.0" - lodash.kebabcase "^4.1.1" - lodash.snakecase "^4.1.1" - lodash.startcase "^4.4.0" - lodash.upperfirst "^4.3.1" - -"@commitlint/execute-rule@^17.4.0": - version "17.4.0" - resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz#4518e77958893d0a5835babe65bf87e2638f6939" - integrity sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA== - -"@commitlint/format@^17.4.4": - version "17.4.4" - resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-17.4.4.tgz#0f6e1b4d7a301c7b1dfd4b6334edd97fc050b9f5" - integrity sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ== - dependencies: - "@commitlint/types" "^17.4.4" - chalk "^4.1.0" - -"@commitlint/is-ignored@^17.7.0": - version "17.7.0" - resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-17.7.0.tgz#df9b284420bdb1aed5fdb2be44f4e98cc4826014" - integrity sha512-043rA7m45tyEfW7Zv2vZHF++176MLHH9h70fnPoYlB1slKBeKl8BwNIlnPg4xBdRBVNPaCqvXxWswx2GR4c9Hw== - dependencies: - "@commitlint/types" "^17.4.4" - semver "7.5.4" - -"@commitlint/lint@^17.7.0": - version "17.7.0" - resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-17.7.0.tgz#33f831298dc43679e4de6b088aea63d1f884c7e7" - integrity sha512-TCQihm7/uszA5z1Ux1vw+Nf3yHTgicus/+9HiUQk+kRSQawByxZNESeQoX9ujfVd3r4Sa+3fn0JQAguG4xvvbA== - dependencies: - "@commitlint/is-ignored" "^17.7.0" - "@commitlint/parse" "^17.7.0" - "@commitlint/rules" "^17.7.0" - "@commitlint/types" "^17.4.4" - -"@commitlint/load@^17.7.1": - version "17.7.1" - resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-17.7.1.tgz#0723b11723a20043a304a74960602dead89b5cdd" - integrity sha512-S/QSOjE1ztdogYj61p6n3UbkUvweR17FQ0zDbNtoTLc+Hz7vvfS7ehoTMQ27hPSjVBpp7SzEcOQu081RLjKHJQ== - dependencies: - "@commitlint/config-validator" "^17.6.7" - "@commitlint/execute-rule" "^17.4.0" - "@commitlint/resolve-extends" "^17.6.7" - "@commitlint/types" "^17.4.4" - "@types/node" "20.4.7" - chalk "^4.1.0" - cosmiconfig "^8.0.0" - cosmiconfig-typescript-loader "^4.0.0" - lodash.isplainobject "^4.0.6" - lodash.merge "^4.6.2" - lodash.uniq "^4.5.0" - resolve-from "^5.0.0" - ts-node "^10.8.1" - typescript "^4.6.4 || ^5.0.0" - -"@commitlint/message@^17.4.2": - version "17.4.2" - resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-17.4.2.tgz#f4753a79701ad6db6db21f69076e34de6580e22c" - integrity sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q== - -"@commitlint/parse@^17.7.0": - version "17.7.0" - resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-17.7.0.tgz#aacb2d189e50ab8454154b1df150aaf20478ae47" - integrity sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag== - dependencies: - "@commitlint/types" "^17.4.4" - conventional-changelog-angular "^6.0.0" - conventional-commits-parser "^4.0.0" - -"@commitlint/read@^17.5.1": - version "17.5.1" - resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-17.5.1.tgz#fec903b766e2c41e3cefa80630040fcaba4f786c" - integrity sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg== - dependencies: - "@commitlint/top-level" "^17.4.0" - "@commitlint/types" "^17.4.4" - fs-extra "^11.0.0" - git-raw-commits "^2.0.11" - minimist "^1.2.6" - -"@commitlint/resolve-extends@^17.6.7": - version "17.6.7" - resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz#9c53a4601c96ab2dd20b90fb35c988639307735d" - integrity sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg== - dependencies: - "@commitlint/config-validator" "^17.6.7" - "@commitlint/types" "^17.4.4" - import-fresh "^3.0.0" - lodash.mergewith "^4.6.2" - resolve-from "^5.0.0" - resolve-global "^1.0.0" - -"@commitlint/rules@^17.7.0": - version "17.7.0" - resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-17.7.0.tgz#b97a4933c5cba11a659a19ee467f6f000f31533e" - integrity sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA== - dependencies: - "@commitlint/ensure" "^17.6.7" - "@commitlint/message" "^17.4.2" - "@commitlint/to-lines" "^17.4.0" - "@commitlint/types" "^17.4.4" - execa "^5.0.0" - -"@commitlint/to-lines@^17.4.0": - version "17.4.0" - resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-17.4.0.tgz#9bd02e911e7d4eab3fb4a50376c4c6d331e10d8d" - integrity sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg== - -"@commitlint/top-level@^17.4.0": - version "17.4.0" - resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-17.4.0.tgz#540cac8290044cf846fbdd99f5cc51e8ac5f27d6" - integrity sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g== - dependencies: - find-up "^5.0.0" - -"@commitlint/types@^17.4.4": - version "17.4.4" - resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-17.4.4.tgz#1416df936e9aad0d6a7bbc979ecc31e55dade662" - integrity sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ== - dependencies: - chalk "^4.1.0" - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@ethereumjs/rlp@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" - integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== - -"@ethereumjs/util@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" - integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== - dependencies: - "@ethereumjs/rlp" "^4.0.1" - ethereum-cryptography "^2.0.0" - micro-ftch "^0.3.1" - -"@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.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" - integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" - integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - -"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" - integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - -"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" - integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - bn.js "^5.2.1" - -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" - integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - -"@ethersproject/contracts@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" - integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== - dependencies: - "@ethersproject/abi" "^5.7.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - -"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" - integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" - integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" - integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== - -"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" - integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" - integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - -"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" - integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": - version "5.7.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" - integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" - integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" - integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - hash.js "1.1.7" - -"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" - integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - bn.js "^5.2.1" - elliptic "6.5.4" - hash.js "1.1.7" - -"@ethersproject/solidity@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" - integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" - integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/units@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" - integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/wallet@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" - integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/json-wallets" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" - integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" - integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.19" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@metamask/eth-sig-util@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" - integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== - dependencies: - ethereumjs-abi "^0.6.8" - ethereumjs-util "^6.2.1" - ethjs-util "^0.1.6" - tweetnacl "^1.0.3" - tweetnacl-util "^0.15.1" - -"@noble/curves@1.1.0", "@noble/curves@~1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" - integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== - dependencies: - "@noble/hashes" "1.3.1" - -"@noble/hashes@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" - integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== - -"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" - integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== - -"@noble/hashes@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" - integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== - -"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" - integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== - -"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" - integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@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" - 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" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nomicfoundation/ethereumjs-block@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz#6f89664f55febbd723195b6d0974773d29ee133d" - integrity sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - -"@nomicfoundation/ethereumjs-blockchain@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz#80e0bd3535bfeb9baa29836b6f25123dab06a726" - integrity sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-ethash" "3.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - abstract-level "^1.0.3" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - level "^8.0.0" - lru-cache "^5.1.1" - memory-level "^1.0.0" - -"@nomicfoundation/ethereumjs-common@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz#4702d82df35b07b5407583b54a45bf728e46a2f0" - integrity sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.1" - crc-32 "^1.2.0" - -"@nomicfoundation/ethereumjs-ethash@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz#65ca494d53e71e8415c9a49ef48bc921c538fc41" - integrity sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - abstract-level "^1.0.3" - bigint-crypto-utils "^3.0.23" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-evm@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz#f35681e203363f69ce2b3d3bf9f44d4e883ca1f1" - integrity sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ== - dependencies: - "@ethersproject/providers" "^5.7.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/ethereumjs-rlp@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz#0b30c1cf77d125d390408e391c4bb5291ef43c28" - integrity sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ== - -"@nomicfoundation/ethereumjs-statemanager@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz#8824a97938db4471911e2d2f140f79195def5935" - integrity sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - js-sdsl "^4.1.4" - -"@nomicfoundation/ethereumjs-trie@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz#662c55f6b50659fd4b22ea9f806a7401cafb7717" - integrity sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - readable-stream "^3.6.0" - -"@nomicfoundation/ethereumjs-tx@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz#7629dc2036b4a33c34e9f0a592b43227ef4f0c7d" - integrity sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w== - dependencies: - "@chainsafe/ssz" "^0.9.2" - "@ethersproject/providers" "^5.7.2" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-util@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz#530cda8bae33f8b5020a8f199ed1d0a2ce48ec89" - integrity sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA== - dependencies: - "@chainsafe/ssz" "^0.10.0" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-vm@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz#7d035e0993bcad10716c8b36e61dfb87fa3ca05f" - integrity sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-blockchain" "7.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-evm" "2.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-statemanager" "2.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/hardhat-chai-matchers@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.2.tgz#a0e5dbca43ba9560c096da162c0e3245303479d1" - integrity sha512-9Wu9mRtkj0U9ohgXYFbB/RQDa+PcEdyBm2suyEtsJf3PqzZEEjLUZgWnMjlFhATMk/fp3BjmnYVPrwl+gr8oEw== - dependencies: - "@types/chai-as-promised" "^7.1.3" - chai-as-promised "^7.1.1" - deep-eql "^4.0.1" - ordinal "^1.0.3" - -"@nomicfoundation/hardhat-ethers@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.4.tgz#6f0df2424e687e26d6574610de7a36bd69485cc1" - integrity sha512-k9qbLoY7qn6C6Y1LI0gk2kyHXil2Tauj4kGzQ8pgxYXIGw8lWn8tuuL72E11CrlKaXRUvOgF0EXrv/msPI2SbA== - dependencies: - debug "^4.1.1" - lodash.isequal "^4.5.0" - -"@nomicfoundation/hardhat-foundry@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-foundry/-/hardhat-foundry-1.0.3.tgz#42ee0a148c025738508530c5882ea76114c1fbb3" - integrity sha512-Fr5fx9q2lKw1Pv+iVpPfGp9e4go/hb2OpahOGGw8rM3sdUR15v+pms1rAiy9Q+IJ4r98wcZrtPy9kJ64GPulsA== - dependencies: - chalk "^2.4.2" - -"@nomicfoundation/hardhat-network-helpers@^1.0.8": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz#e4fe1be93e8a65508c46d73c41fa26c7e9f84931" - integrity sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q== - dependencies: - ethereumjs-util "^7.1.4" - -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" - integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== - -"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" - integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== - -"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" - integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== - -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" - integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== - -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" - integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== - -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" - integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== - -"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" - integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== - -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" - integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== - -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" - integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== - -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" - integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== - -"@nomicfoundation/solidity-analyzer@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" - integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== - optionalDependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" - "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" - -"@scure/base@~1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== - -"@scure/bip32@1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" - integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== - dependencies: - "@noble/hashes" "~1.2.0" - "@noble/secp256k1" "~1.7.0" - "@scure/base" "~1.1.0" - -"@scure/bip32@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" - integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== - dependencies: - "@noble/curves" "~1.1.0" - "@noble/hashes" "~1.3.1" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" - integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== - dependencies: - "@noble/hashes" "~1.2.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" - integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== - dependencies: - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" - -"@sentry/core@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" - integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/hub@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" - integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== - dependencies: - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/minimal@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" - integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@sentry/node@^5.18.1": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" - integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== - dependencies: - "@sentry/core" "5.30.0" - "@sentry/hub" "5.30.0" - "@sentry/tracing" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - cookie "^0.4.1" - https-proxy-agent "^5.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/tracing@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" - integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/types@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" - integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== - -"@sentry/utils@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" - integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== - dependencies: - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@solidity-parser/parser@^0.14.0": - version "0.14.5" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.5.tgz#87bc3cc7b068e08195c219c91cd8ddff5ef1a804" - integrity sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -"@solidity-parser/parser@^0.16.0": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" - integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -"@trivago/prettier-plugin-sort-imports@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.2.0.tgz#b240366f9e2bda8e14edb18b14ea084e0ec25968" - integrity sha512-YBepjbt+ZNBVmN3ev1amQH3lWCmHyt5qTbLCp/syXJRu/Kw2koXh44qayB1gMRxcL/gV8egmjN5xWSrYyfUtyw== - dependencies: - "@babel/generator" "7.17.7" - "@babel/parser" "^7.20.5" - "@babel/traverse" "7.17.3" - "@babel/types" "7.17.0" - javascript-natural-sort "0.7.1" - lodash "^4.17.21" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" - integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== - -"@typechain/ethers-v6@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v6/-/ethers-v6-0.5.0.tgz#841a63a61272448b72dfc8f53d32d7813709ef62" - integrity sha512-wsz7AvbY5n2uVwpS2RHDYsW6wYOrhWxeTLFpxuzhO62w/ZDQEVIipArX731KA/hdqygP2zJ2RTkVXgzU1WrU1g== - dependencies: - lodash "^4.17.15" - ts-essentials "^7.0.1" - -"@typechain/hardhat@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-9.0.0.tgz#c92d562566db9b933ac6899c0a0a2ae1871ad5c1" - integrity sha512-oCGRvcsryRHEDZ4KO2lenB7wdf8WMDS+f9KGcRFiQWcRLpWWD0ruBGRxNjzkTqyPLtgQ9MvZsXquAFPEw7gAEA== - dependencies: - fs-extra "^9.1.0" - -"@types/bn.js@^4.11.3": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== - dependencies: - "@types/node" "*" - -"@types/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" - integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== - dependencies: - "@types/chai" "*" - -"@types/chai@*", "@types/chai@^4.3.5": - version "4.3.5" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.5.tgz#ae69bcbb1bebb68c4ac0b11e9d8ed04526b3562b" - integrity sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng== - -"@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" - 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 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" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/lodash@^4.14.197": - version "4.14.197" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.197.tgz#e95c5ddcc814ec3e84c891910a01e0c8a378c54b" - integrity sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g== - -"@types/lru-cache@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" - integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== - -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - -"@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== - -"@types/mocha@^10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" - integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== - -"@types/node@*", "@types/node@^20.5.4": - version "20.5.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.4.tgz#4666fb40f9974d60c53c4ff554315860ba4feab8" - integrity sha512-Y9vbIAoM31djQZrPYjpTLo0XlaSwOIsrlfE3LpulZeRblttsLQRFRlBAppW0LOxyT3ALj2M5vU1ucQQayQH3jA== - -"@types/node@18.15.13": - version "18.15.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" - integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== - -"@types/node@20.4.7": - version "20.4.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.7.tgz#74d323a93f1391a63477b27b9aec56669c98b2ab" - integrity sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g== - -"@types/node@^10.0.3": - version "10.17.60" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" - integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== - -"@types/node@^8.0.0": - version "8.10.66" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" - 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" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== - -"@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== - dependencies: - "@types/node" "*" - -"@types/prettier@^2.1.1": - version "2.7.3" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" - integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== - -"@types/qs@^6.2.31": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/readable-stream@^2.3.13": - version "2.3.15" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" - integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== - dependencies: - "@types/node" "*" - safe-buffer "~5.1.1" - -"@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== - dependencies: - "@types/node" "*" - -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - 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 sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== - -abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" - integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== - dependencies: - buffer "^6.0.3" - catering "^2.1.0" - is-buffer "^2.0.5" - level-supports "^4.0.0" - level-transcoder "^1.0.1" - module-error "^1.0.1" - queue-microtask "^1.2.3" - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.4.1: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - -address@^1.0.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" - integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== - -adm-zip@^0.4.16: - version "0.4.16" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" - integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== - -aes-js@4.0.0-beta.5: - version "4.0.0-beta.5" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" - integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^6.12.3: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.11.0: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity 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" - integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-escapes@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-5.0.0.tgz#b6a0caf0eef0c41af190e9a749e0c00ec04bb2a6" - integrity sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA== - dependencies: - type-fest "^1.0.2" - -ansi-regex@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" - 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" - 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" - 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" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -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" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.0.0, ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -antlr4ts@^0.5.0-alpha.4: - version "0.5.0-alpha.4" - resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" - integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== - -anymatch@~3.1.1, anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - 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" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - -array-back@^4.0.1, array-back@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" - integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-ify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity 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" - 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 sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -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" - -arraybuffer.prototype.slice@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" - integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== - -asap@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -async@1.x: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" - integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - -bech32@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -bigint-crypto-utils@^3.0.23: - version "3.3.0" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" - integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -blakejs@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" - integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== - -bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -browser-level@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" - integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.1" - module-error "^1.0.2" - run-parallel-limit "^1.1.0" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -bs58@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - 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" - integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== - dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -case@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" - integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== - -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 sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== - -catering@^2.1.0, catering@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" - integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== - -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" - integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== - dependencies: - check-error "^1.0.2" - -chai@^4.3.8: - version "4.3.8" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.8.tgz#40c59718ad6928da6629c70496fe990b2bb5b17c" - integrity sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^4.1.2" - get-func-name "^2.0.0" - loupe "^2.3.1" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" - integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== - -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -"charenc@>= 0.0.1": - version "0.0.2" - resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - integrity 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 sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== - -chokidar@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" - integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.2.0" - optionalDependencies: - fsevents "~2.1.1" - -chokidar@3.5.3, chokidar@^3.4.0: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -classic-level@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" - integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.0" - module-error "^1.0.1" - napi-macros "^2.2.2" - node-gyp-build "^4.3.0" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" - integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg== - dependencies: - restore-cursor "^4.0.0" - -cli-table3@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" - integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== - dependencies: - object-assign "^4.1.0" - string-width "^2.1.1" - optionalDependencies: - colors "^1.1.2" - -cli-truncate@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" - integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== - dependencies: - slice-ansi "^5.0.0" - string-width "^5.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colorette@^2.0.20: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -colors@1.4.0, colors@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" - integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== - -command-line-args@^5.1.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" - integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -command-line-usage@^6.1.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" - integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== - dependencies: - array-back "^4.0.2" - chalk "^2.4.2" - table-layout "^1.0.2" - typical "^5.2.0" - -commander@11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-11.0.0.tgz#43e19c25dbedc8256203538e8d7e9346877a6f67" - integrity sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ== - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - -compare-func@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" - integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== - dependencies: - array-ify "^1.0.0" - dot-prop "^5.1.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -concat-stream@^1.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" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -conventional-changelog-angular@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz#a9a9494c28b7165889144fd5b91573c4aa9ca541" - integrity sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg== - dependencies: - compare-func "^2.0.0" - -conventional-changelog-conventionalcommits@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz#3bad05f4eea64e423d3d90fc50c17d2c8cf17652" - integrity sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw== - dependencies: - compare-func "^2.0.0" - -conventional-commits-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz#02ae1178a381304839bce7cea9da5f1b549ae505" - integrity sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg== - dependencies: - JSONStream "^1.3.5" - is-text-path "^1.0.1" - meow "^8.1.2" - split2 "^3.2.2" - -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cosmiconfig-typescript-loader@^4.0.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz#f3feae459ea090f131df5474ce4b1222912319f9" - integrity sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw== - -cosmiconfig@^8.0.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd" - integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ== - dependencies: - import-fresh "^3.2.1" - js-yaml "^4.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - -crc-32@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" - integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -"crypt@>= 0.0.1": - version "0.0.2" - resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== - -dargs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" - 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 sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - -death@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" - integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== - -debug@3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decamelize-keys@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" - integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-eql@^4.0.1, deep-eql@^4.1.2: - version "4.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" - integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== - dependencies: - type-detect "^4.0.0" - -deep-extend@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== - dependencies: - address "^1.0.1" - debug "4" - -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -difflib@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" - 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" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dot-prop@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -dotenv@^16.3.1: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - 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 sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - 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" - 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" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -enquirer@^2.3.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" - integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== - dependencies: - ansi-colors "^4.1.1" - strip-ansi "^6.0.1" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: - version "1.22.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" - integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.1" - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.2.1" - 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.5" - is-array-buffer "^3.0.2" - 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.3" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.0" - safe-array-concat "^1.0.0" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.7" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.10" - -es-array-method-boxes-properly@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== - -es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@1.8.x: - version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - integrity sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A== - dependencies: - esprima "^2.7.1" - estraverse "^1.9.1" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.2.0" - -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 sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A== - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -estraverse@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - integrity sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -eth-gas-reporter@^0.2.25: - version "0.2.25" - resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz#546dfa946c1acee93cb1a94c2a1162292d6ff566" - integrity sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ== - dependencies: - "@ethersproject/abi" "^5.0.0-beta.146" - "@solidity-parser/parser" "^0.14.0" - cli-table3 "^0.5.0" - colors "1.4.0" - ethereum-cryptography "^1.0.3" - ethers "^4.0.40" - fs-readdir-recursive "^1.1.0" - lodash "^4.17.14" - markdown-table "^1.1.3" - mocha "^7.1.1" - req-cwd "^2.0.0" - request "^2.88.0" - request-promise-native "^1.0.5" - sha1 "^1.1.1" - sync-request "^6.0.0" - -ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== - dependencies: - js-sha3 "^0.8.0" - -ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== - dependencies: - "@types/pbkdf2" "^3.0.0" - "@types/secp256k1" "^4.0.1" - blakejs "^1.1.0" - browserify-aes "^1.2.0" - bs58check "^2.1.2" - create-hash "^1.2.0" - create-hmac "^1.1.7" - hash.js "^1.1.7" - keccak "^3.0.0" - pbkdf2 "^3.0.17" - randombytes "^2.1.0" - safe-buffer "^5.1.2" - scrypt-js "^3.0.0" - secp256k1 "^4.0.1" - setimmediate "^1.0.5" - -ethereum-cryptography@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" - integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== - dependencies: - "@noble/hashes" "1.2.0" - "@noble/secp256k1" "1.7.1" - "@scure/bip32" "1.1.5" - "@scure/bip39" "1.1.1" - -ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" - integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== - dependencies: - "@noble/curves" "1.1.0" - "@noble/hashes" "1.3.1" - "@scure/bip32" "1.3.1" - "@scure/bip39" "1.2.1" - -ethereumjs-abi@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== - dependencies: - "@types/bn.js" "^4.11.3" - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.3" - -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" - create-hash "^1.1.2" - ethereum-cryptography "^0.1.3" - rlp "^2.2.4" - -ethers-maths@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/ethers-maths/-/ethers-maths-4.0.2.tgz#da50d0e9d32ee0e02a120a93e31ef43977ee30d7" - integrity sha512-uot6QPfBuUPJvXOnBJ9kt2/XYHWm2UEUiw/mySuG2k9PmJ0sDVJiAhz0K9VuKEwaJNjlkxeYAAdZERHpwVyaMQ== - dependencies: - ethers "^6.0.0" - -ethers@^4.0.40: - version "4.0.49" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" - integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== - dependencies: - aes-js "3.0.0" - bn.js "^4.11.9" - elliptic "6.5.4" - hash.js "1.1.3" - js-sha3 "0.5.7" - scrypt-js "2.0.4" - setimmediate "1.0.4" - uuid "2.0.1" - xmlhttprequest "1.8.0" - -ethers@^5.6.1, ethers@^5.7.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" - integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== - dependencies: - "@ethersproject/abi" "5.7.0" - "@ethersproject/abstract-provider" "5.7.0" - "@ethersproject/abstract-signer" "5.7.0" - "@ethersproject/address" "5.7.0" - "@ethersproject/base64" "5.7.0" - "@ethersproject/basex" "5.7.0" - "@ethersproject/bignumber" "5.7.0" - "@ethersproject/bytes" "5.7.0" - "@ethersproject/constants" "5.7.0" - "@ethersproject/contracts" "5.7.0" - "@ethersproject/hash" "5.7.0" - "@ethersproject/hdnode" "5.7.0" - "@ethersproject/json-wallets" "5.7.0" - "@ethersproject/keccak256" "5.7.0" - "@ethersproject/logger" "5.7.0" - "@ethersproject/networks" "5.7.1" - "@ethersproject/pbkdf2" "5.7.0" - "@ethersproject/properties" "5.7.0" - "@ethersproject/providers" "5.7.2" - "@ethersproject/random" "5.7.0" - "@ethersproject/rlp" "5.7.0" - "@ethersproject/sha2" "5.7.0" - "@ethersproject/signing-key" "5.7.0" - "@ethersproject/solidity" "5.7.0" - "@ethersproject/strings" "5.7.0" - "@ethersproject/transactions" "5.7.0" - "@ethersproject/units" "5.7.0" - "@ethersproject/wallet" "5.7.0" - "@ethersproject/web" "5.7.1" - "@ethersproject/wordlists" "5.7.0" - -ethers@^6.0.0, ethers@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.7.1.tgz#9c65e8b5d8e9ad77b7e8cf1c46099892cfafad49" - integrity sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA== - dependencies: - "@adraffy/ens-normalize" "1.9.2" - "@noble/hashes" "1.1.2" - "@noble/secp256k1" "1.7.1" - "@types/node" "18.15.13" - aes-js "4.0.0-beta.5" - tslib "2.4.0" - ws "8.5.0" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw== - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6, ethjs-util@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -eventemitter3@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" - integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== - -evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" - integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^4.3.0" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.0.3: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-replace@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== - dependencies: - array-back "^3.0.1" - -find-up@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" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== - dependencies: - locate-path "^2.0.0" - -find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" - 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" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -follow-redirects@^1.12.1: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - -form-data@^2.2.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== - -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^11.0.0: - version "11.1.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.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" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-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" - 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" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - -functions-have-names@^1.2.2, functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -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" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" - -get-port@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" - integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg== - -get-stream@^6.0.0, get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - 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" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - -ghost-testrpc@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" - integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== - dependencies: - chalk "^2.4.2" - node-emoji "^1.10.0" - -git-raw-commits@^2.0.11: - version "2.0.11" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz#bc3576638071d18655e1cc60d7f524920008d723" - integrity sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A== - dependencies: - dargs "^7.0.0" - lodash "^4.17.15" - meow "^8.0.0" - split2 "^3.0.0" - through2 "^4.0.0" - -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" - 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" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^5.0.15: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - integrity sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA== - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-dirs@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" - integrity sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg== - dependencies: - ini "^1.3.4" - -global-modules@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - 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" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -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" - integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - 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" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -handlebars@^4.0.1: - version "4.7.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" - integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.2" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" - integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== - -hardhat-gas-reporter@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz#9a2afb354bc3b6346aab55b1c02ca556d0e16450" - integrity sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg== - dependencies: - array-uniq "1.0.3" - eth-gas-reporter "^0.2.25" - sha1 "^1.1.1" - -hardhat-tracer@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/hardhat-tracer/-/hardhat-tracer-2.6.0.tgz#ca19ddb8c0447150b242aadc20dd9674206139e5" - integrity sha512-omsGd9NN5i0WmIFuEVZIxULfu5v6zU4/Vx+6oIVmziIJdQgZacmP5VmtVhnJEQd7IPDZNQAa+iBbW827g/ErFQ== - dependencies: - chalk "^4.1.2" - debug "^4.3.4" - ethers "^5.6.1" - -hardhat@^2.17.1: - version "2.17.1" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.17.1.tgz#4b6c8c8f624fd23d9f40185a4af24815d05a486a" - integrity sha512-1PxRkfjhEzXs/wDxI5YgzYBxNmvzifBTjYzuopwel+vXpAhCudplusJthN5eig0FTs4qbi828DBIITEDh8x9LA== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-blockchain" "7.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-evm" "2.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-statemanager" "2.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - "@nomicfoundation/ethereumjs-vm" "7.0.1" - "@nomicfoundation/solidity-analyzer" "^0.1.0" - "@sentry/node" "^5.18.1" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "^5.1.0" - adm-zip "^0.4.16" - aggregate-error "^3.0.0" - ansi-escapes "^4.3.0" - chalk "^2.4.2" - chokidar "^3.4.0" - ci-info "^2.0.0" - debug "^4.1.1" - enquirer "^2.3.0" - env-paths "^2.2.0" - ethereum-cryptography "^1.0.3" - ethereumjs-abi "^0.6.8" - find-up "^2.1.0" - fp-ts "1.19.3" - fs-extra "^7.0.1" - glob "7.2.0" - immutable "^4.0.0-rc.12" - io-ts "1.10.4" - keccak "^3.0.2" - lodash "^4.17.11" - mnemonist "^0.38.0" - mocha "^10.0.0" - p-map "^4.0.0" - raw-body "^2.4.1" - resolve "1.17.0" - semver "^6.3.0" - solc "0.7.3" - source-map-support "^0.5.13" - stacktrace-parser "^0.1.10" - tsort "0.0.1" - undici "^5.14.0" - uuid "^8.3.2" - ws "^7.4.6" - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.0, has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -"heap@>= 0.2.0": - version "0.2.7" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" - 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 sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -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" - 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" - integrity sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw== - dependencies: - caseless "^0.12.0" - concat-stream "^1.6.2" - http-response-object "^3.0.1" - parse-cache-control "^1.0.1" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-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" - 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 sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -human-signals@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" - integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== - -husky@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" - integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^5.1.1: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -immutable@^4.0.0-rc.12: - version "4.3.3" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.3.tgz#8934ff6826d996a7642c8dc4b46e694dd19561e3" - integrity sha512-808ZFYMsIRAjLAu5xkKo0TsbY9LBy9H5MazTKIEHerNkg0ymgilGfBPMR/3G7d/ihGmuK2Hw8S1izY2d3kd3wA== - -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" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.4, ini@^1.3.5: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -internal-slot@^1.0.5: - 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" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -io-ts@1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" - integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== - dependencies: - fp-ts "^1.0.0" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^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" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.13.0, is-core-module@^2.5.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-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 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" - 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" - integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-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 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.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - -javascript-natural-sort@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" - integrity sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw== - -js-sdsl@^4.1.4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" - integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== - -js-sha3@0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== - -js-sha3@0.8.0, js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@3.x: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -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" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -jsonschema@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" - integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - -keccak@^3.0.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" - -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" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== - optionalDependencies: - graceful-fs "^4.1.9" - -level-supports@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" - integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== - -level-transcoder@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" - integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== - dependencies: - buffer "^6.0.3" - module-error "^1.0.1" - -level@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" - integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== - dependencies: - browser-level "^1.0.1" - classic-level "^1.2.0" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lilconfig@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" - integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== - -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" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -lint-staged@^14.0.1: - version "14.0.1" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-14.0.1.tgz#57dfa3013a3d60762d9af5d9c83bdb51291a6232" - integrity sha512-Mw0cL6HXnHN1ag0mN/Dg4g6sr8uf8sn98w2Oc1ECtFto9tvRF7nkXGJRbx8gPlHyoR0pLyBr2lQHbWwmUHe1Sw== - dependencies: - chalk "5.3.0" - commander "11.0.0" - debug "4.3.4" - execa "7.2.0" - lilconfig "2.1.0" - listr2 "6.6.1" - micromatch "4.0.5" - pidtree "0.6.0" - string-argv "0.3.2" - yaml "2.3.1" - -listr2@6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-6.6.1.tgz#08b2329e7e8ba6298481464937099f4a2cd7f95d" - integrity sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg== - dependencies: - cli-truncate "^3.1.0" - colorette "^2.0.20" - eventemitter3 "^5.0.1" - log-update "^5.0.1" - rfdc "^1.3.0" - wrap-ansi "^8.1.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - 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" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== - -lodash.isfunction@^3.0.9: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" - integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== - -lodash.kebabcase@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.mergewith@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" - integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== - -lodash.snakecase@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" - integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== - -lodash.startcase@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8" - integrity sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg== - -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== - -lodash.upperfirst@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" - integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - 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" - 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" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log-update@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-5.0.1.tgz#9e928bf70cb183c1f0c9e91d9e6b7115d597ce09" - integrity sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw== - dependencies: - ansi-escapes "^5.0.0" - cli-cursor "^4.0.0" - slice-ansi "^5.0.0" - strip-ansi "^7.0.1" - wrap-ansi "^8.0.1" - -loupe@^2.3.1: - version "2.3.6" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" - integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== - dependencies: - get-func-name "^2.0.0" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -map-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity 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" - integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== - -markdown-table@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" - integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== - -mcl-wasm@^0.7.1: - version "0.7.9" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" - integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -memory-level@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" - integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== - dependencies: - abstract-level "^1.0.0" - functional-red-black-tree "^1.0.1" - module-error "^1.0.1" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== - -meow@^8.0.0, meow@^8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" - integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== - dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^3.0.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.18.0" - yargs-parser "^20.2.3" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.2.3, merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micro-ftch@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" - integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== - -micromatch@4.0.5, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -"minimatch@2 || 3", minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - 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" - 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" - integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" - -minimist@^1.2.5, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp@0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mkdirp@0.5.x: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mnemonist@^0.38.0: - version "0.38.5" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" - integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== - dependencies: - obliterator "^2.0.0" - -mocha@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.2.tgz#8e40d198acf91a52ace122cd7599c9ab857b29e6" - integrity sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - chokidar "3.3.0" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - mkdirp "0.5.5" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.0" - -mocha@^10.0.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -mocha@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" - integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - chokidar "3.3.0" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - mkdirp "0.5.5" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.0" - -module-error@^1.0.1, module-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" - integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - 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" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - -napi-macros@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" - integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-emoji@^1.10.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" - 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" - integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== - -nopt@3.x: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg== - dependencies: - abbrev "1" - -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" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-package-data@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" - integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== - dependencies: - hosted-git-info "^4.0.1" - is-core-module "^2.5.0" - semver "^7.3.4" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -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" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig== - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.12.3, object-inspect@^1.9.0: - 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-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" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -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.6" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz#5e5c384dd209fa4efffead39e3a0512770ccc312" - integrity sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ== - dependencies: - array.prototype.reduce "^1.0.5" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.21.2" - safe-array-concat "^1.0.0" - -obliterator@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" - integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== - -once@1.x, once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -ordinal@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" - integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.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" - 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" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - 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" - 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" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -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 sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg== - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^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" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - -path-parse@^1.0.6, path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - 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" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -pbkdf2@^3.0.17: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pidtree@0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" - integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - -prettier@^2.3.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -prettier@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.2.tgz#78fcecd6d870551aa5547437cdae39d4701dca5b" - integrity sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -promise@^8.0.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" - integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== - dependencies: - asap "~2.0.6" - -psl@^1.1.28: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -qs@^6.4.0: - version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== - dependencies: - side-channel "^1.0.4" - -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - -queue-microtask@^1.2.2, queue-microtask@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" - integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -raw-body@^2.4.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^2.2.2: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readdirp@~3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" - 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" - 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 sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== - dependencies: - resolve "^1.1.6" - -recursive-readdir@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" - integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== - dependencies: - minimatch "^3.0.5" - -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.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" - integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== - -regexp.prototype.flags@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" - integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - functions-have-names "^1.2.3" - -req-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc" - integrity 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 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" - 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" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.88.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-from-string@^2.0.0, require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-from@5.0.0, resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity 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" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-global@1.0.0, resolve-global@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-global/-/resolve-global-1.0.0.tgz#a2a79df4af2ca3f49bf77ef9ddacd322dad19255" - integrity sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw== - dependencies: - global-dirs "^0.1.1" - -resolve@1.1.x: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== - -resolve@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.1.6, resolve@^1.10.0: - version "1.22.4" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" - integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -restore-cursor@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" - integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - 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" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^2.2.8: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.2.3, rlp@^2.2.4: - version "2.2.7" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" - integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== - dependencies: - bn.js "^5.2.0" - -run-parallel-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" - integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== - dependencies: - queue-microtask "^1.2.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - 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" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - -safe-array-concat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" - integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-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" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sc-istanbul@^0.4.5: - version "0.4.6" - resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839" - integrity sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g== - dependencies: - abbrev "1.0.x" - async "1.x" - escodegen "1.8.x" - esprima "2.7.x" - glob "^5.0.15" - handlebars "^4.0.1" - js-yaml "3.x" - mkdirp "0.5.x" - nopt "3.x" - once "1.x" - resolve "1.1.x" - supports-color "^3.1.0" - which "^1.1.1" - wordwrap "^1.0.0" - -scrypt-js@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" - integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== - -scrypt-js@3.0.1, scrypt-js@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -secp256k1@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== - dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.7.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@7.5.4, semver@^7.3.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -semver@^6.3.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -setimmediate@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" - integrity 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 sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -sha1@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/sha1/-/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848" - integrity sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA== - dependencies: - charenc ">= 0.0.1" - crypt ">= 0.0.1" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shelljs@^0.8.3: - version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" - integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== - dependencies: - ansi-styles "^6.0.0" - is-fullwidth-code-point "^4.0.0" - -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - follow-redirects "^1.12.1" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -solidity-coverage@^0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.4.tgz#c57a21979f5e86859c5198de9fbae2d3bc6324a5" - integrity sha512-xeHOfBOjdMF6hWTbt42iH4x+7j1Atmrf5OldDPMxI+i/COdExUxszOswD9qqvcBTaLGiOrrpnh9UZjSpt4rBsg== - dependencies: - "@ethersproject/abi" "^5.0.9" - "@solidity-parser/parser" "^0.16.0" - chalk "^2.4.2" - death "^1.1.0" - detect-port "^1.3.0" - difflib "^0.2.4" - fs-extra "^8.1.0" - ghost-testrpc "^0.0.2" - global-modules "^2.0.0" - globby "^10.0.1" - jsonschema "^1.2.4" - lodash "^4.17.15" - mocha "7.1.2" - node-emoji "^1.10.0" - pify "^4.0.1" - recursive-readdir "^2.2.2" - sc-istanbul "^0.4.5" - semver "^7.3.4" - shelljs "^0.8.3" - web3-utils "^1.3.6" - -source-map-support@^0.5.13: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - 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 sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA== - dependencies: - amdefine ">=0.0.4" - -spdx-correct@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" - integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== - -split2@^3.0.0, split2@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== - dependencies: - type-fest "^0.7.1" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -string-argv@0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" - integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== - -string-format@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" - integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== - -"string-width@^1.0.2 || 2", string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -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" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.0, string-width@^5.0.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - 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.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" - integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity 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" - 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" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -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" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A== - dependencies: - is-hex-prefixed "1.0.0" - -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - -strip-json-comments@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - -strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== - dependencies: - has-flag "^3.0.0" - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^3.1.0: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A== - dependencies: - has-flag "^1.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" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -sync-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" - integrity sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw== - dependencies: - http-response-object "^3.0.1" - sync-rpc "^1.2.1" - then-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" - 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" - integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== - dependencies: - array-back "^4.0.1" - deep-extend "~0.6.0" - typical "^5.2.0" - wordwrapjs "^4.0.0" - -text-extensions@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" - integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== - -then-request@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" - integrity sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA== - dependencies: - "@types/concat-stream" "^1.6.0" - "@types/form-data" "0.0.33" - "@types/node" "^8.0.0" - "@types/qs" "^6.2.31" - caseless "~0.12.0" - concat-stream "^1.6.0" - form-data "^2.2.0" - http-basic "^8.1.1" - http-response-object "^3.0.1" - promise "^8.0.0" - qs "^6.4.0" - -through2@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" - integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== - dependencies: - readable-stream "3" - -"through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -tmp@0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tough-cookie@^2.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" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -trim-newlines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" - integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== - -ts-command-line-args@^2.2.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0" - integrity sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw== - dependencies: - chalk "^4.1.0" - command-line-args "^5.1.1" - command-line-usage "^6.1.0" - string-format "^2.0.0" - -ts-essentials@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" - integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== - -ts-node@^10.8.1, ts-node@^10.9.1: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -tslib@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - -tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsort@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - -tweetnacl-util@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== - -tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity 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" - 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" - integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-fest@^1.0.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" - integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== - -typechain@^8.3.1: - version "8.3.1" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.1.tgz#dccbc839b94877997536c356380eff7325395cfb" - integrity sha512-fA7clol2IP/56yq6vkMTR+4URF1nGjV82Wx6Rf09EsqD4tkzMAvEaqYxVFCavJm/1xaRga/oD55K+4FtuXwQOQ== - dependencies: - "@types/prettier" "^2.1.1" - debug "^4.3.1" - fs-extra "^7.0.0" - glob "7.1.7" - js-sha3 "^0.8.0" - lodash "^4.17.15" - mkdirp "^1.0.4" - prettier "^2.3.1" - ts-command-line-args "^2.2.0" - ts-essentials "^7.0.1" - -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" - -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -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@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== - -"typescript@^4.6.4 || ^5.0.0", typescript@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" - integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== - -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -typical@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" - integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== - -uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -undici@^5.14.0: - version "5.23.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.23.0.tgz#e7bdb0ed42cebe7b7aca87ced53e6eaafb8f8ca0" - integrity sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg== - dependencies: - busboy "^1.6.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -utf8@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -uuid@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" - integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -web3-utils@^1.3.6: - version "1.10.1" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.1.tgz#97532130d85358628bc0ff14d94b7e9449786983" - integrity sha512-r6iUUw/uMnNcWXjhRv33Nyrhxq3VGOPBXeSzxhOXIci4SvC/LPTpROY0uTrMX7ztKyODYrHp8WhTkEf+ZnHssw== - dependencies: - "@ethereumjs/util" "^8.1.0" - bn.js "^5.2.1" - ethereum-bloom-filters "^1.0.6" - ethereum-cryptography "^2.1.2" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" - integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== - -which-typed-array@^1.1.10, which-typed-array@^1.1.11: - version "1.1.11" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" - integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== - 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" - -which@1.3.1, which@^1.1.1, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - 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" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -word-wrap@~1.2.3: - version "1.2.5" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" - integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity 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" - integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== - dependencies: - reduce-flatten "^2.0.0" - typical "^5.2.0" - -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@7.4.6: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -ws@8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== - -ws@^7.4.6: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -xmlhttprequest@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA== - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - 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" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" - integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== - -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" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2, yargs-parser@^20.2.3: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs-unparser@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" - integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== - dependencies: - flat "^4.1.0" - lodash "^4.17.15" - yargs "^13.3.0" - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@13.3.2, yargs@^13.3.0: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^17.0.0: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/lib/morpho-blue-irm/lib/solmate/.gas-snapshot b/lib/morpho-blue-irm/lib/solmate/.gas-snapshot deleted file mode 100644 index a5babd3..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.gas-snapshot +++ /dev/null @@ -1,540 +0,0 @@ -AuthTest:testCallFunctionAsOwner() (gas: 29784) -AuthTest:testCallFunctionWithPermissiveAuthority() (gas: 124292) -AuthTest:testCallFunctionWithPermissiveAuthority(address) (runs: 256, μ: 129235, ~: 129235) -AuthTest:testFailCallFunctionAsNonOwner() (gas: 15523) -AuthTest:testFailCallFunctionAsNonOwner(address) (runs: 256, μ: 15685, ~: 15685) -AuthTest:testFailCallFunctionAsOwnerWithOutOfOrderAuthority() (gas: 136021) -AuthTest:testFailCallFunctionWithRestrictiveAuthority() (gas: 129144) -AuthTest:testFailCallFunctionWithRestrictiveAuthority(address) (runs: 256, μ: 129329, ~: 129329) -AuthTest:testFailSetAuthorityAsNonOwner() (gas: 18325) -AuthTest:testFailSetAuthorityAsNonOwner(address,address) (runs: 256, μ: 18594, ~: 18594) -AuthTest:testFailSetAuthorityWithRestrictiveAuthority() (gas: 129077) -AuthTest:testFailSetAuthorityWithRestrictiveAuthority(address,address) (runs: 256, μ: 129409, ~: 129409) -AuthTest:testFailTransferOwnershipAsNonOwner() (gas: 15641) -AuthTest:testFailTransferOwnershipAsNonOwner(address,address) (runs: 256, μ: 15922, ~: 15922) -AuthTest:testFailTransferOwnershipAsOwnerWithOutOfOrderAuthority() (gas: 136159) -AuthTest:testFailTransferOwnershipAsOwnerWithOutOfOrderAuthority(address) (runs: 256, μ: 136344, ~: 136344) -AuthTest:testFailTransferOwnershipWithRestrictiveAuthority() (gas: 129338) -AuthTest:testFailTransferOwnershipWithRestrictiveAuthority(address,address) (runs: 256, μ: 129588, ~: 129588) -AuthTest:testSetAuthorityAsOwner() (gas: 32214) -AuthTest:testSetAuthorityAsOwner(address) (runs: 256, μ: 32306, ~: 32384) -AuthTest:testSetAuthorityAsOwnerWithOutOfOrderAuthority() (gas: 226419) -AuthTest:testSetAuthorityWithPermissiveAuthority() (gas: 125962) -AuthTest:testSetAuthorityWithPermissiveAuthority(address,address) (runs: 256, μ: 130899, ~: 131055) -AuthTest:testTransferOwnershipAsOwner() (gas: 15298) -AuthTest:testTransferOwnershipAsOwner(address) (runs: 256, μ: 15450, ~: 15469) -AuthTest:testTransferOwnershipWithPermissiveAuthority() (gas: 127926) -AuthTest:testTransferOwnershipWithPermissiveAuthority(address,address) (runs: 256, μ: 130962, ~: 131000) -Bytes32AddressLibTest:testFillLast12Bytes() (gas: 223) -Bytes32AddressLibTest:testFromLast20Bytes() (gas: 191) -CREATE3Test:testDeployERC20() (gas: 853111) -CREATE3Test:testDeployERC20(bytes32,string,string,uint8) (runs: 256, μ: 937188, ~: 944874) -CREATE3Test:testFailDoubleDeployDifferentBytecode() (gas: 9079256848778914174) -CREATE3Test:testFailDoubleDeployDifferentBytecode(bytes32,bytes,bytes) (runs: 256, μ: 5795341072053839754, ~: 8937393460516727572) -CREATE3Test:testFailDoubleDeploySameBytecode() (gas: 9079256848778906218) -CREATE3Test:testFailDoubleDeploySameBytecode(bytes32,bytes) (runs: 256, μ: 5865164458464126813, ~: 8937393460516728811) -DSTestPlusTest:testBound() (gas: 14214) -DSTestPlusTest:testBound(uint256,uint256,uint256) (runs: 256, μ: 2787, ~: 2793) -DSTestPlusTest:testBrutalizeMemory() (gas: 823) -DSTestPlusTest:testFailBoundMinBiggerThanMax() (gas: 309) -DSTestPlusTest:testFailBoundMinBiggerThanMax(uint256,uint256,uint256) (runs: 256, μ: 460, ~: 460) -DSTestPlusTest:testRelApproxEqBothZeroesPasses() (gas: 425) -ERC1155Test:testApproveAll() (gas: 31009) -ERC1155Test:testApproveAll(address,bool) (runs: 256, μ: 16872, ~: 11440) -ERC1155Test:testBatchBalanceOf() (gas: 157631) -ERC1155Test:testBatchBalanceOf(address[],uint256[],uint256[],bytes) (runs: 256, μ: 3309892, ~: 2596398) -ERC1155Test:testBatchBurn() (gas: 151074) -ERC1155Test:testBatchBurn(address,uint256[],uint256[],uint256[],bytes) (runs: 256, μ: 3490281, ~: 3058687) -ERC1155Test:testBatchMintToEOA() (gas: 137337) -ERC1155Test:testBatchMintToEOA(address,uint256[],uint256[],bytes) (runs: 256, μ: 3309311, ~: 2953384) -ERC1155Test:testBatchMintToERC1155Recipient() (gas: 995703) -ERC1155Test:testBatchMintToERC1155Recipient(uint256[],uint256[],bytes) (runs: 256, μ: 7395823, ~: 6396323) -ERC1155Test:testBurn() (gas: 38598) -ERC1155Test:testBurn(address,uint256,uint256,bytes,uint256) (runs: 256, μ: 39910, ~: 42098) -ERC1155Test:testFailBalanceOfBatchWithArrayMismatch() (gas: 7933) -ERC1155Test:testFailBalanceOfBatchWithArrayMismatch(address[],uint256[]) (runs: 256, μ: 53386, ~: 54066) -ERC1155Test:testFailBatchBurnInsufficientBalance() (gas: 136156) -ERC1155Test:testFailBatchBurnInsufficientBalance(address,uint256[],uint256[],uint256[],bytes) (runs: 256, μ: 1301088, ~: 440335) -ERC1155Test:testFailBatchBurnWithArrayLengthMismatch() (gas: 135542) -ERC1155Test:testFailBatchBurnWithArrayLengthMismatch(address,uint256[],uint256[],uint256[],bytes) (runs: 256, μ: 77137, ~: 78751) -ERC1155Test:testFailBatchMintToNonERC1155Recipient() (gas: 167292) -ERC1155Test:testFailBatchMintToNonERC1155Recipient(uint256[],uint256[],bytes) (runs: 256, μ: 3190100, ~: 2673077) -ERC1155Test:testFailBatchMintToRevertingERC1155Recipient() (gas: 358811) -ERC1155Test:testFailBatchMintToRevertingERC1155Recipient(uint256[],uint256[],bytes) (runs: 256, μ: 3381638, ~: 2864613) -ERC1155Test:testFailBatchMintToWrongReturnDataERC1155Recipient() (gas: 310743) -ERC1155Test:testFailBatchMintToWrongReturnDataERC1155Recipient(uint256[],uint256[],bytes) (runs: 256, μ: 3333596, ~: 2816572) -ERC1155Test:testFailBatchMintToZero() (gas: 131737) -ERC1155Test:testFailBatchMintToZero(uint256[],uint256[],bytes) (runs: 256, μ: 3130600, ~: 2612336) -ERC1155Test:testFailBatchMintWithArrayMismatch() (gas: 9600) -ERC1155Test:testFailBatchMintWithArrayMismatch(address,uint256[],uint256[],bytes) (runs: 256, μ: 69252, ~: 68809) -ERC1155Test:testFailBurnInsufficientBalance() (gas: 34852) -ERC1155Test:testFailBurnInsufficientBalance(address,uint256,uint256,uint256,bytes) (runs: 256, μ: 35951, ~: 38209) -ERC1155Test:testFailMintToNonERC155Recipient() (gas: 68191) -ERC1155Test:testFailMintToNonERC155Recipient(uint256,uint256,bytes) (runs: 256, μ: 68507, ~: 69197) -ERC1155Test:testFailMintToRevertingERC155Recipient() (gas: 259435) -ERC1155Test:testFailMintToRevertingERC155Recipient(uint256,uint256,bytes) (runs: 256, μ: 259682, ~: 260373) -ERC1155Test:testFailMintToWrongReturnDataERC155Recipient() (gas: 259389) -ERC1155Test:testFailMintToWrongReturnDataERC155Recipient(uint256,uint256,bytes) (runs: 256, μ: 259706, ~: 260397) -ERC1155Test:testFailMintToZero() (gas: 33705) -ERC1155Test:testFailMintToZero(uint256,uint256,bytes) (runs: 256, μ: 33815, ~: 34546) -ERC1155Test:testFailSafeBatchTransferFromToNonERC1155Recipient() (gas: 321377) -ERC1155Test:testFailSafeBatchTransferFromToNonERC1155Recipient(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 3541063, ~: 2963551) -ERC1155Test:testFailSafeBatchTransferFromToRevertingERC1155Recipient() (gas: 512956) -ERC1155Test:testFailSafeBatchTransferFromToRevertingERC1155Recipient(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 3732600, ~: 3155082) -ERC1155Test:testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() (gas: 464847) -ERC1155Test:testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 3684518, ~: 3107003) -ERC1155Test:testFailSafeBatchTransferFromToZero() (gas: 286556) -ERC1155Test:testFailSafeBatchTransferFromToZero(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 3505494, ~: 2928396) -ERC1155Test:testFailSafeBatchTransferFromWithArrayLengthMismatch() (gas: 162674) -ERC1155Test:testFailSafeBatchTransferFromWithArrayLengthMismatch(address,uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 81184, ~: 82042) -ERC1155Test:testFailSafeBatchTransferInsufficientBalance() (gas: 163555) -ERC1155Test:testFailSafeBatchTransferInsufficientBalance(address,uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 1528611, ~: 499517) -ERC1155Test:testFailSafeTransferFromInsufficientBalance() (gas: 63245) -ERC1155Test:testFailSafeTransferFromInsufficientBalance(address,uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 63986, ~: 67405) -ERC1155Test:testFailSafeTransferFromSelfInsufficientBalance() (gas: 34297) -ERC1155Test:testFailSafeTransferFromSelfInsufficientBalance(address,uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 36266, ~: 38512) -ERC1155Test:testFailSafeTransferFromToNonERC155Recipient() (gas: 96510) -ERC1155Test:testFailSafeTransferFromToNonERC155Recipient(uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 96657, ~: 100546) -ERC1155Test:testFailSafeTransferFromToRevertingERC1155Recipient() (gas: 287731) -ERC1155Test:testFailSafeTransferFromToRevertingERC1155Recipient(uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 287828, ~: 291719) -ERC1155Test:testFailSafeTransferFromToWrongReturnDataERC1155Recipient() (gas: 239587) -ERC1155Test:testFailSafeTransferFromToWrongReturnDataERC1155Recipient(uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 239707, ~: 243598) -ERC1155Test:testFailSafeTransferFromToZero() (gas: 62014) -ERC1155Test:testFailSafeTransferFromToZero(uint256,uint256,uint256,bytes,bytes) (runs: 256, μ: 62146, ~: 66037) -ERC1155Test:testMintToEOA() (gas: 34765) -ERC1155Test:testMintToEOA(address,uint256,uint256,bytes) (runs: 256, μ: 35562, ~: 35907) -ERC1155Test:testMintToERC1155Recipient() (gas: 661411) -ERC1155Test:testMintToERC1155Recipient(uint256,uint256,bytes) (runs: 256, μ: 691094, ~: 684374) -ERC1155Test:testSafeBatchTransferFromToEOA() (gas: 297822) -ERC1155Test:testSafeBatchTransferFromToEOA(address,uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 4802177, ~: 3787204) -ERC1155Test:testSafeBatchTransferFromToERC1155Recipient() (gas: 1175327) -ERC1155Test:testSafeBatchTransferFromToERC1155Recipient(uint256[],uint256[],uint256[],bytes,bytes) (runs: 256, μ: 7759308, ~: 6618414) -ERC1155Test:testSafeTransferFromSelf() (gas: 64177) -ERC1155Test:testSafeTransferFromSelf(uint256,uint256,bytes,uint256,address,bytes) (runs: 256, μ: 64552, ~: 68564) -ERC1155Test:testSafeTransferFromToEOA() (gas: 93167) -ERC1155Test:testSafeTransferFromToEOA(uint256,uint256,bytes,uint256,address,bytes) (runs: 256, μ: 92808, ~: 97450) -ERC1155Test:testSafeTransferFromToERC1155Recipient() (gas: 739583) -ERC1155Test:testSafeTransferFromToERC1155Recipient(uint256,uint256,bytes,uint256,bytes) (runs: 256, μ: 769591, ~: 765729) -ERC20Invariants:invariantBalanceSum() (runs: 256, calls: 3840, reverts: 2365) -ERC20Test:invariantMetadata() (runs: 256, calls: 3840, reverts: 2537) -ERC20Test:testApprove() (gas: 31058) -ERC20Test:testApprove(address,uint256) (runs: 256, μ: 30424, ~: 31280) -ERC20Test:testBurn() (gas: 56970) -ERC20Test:testBurn(address,uint256,uint256) (runs: 256, μ: 56678, ~: 59645) -ERC20Test:testFailBurnInsufficientBalance(address,uint256,uint256) (runs: 256, μ: 51897, ~: 55492) -ERC20Test:testFailPermitBadDeadline() (gas: 36935) -ERC20Test:testFailPermitBadDeadline(uint256,address,uint256,uint256) (runs: 256, μ: 32016, ~: 37218) -ERC20Test:testFailPermitBadNonce() (gas: 36874) -ERC20Test:testFailPermitBadNonce(uint256,address,uint256,uint256,uint256) (runs: 256, μ: 31497, ~: 37187) -ERC20Test:testFailPermitPastDeadline() (gas: 11191) -ERC20Test:testFailPermitPastDeadline(uint256,address,uint256,uint256) (runs: 256, μ: 12007, ~: 13101) -ERC20Test:testFailPermitReplay() (gas: 66274) -ERC20Test:testFailPermitReplay(uint256,address,uint256,uint256) (runs: 256, μ: 56825, ~: 66592) -ERC20Test:testFailTransferFromInsufficientAllowance() (gas: 80882) -ERC20Test:testFailTransferFromInsufficientAllowance(address,uint256,uint256) (runs: 256, μ: 79858, ~: 83393) -ERC20Test:testFailTransferFromInsufficientBalance() (gas: 81358) -ERC20Test:testFailTransferFromInsufficientBalance(address,uint256,uint256) (runs: 256, μ: 79359, ~: 83870) -ERC20Test:testFailTransferInsufficientBalance() (gas: 52806) -ERC20Test:testFailTransferInsufficientBalance(address,uint256,uint256) (runs: 256, μ: 51720, ~: 55310) -ERC20Test:testInfiniteApproveTransferFrom() (gas: 89793) -ERC20Test:testMetadata(string,string,uint8) (runs: 256, μ: 870921, ~: 863565) -ERC20Test:testMint() (gas: 53746) -ERC20Test:testMint(address,uint256) (runs: 256, μ: 52214, ~: 53925) -ERC20Test:testPermit() (gas: 63193) -ERC20Test:testPermit(uint248,address,uint256,uint256) (runs: 256, μ: 62584, ~: 63517) -ERC20Test:testTransfer() (gas: 60272) -ERC20Test:testTransfer(address,uint256) (runs: 256, μ: 58773, ~: 60484) -ERC20Test:testTransferFrom() (gas: 83777) -ERC20Test:testTransferFrom(address,uint256,uint256) (runs: 256, μ: 86464, ~: 92841) -ERC4626Test:invariantMetadata() (runs: 256, calls: 3840, reverts: 2921) -ERC4626Test:testFailDepositWithNoApproval() (gas: 13369) -ERC4626Test:testFailDepositWithNotEnoughApproval() (gas: 87005) -ERC4626Test:testFailDepositZero() (gas: 7780) -ERC4626Test:testFailMintWithNoApproval() (gas: 13308) -ERC4626Test:testFailRedeemWithNoShareAmount() (gas: 32342) -ERC4626Test:testFailRedeemWithNotEnoughShareAmount() (gas: 203643) -ERC4626Test:testFailRedeemZero() (gas: 7967) -ERC4626Test:testFailWithdrawWithNoUnderlyingAmount() (gas: 32289) -ERC4626Test:testFailWithdrawWithNotEnoughUnderlyingAmount() (gas: 203607) -ERC4626Test:testMetadata(string,string) (runs: 256, μ: 1506582, ~: 1495306) -ERC4626Test:testMintZero() (gas: 54607) -ERC4626Test:testMultipleMintDepositRedeemWithdraw() (gas: 411804) -ERC4626Test:testSingleDepositWithdraw(uint128) (runs: 256, μ: 201539, ~: 201550) -ERC4626Test:testSingleMintRedeem(uint128) (runs: 256, μ: 201465, ~: 201476) -ERC4626Test:testVaultInteractionsForSomeoneElse() (gas: 286238) -ERC4626Test:testWithdrawZero() (gas: 52468) -ERC721Test:invariantMetadata() (runs: 256, calls: 3840, reverts: 2156) -ERC721Test:testApprove() (gas: 78427) -ERC721Test:testApprove(address,uint256) (runs: 256, μ: 78637, ~: 78637) -ERC721Test:testApproveAll() (gas: 31063) -ERC721Test:testApproveAll(address,bool) (runs: 256, μ: 17048, ~: 11538) -ERC721Test:testApproveBurn() (gas: 65550) -ERC721Test:testApproveBurn(address,uint256) (runs: 256, μ: 65422, ~: 65619) -ERC721Test:testBurn() (gas: 46107) -ERC721Test:testBurn(address,uint256) (runs: 256, μ: 46147, ~: 46157) -ERC721Test:testFailApproveUnAuthorized() (gas: 55598) -ERC721Test:testFailApproveUnAuthorized(address,uint256,address) (runs: 256, μ: 55872, ~: 55873) -ERC721Test:testFailApproveUnMinted() (gas: 10236) -ERC721Test:testFailApproveUnMinted(uint256,address) (runs: 256, μ: 10363, ~: 10363) -ERC721Test:testFailBalanceOfZeroAddress() (gas: 5555) -ERC721Test:testFailBurnUnMinted() (gas: 7857) -ERC721Test:testFailBurnUnMinted(uint256) (runs: 256, μ: 7938, ~: 7938) -ERC721Test:testFailDoubleBurn() (gas: 58943) -ERC721Test:testFailDoubleBurn(uint256,address) (runs: 256, μ: 59174, ~: 59174) -ERC721Test:testFailDoubleMint() (gas: 53286) -ERC721Test:testFailDoubleMint(uint256,address) (runs: 256, μ: 53496, ~: 53496) -ERC721Test:testFailMintToZero() (gas: 5753) -ERC721Test:testFailMintToZero(uint256) (runs: 256, μ: 5835, ~: 5835) -ERC721Test:testFailOwnerOfUnminted() (gas: 7609) -ERC721Test:testFailOwnerOfUnminted(uint256) (runs: 256, μ: 7689, ~: 7689) -ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnData() (gas: 159076) -ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnData(uint256) (runs: 256, μ: 159125, ~: 159125) -ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() (gas: 159831) -ERC721Test:testFailSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256,bytes) (runs: 256, μ: 160231, ~: 160182) -ERC721Test:testFailSafeMintToNonERC721Recipient() (gas: 89210) -ERC721Test:testFailSafeMintToNonERC721Recipient(uint256) (runs: 256, μ: 89279, ~: 89279) -ERC721Test:testFailSafeMintToNonERC721RecipientWithData() (gas: 89995) -ERC721Test:testFailSafeMintToNonERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 90420, ~: 90368) -ERC721Test:testFailSafeMintToRevertingERC721Recipient() (gas: 204743) -ERC721Test:testFailSafeMintToRevertingERC721Recipient(uint256) (runs: 256, μ: 204815, ~: 204815) -ERC721Test:testFailSafeMintToRevertingERC721RecipientWithData() (gas: 205517) -ERC721Test:testFailSafeMintToRevertingERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 205964, ~: 205915) -ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnData() (gas: 187276) -ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnData(uint256) (runs: 256, μ: 187360, ~: 187360) -ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() (gas: 187728) -ERC721Test:testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256,bytes) (runs: 256, μ: 188067, ~: 188063) -ERC721Test:testFailSafeTransferFromToNonERC721Recipient() (gas: 117413) -ERC721Test:testFailSafeTransferFromToNonERC721Recipient(uint256) (runs: 256, μ: 117495, ~: 117495) -ERC721Test:testFailSafeTransferFromToNonERC721RecipientWithData() (gas: 117872) -ERC721Test:testFailSafeTransferFromToNonERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 118280, ~: 118276) -ERC721Test:testFailSafeTransferFromToRevertingERC721Recipient() (gas: 233009) -ERC721Test:testFailSafeTransferFromToRevertingERC721Recipient(uint256) (runs: 256, μ: 233050, ~: 233050) -ERC721Test:testFailSafeTransferFromToRevertingERC721RecipientWithData() (gas: 233396) -ERC721Test:testFailSafeTransferFromToRevertingERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 233823, ~: 233819) -ERC721Test:testFailTransferFromNotOwner() (gas: 57872) -ERC721Test:testFailTransferFromNotOwner(address,address,uint256) (runs: 256, μ: 57905, ~: 58162) -ERC721Test:testFailTransferFromToZero() (gas: 53381) -ERC721Test:testFailTransferFromToZero(uint256) (runs: 256, μ: 53463, ~: 53463) -ERC721Test:testFailTransferFromUnOwned() (gas: 8000) -ERC721Test:testFailTransferFromUnOwned(address,address,uint256) (runs: 256, μ: 8294, ~: 8241) -ERC721Test:testFailTransferFromWrongFrom() (gas: 53361) -ERC721Test:testFailTransferFromWrongFrom(address,address,address,uint256) (runs: 256, μ: 53566, ~: 53752) -ERC721Test:testMetadata(string,string) (runs: 256, μ: 1344402, ~: 1332786) -ERC721Test:testMint() (gas: 54336) -ERC721Test:testMint(address,uint256) (runs: 256, μ: 54521, ~: 54521) -ERC721Test:testSafeMintToEOA() (gas: 56993) -ERC721Test:testSafeMintToEOA(uint256,address) (runs: 256, μ: 56764, ~: 57421) -ERC721Test:testSafeMintToERC721Recipient() (gas: 427035) -ERC721Test:testSafeMintToERC721Recipient(uint256) (runs: 256, μ: 426053, ~: 427142) -ERC721Test:testSafeMintToERC721RecipientWithData() (gas: 448149) -ERC721Test:testSafeMintToERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 480015, ~: 470905) -ERC721Test:testSafeTransferFromToEOA() (gas: 95666) -ERC721Test:testSafeTransferFromToEOA(uint256,address) (runs: 256, μ: 95735, ~: 96099) -ERC721Test:testSafeTransferFromToERC721Recipient() (gas: 485549) -ERC721Test:testSafeTransferFromToERC721Recipient(uint256) (runs: 256, μ: 484593, ~: 485682) -ERC721Test:testSafeTransferFromToERC721RecipientWithData() (gas: 506317) -ERC721Test:testSafeTransferFromToERC721RecipientWithData(uint256,bytes) (runs: 256, μ: 538126, ~: 529082) -ERC721Test:testTransferFrom() (gas: 86347) -ERC721Test:testTransferFrom(uint256,address) (runs: 256, μ: 86459, ~: 86468) -ERC721Test:testTransferFromApproveAll() (gas: 92898) -ERC721Test:testTransferFromApproveAll(uint256,address) (runs: 256, μ: 93181, ~: 93182) -ERC721Test:testTransferFromSelf() (gas: 64776) -ERC721Test:testTransferFromSelf(uint256,address) (runs: 256, μ: 65060, ~: 65061) -FixedPointMathLibTest:testDifferentiallyFuzzSqrt(uint256) (runs: 256, μ: 13872, ~: 6222) -FixedPointMathLibTest:testDivWadDown() (gas: 820) -FixedPointMathLibTest:testDivWadDown(uint256,uint256) (runs: 256, μ: 716, ~: 813) -FixedPointMathLibTest:testDivWadDownEdgeCases() (gas: 439) -FixedPointMathLibTest:testDivWadUp() (gas: 943) -FixedPointMathLibTest:testDivWadUp(uint256,uint256) (runs: 256, μ: 799, ~: 952) -FixedPointMathLibTest:testDivWadUpEdgeCases() (gas: 442) -FixedPointMathLibTest:testFailDivWadDownOverflow(uint256,uint256) (runs: 256, μ: 440, ~: 419) -FixedPointMathLibTest:testFailDivWadDownZeroDenominator() (gas: 332) -FixedPointMathLibTest:testFailDivWadDownZeroDenominator(uint256) (runs: 256, μ: 387, ~: 387) -FixedPointMathLibTest:testFailDivWadUpOverflow(uint256,uint256) (runs: 256, μ: 395, ~: 374) -FixedPointMathLibTest:testFailDivWadUpZeroDenominator() (gas: 332) -FixedPointMathLibTest:testFailDivWadUpZeroDenominator(uint256) (runs: 256, μ: 386, ~: 386) -FixedPointMathLibTest:testFailMulDivDownOverflow(uint256,uint256,uint256) (runs: 256, μ: 436, ~: 414) -FixedPointMathLibTest:testFailMulDivDownZeroDenominator() (gas: 328) -FixedPointMathLibTest:testFailMulDivDownZeroDenominator(uint256,uint256) (runs: 256, μ: 385, ~: 385) -FixedPointMathLibTest:testFailMulDivUpOverflow(uint256,uint256,uint256) (runs: 256, μ: 459, ~: 437) -FixedPointMathLibTest:testFailMulDivUpZeroDenominator() (gas: 329) -FixedPointMathLibTest:testFailMulDivUpZeroDenominator(uint256,uint256) (runs: 256, μ: 428, ~: 428) -FixedPointMathLibTest:testFailMulWadDownOverflow(uint256,uint256) (runs: 256, μ: 419, ~: 387) -FixedPointMathLibTest:testFailMulWadUpOverflow(uint256,uint256) (runs: 256, μ: 396, ~: 364) -FixedPointMathLibTest:testMulDivDown() (gas: 1813) -FixedPointMathLibTest:testMulDivDown(uint256,uint256,uint256) (runs: 256, μ: 680, ~: 786) -FixedPointMathLibTest:testMulDivDownEdgeCases() (gas: 686) -FixedPointMathLibTest:testMulDivUp() (gas: 2095) -FixedPointMathLibTest:testMulDivUp(uint256,uint256,uint256) (runs: 256, μ: 810, ~: 1034) -FixedPointMathLibTest:testMulDivUpEdgeCases() (gas: 785) -FixedPointMathLibTest:testMulWadDown() (gas: 823) -FixedPointMathLibTest:testMulWadDown(uint256,uint256) (runs: 256, μ: 688, ~: 803) -FixedPointMathLibTest:testMulWadDownEdgeCases() (gas: 822) -FixedPointMathLibTest:testMulWadUp() (gas: 921) -FixedPointMathLibTest:testMulWadUp(uint256,uint256) (runs: 256, μ: 834, ~: 1053) -FixedPointMathLibTest:testMulWadUpEdgeCases() (gas: 899) -FixedPointMathLibTest:testRPow() (gas: 2164) -FixedPointMathLibTest:testSqrt() (gas: 2580) -FixedPointMathLibTest:testSqrt(uint256) (runs: 256, μ: 997, ~: 1013) -FixedPointMathLibTest:testSqrtBack(uint256) (runs: 256, μ: 14998, ~: 340) -FixedPointMathLibTest:testSqrtBackHashed(uint256) (runs: 256, μ: 59001, ~: 59500) -FixedPointMathLibTest:testSqrtBackHashedSingle() (gas: 58937) -LibStringTest:testDifferentiallyFuzzToString(uint256,bytes) (runs: 256, μ: 20460, ~: 7749) -LibStringTest:testDifferentiallyFuzzToStringInt(int256,bytes) (runs: 256, μ: 20610, ~: 8980) -LibStringTest:testToString() (gas: 10069) -LibStringTest:testToStringDirty() (gas: 8145) -LibStringTest:testToStringIntNegative() (gas: 9634) -LibStringTest:testToStringIntPositive() (gas: 10481) -LibStringTest:testToStringOverwrite() (gas: 506) -MerkleProofLibTest:testValidProofSupplied() (gas: 2153) -MerkleProofLibTest:testVerifyEmptyMerkleProofSuppliedLeafAndRootDifferent() (gas: 1458) -MerkleProofLibTest:testVerifyEmptyMerkleProofSuppliedLeafAndRootSame() (gas: 1452) -MerkleProofLibTest:testVerifyInvalidProofSupplied() (gas: 2172) -MultiRolesAuthorityTest:testCanCallPublicCapability() (gas: 34204) -MultiRolesAuthorityTest:testCanCallPublicCapability(address,address,bytes4) (runs: 256, μ: 34387, ~: 34364) -MultiRolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 80416) -MultiRolesAuthorityTest:testCanCallWithAuthorizedRole(address,uint8,address,bytes4) (runs: 256, μ: 80702, ~: 80671) -MultiRolesAuthorityTest:testCanCallWithCustomAuthority() (gas: 422439) -MultiRolesAuthorityTest:testCanCallWithCustomAuthority(address,address,bytes4) (runs: 256, μ: 422858, ~: 422858) -MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesPublicCapability() (gas: 247388) -MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesPublicCapability(address,address,bytes4) (runs: 256, μ: 247841, ~: 247841) -MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesUserWithRole() (gas: 256546) -MultiRolesAuthorityTest:testCanCallWithCustomAuthorityOverridesUserWithRole(address,uint8,address,bytes4) (runs: 256, μ: 256878, ~: 256852) -MultiRolesAuthorityTest:testSetPublicCapabilities() (gas: 27727) -MultiRolesAuthorityTest:testSetPublicCapabilities(bytes4) (runs: 256, μ: 27836, ~: 27835) -MultiRolesAuthorityTest:testSetRoleCapabilities() (gas: 28932) -MultiRolesAuthorityTest:testSetRoleCapabilities(uint8,bytes4) (runs: 256, μ: 29073, ~: 29072) -MultiRolesAuthorityTest:testSetRoles() (gas: 28918) -MultiRolesAuthorityTest:testSetRoles(address,uint8) (runs: 256, μ: 29026, ~: 29014) -MultiRolesAuthorityTest:testSetTargetCustomAuthority() (gas: 28102) -MultiRolesAuthorityTest:testSetTargetCustomAuthority(address,address) (runs: 256, μ: 28143, ~: 28146) -OwnedTest:testCallFunctionAsNonOwner() (gas: 11344) -OwnedTest:testCallFunctionAsNonOwner(address) (runs: 256, μ: 16233, ~: 16290) -OwnedTest:testCallFunctionAsOwner() (gas: 10435) -OwnedTest:testTransferOwnership() (gas: 13123) -OwnedTest:testTransferOwnership(address) (runs: 256, μ: 13135, ~: 13192) -ReentrancyGuardTest:invariantReentrancyStatusAlways1() (runs: 256, calls: 3840, reverts: 282) -ReentrancyGuardTest:testFailUnprotectedCall() (gas: 46147) -ReentrancyGuardTest:testNoReentrancy() (gas: 7515) -ReentrancyGuardTest:testProtectedCall() (gas: 33467) -RolesAuthorityTest:testCanCallPublicCapability() (gas: 33409) -RolesAuthorityTest:testCanCallPublicCapability(address,address,bytes4) (runs: 256, μ: 33558, ~: 33534) -RolesAuthorityTest:testCanCallWithAuthorizedRole() (gas: 79995) -RolesAuthorityTest:testCanCallWithAuthorizedRole(address,uint8,address,bytes4) (runs: 256, μ: 80265, ~: 80238) -RolesAuthorityTest:testSetPublicCapabilities() (gas: 29095) -RolesAuthorityTest:testSetPublicCapabilities(address,bytes4) (runs: 256, μ: 29206, ~: 29192) -RolesAuthorityTest:testSetRoleCapabilities() (gas: 30276) -RolesAuthorityTest:testSetRoleCapabilities(uint8,address,bytes4) (runs: 256, μ: 30503, ~: 30489) -RolesAuthorityTest:testSetRoles() (gas: 29005) -RolesAuthorityTest:testSetRoles(address,uint8) (runs: 256, μ: 29119, ~: 29106) -SSTORE2Test:testFailReadInvalidPointer() (gas: 2927) -SSTORE2Test:testFailReadInvalidPointer(address,bytes) (runs: 256, μ: 3889, ~: 3892) -SSTORE2Test:testFailReadInvalidPointerCustomBounds() (gas: 3099) -SSTORE2Test:testFailReadInvalidPointerCustomBounds(address,uint256,uint256,bytes) (runs: 256, μ: 4111, ~: 4130) -SSTORE2Test:testFailReadInvalidPointerCustomStartBound() (gas: 3004) -SSTORE2Test:testFailReadInvalidPointerCustomStartBound(address,uint256,bytes) (runs: 256, μ: 3950, ~: 3988) -SSTORE2Test:testFailWriteReadCustomBoundsOutOfRange(bytes,uint256,uint256,bytes) (runs: 256, μ: 46236, ~: 43603) -SSTORE2Test:testFailWriteReadCustomStartBoundOutOfRange(bytes,uint256,bytes) (runs: 256, μ: 46017, ~: 43452) -SSTORE2Test:testFailWriteReadEmptyOutOfBounds() (gas: 34470) -SSTORE2Test:testFailWriteReadOutOfBounds() (gas: 34426) -SSTORE2Test:testFailWriteReadOutOfStartBound() (gas: 34362) -SSTORE2Test:testWriteRead() (gas: 53497) -SSTORE2Test:testWriteRead(bytes,bytes) (runs: 256, μ: 44019, ~: 41555) -SSTORE2Test:testWriteReadCustomBounds() (gas: 34869) -SSTORE2Test:testWriteReadCustomBounds(bytes,uint256,uint256,bytes) (runs: 256, μ: 28690, ~: 42377) -SSTORE2Test:testWriteReadCustomStartBound() (gas: 34740) -SSTORE2Test:testWriteReadCustomStartBound(bytes,uint256,bytes) (runs: 256, μ: 46485, ~: 44053) -SSTORE2Test:testWriteReadEmptyBound() (gas: 34677) -SSTORE2Test:testWriteReadFullBoundedRead() (gas: 53672) -SSTORE2Test:testWriteReadFullStartBound() (gas: 34764) -SafeCastLibTest:testFailSafeCastTo104() (gas: 387) -SafeCastLibTest:testFailSafeCastTo104(uint256) (runs: 256, μ: 468, ~: 468) -SafeCastLibTest:testFailSafeCastTo112() (gas: 388) -SafeCastLibTest:testFailSafeCastTo112(uint256) (runs: 256, μ: 445, ~: 445) -SafeCastLibTest:testFailSafeCastTo120() (gas: 409) -SafeCastLibTest:testFailSafeCastTo120(uint256) (runs: 256, μ: 490, ~: 490) -SafeCastLibTest:testFailSafeCastTo128() (gas: 365) -SafeCastLibTest:testFailSafeCastTo128(uint256) (runs: 256, μ: 487, ~: 487) -SafeCastLibTest:testFailSafeCastTo136() (gas: 409) -SafeCastLibTest:testFailSafeCastTo136(uint256) (runs: 256, μ: 489, ~: 489) -SafeCastLibTest:testFailSafeCastTo144() (gas: 365) -SafeCastLibTest:testFailSafeCastTo144(uint256) (runs: 256, μ: 423, ~: 423) -SafeCastLibTest:testFailSafeCastTo152() (gas: 368) -SafeCastLibTest:testFailSafeCastTo152(uint256) (runs: 256, μ: 468, ~: 468) -SafeCastLibTest:testFailSafeCastTo16() (gas: 388) -SafeCastLibTest:testFailSafeCastTo16(uint256) (runs: 256, μ: 468, ~: 468) -SafeCastLibTest:testFailSafeCastTo160() (gas: 409) -SafeCastLibTest:testFailSafeCastTo160(uint256) (runs: 256, μ: 444, ~: 444) -SafeCastLibTest:testFailSafeCastTo168() (gas: 341) -SafeCastLibTest:testFailSafeCastTo168(uint256) (runs: 256, μ: 488, ~: 488) -SafeCastLibTest:testFailSafeCastTo176() (gas: 363) -SafeCastLibTest:testFailSafeCastTo176(uint256) (runs: 256, μ: 489, ~: 489) -SafeCastLibTest:testFailSafeCastTo184() (gas: 343) -SafeCastLibTest:testFailSafeCastTo184(uint256) (runs: 256, μ: 490, ~: 490) -SafeCastLibTest:testFailSafeCastTo192() (gas: 367) -SafeCastLibTest:testFailSafeCastTo192(uint256) (runs: 256, μ: 446, ~: 446) -SafeCastLibTest:testFailSafeCastTo200() (gas: 343) -SafeCastLibTest:testFailSafeCastTo200(uint256) (runs: 256, μ: 490, ~: 490) -SafeCastLibTest:testFailSafeCastTo208() (gas: 386) -SafeCastLibTest:testFailSafeCastTo208(uint256) (runs: 256, μ: 446, ~: 446) -SafeCastLibTest:testFailSafeCastTo216() (gas: 365) -SafeCastLibTest:testFailSafeCastTo216(uint256) (runs: 256, μ: 424, ~: 424) -SafeCastLibTest:testFailSafeCastTo224() (gas: 409) -SafeCastLibTest:testFailSafeCastTo224(uint256) (runs: 256, μ: 423, ~: 423) -SafeCastLibTest:testFailSafeCastTo232() (gas: 410) -SafeCastLibTest:testFailSafeCastTo232(uint256) (runs: 256, μ: 467, ~: 467) -SafeCastLibTest:testFailSafeCastTo24() (gas: 387) -SafeCastLibTest:testFailSafeCastTo24(uint256) (runs: 256, μ: 424, ~: 424) -SafeCastLibTest:testFailSafeCastTo240() (gas: 364) -SafeCastLibTest:testFailSafeCastTo240(uint256) (runs: 256, μ: 467, ~: 467) -SafeCastLibTest:testFailSafeCastTo248() (gas: 365) -SafeCastLibTest:testFailSafeCastTo248(uint256) (runs: 256, μ: 466, ~: 466) -SafeCastLibTest:testFailSafeCastTo32() (gas: 364) -SafeCastLibTest:testFailSafeCastTo32(uint256) (runs: 256, μ: 468, ~: 468) -SafeCastLibTest:testFailSafeCastTo40() (gas: 366) -SafeCastLibTest:testFailSafeCastTo40(uint256) (runs: 256, μ: 422, ~: 422) -SafeCastLibTest:testFailSafeCastTo48() (gas: 366) -SafeCastLibTest:testFailSafeCastTo48(uint256) (runs: 256, μ: 488, ~: 488) -SafeCastLibTest:testFailSafeCastTo56() (gas: 388) -SafeCastLibTest:testFailSafeCastTo56(uint256) (runs: 256, μ: 445, ~: 445) -SafeCastLibTest:testFailSafeCastTo64() (gas: 410) -SafeCastLibTest:testFailSafeCastTo64(uint256) (runs: 256, μ: 446, ~: 446) -SafeCastLibTest:testFailSafeCastTo72() (gas: 410) -SafeCastLibTest:testFailSafeCastTo72(uint256) (runs: 256, μ: 467, ~: 467) -SafeCastLibTest:testFailSafeCastTo8() (gas: 341) -SafeCastLibTest:testFailSafeCastTo8(uint256) (runs: 256, μ: 421, ~: 421) -SafeCastLibTest:testFailSafeCastTo80() (gas: 343) -SafeCastLibTest:testFailSafeCastTo80(uint256) (runs: 256, μ: 424, ~: 424) -SafeCastLibTest:testFailSafeCastTo88() (gas: 344) -SafeCastLibTest:testFailSafeCastTo88(uint256) (runs: 256, μ: 489, ~: 489) -SafeCastLibTest:testFailSafeCastTo96() (gas: 366) -SafeCastLibTest:testFailSafeCastTo96(uint256) (runs: 256, μ: 469, ~: 469) -SafeCastLibTest:testSafeCastTo104() (gas: 515) -SafeCastLibTest:testSafeCastTo104(uint256) (runs: 256, μ: 2779, ~: 2779) -SafeCastLibTest:testSafeCastTo112() (gas: 469) -SafeCastLibTest:testSafeCastTo112(uint256) (runs: 256, μ: 2755, ~: 2755) -SafeCastLibTest:testSafeCastTo120() (gas: 491) -SafeCastLibTest:testSafeCastTo120(uint256) (runs: 256, μ: 2735, ~: 2735) -SafeCastLibTest:testSafeCastTo128() (gas: 516) -SafeCastLibTest:testSafeCastTo128(uint256) (runs: 256, μ: 2735, ~: 2735) -SafeCastLibTest:testSafeCastTo136() (gas: 470) -SafeCastLibTest:testSafeCastTo136(uint256) (runs: 256, μ: 2757, ~: 2757) -SafeCastLibTest:testSafeCastTo144() (gas: 514) -SafeCastLibTest:testSafeCastTo144(uint256) (runs: 256, μ: 2798, ~: 2798) -SafeCastLibTest:testSafeCastTo152() (gas: 494) -SafeCastLibTest:testSafeCastTo152(uint256) (runs: 256, μ: 2734, ~: 2734) -SafeCastLibTest:testSafeCastTo16() (gas: 469) -SafeCastLibTest:testSafeCastTo16(uint256) (runs: 256, μ: 2779, ~: 2779) -SafeCastLibTest:testSafeCastTo160() (gas: 491) -SafeCastLibTest:testSafeCastTo160(uint256) (runs: 256, μ: 2775, ~: 2775) -SafeCastLibTest:testSafeCastTo168() (gas: 494) -SafeCastLibTest:testSafeCastTo168(uint256) (runs: 256, μ: 2799, ~: 2799) -SafeCastLibTest:testSafeCastTo176() (gas: 493) -SafeCastLibTest:testSafeCastTo176(uint256) (runs: 256, μ: 2734, ~: 2734) -SafeCastLibTest:testSafeCastTo184() (gas: 513) -SafeCastLibTest:testSafeCastTo184(uint256) (runs: 256, μ: 2801, ~: 2801) -SafeCastLibTest:testSafeCastTo192() (gas: 494) -SafeCastLibTest:testSafeCastTo192(uint256) (runs: 256, μ: 2734, ~: 2734) -SafeCastLibTest:testSafeCastTo200() (gas: 470) -SafeCastLibTest:testSafeCastTo200(uint256) (runs: 256, μ: 2734, ~: 2734) -SafeCastLibTest:testSafeCastTo208() (gas: 472) -SafeCastLibTest:testSafeCastTo208(uint256) (runs: 256, μ: 2756, ~: 2756) -SafeCastLibTest:testSafeCastTo216() (gas: 493) -SafeCastLibTest:testSafeCastTo216(uint256) (runs: 256, μ: 2777, ~: 2777) -SafeCastLibTest:testSafeCastTo224() (gas: 469) -SafeCastLibTest:testSafeCastTo224(uint256) (runs: 256, μ: 2733, ~: 2733) -SafeCastLibTest:testSafeCastTo232() (gas: 492) -SafeCastLibTest:testSafeCastTo232(uint256) (runs: 256, μ: 2735, ~: 2735) -SafeCastLibTest:testSafeCastTo24() (gas: 515) -SafeCastLibTest:testSafeCastTo24(uint256) (runs: 256, μ: 2733, ~: 2733) -SafeCastLibTest:testSafeCastTo240() (gas: 513) -SafeCastLibTest:testSafeCastTo240(uint256) (runs: 256, μ: 2800, ~: 2800) -SafeCastLibTest:testSafeCastTo248() (gas: 472) -SafeCastLibTest:testSafeCastTo248(uint256) (runs: 256, μ: 2777, ~: 2777) -SafeCastLibTest:testSafeCastTo32() (gas: 516) -SafeCastLibTest:testSafeCastTo32(uint256) (runs: 256, μ: 2777, ~: 2777) -SafeCastLibTest:testSafeCastTo40() (gas: 517) -SafeCastLibTest:testSafeCastTo40(uint256) (runs: 256, μ: 2756, ~: 2756) -SafeCastLibTest:testSafeCastTo48() (gas: 469) -SafeCastLibTest:testSafeCastTo48(uint256) (runs: 256, μ: 2778, ~: 2778) -SafeCastLibTest:testSafeCastTo56() (gas: 470) -SafeCastLibTest:testSafeCastTo56(uint256) (runs: 256, μ: 2801, ~: 2801) -SafeCastLibTest:testSafeCastTo64() (gas: 537) -SafeCastLibTest:testSafeCastTo64(uint256) (runs: 256, μ: 2799, ~: 2799) -SafeCastLibTest:testSafeCastTo72(uint256) (runs: 256, μ: 2798, ~: 2798) -SafeCastLibTest:testSafeCastTo8() (gas: 513) -SafeCastLibTest:testSafeCastTo8(uint256) (runs: 256, μ: 2755, ~: 2755) -SafeCastLibTest:testSafeCastTo80(uint256) (runs: 256, μ: 2736, ~: 2736) -SafeCastLibTest:testSafeCastTo88(uint256) (runs: 256, μ: 2755, ~: 2755) -SafeCastLibTest:testSafeCastTo96() (gas: 536) -SafeCastLibTest:testSafeCastTo96(uint256) (runs: 256, μ: 2800, ~: 2800) -SafeTransferLibTest:testApproveWithGarbage(address,uint256,bytes,bytes) (runs: 256, μ: 2675, ~: 2231) -SafeTransferLibTest:testApproveWithMissingReturn() (gas: 30757) -SafeTransferLibTest:testApproveWithMissingReturn(address,uint256,bytes) (runs: 256, μ: 30334, ~: 31572) -SafeTransferLibTest:testApproveWithNonContract() (gas: 3041) -SafeTransferLibTest:testApproveWithNonContract(address,address,uint256,bytes) (runs: 256, μ: 4128, ~: 4123) -SafeTransferLibTest:testApproveWithReturnsTooMuch() (gas: 31140) -SafeTransferLibTest:testApproveWithReturnsTooMuch(address,uint256,bytes) (runs: 256, μ: 30802, ~: 32040) -SafeTransferLibTest:testApproveWithStandardERC20() (gas: 30888) -SafeTransferLibTest:testApproveWithStandardERC20(address,uint256,bytes) (runs: 256, μ: 30528, ~: 31766) -SafeTransferLibTest:testFailApproveWithGarbage(address,uint256,bytes,bytes) (runs: 256, μ: 84301, ~: 77915) -SafeTransferLibTest:testFailApproveWithReturnsFalse() (gas: 5633) -SafeTransferLibTest:testFailApproveWithReturnsFalse(address,uint256,bytes) (runs: 256, μ: 6486, ~: 6481) -SafeTransferLibTest:testFailApproveWithReturnsTooLittle() (gas: 5574) -SafeTransferLibTest:testFailApproveWithReturnsTooLittle(address,uint256,bytes) (runs: 256, μ: 6450, ~: 6445) -SafeTransferLibTest:testFailApproveWithReturnsTwo(address,uint256,bytes) (runs: 256, μ: 6458, ~: 6453) -SafeTransferLibTest:testFailApproveWithReverting() (gas: 5508) -SafeTransferLibTest:testFailApproveWithReverting(address,uint256,bytes) (runs: 256, μ: 6409, ~: 6404) -SafeTransferLibTest:testFailTransferETHToContractWithoutFallback() (gas: 7244) -SafeTransferLibTest:testFailTransferETHToContractWithoutFallback(uint256,bytes) (runs: 256, μ: 7757, ~: 8055) -SafeTransferLibTest:testFailTransferFromWithGarbage(address,address,uint256,bytes,bytes) (runs: 256, μ: 122802, ~: 117413) -SafeTransferLibTest:testFailTransferFromWithReturnsFalse() (gas: 13675) -SafeTransferLibTest:testFailTransferFromWithReturnsFalse(address,address,uint256,bytes) (runs: 256, μ: 14605, ~: 14600) -SafeTransferLibTest:testFailTransferFromWithReturnsTooLittle() (gas: 13556) -SafeTransferLibTest:testFailTransferFromWithReturnsTooLittle(address,address,uint256,bytes) (runs: 256, μ: 14464, ~: 14459) -SafeTransferLibTest:testFailTransferFromWithReturnsTwo(address,address,uint256,bytes) (runs: 256, μ: 14571, ~: 14566) -SafeTransferLibTest:testFailTransferFromWithReverting() (gas: 9757) -SafeTransferLibTest:testFailTransferFromWithReverting(address,address,uint256,bytes) (runs: 256, μ: 10685, ~: 10680) -SafeTransferLibTest:testFailTransferWithGarbage(address,uint256,bytes,bytes) (runs: 256, μ: 90210, ~: 83995) -SafeTransferLibTest:testFailTransferWithReturnsFalse() (gas: 8538) -SafeTransferLibTest:testFailTransferWithReturnsFalse(address,uint256,bytes) (runs: 256, μ: 9457, ~: 9452) -SafeTransferLibTest:testFailTransferWithReturnsTooLittle() (gas: 8544) -SafeTransferLibTest:testFailTransferWithReturnsTooLittle(address,uint256,bytes) (runs: 256, μ: 9397, ~: 9392) -SafeTransferLibTest:testFailTransferWithReturnsTwo(address,uint256,bytes) (runs: 256, μ: 9384, ~: 9379) -SafeTransferLibTest:testFailTransferWithReverting() (gas: 8500) -SafeTransferLibTest:testFailTransferWithReverting(address,uint256,bytes) (runs: 256, μ: 9356, ~: 9351) -SafeTransferLibTest:testTransferETH() (gas: 34592) -SafeTransferLibTest:testTransferETH(address,uint256,bytes) (runs: 256, μ: 35312, ~: 37975) -SafeTransferLibTest:testTransferFromWithGarbage(address,address,uint256,bytes,bytes) (runs: 256, μ: 2915, ~: 2247) -SafeTransferLibTest:testTransferFromWithMissingReturn() (gas: 49196) -SafeTransferLibTest:testTransferFromWithMissingReturn(address,address,uint256,bytes) (runs: 256, μ: 48350, ~: 49599) -SafeTransferLibTest:testTransferFromWithNonContract() (gas: 3047) -SafeTransferLibTest:testTransferFromWithNonContract(address,address,address,uint256,bytes) (runs: 256, μ: 4235, ~: 4240) -SafeTransferLibTest:testTransferFromWithReturnsTooMuch() (gas: 49820) -SafeTransferLibTest:testTransferFromWithReturnsTooMuch(address,address,uint256,bytes) (runs: 256, μ: 48997, ~: 50238) -SafeTransferLibTest:testTransferFromWithStandardERC20() (gas: 47612) -SafeTransferLibTest:testTransferFromWithStandardERC20(address,address,uint256,bytes) (runs: 256, μ: 46782, ~: 48049) -SafeTransferLibTest:testTransferWithGarbage(address,uint256,bytes,bytes) (runs: 256, μ: 2631, ~: 2187) -SafeTransferLibTest:testTransferWithMissingReturn() (gas: 36672) -SafeTransferLibTest:testTransferWithMissingReturn(address,uint256,bytes) (runs: 256, μ: 36007, ~: 37552) -SafeTransferLibTest:testTransferWithNonContract() (gas: 3018) -SafeTransferLibTest:testTransferWithNonContract(address,address,uint256,bytes) (runs: 256, μ: 4192, ~: 4187) -SafeTransferLibTest:testTransferWithReturnsTooMuch() (gas: 37118) -SafeTransferLibTest:testTransferWithReturnsTooMuch(address,uint256,bytes) (runs: 256, μ: 36410, ~: 37955) -SafeTransferLibTest:testTransferWithStandardERC20() (gas: 36702) -SafeTransferLibTest:testTransferWithStandardERC20(address,uint256,bytes) (runs: 256, μ: 36060, ~: 37605) -SignedWadMathTest:testFailWadDivOverflow(int256,int256) (runs: 256, μ: 347, ~: 329) -SignedWadMathTest:testFailWadDivZeroDenominator(int256) (runs: 256, μ: 296, ~: 296) -SignedWadMathTest:testFailWadMulEdgeCase() (gas: 286) -SignedWadMathTest:testFailWadMulEdgeCase2() (gas: 309) -SignedWadMathTest:testFailWadMulOverflow(int256,int256) (runs: 256, μ: 354, ~: 319) -SignedWadMathTest:testWadDiv(uint256,uint256,bool,bool) (runs: 256, μ: 5697, ~: 5714) -SignedWadMathTest:testWadMul(uint256,uint256,bool,bool) (runs: 256, μ: 5745, ~: 5712) -WETHInvariants:invariantTotalSupplyEqualsBalance() (runs: 256, calls: 3840, reverts: 1838) -WETHTest:testDeposit() (gas: 63535) -WETHTest:testDeposit(uint256) (runs: 256, μ: 63337, ~: 65880) -WETHTest:testFallbackDeposit() (gas: 63249) -WETHTest:testFallbackDeposit(uint256) (runs: 256, μ: 63061, ~: 65604) -WETHTest:testPartialWithdraw() (gas: 73281) -WETHTest:testWithdraw() (gas: 54360) -WETHTest:testWithdraw(uint256,uint256) (runs: 256, μ: 75391, ~: 78076) \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/solmate/.gitattributes b/lib/morpho-blue-irm/lib/solmate/.gitattributes deleted file mode 100644 index 7c5f3db..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -.gas-snapshot linguist-language=Julia \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/solmate/.github/pull_request_template.md b/lib/morpho-blue-irm/lib/solmate/.github/pull_request_template.md deleted file mode 100644 index 5cca391..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.github/pull_request_template.md +++ /dev/null @@ -1,13 +0,0 @@ -## Description - -Describe the changes made in your pull request here. - -## Checklist - -Ensure you completed **all of the steps** below before submitting your pull request: - -- [ ] Ran `forge snapshot`? -- [ ] Ran `npm run lint`? -- [ ] Ran `forge test`? - -_Pull requests with an incomplete checklist will be thrown out._ diff --git a/lib/morpho-blue-irm/lib/solmate/.github/workflows/tests.yml b/lib/morpho-blue-irm/lib/solmate/.github/workflows/tests.yml deleted file mode 100644 index 2a29890..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.github/workflows/tests.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Tests - -on: [push, pull_request] - -jobs: - tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dependencies - run: forge install - - - name: Check contract sizes - run: forge build --sizes - - - name: Check gas snapshots - run: forge snapshot --check - - - name: Run tests - run: forge test - env: - # Only fuzz intensely if we're running this action on a push to main or for a PR going into main: - FOUNDRY_PROFILE: ${{ (github.ref == 'refs/heads/main' || github.base_ref == 'main') && 'intense' }} diff --git a/lib/morpho-blue-irm/lib/solmate/.gitignore b/lib/morpho-blue-irm/lib/solmate/.gitignore deleted file mode 100644 index 5dfe93f..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/cache -/node_modules -/out \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/solmate/.gitmodules b/lib/morpho-blue-irm/lib/solmate/.gitmodules deleted file mode 100644 index e124719..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/ds-test"] - path = lib/ds-test - url = https://github.com/dapphub/ds-test diff --git a/lib/morpho-blue-irm/lib/solmate/.prettierignore b/lib/morpho-blue-irm/lib/solmate/.prettierignore deleted file mode 100644 index 7951405..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -lib \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/solmate/.prettierrc b/lib/morpho-blue-irm/lib/solmate/.prettierrc deleted file mode 100644 index 15ae8a7..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.prettierrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "tabWidth": 2, - "printWidth": 100, - - "overrides": [ - { - "files": "*.sol", - "options": { - "tabWidth": 4, - "printWidth": 120 - } - } - ] -} diff --git a/lib/morpho-blue-irm/lib/solmate/.vscode/settings.json b/lib/morpho-blue-irm/lib/solmate/.vscode/settings.json deleted file mode 100644 index f91a167..0000000 --- a/lib/morpho-blue-irm/lib/solmate/.vscode/settings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "solidity.packageDefaultDependenciesContractsDirectory": "src", - "solidity.packageDefaultDependenciesDirectory": "lib", - "solidity.compileUsingRemoteVersion": "v0.8.15", - "search.exclude": { "lib": true }, - "files.associations": { - ".gas-snapshot": "julia" - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/LICENSE b/lib/morpho-blue-irm/lib/solmate/LICENSE deleted file mode 100644 index 29ebfa5..0000000 --- a/lib/morpho-blue-irm/lib/solmate/LICENSE +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. \ No newline at end of file diff --git a/lib/morpho-blue-irm/lib/solmate/README.md b/lib/morpho-blue-irm/lib/solmate/README.md deleted file mode 100644 index 2bc3e3a..0000000 --- a/lib/morpho-blue-irm/lib/solmate/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# solmate - -**Modern**, **opinionated**, and **gas optimized** building blocks for **smart contract development**. - -## Contracts - -```ml -auth -├─ Owned — "Simple single owner authorization" -├─ Auth — "Flexible and updatable auth pattern" -├─ authorities -│ ├─ RolesAuthority — "Role based Authority that supports up to 256 roles" -│ ├─ MultiRolesAuthority — "Flexible and target agnostic role based Authority" -mixins -├─ ERC4626 — "Minimal ERC4626 tokenized Vault implementation" -tokens -├─ WETH — "Minimalist and modern Wrapped Ether implementation" -├─ ERC20 — "Modern and gas efficient ERC20 + EIP-2612 implementation" -├─ ERC721 — "Modern, minimalist, and gas efficient ERC721 implementation" -├─ ERC1155 — "Minimalist and gas efficient standard ERC1155 implementation" -utils -├─ SSTORE2 — "Library for cheaper reads and writes to persistent storage" -├─ CREATE3 — "Deploy to deterministic addresses without an initcode factor" -├─ LibString — "Library for creating string representations of uint values" -├─ SafeCastLib — "Safe unsigned integer casting lib that reverts on overflow" -├─ SignedWadMath — "Signed integer 18 decimal fixed point arithmetic library" -├─ MerkleProofLib — "Efficient merkle tree inclusion proof verification library" -├─ ReentrancyGuard — "Gas optimized reentrancy protection for smart contracts" -├─ FixedPointMathLib — "Arithmetic library with operations for fixed-point numbers" -├─ Bytes32AddressLib — "Library for converting between addresses and bytes32 values" -├─ SafeTransferLib — "Safe ERC20/ETH transfer lib that handles missing return values" -``` - -## Safety - -This is **experimental software** and is provided on an "as is" and "as available" basis. - -While each [major release has been audited](audits), these contracts are **not designed with user safety** in mind: - -- There are implicit invariants these contracts expect to hold. -- **You can easily shoot yourself in the foot if you're not careful.** -- You should thoroughly read each contract you plan to use top to bottom. - -We **do not give any warranties** and **will not be liable for any loss** incurred through any use of this codebase. - -## Installation - -To install with [**Foundry**](https://github.com/gakonst/foundry): - -```sh -forge install transmissions11/solmate -``` - -To install with [**Hardhat**](https://github.com/nomiclabs/hardhat) or [**Truffle**](https://github.com/trufflesuite/truffle): - -```sh -npm install solmate -``` - -## Acknowledgements - -These contracts were inspired by or directly modified from many sources, primarily: - -- [Gnosis](https://github.com/gnosis/gp-v2-contracts) -- [Uniswap](https://github.com/Uniswap/uniswap-lib) -- [Dappsys](https://github.com/dapphub/dappsys) -- [Dappsys V2](https://github.com/dapp-org/dappsys-v2) -- [0xSequence](https://github.com/0xSequence) -- [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) diff --git a/lib/morpho-blue-irm/lib/solmate/audits/v6-Fixed-Point-Solutions.pdf b/lib/morpho-blue-irm/lib/solmate/audits/v6-Fixed-Point-Solutions.pdf deleted file mode 100644 index 5c4243425bf4fdaef1dcd87eceb2365ba97bd6f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170456 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 ?uKH_LBG3w}|gz7C!T-OPS2=2wL82qXf;9 z-OHdUsT98T^w0O!Maa4)<%kF3f@jRi<9;^m%d)FsPf}g0U}uK)C@Z?rBgui3^IdJh76YQ@3#G`FDpUYl+;u)Kr?wF{~nb?4r9<&Ngvu8(~?}IUILEe0!H2 z8kz*OIm2hFFbp~w~r&JcPbEv8z01k)7qp*}*d}WOA(F{rT zvooBeNfEhLEiFMco!lSG#zv^{7VUcW?xoCngTM66wDO#xhvG6=`JO7AEBd6K&2RIo)@cV=2(#P;=EhEsU`(gsNBAPpB7LqRZmmc@)vMNj z%x&WkwwaE+E8E!5%4b`U>Z?KKA>X?BY4~DSkgI-s_yU zRqfQGzy_sU+27g~RS^P{p_x8m_;&2$fP?0jXWLRT&+qa@lp@Fbk7uDweL-KbFJW*& z$?C@j&&xi^WQwGxc=w`V{utT@+t{VqPK6Q$%*BJFEGUG`3s{GJY$4k=C5+sMIFPvR z8Gz3@ZhNmR9ueb0TO(KCJ^w=Vby`kv+s~O)7d!YHOi4TXn=%Z0EnP~78%tz#e$a@4 zD#{8@6HbYcX^c&v2mH_ z`rlJ$iDDTW{v?%(mW#r}-IR^RSKgp$16FIARxIZQVRAJ~#jAQGz&#IhAw2h9I}$tP zz3jKVpYaSfQeo1ViK%+Q=%3|SIgLvrPXSrxgQN1g`g&yRY2B?aX&q>$Mo`&(OhF}E zZQnw$oP&TYxcs#mIz?vGuO$n{MKMLk|nNfLBSlj^|p+ghz0KgN2P z5a_|L1kGC67uXA7pJ`<22|Vo0zoz_C`gx|N! z_JJhR0W1ZfvcH;K@i0;vNA_E2KVje>zrEDhg`BeJ1OGqj-a4$Rb#415r5gkU>F%5~ z0@A5;cPibjAl)6(-JQ}6lF}t1-7P8b4c6Z8R@eTX{qDV8@3GeN&p14Qsm^;|;~qEH z?>f)(Wv9g#a*GdgYpP-)Cu?nO0TLy0yUCbNR?q)v8%ly3; z?M{kp)|n7BPpg&%1$Sd-YI>Z-sO;BdpPrRSpvlY0WqrcEa3Mb1(!}Tu_sA`Y$i>Sm z!2Z-3(HU#nFyDJ_ly!g-ZP=kyvv8y136_l&H3r&9g?`Pwfub?Pc?&VrpkorJI@AT4 zM|$+!rVMp2;1Ir2WEYLL5ghG;HJrZj-cGRxbDULUKuDI)ruMOH1qnmWAg(kBTC3Z)H%0#^g@s44W6Q6`eDC zf=v{Elx#GFqQ<-E3VBwYsx@pwwApDx+!OAVKc11fte+WUihPr2nf|4!;9iFs#v?)V znJc_ca}ABKNlMI-r((B{D$TT~=E$l+CN*QDo0@ENwB5}WJGEAir>its?^n6*PU&v$ z=u$ryS82BO$u5S@iP6|E4L5}2ibYGlQ3CW@F zD{nqNtE)B9#hWjgkM#d}(u3^}A)_EbWXA7G;2C83-WJOu&@GA1<`}kJ!im z?cM)64gF4lfR;Z%fY_M-E;Icb7G?zq5C|Ar_*41E-~H|pq10v%G5(MJOge`h6rosNDl4HjVJ z3D6jFJ_H2(A2|4+!eruL`f~>-{zYZ{4weEVTz^1i0LpI$P9Sjw5HtRxGJxHZ0m#T; z`*V5uf3On2PD_8NjEA`}KveldVX!=mg>eA3kAKxY1E8EgKSO>Uo<0l`0Q{5#khucG zMZhc#Co3>m0AwRPOjiN-&HtLE_%~rH@UZ0g+4oW{Y^@&cc0^$fdhkmNn4eea&cRi! z7DqWBB+da!_#sL{zl@@!+=>Eo>~=*13_DUmmoA+l9inJ{*5I4_^po(2vtz4g$oKpK z%d&E1_ai8i6*o8WY2ll1zMb!W$x9nLp1#L#xOjP$6*Wxw=B5`&2}nB>g>ATD3@6T1 z=)Dso*gKGTRv4#j`a0*M0Vlcr*;HQER0q{Q5l)Wuok~D|avM3uV8yptL43YFFIP(W z5D7nC{V|ePCWZtP!CNVy$KI37j;E4=!t!dAnQRhHS!&ewQ550%-quy7bG+oSE3xz^ z{g1i2L_`W?{DWmX#7&Az+SWU$_Z>Lnp7HRCqPSUG5&EaKY#wJFaodE%1AY?jY0VvjWPT4{%};qW;VABG{zcd9!2oX!?@F zF9>B2d3$-i2Bva@_8DmhQ(LCu3~(*LgVvMq@M2keux>(Xbqf&T)WUq1h=x(%=#&b{ ztryWL6fNZ!9vNr4`E7I;`ozK&cbW)efhDTVId*$rb}+^UD@xm$o0`Oh^i3u4v66gd z?eN1?Vk%IPb4gQyqUU)U}(V>n`iuFs+7a6e^N58rj)Y2A?u9 z&RY@=7yR}(m3I;YI6``of>AjBQ#{%NmY(3D1^Hx`5QiWf?x-{@Udo8Z;SK~f zXhB^9hC@?Qs7N~GBk@=2qBV)BC3T)pT2COEK7m<-Lawn7mmyJ7TO;418H0cGgcup+ zMf(i9?7eA?&m_n8hVu^FG8L8~o6;5eF>Eqr2f}D?gl$v=5rkJKAyJ>WZ6uUeq7Wh- z7xD)dqD{2kPh);=SxKx8-sm59aB6GqBd{PW;Ol9hw}#eIm!G$s^!1x+7KBHH^;8LI z3RU?UOYvw?McTYM#So402D~THKq*LP=5Q|aW04IanWDKv5C{~oKH9~w;F?ZFk&IOz zG%$0H<}PuHnlq2_8B(*+Ui#57*fg<-B9p2cN|`6BXek}+%OB+tbkWDWIE(MDKJ~>#H77<2cy*rjf zjrM&ScyV9~ygtKNmTj@xrt|PgM6LbSx~($rqV&Bj{Gr=jdbV5S3W{ zr=O1#4^Bu=Uddg=%>ZKSVp=`?P!ozuH0P7_*_CA@9(IZ)Rl$ySDK@Q3Xzjyl=gzmQ ztPaq%nx=7OOmjqti&Gh$xxA1?AhATr%2v6mELlwW&KyZ}zx3B+86g4b>DcfaNUF>@ zuw8F;6;XN1^j|z37WZm`gnhT4uKPU2#Dw>S2>IB010Gb_>zD@2hZ>0-uVD6xxmu zO=L`iOXp|q@uG*Vx2`~%Vd@_psjlqa?0b0&V;kzG0ILqU(i%(wRFbVQn_aNK66(=QyI>D{5SoDNB zj~h}}Di^H_vE<|b)I=h5(~9+C17rVkl_Ot1y=3};&Km^7l%s3@e#B9=?{(S{hYCKt z(0pM0c3iJ{8u|{m4&HWn?@c3nm^Sn>76lZcQ~pc3H247a&iCPn;G$&}ZKzYlOza4o zx*TAMf>gd(eq7=eXH`fGiZ8~OohUJH%*4x55+_6I3UiY66I%^sxcR3HABB)##0fU~ z^!X`Ijp16msJyvWR?s;T3U+QNd6QF#$@~oYrB;D^&6Cs0=nPd@oxC(1%+bq>Ruu#s2TveUUvn53cQJ^h@ERyEw~%1&RgAMpeY`^XR% zIFoB~W7~WXIGwIRt0Ix?cC;<}7P;P`F|JeDllJ+5V(CpLqhI|9-K5higIEY4y&?jrev=_4ajofQ)h zkzVDqRGMQAM#kYS+GDunS0{Hw_U7{`u178|O-bS~PEQ_*EZ0I$;-dSrCFCh+Gwug1~Did@qj+X@cUf&Fld|`1;e8Fp6AM0#`|<9nPge!8E5% z0v#VSJftAXlR!GRJGfPxZ)jv4Pf}byWy+NiJ9h;RZ=$jvg&JMkBfNYU7C+qU|8{mQ z^hJur6pIMVD?dLo7TPi0R*;?l7NA6kgv5v(wp$7J1BpZTI#H-LLa^d5)TC&k62lUf zAcRwu=QK+7D$}So9cDf%>8m&46%gW$+s#KobojDWS`mPSyZ zm)MW%4H&N_FJsZ|1_lQ3Cl;isJuk8IS~zxxfxZs;V0nD8P6^XC!0r65&^9;ZU0al= zkxiE#;Gy>noC=w$44zQ8Uh-tv)@u62I=Bfuc4?at1FAgcx7$_*P#tE8gP^7Wnn+b# z;e=K{6{A?(mXIMf3f$4>hEk&H*J}FKWfLHSCB8=aBnOGLW)>@z{Xxf5B;Atq6ldB- zO$9-tR2CNlSq3Y7*RscTD#7zb-IG3b7q4vGYB(*wHLHLArd_KNtnq$3SUDI{S-!kO znDn+sWbrZ-mxj4k^K($4wYY*_PMa(|PsEGOc0*1dLY=~}G9xh3h%@sq*}CgogA{X7 zZm+=kFsYR70+T?-@lttl7wYA8kdWhzbyZChPF5xtj*dTG6s&q3wx`-Zlq5OrEe;>- z1DCUG-Qxr|s^&m4h~es)YqL?cK)4sz#olE+vfy)zEF8nT`{mm9*xm-a=^As}K4h+VpQ%i)#Wgf-#HIQYxoeNbP=hI*yErF00 z{=qo;&1PnTT}Q0da#^26yr!U5k@XJxQu9vk&TsqY{g#qF2(Ocmv0~*4gWmET%n{KS zG6g_k(P)ik=pl8g?5}iJMU*9YtrIYL1P86kML3ml+L)AHLrT$K@=lxYo7)B_Oq%ef z9IsCp2fYcF26v89M=jCUUFC(@x69^P{S7#n zJ9KWKlOSCCeM71C1+X=nVtJ7ziH4B5L#?3`qCQAZY2=3FRa(a_A7q5rBg6{mwY>Re zR=N0`Xr(qEwk%`p^+X%aR-5j*EaY8gV@)J1Zdh)^yGQYqkuBAXP##?qp@FZ^7MGj! zoPv0HUH5gbR#E&3Cgsc3@O{df2jWG#C1H$?M>SkzTt;XxP*0G}p6c=*lk3a|fcaRP zRknB49&xh-5EO?M2l9Isdbt*Per3xWxWh5J$($w8UR2eKilf(f+=Sb9DX4KHxWKj; zX))9Ae&pL`tYl*&5)zNn%2|w~gFE3`mx>5`EiAc`OOJzC2F^4!ED#y`VPKj z_-LY&$2riamgLD3W%}`Q4paHwBteB@W2acbo zv+nRq4jHoFgv>++-fT22wLu7?rCy47a46wAgq}oSw!0@EphBF_hQZx>1J{Fgzv;Ek!0XMh_rn6{1VFG4JLl{bwaf)Lk<|l(9S-;&v>m zxBUF1BASSot(DP+;Bn2$i{@>GYdn?n2jM_r8HUfJpH8Z(saslOs78^jroi^p2R(jQ zKa8+)L@9qG%0pkQGR|K!Vz{2;&DwRlcTA}ohDvdelFGCK3)PZLp}I7PI`z>@Dp*^P z9!<00jPeqSx-$LDt0Jb_nt07-E;eGNZVIc(C2+D*m4@a?>J4dWLpjUdtnVnTm5^+cIX&i`K*6s z2K$ite4022GQPh= zJZU9+VN~_cFoONpVFWWX&~XJli1COxfUf*+-e5#*AV9bUe1`}K;QbF;DTY=Cb`Nc0 zGea|b7jr#Jli$qFj4T-)fd&mQ?9OOrX>Vj}sRx9inCrP%IoRu%S?X9ASy;j19RA zxVS(DMn-@Yo1T#Y2yl<%WaTnu2N?jqdPaIb57vYJNVotbc|Nqyfnc5Q9b|T(W5xmk zki&oQk^aAu68{v2!~V0p1oVeM1$F?hFoC!L$OL2_Gcd8TvOmB!AYK~aO@FTD?C-7P zALD?2zXHDw6Ta6z8xz2k0I>}hU<1enD9xBSSOHNnaMyGEu|4$Pt4jbQO^|^htAQ~G zr!gBVVA#q80{qeD_hvaOz?A^uN*z@--@_{V@T1>9L!Upj_Ey>TOzkpZ3A5k8_ zvk*{wJ;*ZuQ63Lm36N#7|GD!Bf7>ko&9(R=)%y>8>7N9e0AKp^1)BeINw}DQVr_tz z$RAN2z;lxe1o#&GSRQP^=E@9Ux4*z?;(sWQ->n75ub(J?*gb#;2^-)=4p?>k1JOU2 z>oNhxKn8dRKwhw;=O8;-J#Sh2Meu~@*07|0+LSlXn$hUr+pg#fIG4cyYAFHxfQAOycf4BbO!G-xcyONq%Bu=BCj zI)azQn^y#N>o2I%y?X6EkdK<}TQ9xi$ECEuO&9?G?T z+d&3otp(d76a*p2$49-bsh)1vyF;)a38ZQIuXV##i|_}(T#G$D&CPk{%tEufx>b8e z-xY({Q87oOl}SzC-yovqBpNE1SX?4iGx>Pk-g=QxT9NC~E^pXDwL*6cNs8|UjmExE z>2sG7^U+dd(A{m2M(VYl z@*+3S*CgiToz&y@_l;CWH3jby@U51wu3H&Ym%im@VrvagjjYCm6~B3O_HBPVzU*t3 zvEc5r?IR$m&n}jtKQ9VM5#7%U1AZ>S+ZAy13Dn|wp!u8o1x7-4+ol6<^=6dUp6 z{yJVFmlVmpG=|h>;I^oMPj!0d=nH|M(-41BT-yDkK;7}6v1_7Azg+rt^82qdFI7kY zy=tRl(+ij(oSMXZlY~GhssPbt6osmBE`_@jxh-;{y+u2a?X)txs=D;{@o;QZK zrmyQRi$^k?D*AFuq9X8O)eurzTtKQfGeBuIXm0h2?bw){*?88ecf^X4e5%%S<(V#7tln0lH2jBP()L})zX;xVyr zQHa#@*Ma6<$-U#KRb(tUi5#?kLQ|w!!Fo{4B5_plDjko_0xBQnwPR94;Un=ds~kgN zZ#Nsgx2>5=GCtQYZFPD(uDsFixPd3@rKvr(DTEPZQO9;Ch%%bmF2F_-65t4%L5UED zie#=$N`l|Ks4rxbwN;XanQ4ka-eOJf--OIdr@y zq{Y=f?FhB#YAbqdFkc_3JLy|c)M8Q?@;w3JC`J}>$$ty3ePKn0o}qs#O<)uSW8XEt zoRHwmJUooGCz==gF+;tvu93NTDfFPaU$iKqS;o`L-+p5?GR)Cwf!h@u9*G;#0X3wk z>3z&|iJ}H=hht;7x5w&hkQ!iS#vLXZR@EKS*j8`%FWrR}E1{C$PAqNob!}_JXLf2Jr#i!I(UpbCLyhXek!fe6+|U+YHZH@ zDSW`6*gd|k?pu#j0T&RF^qMqb$oild7~YddLq z!bzg<`{F5XxQ<#Z?>E z{v$f|$yUH@cWg46v&jDoC8&;N!3}#%U?8>~6#gj{&haf{{!<%=NNWeEn?Vf&z7-cH zZIjBzeoG(_>k!bUU{g}PR5LJm;v)r3nlc$=7}UZikl#qG0%eI5l~_S@p?$061S0i@ z*EW%vDD-}%>w?J7rNL~FhWbJKv31I}PsnE%LJBO0FsXtWqXv=k^9-ueYLv2<~lP88ERr~8{4L@G9)}k<$gXk?yhZkz69!5itkzwSq zjxDWt5*w0|FjWGXmMm_zY`5PWWjCX?_5R>% ze}W9DH>}6lGI2{J#FHFPs{0x1 zsWYz$)U{}#5Lm=sLR7;Q%@v|HOcSt|Qut!^tk&y!VV4%Xxju6WZMI&4m67D+*n?v{ z)QI3u>1@!!XrZa)w*+j(8b34Vsaov6?wySV^>e(}WUP2PEVw|7$=~UGTSWT)b8PS? ztH7%bSjck$hJJGFZ*ir1B=Q3zlcN?IXlQMu*Zw@NYDK16gI7w!TY&Dw=JL6`WZghS zB!yH-J?YoCn$+4zF(mfISGfoS+hSDE3}}G6C~@l=Q48f|8+#fC%J5^OLRB?Xw{HN9 zKs)Kh&bEWwTLmsa>G?DX_}h zwd#}6;!2m{7VZIl9lDzlU2Q{xub|5D(|j!I_IT;W0kvgk+rb=Uf29u@@vrl;lo&wS z=5uJR$%0Cc#>}iy+&&#>FJGil_9oWQ6>ao^wxMTvR}9bUYAE{ZqbX4(IS5zDl-29C z);XZJ7nd3bi*Bt8RXlZ2kVcI*hlV-OyXlW$Rr2we<;*D|l*R3iO9rr1($_adobf4p zB`x&=24;|X!h)}Da4$MTD{84 z@W#?1dz0n|ZOQ$?SlvcXvq=ebcG*4sS=l-GnIDN7S}N)d*$HP`3Qzg2*vZfB%ngk}dmNg$W@ot;$_2YbIj#hZ!(J5Ex*lfwoJQ1Jw+&~vByrj7ZiIDO zcr=M%T-}!$M(j?SP&pMuw*sCuX)dTA+ymX4^2Wfks@IC6^7T5F3%ko9%b3s%>0m@M z-#)gy2Jy|v4o~jm?ba?HwY0L)P`4bmcHE#Q$=a^hWxfiZk#!EQh!^|ZC1$>z`Bkf8 z1G?!dL&)(W1;f4yr8^dBR2)@>26H!rT;3>wAEa1fDp?^>(IulJuP$oN*_6Wwa%uqkld-kXSi`(UEoR_X>e@> z{vw~6`gNyvpE;x9`Fl9*XGX-VP2gTnRqZ4-M-ar`f0$*$hkLE4w@z2RWKG3f``HVt ztsIiDwvEx+dxgWLYnP_9p+`qI)vJjnF^1?Hcq&Kx&@*IkxKM_sYS)*@V?xFsCN?k^ zQhW!m!}C4favR4hgl;#0Qp6UUXbKV%3R*&2F_{}m80_d**|x5P`AkyAUtVNg8fCeM zOwGEGTq%<-#EGCkmP^Vf^fRg}f0b-?x&))t8izT$6DwZT1*O?oqH<-X#>|pT;(3hQ z7vQj}tZQULN0$n6DV_F6vMzHzi&o@4d0A9A@>%=XR4My(Rf+ecAdJv^;bc3#d1cgF z;R|pDzV#B{z0A3qGuEKYnQbHW04qGMbAgs%NazlimVliYeV+TdTQ@1{K$*_*7QGzd zXS3&sDbr$#Sk@Yaa+SyB!sumty@h8!DEiWXMv^Died-G_0lIecEMKw`VmMSueY}s*FPM&m+p6PY;NPg8hH{ksmLv#r`q+2GW<6 zfBzpj;k-E{#m%D^n<-b%IIKLhwP)aMgo9mgZ3fNhOorOAkkshECDzq5loxdnzQjT&e5Tr+uv5C( zAdIl{XrE?7s|Y8l>ZDfxZc%A4t{)vVT5TP!9osJ#j&{JB7zXjBCBJ;PvNOHTy>TV= zwVgpxV$ey3P0~_(!Cq-m#9d^U5n zP&En*7mx4hSjFh~6%&kr_7#>*4}aH-Z*Y{`5i*7U#;9Qks>-r?TsEqmx6-))zu2LeNCvdO zS2hGzsZ#90?we8r0;MON(8?4Yf*`lF1$mf#70e7Hn{%w^rJ2^(_0-{~uY?avWU;ax zC`Ba~jKOA$B#BM3Rl|(*t#G$L13%-$%M-E|YI)hhG4z_%YfqaVLyq+_-vW0pzBW;} zAETyhy!btRE>nW>yfjhcRmO_hbpzoJY~8qd5?n6td}fNV;#}_54rjBOc9I;?J<7_9 zo4J2RiX6Y*fd7sjejtkM00QI!eslg0k>dZ2Km8s$Fadze(1_WX704U{vFic!jai?G zjf=|&#AV3E#=&gB%*AEM{5$f-@#`)2?~NfK`G|pwlL?qh|K1p42LY|-2jj=TK(Fj4 z^2YMBx{Kr2`|AK}czEA{wCy2n>N|O32O7)(`~1tVz^}K{e<%eOR=~uK^TE#dA3ef{ za6uql4)j;6gx?WJz@hRFXbiG5aRIdLw=A{qmGB^a^KmP#Z9=@k1dzXdu}D$G^W^C2;;k5IBFmYYyxQY=E;h3lJ*_@W+2t0^5V# zITt6}Ux7dVv@5dzZUuh5N&fwj$Oe4ufB`iyjPL`E2ehxuK)&K1xjFv+!T4X%cwl(q zSMPz}*z*HD;`}L3^*1yRsDJ+osN|>5p84k|BImD9Vmzz>2XL?drso9EG6N?I;DZeC z_`iyp^T$o__iz8#PlFF{|F<~|CN5wb06n<>KFs7i%wYh>f&cQ}XL7bPvT-o7G%#Yc zv$MCdHDY1>?HOR9X9rA}0Uq#{_O^Nk_I8XveYPw=o1An0`myi(ea-xUNZElSCNNyX z#>xOh6|(~_t`Cg#k3RPN{?0ZwU^3+3&}U|0Ghkt2;^Ja80OooOS&f0IJ{G|69*{$_ zau^#j|2%BQ`NK)?U&1cnyz)EPWeErm{SI#)ayQo>ayNTYkF_a}@yKSOfy^qW=n0e9B>m{2*&!jHSFU&G_p%8mNuCuHO)Q>Cwx zP?%rku9{<{j2~ot_D!G9uzhT6B5kh7He8!Ldrs&y;rlK<1axdFZBTP;1TV}*xvRU+!rv(O zU$^4x+ihvn5Ku(Rp$x23Ay!=t?jZ-Vl+l1I#F8|q!4+r^_MtkNrZyT>SpMK-5@n7`FkH(|YUi}u&W%5O7Hq4Gnu&b%+ z6JKcH0+(-3qpm{JLbeu`5h90~0!56$Q~_mzoL8^4#4fr!^i$iK=T4_bGHCABMlBpc zX_wh{*Q;{UV%;3Fxbe@|Bao0bBBV{uqu^$$grqK46~buhccHAyhhcMFwYgz%Eo`U4 z&Qol}>JCFFH_{GGH8d8wR`iE6OyFSp&lPWH57e@HUPH~`8FJ$p)>j1UJI`|EoOClu znkS4;qPpeG>Q_=U>WYrp%cv0yXS0Exq!cSTR-a3enGS?yX5sGconxFL0@LKo%*u8A ztWek(I!CGmJq=r`JSv%|S11e(t?OBJ2BXEMOqf|R*`jNxo4&%TZCXskiRC?TRc(rg zx=jk?`)VYsr^8R*XLd$8%I;1pr+SAJ8D|&!TC?je_2!Y=eYM$B8;+)Fta(8`RqwJ> zlY__;;!GF)Hk#oAXTC`USpu+Q#CRpfP)yE%I4Wv@Q~F6gfXZo#_@iODu>F*Ztn~id znv#IC3O8FpUz*c`=`Ww~yC{0&$S3=fo%J*j3&jhwwa@v^yD5NSWS51rT2n|>G$&1x z#Fh5UqRg}mg5A*SXI!{Ef||ivEO0DEa*yh`7q%y#W})q``Qkx@*IDxOiq0LHAIYX#_3zKm)_2hU2kni13_M zW-Y9Mm=!Ha%!iC}HNKT`Zn8z+FXNA_=IR$_s={abmTv-_-ID_~wOB@8!l?14A+|)U zMR2B0^U9{#4agKlt#&00+>xkSDZq1N>?uly50?d=prc$M)o)}WPRbqc!-S9%^tD_L zLQ{qun8{{rQHVXYw_e|l@f)tMiFD-TWk}}wl!60K?!6h{9FrH=<7hHV6~&`MRUdGB zE5aL>seA>$r?bo>Zy-Z|^qij8 zGH)PbR5;e01jTcxcMs;lY7ASF;#Jk&KNIX&DGuOwVt^dK)=p z#a?Sq4x43BK4KnK8joO}OY8l7`BG&B&&APzi2K`jJXfT@Y!5%7!mzNfH5=HBrO;0& zV@U0e*QH%l(SLf-xfDh|31#qH(u%RGCQqd!H%#H_3~Q;4`-i$~+{Cv%(a_rl+JU<# zAKPDuYw|_zbSo9$u<7PAqNL7h@k()Rnt>B?q90OAb>tg;U0{?iI??$A^OA-4BF3#l zyeqc(PTt>T`kCr39^rFU>ls1vkz^+f4%()+!KW1hI&{o56Y=lBi}~B%FF!Yr*xNV? zfm=q~SVV3r(}^h~5ONWqtZQ8KuU{0@<0hd0Tx3!?%r;8RN~7fb+_pMhQLiFcfLa`j z=vlRXod{W~Z^IJmoDX!s-Z4bfVP=A!WISZ5`pACo!1EX^aF}`eYt|F?6F#fZyc^|@ zT?JPL4dBPu)n?`9JIG?a!t(IJmQNS0AwCu}*UO2xF6(3aM!sWAXmF;2dPMB?X+#QT zVVwrLACj`>?K`Z(A_)9C7W)`jQTM zlFg2}A{pr}z0ya-`L(lP5PCL(bc1WFIkHe2d%Ue#SbGba^-ykYA+OOb!3$E+G@^Po z!BF$yHitljI8tlkTb{S-K3&z1GR>aj6e~3?4>G`7*AeM5^yh>yy|m-h^lhq}Qc1FQ zGGk|cJiIH5BE*8!>cWdZDG*OSmoPN|)--??E5fPUuQEs)HFgzD4_5Hl%Mhu)e8O%M zud7`DwiK+(R;LTz*rI}Nk2ztB+hp+M@M;wvI{Gp5kGhqx-xvnJVID5wvS?FJR z7oNYzUH){as?HNPH4>Ji zd+d~MLmxk10v8XR+UexMp|j|zWICNWRwKgk$S_7?1<=)~wW?e9M{OJ1M9jOpOgAFs z#T`-HebJh2;Hx~ws!7VpWLUu;vH`ce_0*N=j&BkByWY1pFEPWUp5K*55Lom>4vXVN^ZY!Pg{NA9)~$7Aiz0jVW@*k^H#Db=Wg+6U~LI>fGa zEyu*Nw*;+Uxu7kC%jq4__Is^7U%pDPf7qAz** zC<3le${-t>EMNXp=K`J-;k<>yw%EH*dmM4kc0+UO(=|1rwwc+4BrKFE8~6GxU((%r zF@p%tGBXS;b{lp0N~sbw$mYG|a_nHx=@&o2(+YKCxu1mM<@u1seKwgO1VZ`zO1U3R z<2p=~Z*d!_#%1^>XVFI=qgb*QqCASn9bmj)bHHD$o`D^vYqS2K(Tf&C|Ay5?Dg;{i zVmaP_#okzkkGHhgN*8M$94a6~q)TJj@dadkdlgG9&ler$7|teC%E^;=F))UGNsHw3 zmc=XL?_RpTzix{j^Av-d^e3i91$UJ@@v_FKAD@+eir+fzri;}^*NIWckHfj|#S6>* z_A!}g)R}0oxd5UuSa_)?kzu4>#2&>COfMfT<2;m<5KWku)3m2&p)F200>q+Xd6t5K zZLP)~%^HvRTib6>k3Ht);1SM1`Pn0$ytm48ul0!IA!9!hGVrc>bR=oNp=-cgettwQ z;picIw8-=v2QZ7R6nC)F1=pd43m07@CZM(poNcA{boRov2;3zP^PXW55G14yF9~rV zno+c!QDeOeN!K_em|=m|Ke*eDr0t0riI?J$o<<(8>9n_i9``-$DHnoR8YBt95;FRd zlZUez$e77QKylYqKJodO?jT|%n%NP@G2pn+Mc&q$4GIf`Htvv&`esFqIQhwNVJ34E zTBbhJi~w$1aA76Yqxxhqaj%9-MvbCCE9f0~L5|s;*GF2w@tCqNbP!I9G?nnrzimOAEC`p2>d2@`G8}Qcx_GX4cc#!_N%3Bmy?cO$T4u6xb*?#^ZvN2M$z#3QiXy7zn>dpt zR{TpCmGevuh8trN>U;Jh6^4@0VLXokqa|sw-K7S4!*PyTC=(f+N*4=?_a{qwE=CHQ z+5LWQ1I9~;WH2*_ud#zK+Fu>QZ$CaduT;M_CTfOQEZD52LokrKbfd0g17 zAA}H|*Nr~hl%!Y(#2ZE*(GDee!*wHJa~KYqnS69$jVK<0n=Yt^mEY|!-VN16cIZsp zxCfVy7)ShP`~%1WezoKCz3U13TbkdG1NMIp^JDpQ^%uX{yggj3Y|ZS=jO-ZYt$++X z!M}gOBkTXZCE@z@ z*6M0UWyih-!JTgk%Onl71`~K%l__Bpd#@5|#gI zO@6(b{6o1s_(gKC0`0aR$^~#w^~7& zK!fzFo5%MXh3z4!^`}%qK;;Bzg;}}&H=Iv?20TCp@2@TlaF?(GTL(J_Cm_%NzN@kU zTL%juApI}#mAsy<8U1rTYcqR2b4I{0!9vg8=x+e)KX)sB*gyW|G4^+B^6SUg@5KVl zu>i_?7Jz4de+aVzTM3AhnfZUg4#M{H37?ti*Uz&L^#W*V**MuB>`4D{#%JYVV_;@w z`;%jz|E)*OKP}3ypJZ8pnJ2)smJ4w41%N0!8#6Hc0K}hi0-g+jWh)1e49&#$NA51a z-&OTk4FRR5k+Fe3s~(3T;Ja>M%%sl_*w_ zTyxOI*tT?%BqE;K!gG7<_cxTCZ}e+#-nh@-I^|_Pt4+Nh2sK{1y{Xf=$h*HbOk}Q-Amjg1@x#Y5X~63;X(gQcI6PoCWPxOl`Tk=n6FZu3(x(t#zFc` z?|vvLRyDg{V@)Ax5j~l7cC6g!({1CRYQnpHak(dD6Yo?g%%mc329(Kn10@pE<&WaT zyaTwg70*XCs9B>`Mx7S|)sbn|B8KQ$KRQ3g)czURNW# zsI!>xRw3ht@?h!Bd}2{GEw&v?*pp!|824R|Xisx;>*2c#y2)9*^$InVLq#G83MaTfVBY)8P$^k@`})^-*XV~%p0Nm&i#`7-Y-IdOOl z@?y8A3$~ofsOixoWtRlNGZcx}r*RKS28x~(UAvD)9OBekt3;L}z|e**+v*2;kMN@Nij)B1bofbEBMS3s76$jx#7Yluw@R-HU)^g|SO1 zU%}u(g<%XKl%T+^laUHSLHO$k#6+%SS;7xN-2DY!I#Gq?p#SFmk9Y2Db$%UO&x7B|w=8vk4E zt2H^R@MR zDSM2PR5bnYXZoQojM%&r| zuV3~uv->)AVgK+0z^lpMO=vc=s}y{2rG4A_!S!{_8%Y($D9Jckr?mHZDhOR1a%C>A zY2I>6iFy8t`+5?-IoVW|_V)TXR|i8O1LD4Mm4-{fJ@dl zR&G~ijaV5|O4p&0*Phy^r~ES`c6=638-^|CjqaAHNb8k5jD3!rL^_P8kodM{50xe` z%}?s~bgV}yxT59cTBX&YrHFG@_6D|bu0xdMCB)(~ck|&WS~K}5MuNIS+@bLxuY0ZW zq-xM!^$X8mS$BV{od?r!xYQlyI1T)8K`Xa4GtmOA6{3{P?tkTZyKVVrJU zB!Xg-@rwf-rXCF?jhbeF-n|nl#KyqxB)~b=vaj=VcusRA&&dMa8|F-bqH0kiu z2DKG2)fM(&snljY<#rdXs-3z@f_Dm-)L4qi?QYT;}mk_=9$|SI?D7pb;So^K{vnuY@qjCQje^@(qLO#!={Ky9F8t>WwZ^4U$!Q&fF&~pW_$e>GgvA8SHGI z(){-X`f&)3;86y@fU|Iev=(EEdCp$Kl=pMqj=aycRx3)#7gwND-+Cz{TZ>#=^5_i@ z7RW3)H9dD6wKJ5yPSj|#VgB{)CkQtzGj;ALXJk;LwFs6yI&CUXSyq*qtyKYSzeKiK zhk6fm*L6qNYm?@Mgcg02WkD-%=r9Z;q!|VuF|=9t?df?DM?2{Dby9W`pN7F! z>GQfW*}Y(CRDgkYOzCIF11(@1MF~+_uz_ZHd3RkrOl^m34kUc!*xXOB_(qZWj_d0< zE`30Qn+Wa@y?$cL3*N2-$_%CJ&r)Lh_DjI__yw)2&>P~C?=qijzrp#)RO!!Om>QF= zd$1y}y~|&gmfxvHY;_D_r8i@+qLWF^C&hORk+3C!4p-)w$@hZvBL7ASN+WDnVNkA}7je4dk5FQ2yOY=5WaCWa{3}rK}TPTfrd@e6xTRRt6U0DFhTF-kSitv_(@1zl zQ7SZaKsD_8&!qJ%z?9u}OMb2%2R}Qdx#7!z;*J3e=n3}>N5A-Vco;2&UBdD)c5OeP zij#xtC9GaoA-WTJ=_)aD+45EUExgmEpL;5n2AHl~Iq&C#O!Mw+XB#k#jhw7(399Jw zJe0vqf1)dc;Qc-+{K6VWiEy2leQ#6+mS8K7ZU5^YBcMIw8YY6{eY2@|AQ(GxC# zQDMD!)3@0E11d+?ccz0PzamCclu?j1l+r$|C-76R9cj(K`~^-x!*j z%^s2Gb3bW4xDBl9bMq$|wNqt%+3o9Ks3M5R=XZc?_;8;bzltIC}bN%N}zsW zK8d0xO3oVgd~Nb-k}wS{n>)c{I`g)i3PpE(au^HL4*}rtkJMp~{P34MlzKbf88evp zUq*TH3ZaN-X@?xZT`-G|MtNm)?x2IwtPxoT2;DMi+xWu1L?|l`wnk{Qh!2ju;jiLT z`RoKwWNR~B2tT?JL^K3RUDmjZKRP8WU%yk{WXh?0Yghm|C z^4~)AT{-j4OIlidu9``>?}*ed4K>&3hlZ)vhYActAkM(FWl)|v>r(hMD@TJ@GdCSx zvjmv#H&&`0jBD7dg@ z>9i@3hpki>;!o~u;!g@Y;OA4TZHHs2f{pN(D@hLR5=0Tr!5pfxPGTH5DKTbB-&$XA zjULY()khmCZJ*MU1oksKBf6p|r0{c2^9&a|*EFBoGnn$_jMA=|scgO)XDy>kk+H!> zjOmj_?>Q(yBx$9C*bhI`_xW7^rYEZ)$Y~^Pxp}~m{5fcgGj z$k%jz;*Ng4pjTX_E92nKM$g?v9%(&px5H?>(8tEp!a-k3LX{K3H&hFt3n38_M0gSA?i}gYrSaB8Tn=~HFV&<HIEo2Hr834w;=-13|@Se0dN~ zXRM2sve=*5<4F3u#Z}Wwsr<^`Pm45T3(%m=GJQLbpV3!jGqBAEhrB#tfwrBms<|FQ z!Lw?wFJ7Zr^q3L9D=|O5GU%>ExyYee+?*j%xQ2VjEqA1owLCd1oGzFYS6OmZ$U7Qi z`;W)%3X)5GyN=Vrz7xEKSIN^h-2u59&DJi8Fc7THrvk~(sZ1<}@K&*Qr;sPJhL^eT zQcURE+&|LaugWzOXvc4|%3dFfd8D2B9GLJjsUx=9FPR(3R()h-WFX|$)azJu&W&}k zce%H~F6O%HM@+h}y1Aiyc_)!R0c~t3>@e-3|8+OS;C+)}FX0D0)=UZDFzWH%WL($* zo8KM@v>I<@ChW5W$dgV6`9MO((&2d=?{RqEu`0?D478?hHsXxe z&VRD%qO{@Jig&u;8fLQ+sx?%I+hR(Z`4#gSn1})O0RgM+Kzo`BT7Mi4CZ?^8ewo@B z+pup?VkaH--E}DYNGBgW}x zBfh_=*TsasrxnN{8A+0f8(wu5G{aZwI1+MXOFa?=F#fpt`_H`q=Ku3WcF>XsXm$-+ zEd?d-0!{Ea7`d4_LA*i$P;>_iGY9kk&N`5zi;;tgsktK%L)7+dLv<~&pbMv3kWc8?C*%jlCzT+)=zQi4)`(LsT=wp#X2_S^=iPImU zyRyuqnkX_ckyR|tBm0pug4~f%0~EM8jGoEY5l~Feh(XR8a3{O;IlYQC_v%6`paxU`d7} zNjiK}Nvx3p)mRFTQD^ffn(3oz6&??xgX*F{+QithzWAs{X0t-p0D2kaDrH25NiVE2w9>fT?vTcVt#DtS-?S5T8Z;z|h zvSkg{lFyFbm!CPjXW2fXzXvEbFV-&;1uuuYKU~!7Ir~h^7qlO?-ItBV4^8x}g|Kr7 z0LJ7+e#9!gRz^bRa~J154v%80fZX_cPC=*(i|Iv=ePw)?rV4N;$fmga-6O~^Sb7^Y zywvFF3Kp`%YDLK>_;zSYfS1?pH5@THG1x3%?xY*m4*VS$Vf!Owwm!H}>ME>np5Lnu z{&d(J#cq-3>>?{$pzW?CQgd9V|ZMtscUA8Xw%e|NZ=SWEHfSsCT3!PZtWCny*k z_mg8dQ(~qooi6xXUsN}1AlB7GAe7#k;XlkBISBt?D!S(=)-y@40?wy)+hC5P5lkfX zj~x$^xyQr1udVXxc2iYC6Gop^TF7U4F3Q}#u}DwP_%u4kBHvHhUmQ<&M|(S1B1BKI zwFen9yefV`djs=hH_eVdqFlD5gJfgfAX5O_X_zik_N_s+|5`)!0=zWO`xVxAEmFA` z>|*P~VpaX-l_2h)qB0lsot^qVC#U%`dwjHB0j3^^&96?}*Rgsd^{S1G`H3UiUmaiL zIT^wChkO0LEt#fjkCFDexm_>sH=B-PaH{N`iPp{V9+MksAV6^-yj0Q4{X*E|;x?pT ztbnF)+NX06Nt$brQ&%OOx3PlO>^sim*ImP;M@tK$M#-L?r8@32yO&#L#{Kra>^I@% zH2N9X2;CieR=a;9+)!+$dW)dYV(tvoG_XLW!M@>JRvHI%a!BJCh3*nwS24dT?A(mf zj{=u*jvSkAlc2Uh75`)k?It_Y)qx#~@GW@Ub|xX^+94wx($Z7RMx$iW3;ow~Ho|42 zM!ZS})c}EOYM4ViwUr{t{I+*;RD=y^czT>`=s3`=o3D%U@u#bq?r3KnC0cQp01||_)@XEw7rhe3hj2tbgR-?GiHwXO4!e= zu1%@Yr6XtKx&cUN(qzh4G=w=F3A}{Rd~c71;9GOst6Sd$zN?JtzYjozVF*#h;wxqo zaXW+A{7j;&iD$Py`@NcxhtOhVS`&i4qa%Qw@mPpe1(I{eTv$}dL$H<+>|sI#H&e$& z$g~9(N*~-GX=<`4U>pCTYN!b+BYz_t1-8@(yF};*%A}zx`-j{3nYz`%!d39AUtag` zaYXKc$J5Lq?;S;NT;tkmC!h3QF;x+*gb^$?65GOcC1+Oqa8v#gi z*RS&fI$q9glT_MWadO9t$Y|b0!>$+CZ-g?`C({&q9#?=N3@WANC^Y1q!)X2?*iLU(gy{7V=zpsX0hX@%akIc< z^To;~)iHtN!=-$VZ?~^MvO3pVgLjt*+S#Q>W6<2UPW)452|W;*ASLsyGL%- zeR*pxsyD{d_PecKUCdvQR>=U?NXrKWjN>$X41)ntr&IBE9qA90#mk1wtfm`#eyg(L z-afRmaOu(^*PC$*v^d&FEh!2%u2$K{nhSWb^PL-F39avpPIk%kiEon)pW4 zhp&+uW)WYXhR)4GWoQ13mx`2AIQ>P&Ql-m?bu*p%0OUc&`x3~11E;&9Q=U`i@+~`m z@=Y$OUkB}xGg?H$ck?TF9DS)l6zXO-Z-EM2ox=v2(q#08+ksy^9OE(iD-La30JUQ{YHax5$G*15S6{v zyNZR94J%eGWX&2bT!RV=6|H8Edy?l*0+mH085?Ytt^%F_qR%;FaEoTxq4s=BMjN$P zVrsf~W#-atRR8b%&cTTd|pI6~6lQpP%T=eHOaFq_<@ zyngs*`_pu)4)1QVUPBlj%b2C*s`Ob`V#XqU?C3znoA$edW0Qn@56+fvC=Tfm^ubF1 zH|?ts4Rk5`7+%lAS4v=Py?)tzkZ;EWIjv~a5S$^$cTDc=QwnW@tefqBma0#1<4p$6 zbA!#k68`lt6fQO+E~wz64PlT4&b+J!~6fgA^{-Z!)$k6P{d*ZQgxwCVd|2ABjcN6fhn z)@>h3yb^5gsDTAoo-;=|!Ybxt9Xg*;Zk?(XKN7BE zU=fTOKh#ND$)teXP-MOjo(+?Z-S|pTE9gXgI+x-SeE`w(tK~Pz>$jLNxRakntU8tn ze#R5nnP_xhtlbV@@$g`@P!ImJ#8@a=`AV)~-cPX){7Bt0B^|w*4EoVVOQYTaO!-R_ zPRN++JRKlhfY0W8`Ked|!&OdL`Nu8tS<+P6nB>3@+tF^=hBoe<38Q#Toqq4Ot>-y3 z<-9n<9Y=_-FG^%FZP$S`bUM3Gv;z|-HWt`*t~A}a3m1Hf07C9`y1&N$);;CLi3}cAiYJ!7!*Gn6xUc2_isRIRmA!$Mp1=ze(oqTm zQq)%z>vM0-Ya*E&rZ$lF!2LP>Tz2pzdkzsY;I zQj{4wMpAxYg+vn$hTlg1BY3v~5VvSyBY{raZr)xITZ@crb9%)#DGv}RSxOcuDbC2r4}`W^mw;y*UH1CN$(KXGO5^C5gX*@ zB=s1$qQCyO!*<<(XggQ2_0!qLD$ko*b8+oVpFp*oHG0$EGS4E@pP7eUu{;f?dOlR~ zxFe}zFw`vFr{^1~#GIp!tephrsR=A`V~K9yNoTwda+2p1S6xM|xNdj8z2tkJ>s6f( zYw|^-#*9RKceW8B%R5c4WC(sFxn5}voXXHtZP>_m?!6NHQq?S=wC<%%O>9m~;#ue> zO-vE0{c4n!(5DF)HQMKE`VqcL8VtJ|#gWr3bN(PocbK-}$H@%Fcd@TT?4>TgcLWGM zz)tEhv|cKb?_^$Thp7ylGYfCY*7nKUj+J+YhI!j9xmgGyx@RN^j1;O_=Zbr?R)0wA&V@5f4bJ z;Ix4E(S^bo@}V7MRDG2n z!F{LjO_NDDg;dfyR3r!{I&>qT$~fH<$}M5IIw~t}bF83dVul;?c*l%0y9nM%6fDo= zv*(G#?_C)yfPn=7FlFKgsP^IARqh z{cfkf!X|N6VLDLg+S2ZY7OIM-j?!C0W!6%umbyEN@NvHnj@Fvq{#kpK)>=`U^9v=7 zIT$Lm7_zW+B3|449ea}X1MIv#i4;r=6mD)sS%_3j`-eozlAq+gKYsp}ywC0G)2(md zRbU{{>2qn1XyYvhKbX;{dB3qcUHI^sTv@RHaE$8&s&stc|N15cwjr%jegUg)$2u5zF<7qSkJn! zrohW|PM8nqkEY6AO_1LnY#1GF%{R>#r`4BM<#0!1DtVO^ZqLb0X7}iBZ4{~7uT%k7 zNMYC4FAm%^g5JphB3jff^EM@vDILf~-kXmd<0bPzCE3F`;ovdg-1n#zIQP)IxnStQ z&;Ycu&z?QUL#u+O6t4r zG@>n^(?klPyD#xS&6l>^UiU9fFfIF_IWl+Le$7FK6!2}4hr#oN(!+Jr4TZM;=Cs4c z>~aI;1=njXS$n-|E})whI;8sJ?R6lgN>@H|P_+DS=8@pq=1TK{jPL+Ycn+vs-1UAN zM8BVA(LRD?pVW2{?pvVthP_QsuK>n_Ch5paeOSWO1n^Ia8>o<@Teu={m-!A%T?*A5RX! zuh=d3uz?!q8c^u1xaEYIQ!Y;ZwE}#*oT}YSxkxYQ_uDi`OIUNFxqQ*qwH>LQjQnVM zlB?g_om?DBF5DGAG?VYHcm#zcomhr>#pBnln8tgijZOu)tId!k+P2dq?w~RQmYu62 zEMfDyqZ{40a&-&rmslBO&T;msj!by^zM6Y)_ufg?CU%H+tz zIV+5(Kuv{~!bIa4wBwfsuG^qjhkMGE=jJ0CZV_Pg;qae+yX_uH3?UWrIW&?e z@=~z~5un&`n`L?r+a7O@F9i=C$l?QVpwo4#Ton{e*J&Fb?hOVu+&|!?KHMFJwEu{{ zJ3IE_xpss7A1!_UpKqId+C$3?N+|=1Q+Uc)&(6pV0MR`VbAb3RK%1PH|8MRN{MS8A zTr6yc##~&ipcFTtls=&SP3!=}rxYv3%-pOdoLsC%h8!kr+|2*HQ}ijz(?51Z{-NHlIQw}Er9)EhzH)jbqINow{=Hky zX30MV^(LU^*TUF0ySJY!+6CX=Q(@Tn_}Dy{YsY(^pFcK9Szq1`Z#iGBZ+M)pI-0dV z{sf-M&c|a}>$Pz#r!m>eNi8I;NwM6H6Kqr~@ZKwpdDgHHjOKEYs2mm;QGL_Yl$Lu{ zC1fKuVXsm|PS%XC1BY(pl2#I-TUb5!E7`p!%G8sOlPJq@_?O5f+RxMaU`jk*hSFG7 znT+goo6ijo`=>+)@=HoLjr@;uD2?R>6v0hK1q$-0YU*skEU4(#C*W4Ad{(8ZpAx%v zL||DI3U)`Uwt?7mdE*d?8pIT7K}g|&Nsx771L81>q-PyblTiE#`4(v%9!TA7ZwE$C zrj(jcMgW0)RZQKON6MB1)v{W@8RLx7to@c+?6K>LY(g(wmjWY9bX6WLFB6tFRb(lY zJ|*Fw(kjD9k*M-Uov>naG?SLgvc46FhI~Vs{aXvQ0yh6N?=(z0p5{$|4=p2wBGEN% zMN0xcckf%i=dMB}p}qcE`(VhO2#z7w5d5!FMXy*P`UysZ2&>Y2kVH29 z>9U13Q=)ij+m>SJp~C}k-@r6B7?Qq1!m)fSymtn}XV-GeDKo-WX#FuQl=u<6Jm9?} zV14P$8L(!`>LXJ4+HCS0CrNY?g;+lg{srx(e z6TU}}}XOurl4 z%9-zsX=sPn0dk9N!GGxZk<~FK-JmM}+i^%IR-IQ&-zIc*Yyvw{++$99CFl6D(P7Cd zw$t9Hu!aT&=@UAahRb?qRdoNoi=EC$M+H@neq>>oi{eUX4n5gU`bGi_x?O$^t;JBr zUv?#=?99l#d_tw)mO7LYFt~E`MviUdQa#*NN-i_p&Q{z-ycVE}-6nf-mPTeyZ*E8h zYUPm1zDBr6HIJByOoR9EtnzUn6I)ps*Vim<5( zh6N-HVg*7TIiNQRPx=bi zrIfg9umz%*$8*n*U6S`$6phz$TeyUnJmqr)dx)g44{^5Wey0RmKZaHMW?v>rUl%bi z6zeO;t}fhDC+2~P4c(E;IX!^URlZ2?!L27|zwFnoxxR35t?2``wTIl@;hD{PqWN}Y zKXwAb>iDVZj~08`Kes^RGuIAot%tJfuW-K$uaSG=;cEZh&HQB(=}S<8f`O?C9MgLf zM_VTcBNInrK0YP|2U{a06Ckk`lY*E8F_W^1E0CD!tu;tc(J_W}ZNOzQH67A8i(CjoU%;-`M@`LqOx7U}7n1RL?w z&wijUNq};qy?pxgwRa}Q<_03RuEbhT8=*n;LByQg&-8RQHnu=VVy&mG{(pc4;NN2b3LgDOAO8Q&rT(vC@!}pJLbzv0p4|hqS^nkd#mQJ-oQ(Au zwZFo}`V8Q|x(>^~hl}-Zp>_Y=TnCh^@(CxgKlo)!Kpu&ngw9z0XN!--9MO&yYN4Ed?FDpazOm ze!}TFizBFbL5<_ZW1lnCflj`7>~mtW_n@4!&tG`XL-kKx1ZZmYKLD2f-vbMZ1paRh z>@)Q?2$C1np1GJoM=$mKnU5EA^y0D4oUHGOxn4Z>nWYnS^nyJo?&#?eJd+##6Qa+Q ze}8jTj(?9R*VCn+dSB3x;lF1Ee`d1)Vex|6GhM-Z;^)wOQ1Rli&ym-lqZib;U$6&} zcRykH99Rh|UOW~QzVvkRB}(k6{9E7j5;F8Rh&lf~!~jtC$^U;~{J%MzdD%GjPyPj9 zeg^Mf+d{7Yy8D-r<6lN~Ad2w+rg#5bEC1SkzAUZ$?b&nxr@Mc0sK3=O$ER_!6KJ3g z0#3%<7&PpDan$D_FlYez;;7G~8c-Mi;+oH$3aEAXqXqcWxIahJFGKae;Qss|{{59% z{=D*wdp`O4pB>-7SNT*M{=G^7XmI~>H-C)nLGy>_reEi;W$P7vX_@`P|4ht7ELql5@D?8JFRm=9YF_MGz z=>a_JHD)ulVdrpU<8-wJP4`|N?4LIU0C9w~f|l|A)XQ#V?qh>mS0d2AnROEL;xu91g616J}#( z2Bnv0e;UR7yMU_DAC1JH)`Adt;gR`Y5(a>n zRoFqs{2}bb>BtOF&futo1y|dQbc(9PA+MIM_M=VYI!mt&2S~(3~BF-`|8;*jN}j zK>QSc)>RifM{{czBSUjTOM6hoejZ!=m+Jp=PY~^ZInauo#pnY!2#J4{W8q=}HHEDI zfPxj&))@nAIjoI=Y){fJW1~L}e$o2ZM*OK0`lpUS)Br?tU~Br+6Pkh+yZ|rV5ge14 ziR05+(8~(aUo|{6GJj~0HL)=TngNJGv^Jceq3VD7&4QJgo%5eId+)cxdMb-wFnNDE zZ1u7|s=t(TDZX{)StKzR5qSgSCzPhbY*kGuMLzH;l)m$|HVmzQsDJbt3vEMG4off! zv)BjySbIqVC*XpjeWvh)fgRc6qtcH>lE~4=kt46H?90^4RF6{I11EWvOvhd2#h>6X zU|c9-)ci)X$EYGv3UES9y;F0hkwly)L%o-+2sveawH-KURLFokU0q}$P3CssLQj0P zjBR=~>}d9@c9U~Brb{1LzhW%^o{ijB3NPcgk5Kz1}lNd zy=GMnlYVM1ys2)Jx+!PP?^!}KtWj;Q{>j-}9Wd}6l5R{U3(X|jSNlYbz8g%sJf`+% z=YU%dTWf{q4W zZVC?c2r8=~{od-izY{0F^t*+FyRR~gX!D$EkAGm$a|bs&1uad3&EIivF}^|IVe$}8F!dC zRE6U+kM#iQSgI3OqDb}LIgHCw&4tSTTSL`4F?d=MU27U&MB;FOl%+qS0-Pi%C4Z;H zo5m>q{=`y|&iGuFmHd+KbYIj{Sap)n5@BorkvnNp2Uw3EGYr6w(~raz4I2tEls6aA zo^vU%9>H@eGj+~>Ex}e&FlJH+l}sV@0MTDj0ov3Eo>l*~mES?vN6qM@VY5vW_mu?b zE`4moN!Qd=9g|nHRWaTdSs&A!9EMk$k(VzLH14it`s(7OQLl+cLpEhoR;=_gU~BBt zvSHz8PYF{iXFo?m3ebN<+Pi8%3NExGeD4V!>GyUZ#*uj`kS4;{{w>k3f+dCUYa`bo zQgx_d13=PuJ6TM_8$Nmul02y1ZMm;SosjhG$c$abva^Ums%L|`a(Gc2%m4om{Nm2?A#wYN~$e@ah6KA_Eq^evzxEB zcv76XG5HR1e-6ZS*T(@?$GG4|W=xq+1GjQh=s_h^LvhV?xo|gRRPw>@i4{8~SPK0G z^ZL@e*0WL3{_J1Dt+v(81cFlnO(vc5dz7$yheXiNQDxKseZL(hkn@K7r-O6x!d79o zDf7!jIr+~iQmXox%R4pkg4yRQCGe(GV%Rs0q7a$WX6Ajr&R449OjaEBInKM}U$oUrVNNMI?` z-=FtJRAu`n-)L-k#Ikzp=M^jG3O-C|@z7Uc{yMg(%lN2uPkc8j(v8BC)FvD07}d-- z(p9k9kL6d}-FDoLi$j8uC!O0am7rFErRj1)B|qJNH2E!FfDL6+7=5(KWo6SHcTCrN zU__0zw9@;`@94AS{D_Vdivg>*Ju&)aU*Iqe@4(CJEAXPyfymtlDc)F{V_nskIeH-{ z9soXqy^kNd+^?Yq3PgdZt-0q4H~-t56%QXxoQbWO}ngpbqGr^|ajz|{tM zF&8NK^#yHWrLHL9dHLY(3Kc<38(tJzvsXm z5G?tjJjPYsp!m!h7lIai;LC;GGJ+(D`{N5*`JKsyox}HY3@g z+3q^3!-PH>V9 z%Up!$>PP2SU5+sUZ~NaP7eosq&8y{C3R)kN&M}ems!>?l^^oHiicBr%SL(Hg6t9}R zA@RwHAWu-Hq$t2Bol%&)lo%1fAnZ!Zj;04&f1@}Ho^|-%IHf1<5}AE>klLW>#hDsbj0s!rK)FJ;Q8<5($q*lIo7M`KrJ~FY;*`2Jd8v!jt%>C%Feb z+A+2E?L58pN5VKHseT~kHSOy}EV-p+jj3zhH}RGU>G7WjIi~CxGen7^MPOV6O>^%# z(5z==?6Xgae_xmN1R8CTi5sKfM3J!uWXLDQ%Gi@vkhsJ{b04%*c-SW{5$lnRe862{ zyUg?2M&Us^a@@vm3bZNUoaDISxd$aH%-6@z7KyV99w+{Wnglx>^iCw=*#G#;aju;R zSD1@5TPO)YJ~GVy1i?PoHO@8Ws`RRqO~+mLM%{FrVM?dWa>k3{@+0)%`bNz!D7SzX zE$?^cVuzk@oL6q-;n-3MMzh9H7RrY zA`u&{reJqhd57B+QEh`6Ae2&|t$NP$E~bsrRI7Z_^n4Q??onmSWH_9>EBj0O=Hn>j z=fH~8Uoj%3*jQO1^?{dR^h@xz5m0L+k~^YZuD|@3!vYF;VBlRkZG$L&!OeM1GZ%8YAd? zP!nlp1fR?p+KeK!IRveZktNO`mH)3mOQ`_6;zPO{O3iDgFeq1fSM*Y!um@FaGQtGP z*lTKVwT`cqEWSrLMj0s_k;lz5oOBNZihI*K9=oHIjB{S>r3Y#I$JM;|@id^Fy zCCKz-B@peYmg@7fP~rkcMRBsjHTT8MCg0^9Fw0k?Oz|}231nyZVh-4@L{ITGFgvlL z=L@JOG~sJ4z!7yr%}T3MF^R$xhsK{0;xI(zFuf&v-wP!0N{}l^m&?|}KcGJ8!g77Y zBnz<1Zj$qapcHv$;k7$9u*k2_y#&71m1+m+aZMp$P*6!UlwhVabOMhIXg$uM@08_^c3cqA?R?OMa@-D_Vlj~W&4&+NJFYOP8)4)|pq-4(1ko19{^ZW78!yDbkvB3pH!jx^p_ktvq%%~QELf8-u9r8|6lE2B7iY-_`Vi@x zlyU?Ui?ijJ_ERVKGy_x5_i^gD1YFc3OnXs}N~t+)h&1bq zJih3ub1ryf_2unNf1c2+%TSr&=loXLM)dTi3OOmpa zINUwhJ(VUON78N$>Gf;P2muyy7N5oIC@%IkCkAE%w}u~EGW%}{pqA~d7YmxC8VdV} zO0&7?E4yL$DCw6|6UH6n#%K;3MZXq8JBRe9!KQp$gm7&7?HY<@nmZ4xLnebQ9;Y~f z!Z1&dNK+c2pM3*JnM9r**$wGE{zRo-X2LN#;Kp#18?`s}K%e=;HZIRXOzRR^2q_f* z{^t%2D=SS?$qll;a37UUdGPg|oeba7d*vQ=F~V@ia5kj16M+&X`c7Wsk=UD2nnfh^wq#D8W^|WseX*JwBKk&!~ z2CY5o*DVwcbsoz<{RDV=KVq&uJPu|hj8D>UcKn%zAG_O~V$9GH`D?D%6Z@n*B@qT$Y6Z zXI^QXlgBo=yZ++ZYLrHwxxAD1ku6SD8)3hNz)p;au)#nyjE2W_G^7Tvz2+hzhL9F- z>6edhcxvsX?xQ`wmHo^ICwHYaDW#7SXT$W<^v|>^gkw5dP5?98Y$TOmIng+PbWMwY zN5)*1Su{Cih1<&p$V^%>-#6s>uwBq}xX>+L-G)70kU@Sni*p*RyF`cHWdKyBwu;&c zzJPfxVzcL~kf#&6U)wxX9uV<5DznL93I!|I17T6XFEe)(W%jx}yy1-wYg7ODf#@X* z4*?kI@Q-l@k$Rj(gCw$FaDJ)`1xSo24wW`YygsOW#~4lMJm4as6x)5d>3%j4O(WaD z7JM0vKpToCukGlQjKCH1)<%5u%Ua#B*32zEg}!{&$%!3Az9vTtuX!Rz)p;TgTAgyA zCiSCmphE?Td3%oOe7)pwTBdQ26K|rU%WV(+!XpvbCR`xv%ZF;)#y5<4 z(#r-nVPx<#Ir(P0xu8c+menExuF3gp9v+z`>VtaT~TIj&R9#{{qUTgp(I8mp_*40lv7W5YFfa+5{ccwh$g;Ud;5h zFE|jYdBWERmvfTDJyf9k9&1}^!6)k>?shDXNbHgOM%j`XG9W4iSzS_GPrM!Sl;S2N z^ZG);qB82Ry9%BpDW^=B6KN3vh&R5oEs!?D!)x3xk>$IE-Vy)#nETQP;*utoOE57M zQ55 z0siV-xaQ?CLyB=fd-whGdb9|hO=-|?wNz`x^@kHCJvgWL%bosfNFT`XSq zM)&(2zWI_|TDp{DB%9=0M*;I`DU-a+U@ggyj<#Hv&PX3bLLNGVOT5b2BFS(ivXJxT zW<##tG@-{(RK_MHGiIO}doPXVr2$*i9;?LzB)?NtttD_F%6Hvvi)G|c#YJWHNMspH zW`weDf5`b6b4UlI0rJpih6LKKn2FO1s|DCVHGO!lG5NFSrWpyHWYNRi?mu5Q+m7TAl^1h-pJn5!|H*p_GJ%;cWr zdAzz8`I)^gu4d4e`8k&^wVoF!z7jd^4>p#PFv?X7YXoa)CSs*&MqbBBZ)Zb25ompg z^aFAfR;5_x+`!2>L^>|el}A0W2NUW_luUSO<=2oii{OOP68X&Fx?R04G-?iqg~d4=3R#MWBakp$XqIHM6%^{V)al5*Gb@dpsT)`y`|?wG zAnH72USwvCmcR5%W`X*53&EdQ``{v0Wwytx?ftuWyL+8`Z4G@|MnuMCxPX1r96-Q{ zQu1Z3oy~C3e3%mh^44^HVwDhWeOujzn$>z`h^J^YB2it4=Sa&<6Mq-+?~!9zdL3-G z^0v0ROxe{9Au>H9?q4YtZrrc2KBywGQKT@sm^Nvn?-@0EZW?g666UpND_3l7h; zf7R0;Ay0&=tUj9=NjC!-1`IW%-L(V|MUS!yZLuYhHe z)pSP1J7()kfA|sP)@`4_S8k3YWGyq%GoOT8`@v;^rHG@N@$1=G5l&S1M4dd}s(?k1ij%254R=>Ad!U~6DfDs(Bi}5WA zj5zBg-Tg=dQJd0xUs~pmko?<9nfhQ5f=8UBX&r%PP^@`D`55$}wCbqVp;QwHUrBg6 zqPHQT^WaY;?E=syAQ;7%){tW%2oY|Hp}W10Nuank{fPiDep8obH!M@cSb)gjgUkJ4 z_#T)wmsn(j9_n8teJJfguR@70d_8+aLP;>~BSnRGAfi4PPe~MT4fEUb&ox6p3UP0pU~2x#31W+W}m@M(k(e_%I(s19FHA5tR$u z{24S2%E(Mei18t zJrS#(Ju)bQ!7>KmYYyt64X+r*S|ZmsDq&9G)FWLf=-(3feZ)`Cg|)|^7j1!Kl&*5z zk3g+hZNO!G>jg8@RTyfi&%LIp?&nINopb{>-MJAu(~Xf*O?U#)0RBa+1yz;Q##bd2 z4;8ulogK#7h#mV{#Y)=LtsQ*7mI3=3rFwuXUU~1rPt@fQ-W8r6UIU$7{wsFv7+0)v z$(HnWemkP1J0^%+i?^4KqFj-crsRreBv~leS_B0dBS7|cJj{k%?Sfn=oLr5%Sue>QI}HaQRif7 z@~T&K$m-mb%rQ7$$Q21+%oS=s+3~Bjemj^GG*{FUC0FiqQqR5<$1AiotYhh2lsgPv z@jJZ!{A1j;^$LVSHEmRIm=oX3=F%c~4M>-dl0M+I3SXvd6e^~Z#3E}>(c zm&XEY$adH#l2>3Sa*rEMH#3i`Jogokb#jk)dfR7XK6#UZ zw^%&)liAy6@(+la-UTwnO#JVPea@JGH^ z0rwLn&;j&t{$KXqK#m(Ekq%eO6%U}p(^mV-O%H|(L#5usNIVZ-#T~cZCgV z^SL{RY2or0zjeLov(q)+z{(}qF|I9BMJv`>&UE&g`Ix(C#zxXeNj5#69!1#_<(`k) z{MocNAGK#zYKkr|hxkC9N#>S`^-zlH_HEe6hY!m*#pb4Y6g%WQ=m+XU`ds48K->e4 z0-dg*8#Z|Zb~#@7J@mN2fQMupmx6?eLpyb@gTBLByk^FNMKj~~230BVR9QFiK7VKd zeBj{yrf*n_*Qqa7^c@G0%Oo#cIDeEF=d2v79p->5GtxO(W&`ef;#&v;T2ZB$pjLoE z(ww2Vg9<#ISxpJ%4-0_CH^$nqIeEwlSqX=CJo}%_P*gbRST1_Z*s*;8^Qo^+-S@Qz zQ#5duXjpb_9A|A3)^KRzgZM#B4U<2;N1sk=ziN;L+fyu>KQeyoX9i#~p|z){mK z9zDTIIEy9q0ZaMrNJok)f04+}fx^hd+$tQSHBY^nk-l)PXZAp@cyZIA(w{J7c++7% z?!gz)s>G<0aWwn~t=4CrO!2J`=VzF`7S8%1-l+5E?rlk%P>UJP9}59h#!Oy6zQCK; z&!s3gXd^ZE2cZ?XYZHd_2hl_mA0}cS&|Zv%o2aNHF*qQVnO4$%nhP@g9WfpaWSM6l z8U7fV2~shIckb>n6T}bXN>O&@V>FEp!8r49(B_tE=`U>T2;&L1zP1`rhDz5-Qkk=@ zpRd zVe|DMPA z)0YX~_%&Il9dTrpeh!SwO$kvIqeEi9(S>W}&tOm0v9%rvhs7`1cSuK%13^HRjh|&| zfpk(tGDiDhbTM-?PN^d+mk@y>t9I0}L=y8}6L#LzL`JI$6)2Djf`&TTW9z3Ho&o`# zMxj;isxfn0utrqRC>Uc<(?x*aZUB7?0Ur&kH0b@lzmN4!TJm2`mrtG@WRSNJ?;X*XKZN0p-g$o-@_69liMODH5Ptf(kl&;VmTBOM+NA0Bs==l`G>nq$-7 zl$I1>!aib!l;%<69<8l1%z$tO0jfMwR9a`jNHpEdyLd@`%HiDyc48o>RZ##_(AL(} z)K*sTXWMOV`=uXUBeha*tuhMO=WOp22DJk4i`QMNVeDArA($#wT^R8W3h9g$k> z9kK}X1#qK5TU-Z=Hav?zRr%~dYr4!wPt{I;`N8D=HVNaBq3i&$Ra?Cg=BofK#Se3n>)q3|vC%p- ze2=jqrxxajpjrlV{`(^qG9x47gSeR_&z$_3>DZ?Yxaub_!-0W*b>GCeZ}9j)jUg%- zjn8AZFQsa?Hc%zn4>~aWHLfA5PrNHx{`0`OaHaBx%#G9iBd>&GX}?Vg00IGP)RId1DvGY4uRqZjD3U z6rz>1%8U!t|D=(g`M`w4HMady>B1S@C>1VK9~GdEkMuOCHhT^f#yg!aH3ihlRAAR|OV#e+&R5cObvHF0cXoB8adDGe@#6$G zqV2LP^R@NAEMTB^eW^sT4}2{-i<-sh^mEdbvYnJdiSr!=M9~t5)9wEUR6wi0^R>jC zd|~RQDaog%UPSuWCjXd29=??APGs)Z0%* z>|0rm8%$Z}QVDtg))&W2+q-Ic!N5qI#FJ<3CEpRtmv43c_;UTaO;7wT8A@uWJ%3KZ z)Pwd=sotOxukK3iv&Q&BH&l^~_U_rVZrUq9 zcE0sx@|z_4yBH5A-y>JUAv9aY?lK4L)Uv9+!l6S; zu8)n$nRzxocQ9$E=hKBCK+i=SkkriG+^*Dm(?Z3n^{q+Wn%!b=&k)oBtR191!HZxK0_CmI@XoQ|f6>Ns@h z5dU;H^(n2w`4M2^9uQLRwK}V4d+NP}=B&C+AXL~aJSI@#Vjw7PgtEUZWDq_B`WepK zHhj3aa|O1HvT#&Q&jI862IP1)7xB1@loPUTW3nzs`r8jqrZFa?#;{5IksorYHDR`z zOr{}|ttO*!$Yfo6>a&E6#U(F`%PK=ZOEt1kx)jEbC){T9kjViZL#v6QtTNm|*$;IR z247H=oI$hMqsPjemslW?!UE$LWG zpCDKAz?X>}qfy72R9OnBCKE%J*45;xHrsSsjv7EVZ>5^?_o>6+MrTK7O&v~*6?JRq zTH{*lvldA&8@+V6W3=ncoT2_nj_I!HITQQ~Oq)&t+6{UItdR0$($5;tIL;+Sp zzcFOv^J25G44c9dZB0xyCN!+70sEyCF98ZG0lWlk3_g85<1_3uDoR8aY*@mBnL!{8 zOP~Sx+D6cI`=A)&affQ}TVCdN+fi(Fk-UPKLv@#z^|h(7NS>^lyx`R>7q>1Oa{jCL zzP9|PJ=-q7eA~7wFF&(^zDh(g@X;ANlc~3o$>fvUZ-1QJoxJU<)l7}2irA{yctQheUw(xnHl0rHgQ}*S{@6D7)k(K~Sh7sK zY|!PQ-=6W@45YFeHIRv;K;xxs)1bAl$;+h99=B4MHik4FosHcGV+>c^7T z4lz6gC5%PlH4G1yG4Z2a4>Z~Bls_<`x7uj-IfoNQyMs;+I$0WPyA_*GcYrcp|678O z{Lej&NhEt7dm4XOqVE7{fbI!tpY93yY312~JjzsWnq*mEnr&HOU*WjUzSsV-?_>Wl zpJ|`*aR>FQ0X0_*s=D8&j^QXC1_gaR&af|NP!*l-xq#0Z2>6tM5A~U6!x5XE@e0BkORu;ERdae}f~*Yog9g&D zG$V;oS2$LQ9MrdOp9+*ZzH*^R;u^*dmSs^sSxG(7`|tc}>m8R}br;#=`0h`yo*4Pi zf%~Qhw{IU@J!}7!2S1*>;8%C8bG-EC7u)L|-uuAXnZ20=PDy$dq;0q0sjF7^J0apua&|oNZ1p{KRFd!A0BW9B~2dxQBWzwd} zG2SK?kCiaxd#HrnV6UpF!8Q3PPX5uS)TiuK>cMy!b8PZ^NM^TrxcOSMINUbXcClZW z;J!dT-#OcTk$JiETJt*Rb^Zs<21ye*(-}=>izpL(E@5-Zent8OVSio4O!{DFT%xyw zJ^(p%enO8_N=T;Jo}FTQc8cv?y4c<{LtCU#&C5hYYnHP`bR#=n1CrS-?X(-4 z+OIwTy!Fnu@E5hgP?_s~nPn03`P*J!(*p4U2i z#$COFzq@gN@*kftYXLWFqAGQu-ZqoR_kbz&L*h|3K4u+f9InE39QA2+&Qap(T*pzL zR_z>Rg)2OcGGDk9C7sR&Sm7vf)N#~vOfL)eI@5g9ou+N3XHC**VYK-cQLv+UgGndI zlEEm*xSp8J&j}*#LPWs~)MOTA;R*T#`^%POOTxh3P?}8eoIz}-b03!^Ln1d+VaP5V zhO|||17C9U!q84C6J|M)7pah&!+qq9R?39IXm(ZrRjEb=$||!u7&x+<)uFpA?PNWl z@4vA%n5`SfnOIk=pQwD_cWeDC|CY=7Y(5QI*}=xq#^jW*>&7-$0O@OgJ2TI_(^dTxoD4 z#mGXZlt{wELJn>n+Bpi|tU<$tC|!t!9Nbv6b2NJSe6vD)vQO7Sdw}3*o7wP^fW;7W zxdL{!gc+@(7z~Y|ER_T0GS0j{yw;=(izlPVOc&V#6Bn35^9^F`3gvDUXdcU|r# z$3u=MO|P5Y_A7da*HYvY^rcd%u>%(r0X2>4Fu3dv$8#2|)8cSitY%a<2?rx2VcCLv zAd5BOA{n9{w~FLdriyTRN!S>9wi)Uob)~vN71jTRQt@)7;w9i!z0{jkD&CEneJ|+) zR&py!UcXk$uAfsbq0^PiY3ikc?S)XG@NsCsJ#hnS;3I34UU3Oo4)_wpS0Azj_X$7w z0a15-gG$E1w#BGuz~z+DGK@|Bo$HPZu4>!9e(L%j+is+9c0NAtnw$0$W!VkKpXnsc z>bmO>-gjr~xEeS8`qAXY(~~Fu^z==whnYqhgZ$;fbto5#sIUjk?_+#yZ0(tVmK`l6 z8z{)KQKXBF!s-19M+;{rUYctTW~ms`TN2Z$H7#T%Au@vq#NQ*BFcY&Gtr)+Q7j&8p zK>|^g)#BR|HRw?pPkH!?=Hc5DPi8N1=(R)YAG5sGa8y0mz<8^8K@J%vCtSmFhH2C6 zle7iGYBCBJI&u2@7igk*Rk%b zcQn1I@x=^>DZ^*1C|l6FYbo4w5II)Bw--8@tz>p)=|u9trdG0bjX1lpq448QZ_iN+ zrVO5ZE*-pgUR&oSFJJRP^2puSeYXAG&dPB&j$Qh|eV46xSe$4%zjRFLpfBH<)tLPD zm32q2B(>ynvh5FB51f3r;oCR>g9Mjl{WlP;Mn1(%F&J=d7Padu9YuzJU_4n(_o&z>rq4?yeJQyDt{|6-%akR? zrKXF_D?Hc3I*9qmn#@=Q;R@^b~-QN%IBH+JTsqX<~O;r8*$B*a8cLB-cM)OHolsy!gY_DqIgUBqZjIQD9TEo&Mu%!NHjiU5LVzE9IncY>^cm_;yIJ@bb?h1&UzxaYr z_U->-!NN5+Bu~8gX7a>M=U%&D{_5-I&Rg4m)W(Ucwr;;_e!y!HN;xwjSe zJh*mm3JBT1;SXfe{A;eBF>B2=CsSiKj{8mXRS$2?p2soC4&r*aWe-?UR3dCRT;4SD z6_8^jE$MvV!d;^5R=Ew%;<+s3;<8!5F_K;;xk(o85^lGeJ?v{cmBAk7Rx=CeXWb4R z9yf;2IEmWOG&#Zf+nZi#dEi*02V-!rjdQq-AFkNEww`fgk03iL9%m6O7AK4+gl{Cx zs!cbUF#9Nv?ZMgP9gH`W@l~RX&mS^BlSY-TwD110>mZ^V5vMG^L=iXnY+R`S#Zymz z);~R}r2B&s75#mq-HFKA?x~Tv!UgVyzIl-qzAJ+3eb)!?bZ_(R^?l*~L_4852Dt+IG5`xUna*01_TF0XREExg156^ullJk|SHfMr|A8r^ykn)EODd zNKluNm|dx%VF_vY**`Uqwh9N)J{1LQl|~;>eC#%UTo@xwnfxgE zP4d&^&fo46Dt^8D;9cu+sYWT;gIkkp#Tfr6w_idNCD6%ws;d@-YN8Vjv>Hu*pzI{@ zUM2HJU5=+Gf-o4l@Xz z!bbI3=_%cQ^_Xf@q?RH7 z$ijs2;!EQDqOcL!xt)-NalC22{Ju%pXd)&SSFQ3(GF>S*%T)fA_4PN>?4E-T|9Nq0 zeL3pUqu{Nn_8qM`QqA7g9c6E-vae|4nPXALe{0l(2Q3E=u94C{vSV$Fabj&t@T_Td zZK73BuJCw8NI8iJ?0v2fE6~XTE&mg(d-svfU*G#C`TC9# zd4Y1NL#&ti|1R0>Y0?{QQ_h@304piV6!MkQ>C24h4fY zP;fm<@*3Xk^1#;HgqiKVyfK}L8Me4Ef0Br@)lX+CUePk|R!;E6mj^QMReosW z43-Y)(r;P}{Ow9Ze86;X*PD}u>Q2P!u{=H|eE^!iP92t`!)1uQ#AkLu+*ZX7L(^xW z>@7>VE!^#((?TO8T$Vm3k3~>jl~uBJiG?@O*w*Kp=FVHaVQTXq)+c{O2CnLNX6=Zp z?n%B)7M>FuI<5btTh}MIOC9xl=A84J@`An1^L8}$7ADx-bH|KYRQTf-+0<{rhzZO2 zx%u4Gr_#mJtH=jm?V3f;&!r?ir@XJ9C1$XY24&`1s2P{#Hp4Z!8{tmr5#d4e9-+~O@ys8n)-v!?U?DNYBU0-OyDWcKSeKG2xO-Vma3yp(u!Vk9pg2i2ZmUM70v z7+c<{%V}o|yx4YNVDib2k0#&v^VR@~fMkNPfO}w1VQva&Y(e zrzaA5nU3j6h`*uGbH>yg_#0*~PvH#BRjMzPtMc(s`A$aVmXi8!GxWDvhW;+g(7~T! z=uEWXG%oI4I&^uWui$6DhGM_|5Oq0TpO@;`PhHFgLFaNi-43^)^9!CZv0D(lN+3+! z23we&h{WUUv$IvCfpNUY?Qz>(PKx{<4VPtJ3>6@k-$TBCWZISW%bLcnxarX9Huwg8&k;$nn#o7?MM+CD&lJF zp&sr_4CFoBAd{|6Vh8WisAiUD_&-&7Td*@uHe-@(t*@OBgO2#I9ey86>8w5Y_^Dn#T4p#B1&#b&#u46AZlz>iYP`kgk6S6_ ztZllqxquYp@*&IRLzc^jEH|bZh=Hpb1K$H0a$>X2K26n(Q5#NV#zN(T!OjM|&Rf`5 zTlT8-yRRyCMuze;OpN#gzCcbu(3xUt)D;WGl&BbsM7`$RFu1LbFcx+?G#O)gQZ!5g zMieBc4I!uxhaq2JpY!p3ew=+FQ{80}FwsIAvrp7^nu2qCFRfs}RZ`fjZ*+2~v zrAGE!x9pTD*(p=lls#Q=+sFaoxh>eei%V_c8)NJ-=i??N1|yzH<SY;bwx#4R$`<_ld99cUy6WPOociMytG`e#z46&MvE$y;kHa zclKiAx$gioYjNb5C0m3eC&5(-6QRg$5-4m}+D;!zgk_o@Mu9Vjzz0S6x7GTIpDdBO zpIah7X-I2vrt6rt+jM}wg4F$eJCljq0d!WRPZc}~lTu_v0w~AqYd{4Dh4Y|dG26H{ z!qLKj#6ErL!9pfG%a*JrK@Wr~dZPstJvA70tOrJwQEf!3ce7GP71*2JOy9oC_U&Zb zX`i97qu`qT`_-3U-p{tA@pyWCA^TZcNahoy<0x3B< zsT0l?FE(FlSz}g=R8p$UeJ$f?tuRbZC}Ye+EQZ_Z9l|Dgld@HKNY>e@)nX}?s8f=t zVltacB?W_uX@YeEN#NE}QP|Ia+0QvuHcyTAW;?Za(5+x5y;~(sX(zoCZj;`?x7z8A zwLwdmRvL-113PRXMl40!(X$fB9+z?1;Rm9iSr@BBZKqQn*Q7?NSwhL9TX))+YRX|> ziZ)bxI~iN@Jt@X~-J(YtaF1G3o&K0ObNg`T%J!;juHai$^m>=VsV(X6z?AwCx%73Q zsn_|Aw6?{Bc|9yNWS2^BzB5k9%5J z(!dVkfQd7jhMvBaB#au8M2PKnl26Vqb?5XUGl=v=a>`@LI;rEwZ*Cen{@23EA4Z7J z|JX-7{G-OC>n>bzLd+5(doy4CAgg`0i@()3X4SvqHM#lg5_W`)A%&tYlNF~dD^wN) zMK4mSmlaXq3Y2M!?7GBKa9v_anocKWHJa45E=g(8#C0PPWnwUtNA21EIIzq>yVwjI;g5zBk~ze3po1{ z_weH;TZN(_;2hNVE@gHE&S9I97*U1&-oJZ9m69k+2g|DDyd3`B?(Q56mZgI%HIn|C z*BGgiElzX}7C*k*fx+B#Fc*U^7W{69D>MJu4+^<(rdgnzumzIX?s{6F9Z#Q3;)Jgf zSK?$h|Jcm_YCc+t?@F(M1^mRFsP$QiQ*}E19=~4{Rnckm82#cl&u+_87Qy53`l*(i zu#Iz!^CWzAQk{OPI@vbEG0ii>JH2j6)=xnBOjpcM-zfT?7EJ+V- zW>~Y^F>bw~CC#^~L5d?A4%;x?wL_(aH;=jC=K3#_&nDNB%l6*WFuM0O$?K#Ji+#@S zg-;|qJ0BIu`jykKcA43kKwaua=}Y8c7xW}g-bxoW2E-8C3^+s1h^|N~ z_QYcYq-sz9*l20AXH={~njEQ%Es`!1R!HlG_0p|yr| zNdqLYLAu$yDfZ`>7`-3uxQh$}`b$W}W{*p)qcMn1C5%anw(1ituPogXW zQhqRK6{wOQl=Z&swEMEt?&~_@^TixqHd&6W=s40Rh&*tNi;g2JIxLVF$R^HlCiQ7W z%|)~*%y}Wqc_GYsAsjaz`*;~`kemZl|3qqt#;73jL{pqOxBYTt}h*_en`#tOuLtXW!h&)xU`@#*B=$6Cnn zXPKm3*!juUg^!?sy_x)w_}`g7{p>k+H^kReU3T_pKip~eRiJ-tXI?>tjm2{dD%6Z`&G?xAmz}w>bUv0>Gd{~t zjKVuSSV>uu(3)^_V>mQSrJ+Jc(R>a^LcHmgZ*_tUV? zZP3}-_tuhEuXlTVIYAGjICJ)eyL&c^9uI``xEk>y!&sDHmZ`eGy3cGCgE7lpy6o>S zbXhgP_lOmIx2WT%#SL2i;{4`(AwSPcyS=dIT;%B%`czj(9UC zXXzhtam5mkvv*`wCH%YT^k>sj*DqSSU69!nB@9Z!T4h!H+wA?>f=QNeTg!s$t}my` zhAXojoh1>dQuCbXLg>1d+WKzC${x4J5fOS(R9+FT$oPBz@V#{1!53CM_v)A)lSikH zADDdM)Z%dM2jt$>o5tRDf3j5S828NbyI#+Y=8wH7xrFq-W_>@S+{f0bT^Qu@a|P>^}A8_T}n<=A5kz-sF$bbPVI4>!xCZ4!{#_Y8;E8D zv236q8;J1fPZv%HqS-(!8z^8*ID&zw0VZd_qrVZB1VD8DIst+38`oq3)026c7*)zO>Ho2;8$!OWJcI2^P4V?KSXki-BA zeRi>|cMRsB9xxX#_h09y{;1nr94v^EsN|NIj!eH&3l{5xLASt-fjH{3hV(%b^BVa3 z#*(Ay+n*?o=3C50DICZR`W0Cx3RFj;`FWV8lY;(YUxKmv23&iOx}lh#xN+-NB^nt| z8p&d^k?2S}X-Qa$*(2Gbk>WG;*;oJitc>crKCjWoppX+q&25^=IpIu%n_#3)yz?UR^eyP`_;~d_z?!j z*(ji#vDa_xbxS>a1H0sun33)gE_9B{AT2M;oJ8jr@Xu)YSLm5{1TLq?Eqb_6vE?B) z{c-b*XRcWE@Wk=c2P7{z>%4haesjzH-(M?rShsI$xwonxd9$v0#kD`){dDs0caS&K z3vZY@q-ogjc@fXdc;)?b7X4xNc`vN8Tz})Lv&WT}FX%B~*TomT)U@n#CRwFucXjah z!0#n;bX&90kd1{T8pPQL{vQ(R+iBBIE&bl}ah*nJ3HyeL zkX90 ztn1?M<6U7JbtH4ebxFTu-oE{Zzq9Wh(DG+zicVrm7-H5su}*nb5#8;X)5QvLfHFcn zQ@Pms8|gEvYyxUyKi1Ldo!OPcndM3hoY>8J?~KvxPL6i%^9S&Wj?e|FC&I5{~EfM5rddH-$*YbhOTAA(BNX*xl_wX z`i09F747=&mg&*-Z&2gVK+0_yL%$DhoYEh0*~G>Jvy(r*_G0pf#RtyVe#Ps%rH+$3 z-c6po|3+f|To`wFUY4-hAgsvd2N5$tylYn_2ewW6{_gXoX2*Z(Eh*!&}|#k zb!Pibn%UBaYt)hv{V&=wA1r^7{_M)YzoBEtQt4HIuWGgR6Mylc8oca^_B@!uu9zxVmVk$K?nyyo>({D8G zHytw>HPd(#6{%67nNPm-#AE~oo2;qfFXgeeL9f>o$*Cw3Am3BTNvWjAM}4jtK+(@p z$Q-Kh1I`{*;}z1ZY*a8#NWx4LJ*s9fZmJb9*n-%kIpU*)}T+>@3UR>Rt;? zqzR~$ji{hfR2C6YQL$o+67!52lYk}mgtipXJU5Z}p6!9LB$BA)i3SUizacyYcJ`g~ zyZ0`$n)mtq7v|hEcgnqU&hPyC_jlfL!ExHi)Y*+rUA)MQu#3)!_;_ZlJ>D4`KbJYj zKG!)XZapYHX!=v_wpu8e$VUo%K|7s4U7HY@&QI57N9OVKv_+9+{4(v@h{;E&8<#A@o;%ro&UJ!+0kkM699 zBxe~O<18Y)i|+a%NtKa!I1-6Fnk-jF9MW}c%`~%?9kwjnku@nE;Z55jOpM$T&&Dm& zlx0c6u9!=evrE&5^VmrEPqowD7iRFI4!3RP973(A2GKkhgnm)F z_CG$VO^#Gh?DIcNu1TNp>C2_dUMRg@FUG>9R|)6qeBk~sYS|C_lBF;IaaRxf>my^h zuDi4I#~yu*@j2jlLf;`a`#fX$URD#ltbj>|S<^I z7v#1cS6GQ!lR!}wH#&`>k*J*=DUFmz>Z6P{r#+-Np{!F?aA-rWws$i*>i$voj}jG1 zi%Ey0?_z0l6}n2rbzGy^pf(wG&IoRlG)kr4I8K_*bxCv7S;lndVl6NqXOS&-oj-U)pbc>NE?0GS+OO`$cK1 zO0*^X=bO#6<1Z~$VyaB`{bgtQuo*K2owGv+Av)E`in~MRXHnmZ%gV z)6jKfS-S0nLMoXNtgEaRQdA^ZI3z2fP}VEL!D3y{YHV23Si+`R7UPhv)7o1t5fmW{ zBCEL?*0!Vbwq=zyO0U8y+tKzd=lL9YyQ>I2t~JHlWw91{ldEKzL^$%hD$0@blMc~k z(iQ(CaiHr!7wN!C=^C_DR`Y{a1;rMTKhvZOp+nkPe()B;&Y8e%J@3%~NrTa*QfFzR zh^WC9PZb@S|B@<(yaPwm{ZmD$I#ncd-@7SIUFW@SCS42>qN-I?orIW*st#45JxqIAC`QhOV&oj{VbUAC$jVn8u`a)>5VxY^ zQX^P?GHx$ve?!W&nqjA*`nUV~aQ;8mgm_udiL_yBJExpg-Bv?ZP-TRvIU>iloW`H#aoK(2-iH5k_1o z5EAR_=iKLL45aTsjkQGL$A<8CO>oQM`)I`G;E)MNDV| zW&*~(4UK50sxcC)B8~W~DdUd)7neNt>P+^j9`@OJXZ-3{$Ha?iPRL!Q1vn0t!WcKt zv3Z0oUdS_|Lzasu{F>u)h!MO{H_cU{s{M1)&;8;vG(jP#HWQ@ygzTzFjoli#3;po@ z_e%@JsrP^T{{575)|VEb9=KAc8{_!AC|E4c69FplL^=C4$L2&D`*jt#+H>;5G$HoT zzq$mfYHPJ?+Nw}b>5BK?M?WkrxL>HJ*XaLiX#ueUzF=5}Sf!|wRx4o=+-awjCH4** z%93Hpa8H*O+;kK5mz~kSpG$KmGYw2Te#&i@b-5{_Cz~4erlz7kBGR53)il1TOYdr0 zs4r-mJM>Qdw#J`EA5K24M;d~Zw|c1JL3>Xmo@v;cc%fluVpqc-A|EtJr$-URkx=-N zFvD?eHH+_>hmrJ4DQqy_oq+G_1p?OXlZyxm?f5NEa2 z7GlGz!twJOFK@(+=@z5YxYt-~^c(zIW4-Z}!5RYzyN2dhs`)&qU318-qV*6AfFu|K zg)A6#RA(|E{$&_xHntr<*M!_(`h;({;e~k>y_bYR&6}rI=?)+_)VbZAET8G zXgC6lyIfT*wUvD5$(Nq3RLjw+t)(e76n0eW*#_W({0lV}Ne}L;HZToqx8vEaQSVY@ zdA4q7-TFGdNS%Mw&ad0v|6b5J1W|&zVMU0NRn`=S7JG|$T@e*&!4Y>6{puK`G{K5=Cw15iP0?ebO_9bDLfHOj;fQ2wvHDM2K4K}j@o=>#gj#3&@|_3z^836h5Cfm>_FOW>f%I?S zxiqbp>CRCP0{9o&;a^*!-b19GjKSd$jYPuHSWO)(hz9nc2jop`$Gqnku77dt7310# z?YS7Wj=uedt1C9dFWY^`?axfHDUE3FP}5~(gl}1T32!Nj4{vNI_btqVM9;W z=9J4$IB8~gy!);R?)hg7S#j{_ttX8{A2g(`hKViX=FXmc(p7Xd-9}aujjUQs1$x!J z7V(-{%eV2PdA>8VA%ioS>U3-R)bx_fnv5_i)Di7So*6we*(G)9=bBy7A0!t_i}g#) z%c7Shdo%BAdt!SM{~h`=_GRMZioKcsOd`v-m@VOi-O?pBedy6RkYmCAWJlPatjHSVWH91c9-UYJ1* z%Iv5Vj|w3JN?FtB+^frwjiD3`kc-{QfOKLwSPz^RkOc=vt7pBiUMZIx#=QuwLF>>4 zbP#bF)QKh|7Ev3Tt{X(xR0XAQ1f+++(|{aGdI(65YF0gzw&AT&dV44i$!?JFj1rY& z+Xs0EC|ND_GR@%JK0=v&gQ?XEb96$IF+dK;Cz$Rk!qM#!t-~vE#A0fy>)CLu4E}Y( zlRZl}Ua-E~Eq(o)7Z>5ej2|t3?w40Ce~#bL_s@GL-}~AXrLRiw{T%(|r5Sg<`TFix zpuW?T{{8F$!gZ7AAI~$f{)28cBs9PX%Fvq7THcsSWtM%xxWPoGifAg)62j^^C#{O{ zG^ZjXB1&|?L>Mp;5Ky#Q6KP>#z4^{7o{w*5*Kqov4uG+;hBE2XLZ`*1g{H;khUUf| z#t*YU)gQMWPim5$P!{3^>_YxZZHc~0e?r?LZ&kKvT2#AD`xvuE^?Byy<_#umBFa1K zhC+VRTyk4$n03rv<{+^bywdN%J*LU62Lx$u4>TFG){uZNSEs;tb|~Pge|K*LTB=p^ z8Db3*Tg^4{r_Mkwctl+AeT)ESo(mM=0y&HWB1i%ej88{^+#*1F5#V=`+Fc^bh@B!9 z4TwK0^kX7OC()~01@9Jzr3yO-+;JX(lqIn(^|zjfngkU{25J1^slLZwt4j&%x7` zv%=HT7vp*SeEGug+;nf|9sb?W2Z>KYpM<}PeUbPCcuO>s$tNj8nvkU2NgRS}^&!zw zxJ{pcN9$w4PF68lAt(#K?x6)R!=fZP)+ zy>$gN1B!&01e!@y7N(SO8fplD>v4d&z{w79xf71lvCsEP(#LUDL$iCT+NfY7lFg$G z!gf$O>~!S(oj1ID<-&Jvp8J!Q&3)PDu3Y}hr>ckr2$*;a!|rz75Jx76_i2{*dOd@{`>QvmA*pZzr2eKbZoz}>DCMH?%RW> zY9r6SW98H6?AT*HC_`kZh8jvAmcF&J>vvp&?!WD{OP-)ICq&3$75_F9Lyc}_SVm@| zB{4MNCYB@~)_$fxtxHM0LEn(*O>hZ1tZp(>sE~A4Gt&x+;Cwj5u>zy44Wn>>2*xnv zaz3;K1~aC4DkjIU_&x+VTbqZCEI{s7KAkD7VNk-Qt2g25Wc4y(h>tWte59JLXQtVY zjC}3KkHdca_;V2RkfI6Y+K8SHRV$ds;)xg04yKAZj1(rG&mS&da5SDw%}iKz2l5BH zXaJ=H>TeZoFPl7U*@7$z6484t*-0_BV5Sf;?3-@95#`BxTuKeC*0w@B4P+5MP1$sW zmdx3-c5Ntm^YSz2q(%-u>-1f_*q`3ry{Ite9OviCn7J3+ee5E#@=h&HWj`k?uaap( zzjx=VDj#lEbKx`9(P2TZNK`bdb>ZfkqBzN)ulQ6aJ&Z|rGE zheQy?R+bqGf_N3v%j_mb=XQLZYw_u{sf?~pYf3cInrkgDZuWJ6l>El6hY&+99^V~9 zR?Lmfjjf7t&16dOjAr1*G2q6r0d5=vZcNL7z}e3|ZcN`r%YyjaIOe6(Lgz@Z){nTC z0Oc$*QI4t305N5Nm@+_2ncA1kUFJt-zsY6HPIEHRG`z}`z^hGIqh^xQidhW>AJX*7 zUOgWZc(a+vH!rKA>^VQ__%iMGL!MSShXxi6%l9y?lC#gpK=1RSN8Ln($0+OuY>9dg z=S;bDj9B9k(X1=45OC3Yb@*w^uDd;MpyeC>eDJcje)!@wPt5=Gx_|%tp(n0e`P8qj zS@G1l$*H;F^JcYgxC?cB@E}5WKe+1H!f$r1c$RH?tM{chUVi0ex@uQ547(p9dG|lh zM9Gqh#0pUK3=FRv*T#-!cjz3Pio_Cym}F~qnB@^;rg<@}Dq0|OwP3md-q!?if}HHO zjwtlYs8>c&5V%nnz*7y-hUvu0)Pl7EMg`iuoTTrQeW$NL-bE)GqSsKlh61nP`QfdQ z+B^xuj*W#8g$>bzQM@F&F1jJwALXJr3{xG3DGkHqhjU)8r$z4SAgzO%W$4CP9HgcB z`6fr)7;p--a00sklz+iSvij18SFIU{U^8x;#JAY^}0R*^1&jz4=e&7>^ zV2C+G&{9a32!~*(@9#z?Pis83dZs}%8nJ6^n0g^%ukN|Ncloa;^jx`U$`3n;9q{#i zU622)?>zj->T9Rnb6wvHgge|$CbxrP7Z?#e=_aspJmBNQi4{LeeJpS`91F^3c^wWc zB#01srMI9JpcSDdAMOiO>AnE?+!p|!`@GT+7z{NQS^-)STI4O*Q-ef!|H`xjR~`kK z3M1(7PnOrn>*Nh`ul$jGP!<_EBQKFx$!q;nd*yyv$;d>17dgzz0!@x}Pk^glj~Ia$ zI7JY1Jj1Q!)^QuSUT!ZZ^l}F|%y3z5H+jZ!o~eiFmHp}GVEQ?QUY`R&!3BbX3qtB} zp9&=fZj$s}B3Rl1rPs(*d!BZ`P)OI(ayRbaKS1D<`M$lUr-%Du*RG=xuI}g_iadX` zG!>14*>uo}?ouyg=S6rmFZ6AAeyQW(JI@%_pw+$eo?#5F2CWV)$LIJHxmNx*o{vd9 zFLE5__z;716|-TDvw2m7A*~CBR29UuZLT4bIu;{bP|qpK8Wm;KPIa=%QqY6jPKVG3 zL4aYcf=@@S1Z!WTqo_(?=L0WQ6QS_0s>Xhoi&9&nRV6=RSMu zt#7Y=$QXYgH|OZOofGF#9!b^``wc}<;a9e@K|uX@yggVgU%SI#VU^V<3~CjEIwzbh z%#vAC{|A3qVC4W^?d1R}K}QZctY5!Km@$LBO2Lkh4MEW9;AW?u2B8l2kfX!H35ZG^ zbZ;SN1dii5pq*rIaj%gy;9l3ek_Pj2&hJ=6LV5g7%6w^ll7V0OyOK{rhFZD zHUE(Oitq>SJz<~lnfO1#w^GDW6rN={EC?dq@J-=mNy>>rSQG`8<8r(b=6OXSi;bfp zdyc1JSXE^dZaXqvndiV2TP@LNqqATOTVCSz8lp=3s4$>D)vNQDV?3hvh}0utoI{9c zb)C#)!qCW~bB6(A2C`y2$P%ni>JcK07z}I%EPW=S>3^*ndr>(-0X_N38cj{=K1@@S zh)F#VRwC9?tVrVmv_2v^#-VVkNC-^oV4?LR9{L0sW#n5}EXQ@4sZUIAua=^#$juc+ zS*ob$5NPzMqA1Yh-7Fk7R{0eZ0cO$7_`xTkzjsp=Wb|)}(!+ zxvMSoptU=`H{KuTvQpRxM;&6%AR($NbZ^0cXpLaS8Ge>5>D9);hKYkcqk<))f+eF4 zSTZWG5w#lL;isz*H3uvimF9y2aj1$P^Em8+>{7v4QW5#DPKr~u)l99L_`x_{5?>eJ z5buq1aTd2mqChuMprI&GPc-MD5^dWD%l=DaM){60W0x5-oX_2QUFW;T(WDqu?;7~? z%$q}C;0$^p?}0hIcrwLv3|Kf(!Il+C5fxUj>TJPCAyaXDf}zOxZYo59F#G^p8C9%) z^vVzBJ~G8pdYTrEyW&Z%?t%5AmrNXfUEdY>w#zO(e7yx&9!t}pjk~+MySqCCcXxM( z;O_43?gV$Y5FCOA*Wm83Pu_3ele5?U`*T6{bWK-Fbx*-F!}NX7%lT5!Id<~?+Tq1= z%abg`Xcs%|yYk&nbFJCDm^c3cgt-YyMUm9Rta== zD+a%}?>nb38$sY@d`KWASdYMcQI;(20~g~a*ZlR&P-N}~UltEUD#<^eV8a}nPhrq+ zK;)vTS9l2{Osqc2IH`T{#Pxp7>-TAa*7FeEB|wAk>9_EEox`rz?VbWpV0%nQt285uH1r9C6XL2jR_e@kQ5kL;#J^siAI->aM~`7 zOR5@7I{3HoPCvh!@;Vsm$!j75?glgnq*eV{)xzdq5FL|~iWTT>FTzlaZ`+|H&TzN& z#f8F1i!`u7+QC5u;eEJZp$U27($6hrdq1zUD+oitef#mXZr$@y5@D2KmK*w2BY$^Dg!$l6y{ly0)AuWE- z=?^7e$0Uy`@o(*w)3!QwxbcEhi0-G}Kw6EFA^q!0MB z4C+IU`S+@&{#{|wO;?`WR-@M85}Z#~I8U!&i!A52ccFc#twe6BwZ)CQ{+O+l-p;r4 zQ~#}ZOM@jB+B#3;_ZwP5TKfL^$mCfhvO3ydZ^QhO@+SWGhuMsuW4xE|kV`2J<7&K}ZsV+XTFBf~HpmxtkX?fh1{ z!M-_ZvCx>Q*Qeeh-BNxPJ6=89YV5@OGHN19$<~Ltr{W1Q`qQyw_(;lSpZhzWTO5a^ z0Tq1;CJpRT=$c4Rd0qKtNkZP*C~`|vO6KqG&ad#3)@e(1Rqu^AtmnO9kXe_6FYPzY z51Q|L@Y$z+2AFnGbP>M`R8U>5gX2EEL$@iR2I5hI@~IV3Pehk1>86u@yJQWLH@P9p z<0~hY5Xb!%V+D&q&5fLhyhS-h?LrC494BK?@JZQbiS$P0y2cd&Miz-j@^&4%JIA2s zFe>~7#X2scNNnZ8r5%t_VzvSv6857~Q#X)y9y#%rrMds~$!c5cZ4q9HWp`e5Q5J>V z2GyQQA4^_v6QZ%UeR+NuG5`M zd%dPbloK#BU5GE!d(75)fH;o=r^S>grmxh|_u4)Kuh(rm^>tPDnwx(v&sRmAfhY9e zD{0i=G`-oY>*4bInbWjpGmlPO+IpXo>SA8Yf5iP=$L6(fRPIew7S8Orj<&Rb;|l0^ z1=<q3e z%hmPl-lGBSpp2%wmcygby?ZTz?{D2JQvx(|2(E+EaR~RUqPZJFiBlupd@wk@E$c?< zs6yUGv|r7~z@xJrI?Qg<=nH*B4@hlllaBE5u-w$BM@}+nk$G!FO4l&?X<@Fkw7e_@63z1qK(qhJdO8@SaJli zyW|sY6YvusWa)Q0 z8aA87N6kFmcsMrG>)`Gsf}V8B6ZH`WY06B=Jvl3vD-vQUEoSWHtQ|E+z8;Oh#{TOV z82GIwmAltT*zsh%YvGOrz<+dr$DP7*a3uJ4#?KymCR6f`J z^1R*C6)|&;EVeiaTkQ&pFzTXZd|Vha4W#wE^R;pJFjZ1O2ylWP zy=te`M7qg2kab&atfXvun!g<^fSu9li1juhx6b zlhS;Gh4;oOZWvkyot12DqE*6a3durQjL9es;KSUt?1}C(i7T=`5q*LNlSX0n)zUo7 zGmRO$cC3TRC6Yt>MT-A4AJwPS*SN2$&+tuh8x`H(-}G09x~qLAd}{E_5U8j2kEom| zs@RyC=kHBN)l4_tioo;W-$?l#czBGvUhIxZsdEA4{p!*y^zMx?oN*P6j2Tjx6$#R zsiYvFvT7CRg$C&upRc{T6nURF&+}%wdRz3E1_Hj^y}6?x$fQhgeX)vJL-~@8Is&C% z-T6Z{Y1tTqM1D1H_wDy=)0)nGGmCqi>B(ZmkkS^un%k8G5xhc16g!4Crt}oX@f1e$ z!Ms`C{NN&J)Cm|s;S!W}KWl%ivE@~u1get(W%R^_paMRgtqz07@oM=T{2-b=bbvLs z=t=j5zB5Ad{BXRzCKr2r;og7V7i09$zp6d)FdXBWUY`#*d^Tgh4BaFciUxb^q;Iz9 zy3%db8nzTemJE`Xl2`_6D_n(gfw7?NZCgzi=lCVRCwJPzS?f_yk&UPeh5{w#7j@Oe zWW9@n?i0qp-aBS~UegAe(Wilk>3Yl{UYAozqj>_ucz0w!xro6foGdCLBhSS*<`_g% z9k#D28v!3}MO~_n)gmizn{*=)XoV^%O^H+9WCE^{LnWuEz&f^O!PPX?lq0^&cVc{G zy@TVFdDq=AwDJ2*g^Px>!X0#>U>O(Qyk`N0V4|5IX^$Y`zt~fA%Lug)IpaR{I(*hQMc99X%Xt(MKDc zZGExL?TMM|>k7xVHlN_x;Ie^vxh`H_#DB<%C8^bZfyxp|$KF|F}##h{3{+H(DlV+KT0*XtFy*Jb9 z<>PF;igZ>cfS79mAz#@I*%}7p5!`b5c^d!CbbGuI%TRaK3qy{or(y3zzV80yXt_1F z+0D1|D6|~+Q%du0==E&*%FGwB_k*JM_?V#Ed9qP2L?c^__Q^j)LkDY)#YdpN6~Y-x z_rQ}Robi^FLKz%k5(L9lWQ79D$NUR{CGK~#^43fQmTFWaa`$qwsHPwJj)I8_quz)cLg^Eo$wCJA1c06o^%d6Ik{8^sCi>+=4%QX%H)WX4A?ds}EcN zmv=~{^$=(%Pz3XD>US(`A)|w_CQkmO{8)=vG(y15-cJ`qSj z^H6y$0ja(cm~6SW(qff~cpBgFt(=-TthJn2R7GbMRo6+usDdAb7&{S!LcVgpd5p}H zJI+^&)5J)7YW}ciyw4uN|gp` zS>Hc$6_rsKNgiA`zS!O-KpG+n**NIBoIr4dD=RU?upr1W``R#=x_XiJgV5wM_>_AE8T6 zw_M*^4{d*eTtb$-)8WY> zJ%tSgg#FfS8#m}Z=$f2L6O;qxZ$lD1m;*d=*}M!KqfKr#=;|tzq687O0)zgNS~h#> zzLe3E^LCeL>Cr)Whp`2{mIWt#pS;_o;N0`$#afCgbBS`a7nGQ^?4>a4WOnzcpNO8v zDx7VK2{0FD(q z9YN#54dU;G@b(JXKEB7S^%17tjyisZ>#Rr1xOvYNjBt^PuQN)rCub?cDarcs(5ooi z7J4xfw%|8>^m@rWg4I>_68jjtjJ0Rzja8R^@qZNVQISu3QSVMt-{TeGf^ zqi3OQ59vlSD?mj;DuM>1TWRsbM525W9wOkeI`xOQ8JJ?H_WZM0$Dg>WxBXZ8R z{L|SCa8FP}o%=K5Q=$`GBY~s9FoCeQ}8cQNun75 z?8NZ}#gk7|8G6dC+vs`%PD*lj;r99X8S%GVO#S{Q>@eg?L@W}Ir57Gh<}jNd?CRK% z@C1un+Am3sF-mokmi)mKtm&-paFas0d=y67lT}o&Mbqw#DignpbA7)`v9!HZAXX2( zlr$AzqV~H!9fq2n-JOEH3Xrp`>fk8liuuNG9!tB@O*C!U6&Fi|&(kVy@}s%|TSl35H3!9j%KFKVHg4uvBY9b!wA2ovr@;hNx~T2Ngx|#Q!&%L z)d_ybz~zz94xe_NouVmkr!Slw!5#J%R~IWx+(8gs=81qg98Ch>lOc;s;bAi7(R|R4 zaU|J%FFDc+sS&MqAUvyr=PzrjE{?xYQ|)z1YV$z3hhhHG)zzic_8H!(SQ1ut*ER+w zTtjnOeC5z2*Oa{uOZU=NFm~>9n%?FnYlVlJ?K^!?B@Z@BFdRlw9{NdSVFVnJIS&%c4}{nljUEEtOeuIC-Ir9XCVV*TZ(d<( zY+6vo;@9_^o64>g4_dR7t}_s=LfS zFf}54-C@k^OBIWo8DDzW>YdRsHH{M#L!LVDAc`{+c*jIl4MH18}~8 zyu6Ve;EeEpzG#J=t&D8tQ~_sfjVxS<*kBliT};gEU5U5>d}bC-RyKgxf5C~D*=WoBhz=}N@;ha}Fz#L5iAC=K8cTbT&k zTiBWr0eJL(S{D&<@Fdcq=ip!i5X6}{xrpdlS=bmjnK%LPWELhSCL(4gK+9b0+^k#x z)bk$;0D{)Z#x}?k@A3>{%ZzMs<=5i+M3z@@gx&q7>pW3I!pj~H9Hfa zdrU+C+%f|fE5L34$pL8P49x5-tZaIK{u2R!&8)1f3;-%R7a#*bdjBo_SN~V{&k?|w zn}~&r=%3n%Sh$H;|J@erpPGr-{~+l9Od}C12N5eL5eEkc12;Dd!1#}fn~0Nzg@Kua zlbe%>4bbDiXE~Ue0DT5n5^?_1`@d!X>Bj##A|kGThVr-UU;Dqc|JD61_xJ3-+Wx0^ zf6sEWu`+P6adL3{Yb;Dee{KHVw||cH0ELM-xc}uYPQY*hfbf55{^iPlhWuCe_lV`6 zPW?UlQ`6tvKW@+?0?aDFhkuQ^08{*TV*g|I|J4|vx_>;QN5suc#0{9rKUWYZHxV-z z)4$gY7Yks~{I^SbfD21Z<3Ee=pUA-pn56%GE&cx@zgd_C1c?53*zwHKQ(m_ZW`grQ zqPLR}EYA%-~t_3s&|N8o& zm8&!CYTbKx&U;B#_9RcyPTneKv6P;KCgJh|V-nG16*;91d*Mi9G)VEPAQ`MsQOjKrjV_Hx~d@p7}pe zdB8$Ybx^an0@#=V0?nUAp#1L$%k_6v{Fe*Q!p+Y0CzM;+x|%rye!?HH>Syl{tts*Bvf0Qecc!nTw?E? z5nA=n3+Krppd#P}b%SQpi?fmBBmJOv?zkC$kL$A~yUs?w(FrXqM7lg*r)mqART|S# zd)e%{R@3JwG2l1oAL;&rIH!dF2Pc%$IB}_Mz-H${iSrgiX zL^+^3d@}n(W_z>nH364rhoBHHTK3D!MmAIank&fC7d|u0dZ))2o86KoN~3y^S%z-> zeA(|Mi6x?DF$&wBp`kstApy(U*(I(e62pO&)pL(Ko{r;PK&=i~t+sr!ArQ8!B$mOG z1-YrgGf~&8R9KMrPqr{W!lDhaz0;oVFfTg1#Nav*a!WP+25OJd_iZD|-R%ND@`E~D*j~`~lDqZMWL$lOW2O9V=~DT<*z&#Y^Hrxq<8r|R zTPEgUl)o%|YV|O6?LFfFXEOe$*-w+7Cav5E15RBk?(Us=Zh{vbvpQ8RazUB4u3s0? z9f3EJU{LoTMpZMe&Gl%0>}32b9prN^V?)PC(8yEO1S`9>c5KG9D%OwKYXy7%N=3e4 z2+_QoeDGuo-O#}pFMX6Q$dcw0E>z1xRCmI=4(`y@(`t^Nb z#xGdmOJm)DCu9RTY|D+G{*Yx1{Sed8YDS)|RigTgxHi5DlO6DUeZOCWChbd&Mmo{- zP|kSJ!k{eeC!x#)qi!?H+!$jx_A!B&MwtC>-&7Z<{~i^_ z$8G+g?=C|7^WrVG<16(GHq(y(JfiKRC!GiA%feiKm>+!Wa&f3&s7}L&j>03heJYC~ zeA!lvJxu2mUGC)U@t1_@cq>jrO-A*gm|oyq=yJO>ZC1Hj0`4N~r-tu^=%PhtrNLjK zqG2G#VQy}nhqzY@YYhAIGZXU;Z@o4c%7^Tmw0}?(3)heHNTYeip``Hd=@d_<9nd)jw;t-U9uXV$EYf0Pys1cUBOEh{&FZaR zW8}P-vDR$ZQ0b@`6O)IVg&I6tk-=SL7C5KP&g|qWJ6{D&XWSDw6{r{N#i6%l7RXJH zJk&kgy?Vqx+P*4RgJ1)8S{vKJ$h*&tKQd@njLVtx%oe-OHrhnhUzE*Z2Q}F zlExqq3X*wCJQdqLDSCkt$60c{X1+yp=z{RGV2J(mvofQR@ejiU_^U$(^g~0kR(od? z7J>k7EBpcs$t>gMQ2vt>|J|JFyqZ&g=csP-kfd&%h0N&;2A|(Ewoa>Kba)t~b)Q%5 z?9bhP))js?KSujA?;ANbkoy3qz!w4AYZ?RVUdmY%#q^lNgy>`Q%b;_cW2_`gkm}2+P@zIGc)o)I}e~j8U7l7iHv%4#bNVdgTucgM$;ByR-%0b)Yd~ID2r3b->bg$;l76XA`c0X2gEv*PX%*6Z*<6wC zhxcz7I|XlKb?pkMfWL+sp;(AvIp(Bxdxj~I!YDkU2*xG^`$VgVRr63t{AvKULD;4uI0U@$XAq^K-4@Em{rLu{et@uH_w-K*+x`n~$ z`a;+eV8>CMDLdlt=CR(h{Kih7s-N?p1c>o2V?R^4c&`y@KnGE$u@j95Tp!GkhMJkaZUL`7Otm ztSxaX33DQQ|H~P|M}e3`*#Nl$Nn^B5+8icd+GItmr@%Rjdu-qRIInT+eMiI}MDO83%rFRl zIO@XM;nFd(5{|xsW6$sWU~Uij2=U0_k@1?t8&rIF$oic6X7={$&E1dlv&=Egk$Dpl zW(JCXFndsXr$kCTKZ5}y8WX_9@J|)1)U{5iOWsWUD6}CxDFME-?_!3nSha*Q8aB!#}=lz8sO8wb)mBf;;eK-;iJ+ zo7`b`4uK=pNPzid(}EkmX31fld8)Ko4_tPi<&;-D@_Z}~@0|DqaYjL6|3WjI z_-5t^=NG^j(nFhBfL?KLFF%a(NKq%Ro23a-PkbJ4iu9b=yccsU5=HaGzsWi9YRWo2)cBdq z4<_V8aMzzcEb1&pJsnOuNIr;R6yBiolzY|5h1JnR;1`SXu90F6?#+a`8N#^3TQt;o zJxCN`>>X~rj=Mv$HhdmFHyqy8-PTBn-mWA2V9K55jP87?pEL97WREAx??mv1fPf;i zu~OWj*@rM$DJd{BxUudCR!@9&XHK?3jVX)SlXlD=kEayUod}Bd&*{a zc#$5(FXo0?TLauoh&EK=5Z_=W4G~p~%xe!m0^X)6FtEhGjSopJ2eB@KVJlMm$WXyW z<>z9_U^=}z#Y!7`@z&{EF$K|$sAn`1`figY8%p`WwC>mqUNhgM{fz3evM~m2qwz!T z4)fl*6*^!{v}Pau_U;v}U;mo!LJ||@SsGMHCQZq_FO-Dl?nNXGN+p()hr+nyvVDgl zfW|~YqZuR2_}T3v{k!}U0B&qFVaJE$QSU`??F2@P*~a{yE;eVWNc45rD+1966 z+NyN;kKmexVnpq`yV3<|9{hNJDI-HWWHEip6SpK&j^F{nM^Cz_F@1KgJ~=u#O+Evnpq`jC9kew>>o;vELX_A8 zf&oAm=M4LUz-Vov5lpY=PyO z$+qo##sl6)O~>E;R<|H)A@Z+4FwyW1BjyX=0f@hXv5Y0V#thIC0uBQR-EXmG*owWA z=jIilZKSceSY0`wRJQKj_wKyr8uRDwyjaZU_iHt2hGCC_sauR;_K37w^uc3+61}K= zb%6)GS3i02G!t?LJR=Wy&-Al@WueLn{`$UH%9T5<`uZ}$L{A@E2xnz4xZRm}h%dC` zx@YIurS%$Ye^w1`G7VQgq@IAv?5>e+ZHX~#zz~VqFu>3YA%HOG0~oE>wR`I1q~@*r z?#{L0>(t3+!ptcHKAONE3mFTo=E*FX@6*%fmLazO0zV;E2Y}H|{JLvDWa-A)s1`0E zy*t@i={fnQbo67Mr$8q;EhtuJJ!Qto?k#J(}g@iAFqJ*Fvys1LKwTcQAp*FB?F(Fu3 zB{WjMJ+o|oI|3M#g<;Fc$Y8A%lJ%h!Aj!Z$D(>&^oqwMh3p!JKetzB_(wt7nsi}FH z6V2p9Y|jCoI23V?HP`t1m0OfD1yc=l&G4WUlnN&5>H!1YNO*cqTwFXMu<@-b$kFq6 zNMgB8X6J@DU9|gsw2>ORw~6LKSQQJ~0!=}cF_5?t_U4J1nP!5wh?W*M7?V0*RYk*g zH?_%1b|G+jeT>;$ogXtEyEU39VGIrrvLhw8^)OJ>w?fa?aDzcBHVAzSGFcj zK(57E>yNU8#4Q3ni_CXS!S3vjJcht5g4~ECR9g2$^2I3&m7Pd3e5l|9%eEnJ+#h%14zBDhF^w92hOHbqc3t5ugg|$> znXns?%M7O}GNQOthFpwrcE2)_UZYAK@Pu+W>LRqZ!=}{gc=}j25|m z`3eHCN1TLa{_zO^CVPa=w)Su~dp9@-nLwb95$Ud71N61~u;AXNCF^dkBY)WjI4992 zJSWL!@lL%F>~2qc{TtXtunr30&^wNOs1EY_4#zO$Ho`FEjy&BFF+5>d7t;Z9JFXM% zMsPd+HR(pjX7&@32mhmyC*(%_6PB&G58k!t6MZwO05BraMMyZ32>`gv0MEOfI1Jft z^DC?!x0P};oRWP5v`^Rv#+}F=00{kc#kH$H9DK$0hT%lW7uZf{94WZNkhH_v0NV)3 zgOndCKYV1!xqAyhC&L2J%i^9e*W||{K3YRtq8__?p5PB8y)X)-y%4Xcm)p}xJEvE? z!-9jX5e`C#yTG0p00c9`HAgr23~4VsBiUw<$F}&e2m3G%(kB=rDM5$^(pI!d|(cweh`;LAMl%^d^I~q zSLMTmJFo!0GkJHuC%(sbLLxtSLK1?&c%)ARLQ;ZIK~jQX1*AUVH&7qg9>7xXBhwGw zyQ1C|Wak48N9qfnLFxzvA9ixB}mmenM$P>=lV2?G55RtVjN=UhtPL zCtP-Yagr-1{LGa93@=;wyk^b)s4ZLQTXKDA%aZ?;SUB0THB%&Kj->lz?QpNeR8KSSN;evK?PKFW03nHID7K?Ay~6u z@Q2#$uU4Kv>-qvM_wOX~^Y`87*2$d$pr8Nq?IEY5VX{vUo_kECi3EDQHs@5}9Pc4B zs@wwWn=N|FtD87~A%+MMmTGkp+Ll_kKE@yRy#Owm@HAsOiSSg_<_mkDt>-)=LCrIM z=f25=((n3fVl8GKm_t=dl+Nr~JMl+29%S4*ET15Tz_>kv1A?=PTNCJbL*YXl$VVt7 z+XK=oh)ysb1f5T)hXZ85L;jscHAJ`X5bE!uIBGbLNXnVW^v6F7*CQ|BT|wxCH=+R5 z49x~Voe39g1aE-iWAv3u>|BJm98-B9W!mxp&%FBDxLUdT7~sMa<*wuyrBz%bjB z+!YjSo=r))vnu}3-%{ezG%@lmH>PPZ{Fqufo?1zm(lp~GncJn|N%MCp|1}cT*EwXn zbj)x`6-fb_i=kiz>TJZ0RF|p~1Dl_(6YNLv;xacQfzj{Zvz3RC`dpi7-ZnE{;P)d!3nWVlj^@Atd(cHHTZc+v>Klw3f{L+v9g`6s8 zf0ObWi}UprBd4^Bqq-e3-L>}(o*xGf*^e$TaWzHvrrPDUbib5Mw#$q-%ZYW~RwROS z^=r_Z+d*Ng8l6qrUD=@CHbQkFvLOBH;wBg0&No2YkzP7pd4^6t^2$4O*sF9j3pL-z zODtp0*s^52txfI81Y(^ycY!u4)Ot%<`I^zJ2XzTj3W~?~TClXMq2DRs>;{$ALr7bo zC9P38tWmvDNAW276Hq2&6YlG;ITa7a!Q=34s*J{DP-O6-vGad<#YUW9(qsZR7 zeW&=zq7Xh+XLjp~BU`%k+HpX2G}$Pdsxx=;kizgai*~k?rD7p@6l#q}QTNg1VtYR^tSClBDJG(e-T04cMB^-ZAZTs zxEF#u?_-$72fr6G{2-2${0sSK##vw4;S&{CL~R|vwN)cyxd=C@AM2~cESHf8QlmIg z@2|(Gcg$=Q?{{tZMucSoYuM8d+4-Y4P`)8`$KzM))@Uz4R%Bz$D!h260xQSC_~+u8$z0JUHG}QxJKc`!zzD8c zT+@qR(K~6IQ_zpqi*!QQO5my25{dwVEsCSWQuL2lpjvBQ(znu)|= zl>s7JVqk3@pu-UdRc0glBP`M2rRDJl^6Ptzr7%Crqo=$AM$&p#cPXRv*k@R{Vk02h7!}RCwQ@?w$xb6Z9`S z*DrwJ*@pUy^_YzQ4x&?Gmi!orJ(}}Na!KvH{0X-73iZ9rBAq-+TNLkzg_u$K3hlg* z91gp+7n&OEM#+x$aPhGtvT)5$ktMdMdkLi(gaKZe;;MV8ZA;*<#Q}UOLhcv|*)USE zvSTRv3$DNw1uKs86*z;W?~rq9Auf_d=ABM6%l7_~?HgO-59B>Q>_H#P$L@veVHY&6 z=*Kd1=tYylN6YgtO#a1LsWi@now}~VuE6Tx?JLp#*=ptPDx|AFpNo)9)fMas=J|gm z>ICU)NM4ZL<^3Md-K$TWAQ(4ONB)W;dBJ?=;r@iUv$sXjGsgR-Q2b~aE*PcnB59B8 zb>zO^dr{Avbh3SfebSsFi2geDMvec0onhx3E=brTC25~=Fq+FdF;M3-{)6;G=iPwxSz}xiE&dTy zkI&0t-!&1tYIjS+Q_#Hb+GCN5POuKKOW7~xS>dJaK=9bVdkZfKS9_dh~kxC2)rD+?KlWb?35MT(_ekW+L{A-))5~W8!D{TWs9+a!K5iM6`b~(WxKhBK{FVF*C%X#ZDU7|f zvA&84=a$5jNm+wyZ*41d6aM_SLbhxs+1+Qtm@o7Q|a> z2`HQA!6>E4G1N4N<$?Z;HNC)qG)li9CZ@MMSXtOwJ z_2~PLCTSvlX`uyr<>>pA+GdTr3tG;~T46cgS;VTNNy~4alE318eFywxP~P-)YfFkt z0X~u11;%1)eWzrqF@bxqRh z>dr$rJ6b%bq)CHYVF#ezj2x(CVWNr81Q4PaeVdXFH5|@&DzQ7SJ=LrS>aBA zb$WZwHc{9yBJL~A0-mmf0Ulu?<9n-Ws%Q=o?C_by%bsBxR!Ziv4+UF!PZU>5V#v0J zNeBzt1e#UF!)NLe!pi5aj*F3(O@ACP>r6A8H$slmRgDP7)X(B=S{#NP^m*1kmD(J9 zPo2cBiJ^n6h)0*LjZak=O_M@VUs7HVu@Zl`!YeO5PdZ@MizM*D8jwgpui?RnN`P`! zRC8P=pL1{2E3&O_C|XEY>NFLs+qRk85s0h%P4%;N##PNi9bvt%=9rEk>CUO^`x}Bm z1Defojga!;5t;9jc0?dOw+>93YV%PuW~)X-MyCZX#Y+kBE+j3<*LMrFbgU|uMUbm!p9ara1Q~Eong!pG|zgbbjzb4Ou zQb6_BTEAPH6@SY;OK=}wms6PNOLt?fk*lNFg8KwH683&9~#L z6&LK~aCLqp-{wJWbCo!*d8?XRC4~pqq<+$TGwg(9tqc`xE=m8_y&uzU0iX?P1aM* z(NN@ft2nw(1Yp~P~eE=$9xYQAbXd-0rvm3X=!Qv(HRDPbuV8YxaYPdnb5y0VrN z!~)G`vLvsmHo~v@;QhD_;MgVFx%VX&@%6mtY9D4Zz%#&?!1?yBYsYtU*sR@shYpWt z+ij(%Vg^7r!!TQ1e$5um9?c5r=MxX+uUr}#`2!Aj8`S|yos zJmXS#u9~!3xI90y%CqQFyQh_@k86%~Xp>pCn!l73m$O%SaZhDSES!bB&ja40?mMKQ zz`jq$eH7I$!knKoBl8MJz+V$f<0$Ud3_fUuNr@$%bA$>dFX!v3Sv+tpSh*@1#+5(R zUhDhNGu5k^F2&8M=Q=q!$zC|&xZoUgA0x1@Zy37{JTj@DJ|N<3w|871 z!hz)jP@IJO=8P3PrCO~sOv$RQDM;CIBCDenm(JQS*DG@ymwV~uh{kUy>8UiR{Ks>Y zWe?j9a7@Ao@IZqnogHgGDL&Od57+;ycVqH6;IK}dMk&XqTx!;e^Y)qb(jbRDy%t+95&YF zc+OFqEK6B_O|P}b6SVIY*i3i7zD@6S8VPD!-oXA`*I^vbz4YMgNt=n4AqPD>~OoKheqw-<(@g!i5HMm|oNSr$Yj zQYbXHbD8i~jE*wP$yuvPz96qcfTexd9$wpNytW?6;f?9qS>iDN4N?@avm!pwAf6H9 ziqdz;0pS)eHDE1EZM`eb53rd@;c~h|c$mX>TfZYRN_wXYSLN~rQnixEy!njW$onK>@vOqJ#N+vftx;XHg*$gc<8N@-OYga@73k+%iMJ?cA;Iv z=?5O|9(SMn`*_?l2^K#*_Pf+!Xb)__b4}AX?7P-;6=2)(gukO+U|gga?C3ATE}5dx z98zOED7eKHIx?l{@GDJe#2hDQR;{aypUPHEV6ZREup~>H8>{E$QT?vwW1m#7a6Bw7 z!*)b#F7hEiA^VlN&VbyspDsftKR9H9E&SvUFkfL`u8(>_pdo4dQzZIG7n*wH;*8^Eh0{M@ms=n)WE4p9Ya3(Lv7_ zEQKjsQa38XCJ**A%Ir`hoA&6+WMFmZG2qHOKLnF8r=S%jrcA)g%-ON+Ri@E)X~WPS zDs+2I5BWMIcgOpyG25%FEs3j03Q(WPAqrv&zKv1V+vn>TY#-(Gau1tkU+>1@djoj8 zvJxx0bp3h1cZk^~55Yr=zaaE%RvfpxY zQb{VOlB$zRet&%{76}imh2gJ_X_H0G`HmB*%&Lb0UaNt%!Ic9X z+o7=%c`CFtSw*NQ2Yy;ejacU};uB->1@TNJvbe(-^4Ogxzie(OVMXI8bWFK@Cy!Bv zOMXs-+tUG6FYJs3l8Bj{!ew%z9YKM=?y1`^t215?HKDswa{0- zaM2A#Sd-O$<4PdU-$p+Zv~RP3kRC=D1AB8wIyM+%=GvDAPI5Zj$w&6L-PQEfBNNY$=NRM`3%R?TzoYb2q)PUraRgrThV$%6ti>>>Pio>d@T^ z&Fc3ZFx?yj%f$xueHSRvod|R`5E$4w?M;wKm{*{|?4?k5GaY7-A2~U7_BH5tT%Pz|;eG1+q7>>Wz-TU)7NtcIhV;gCihAOFj zb77wzb{`UYZyn#+o@D+uN$Zwt%T^v#CRVC9C=@GhNHc9>55gzN9D>?ZWKNzmn{|04 zU87cueh`8_BlPq>7V&Erb4uZJT;|f#$sO;k)c|WS-v+70u@K@^Xj2hDO|M$qCBG(d z@;qQPnPjOoc;|q4b8KDto~rQhhtBxI%AeN3Ve+Y(I!mZ5k}(^NprQK#oXn3CX#{on z>O`>0_&ud4S37+9yD+6;MFb`KAht^&uAS0Q+_)`i0i)rm@dt$&6F~`0h+|rOShs+) zrV4d}ibZ+U;eF*_#l=eGL&UmpBvtDoRFzRUT2p@|AvXT1Z)7v}i90gUVx);BomwSc zx-uKn9UxV~Xb=-xH`GWDXwfa4^Cm8yp=K)#n{yK&8ZAp!M{ugFxa}OeuJa7WmXcO4 zGeg~Eq%+(HL%~5)J)br-BSwO@ge`>j!ToOWI?=NpPk4Sq^m#DGN3$3I>-HISs2)gFGn|wCsuc#?we|8z9;c6VGimdXVjJ^_55;786{VfP2y@rCy z9W$_unuYW94Td>NJnc3HdG?BODS|mM*s^mzBL^i(^~Irq{XDBc3Wnif zMDbWtbj#0eMU5o$vrSGg9L|=57D+$F~cH zG?(|+66B5cY|H7U)3xBh_ITa)<5(dOa{GPtqn^~Ak!*K|XLD^Wo}?^y(wj&^*Pp(P zN82e)d@-a?qpVy9$Maejw=YlXP%M7(D75ZtxjS9oTtBA!1>QP5PAc%I;7CI@Cot%# z0lHh<9Ui89xQTNoD!UuYu!VMp$fRTW_)eV4OcqHX?anGhFSVZC$z(nur_=b2f?NU! zVdSFbQZ)SyagOe;f4OWb2R@=aMEy*+l3 zXj)ynzYEZjza|2wNQP`6jVw6sy=IUk{b1;+l)*$}FuE=xmZX84;!U3KG(lsK@Rs>r zIymw#Qjw_^h(*6th26~5BCC`VvH*t;6WQ^882mu*4bS0#*(BNi$2`jJj@!;*S<58n z9+$?~Dp~jGKm7IHqjTpZQ`gruU|H2L*irm2=Qvp&vB z`$3Mu#;OvIVF!9`zBj4SjO3>bFcI=z-gf;1iExS63H zwmCRUpn&p#h$YK>>eO=6JrXyzT$vhq)0tD=GxoebO(dd;9^1IS zxS%=#+Ux6_)grf9?HxnD$htbw(&aBTka}Zx@OesF!i=mpi=?SNJkkq4Z!SM-Dcsgs z&~sGt2vk>BU#PaMFBzFJVOaAc>)wTQM+ z8gQ3@X<;-|WF5pUnzEI;Wg-0`hZcO<8`*m%I^BPH*YEL?T(^?nYVucK1RcTa6h$)z z--`a!qa6psRpH>*2zg4P*Kpw2DMk73x^7<1V78L@S6xkxs~>uE8{_>6bj>yd-D%|- zGWIf|Fy%fS+$n5?#0P%85WT~WD&MVF-8$rYWM{c5S-Uy+RD^JZ zX=bg!(w^ROG_@2ixP{cp8$rvJ^W%my`yonMk(u04-|793)ZqyFziBvgUbP&St1@m1 zF=m{lges$7Y4-za7^n+9?JKSysW%hhWGIBGIcxk_xWAlH>ZM{hxp_x&6v_wNhZFMn zkoRyNjRlhq3GhBkjRo+_+6;3P(^jJN?Z&cXQ(p({=%wt-X*&H~hR56I3ng=Sy<^(e zLtThH5X{p{`lMuTqTU`dTk{`XCt{hmrq+j+#_I;zch^pVt5%Be*0P52)5bE=BRbT$ z8zT-{`z-+8h;ZB>p1k!h+T{lRwey~h^nC30Q*6b;@ye_zOPw&z2Wb%oJ>-9_U^Zj{ zF8;i>5=L{ygp2~Qz;9#yQkk|ECoIEZ_OVSrG(PJMUtGmNK$3EvR8u>a$U6flZkY}E zmMn4H6hF#e9q?9=t_y0}pPAHhRp>F>_O>5z#%gOP0s1`g>eH=O?B};734M-#moIMM zp4u`Fhe1vciLU8)yDJq|_7MQDkVf))T=p!UER2%m3ms$ZoyvX|0*1Y2naGw>*#d@>tf=&s7vfxmDviEL{Y5yn2UtI4lOs=Dk+G^Ryl!(&CCXz$k}@rt)(( z_?%xAh)bo&^6d}7kw<&hT*v$5Gaq?QbLes8@miZPl`$-yYH;FtD)*gO6ZW55wL=Lj zodUip+V7W*Qlx0HJpmjQ3US92joqa2Bw*5C@C|HB@Ci946wegd#^8$l1pw;5O7)zx z8rqhtP?LN6aRXAUXjI2uqu$GkOzSa~$-unyON}GX?bw*+Y3Ru6&1I`JJ;i68LM$dt z%RS=5v{|dAWy?Mjqth<&vgW4}q)mf)b7}ol?--=e9>o8kw%+b=cYS#nOBU32r}lc;?$xxle5YKiSEV9X@$tB; zyy|9sK0tNDkP58`7*{(e8(xeNwuUiU+58oG0&@fIug0Y=GHi}h7&qm_?po12GzDZM z^M(18KKC!mH&(2BBTXu{+)V-|SDoe#=8$+z4;|^awo}WwzTH8?7*!1IxnSWUnxnYa zEFrilrGckrr zgulKs$O@(*SUS0TvcUzw!lWKST5h8#tedz3zE|T{-x3__l|4r>$)x(eod}sn z&d^?Tbx-wixi|H?ppS0Z6#0f~l^ikLkPhUgLqFY+g@=hZ3^zk3wfe3R`P0%&O^<@R$yuuS4NFgxD7E$ zXOK|_QT+A@Ka!x*w-go4zPK6Vl z=y`n`v~)?O#3K7qd$x?aTdc)a>7+XJkn;xzE@d_}7k@61FBW>p2=8H{!&OP*)lUC9 zq~))P{c6CScZ0L`N`Kn3O+i581iq5zTD`Ykt*?^Y(gy-%^e?kSw6bHElnf=!1WQ$$ zm?K^u%7;PN-MpI3B(2?g2R=%;bn4$-j!j|3%S+_2W9I0g{?u1r6YR!jjaiZj_S#!i zI^`bnG}AH*k=5)S7{hNn8=5(umV-7#A0LOZC@;6N1iMgq*LsSVi%U``mZ{j`oH9_* zJ^n!UOzkQjYvvH3|JkLptLufkZG>ujozRRcX{Fb&J>GRf^mD@=ztv`K!@G`c!8s8b zv$P9i6a|JK=VqE0B}Pp}Ud;v}fLCz)maN8gGWz~{@7;E>NZXRSk`kr=`0iud@#Q-F z2Jf<)?I~+F{HcUVKr`~nd0ABW>vbGcKyeR}_*YBZ*d%(jUpAT^9^C4}E~yL#X{s4K z`G2Joi5*+aGc4~xfo#(()>6C{QdCFD4SZDi<0fiiu-_{hs)pxA)kmt=nv*%y%Z1eg z8Tq(UOOfzU8OFWI9^$pf(@!RJl17AWh#SedVn+@31K#UbZD5 z@8`6c?#dB%R8jkI*S55o8W_AX6Lmas%@oLIah|j-w?3yHmc4|R^jmk3$yuybnjw{F z`MPcl?eb7={4v`1FE5d-X+2|e{-o)#svH$u(5<^3rba4al`|3qxZ2X46w~- zFyUSf?mui=XrHUP`yPL>H>O>r>=vd(HzHa8+(3P}+46La)@^!s;8ZWnmUThCpAEr!%{XqF7&2IM zy}w9*9l3SY1>Rh zZM93;vuB0+v$>FWh|f;?2@VAc0i1kw~tn#)X2n z7|L32txg6Xk!KRw;G2U{fmE5w#$?$yPxfCOL&iv2^r=_n9}7CmePpWKF^Qr=D}@%% ziRA`XSuR0mW9yB)Dfyz7dHtgoGwthuz8WgVLrQj^n%1iVDek@syn~76}&h1Ig z(eMwRb!;J2-%cBk4Qy@K1EU9L8(%xRue&f{6(T1ud6w%L5V5kxCCqw1Y3%+sNX&>R zr$wq8*LK@xbK#)DXj&&5X9qF1NRK6v18t+iqzMPHn#FA5-Ip5Y8|Ea;mgbjTmXQ|S z(x7|(%sk5<@lHpjX;#*^q~(i#sNDg%v&`@10I6z&Ux4Ss)8urCBHp6{3Et`b>-C?$H_fz1M3-N4lR=gu(MoNTDuo^`K?+`sGEC88yi1?!o=hthz>#2{}gEXqk){(UlqwC zqB*FntSknY0YcKW`FYkf>n`;^>>oLP2mQcp%e0tL&u6SHY2%=G(cHSp1zjzi%Xg?0 zkW(Zh`ylzoc>N`{+N4EabX=B)UGmOY%+V{L&d6)F1u@{q5U~<}2*NNz;?EEeLSqfh zSh|;IxeC<+#Zt(LlCd+k(Ua6{!?FcHI>1~HnpwaLN=edMR7^x{n{=z}T3^Qw*TP|f zEPRzJL}V5C09|XIxn`d2-l4(2b#i@+D7al(D`O73L&P@ptaCHX?!x?tTT2?CBPArm z$313xwJzuD!g_vZVb6gGiH$4euBJ1u)4x)qJLo|rgJ6mi!G93|%=l_DYIx>^trkC9 zAQ5i1CstoOiJ<-BM=me=gjExTPlk^Y?!r0zi|34SR4RlQ)r~b=s9$*=Iw?%Nb$FFF z@kFg!p^-PA^w_k}+J=LQ2z-R2^=-Ku>mu`9SWa!Tc(en;`l(Do`VspjEn zByNhFP3a(INT)}sEj8XYuok_tsAgTwdR+9opjZ3APYb(mv>H{tU2;DC zXM=}oHr!lVd?&`G8!3_*r{Op*kE$YG4SyY(DhBPj2L_0QT*qLuyf5W+U-?eT z`Y9-W-!i*56kk0~J-qy|Hy*xiyWRGiF(@bE**TYev03GJ+okTL10DgggmT`OwbsMH zUqZJJZcVoYwb6CeZy^0vP$@R}N7=h)jT77CF6|hpnyg)5?N^Ed+_*KA$OD3_R}ju! zTt~<1vln*uSDVg`?a&HX`MPPOm)!$}nXu{p`tfCH6j3bp(@*pUt~DHuTMnoV$iXgb z|2$aS=HBGqN9i)Khr*{oTHm@Wx4Gb=JT}5Cq6*5(JcNQHuDL+EYeaSk<+u9xAg0n+Wbmfqg! zZNIWm7oVOHq^3^eH@!UDja+XeiqZ>yZ3eF&RS}H1?`|)7!9RgGA%LI?*R2jy(>Sqc zzhh2d|Fu4RqLa-{&_wcA$71mas(@IQaZLJ$jm}3v0`ZAl3M{V!K+@@By-1#s<-?GG zohsU{XK_fsW@T@WelSD8>LVB4HC?>zon~$)5fkNN{>X8B!yeW;+S5ZTSYFdT=hzI2OnNbNH8H(!nNxrVqiQf?37(qu|e(5Swt(b=F<|aobu0SecbX1HYQ(GB2 zvSoM>`&5Jcis+E=5UZVS-0T zYF3})=TEpl%rfts)i(%oKiWTJy1nq!TDp|ls1to;V@*mNo)d&KnlD@o6-$L!XYk1W zvXcca`6(GO=E?#;{9U;CJQ`rXxYG(o?!NmZYq4wSQgm}WR9;ldN7-XyO^=exo2()u zh-cys4jk+6mO+rJk_*d0Vvp^92HAMILo|Nj|dE znK26be@IU5&aGF$EImFH$sru7V$FmX1yW#ur$pki9V^>5$BQ<;@CYzLwVAr*S?xP_-=YUF06;<`G}yTRwzodT4sN;nnKqe?0yC{L9QV|5WcoM`R( z>iE95^<%e$GFezXwxPdxWp)T=HBQ9i|5dgv|Kx#xq3|hAqLgXU)gucfN%$R|ta;4+ z3|)Ke=p7W?dLm4y*X5`J8Woi_=Tp@@=z3tCoT;xB+pHGSv1Wz(`uyRmZ>Pvixid>MCv$4NZ(!1xCr_}gXuhMU{yM39e7k!1%D(9SSKmZ7)A2h2cj_P*hSzn>tQGdbxIy)j`(h z;WW9+nm_Glb?%GwLW@UEY@O=PxMhkxbZ8S2NCE_dyixXs@;(OaIo`KZrKvhgii`jg zSWpe|@m=x2!0jJsRW8B#U|~BjxLo4wz~Xol0XUu8ZKP^|g#6rzCKXO2u4iO=tkF;% zU?R?XAa0=cw44&Tyzt;c>FkF1qEDIVD`wWSLWp+-ipKKCUlG<>--g`^fHz(~ltPRK zEZ?NOH(p=I)Xx?t90LW3I(rH$6+~m}S5t@aj-r0o<;{ z*R{HjhtQu$_V39?yl6C?xFa{)lAyb;=x%+{4F2L=^%qwa&R@*w>sypp<>c45pC)BF zvFy|0#;7{KX1sfdnDO^K5!;kTg@^@Y)%}n#SP{#uW)<=mFZ~+&(ipH5Y_=P7f8)Sm z=j_G|+GxSd5M2)CCsV+gls}N+USG9Yo4ixRfyN@>n`G&uF zzsMpt-OdL*l2M!iHL0AC)SKMGB)6Z#QV@m zj+1retER;OhJVYv~fru|{L(h=TL&q3fHyeT*DCU;50%r+fkZZ+RO9gCyAD_`E) zrA{_5Ff&o3zyIADV)^vF{((OIQycmxo%SD;+JA6yBLBk0F^Je&8UKGa_otZlpLpHBRP%q%`zLnx zPonLgseb@%|K5dvK5=vNe6n=RES&!#sImP^bN?=={pag{8Ib>}p?`MmpW@s<^Zq5p z%=|ydX{;=tz53tCX)ON_Ic?-qPD5#Xp}S8eB#rnYg#<@K64{r7oUjksrK=?K_h&!P z=R8%DCm4_eG z7x7@XX)AbyQS*rb73mLHX4Yyy#xALo!>DB%fk*i5q*Qg`S&_uoKa9n9GY8E|hC=z3 zENaYvY*a6%qG&a?%A^zIIl7IXvBzr;oH8<+^!zk+3u@Zdjdrj1wUb@Ewz>CBx|TP0 zn5y!0v`5~-?L;y^{`(sCZ?xn8FrEJ~FaMjD_CHSJ|1FyK@2iK>e?`;&{rmryC5H8% zefkHQ#>~m`iDv#E(KHrr7OsCq)5bi%XancgKX@kCULe?*ndwQ{5W)vpyQ;XqvXX{tzA>5XmD|yC8i8teqbQsYPloP|;fFI3v;`7Mi{MW1bmB9NwD3`eAm10Vwxhzq8p)pDx?$ zMR144G$WB1U9_Zz9gkcbb^LxD-g5UMaHCeg@$SliJMU^4nlW9Ix^MkrFBFWT$6ee} zvb}J(ur2HhZ{Q+dkvx~3=@xG>0?BSdG&4{MJc%#v{+3u>Z1|n0`rd03t1Ch~Nt*#~c9*%fdOa6RPsB9` zWqAO0;cFIdlNiRg%UsR2uMQOGmDpOuG`_>HG%6z`De216yZBVwJg8q@^y7NJBET4n z!qlbg%WC%9(?7goRx=gjY#}OrZZ3$B)?spky^6M8+ZMNLR(d2 zILI^Q{4ThKB1_hsZ5hVd4L1Wi31d3|KYTa4bc(;QfJ2T0Hj)2tu{#DNPo5?e1K#

*`1Nbn;7m8?zgs_5u3-TXhez{v=!47fEk#<>76xM%Oqa{@@ zUD`L*!wYiWQSPS{`j}u0$?Fr4iz5TvhT@A4BR%Dxe?J>pu~!rq2{)Ggp>A`&WwZ|+?J=Y-;aL{?IWV*Av+c{Qd4A@%Uq;*7e703yFPg2h;5UxcdQDmSs zK!i#CzBOy&H{^#5Mnwcyd(tfdex1T{7D-{dPCw;tdiMTQJDK?G^o4nbBr+0G(J!Z$(l zju!K(kQ~sxzKQ0}4&tRj!1K!JD9 zd;0CFmd7zkdZJ&T8LjJIzhHSw|HvPl3A=%P{$%@|37&-Le&dp<*A`dCOK;EC!vpB^>sUzZtU(68c(T_KM5c%nLeF=8`cYh%Q zfA41Pzo~XdCtgH@$mAQ>Jm1asHXN8n@f0-qEXA$OnUj!BW*hCJ~Bo{Npx`bZd$RyH1jx1x&#pJ`GJ%oBZY zlS3Ry9=B3*MKsW3!y{Eb#sEp+V$w_g0i__r6V?y~Z>;2mEIWiMsWG04fXnD%jUt(h zOxRcWPyfy_2pKO`z}Rj+do<#AZF^@l7In+pKLA1&{9Tu~ykE6k zWza+^^qULuw?MOG))B<}O@~(MMPLG^@M^)=%Oba~yj2^p%F*E7MZ`T3=H6ZsYm}P% z*ceXSX%{B)`EO{7hGI=5y~b5p04|*6tHCz3NxErS5X_6JFfw`_^-sH^ZUgonydZ?i z7N-D$Bs|vB6t?43w&59)4lEGq7*H)Q1WuCSE5#2AYEL3%QTTH<6nOuW_^D3ldp*mz zvJB+mqN0X_{RHFu7u-mYKan*0c8$#RsS*ieuUnj1-RdNoPuYNzrwijIZx_PDO@`3 z*H!X?Gm>cePnf7uVQ!VFn>;gc*DySPu5lvCnMPKui_q}z3);|*IkTlV)Qs7J6PBAD zu6Lr8wkPGhB9QI|)ZA=km4A z)kfUY+IfZTUv(?eInUCv6da)Z1OTq*A@q-N>U`=pXcJFzc6fj^BVrtmG`C&{unx=Z z8|#*-wCo>PTyw^5DNS~cDFuITRCt(TZc&sw1^&&=fa#h+vdp&B#Jyki9Mcn>gK?E? z^4r9%r@x!nH|?3^*)u*^f3dR9cZ>2tkKG5o$P%kKpvYuy|{)!UZBhuJ1( z*$WV*{PS>DMKVjykNJhrzqN#btXsbSmAS<7peQTo$$pb6*N3w^+ABM-?Ks=Vplpm; zCB7j=U2{QOSK0&X`j5*WrUs*#@5ToJNG)b6#U;#wRF&3gp!92es4weX5{fU)Pw4wT z1s>z?mW*88#L)99{$4EgqM2eA<`+ja^emaT?V6TQd~}cz^wlH1`kUCWh`;Ru;D);L{C6QS6JlIJ!U3hy-KH9UP>ic|kXQyYSiXkAn}TmSMj}EAPz)60!EHJIXvaJ7azDy|YH=#i zJe927c_j{zvkh>nn0^^Ezg4zmye;+lF`yUV6drkrNR{XXe-x`N?!}^zc!jD-#Jy7^ z#U&$u|>%p(@{{U3%B102c8L3rkLUpJ&OHF8yx+Pfd1s- zXOK6&FDY=E*F)N468&5PeX(zv@;srJeMh0ZVYF>A=tl#I1%ip%pnK>MML5GBfHH;P zfj&3r=@#QccTH{@>$?D~8g6q@+OS^Hp?5N0$y556Zo{B2q&$X({sL&5Y=1=;V!cA9 z^wHn;q-12fB0x_{eoPDv2YB_0VWVRwKcbRwh5jg?6%BL8JScY~!P6vDqhv zvH{Xfx0wLxhTCkEf+pMOlya&^!RX z!L~Ie5}SQUXaE3TKQ|!Mg>v1{Pze1cd2vJx54{{v$82C`h>UK_S{)vm0XWs)Mx@j= z+vcEbV5^P{EeBW`Y-3V#vQ>wMCZ#NP^~nIr%(lfT=UJ{G(0`@4WriLk|LpCn1(cZ@ zVxrTfxCMn`0@&HEFwjSme-8J>1LzI5zffYaRfmKI0_gP(1<`MklSlfjC{0;d;zMx& z0HfU4&|<(W8%tp55CC9kNQ#c0{B1&v0DUL9$Rsx?)RM9!xyU%zKh%M;pOqyjbP51u zVF?RWqWrw}(JjV;E)Kw8jhzr9L~jP{GP9(I8UPRs44KhW0Qs!3J%1uYjVa@jzjggd z2=xJwGowz3;iFdrekO+)kfw%GQ;q_}8c<{7x&%T?nkkClNScgnSei1y7R>Ah1`!@S zx(LCLNeE#(PkPo69t6OU&cnObzMpHOx3#0Jj|Y09`-$Q=H;!L$u^9%4*WMG)}Oq z#6HJ$I57SG%tqpkxQe(6SaGtUmAk4uP<}16qj}#UI}Ym?pT(LJQ^8ghSHV*417fF) z#E&#rvlxZFN)qA>aYVE+$I(Sm(@Hb;1foKV4?#bggRhf&-H=^}IgmMo;W||Dz}gP? zAZk3CV^vJ_G|;Ex#3}*_W7UATu}a3j4hrgqb=dftq*nXpzxmq9W2_2DHZOBF)85nu zXp1!Ym|CsJ-QnSV0%mI=QzD zpm1P^#oZC?toRWGsFLO_W7=I>Pw_c!dV|_q_^1*%uK1ijts!kjondoF2zHAtT}bUM zailDrrNAq7WF$?b_#8703tTUB@}IVszEC{QzhwluQWNAk0jE)=ZIyWeM<}2GAdmvA=nZ(UxGYl~sYD0Dl6H~yq&_RSr3C2!U6huEj}WCRl|3S-U8Gm2twFc6 zAO@grPF>10r8FK*JHP@Gltf)#cuNX$2I^+lB~IS}GxO?#rfY#}%9`R96d*I|^6Xo7 z&>k>V>n^}AGq)~cT1i@7NmJzLi*z`RfSd&?h*BD!h9R3hYnor$k!I}kR`@i%G#kxW zHhac2yL2S5K*=LQ2@>QXtxPRjz#cj+CXG%VS*Rjufe+G@<^Yz^s4AA^s|XjTPyduQ zqK+(3k+8r3#R8>i66!p#z$3F&0L39nBp?XsC*U>pp3-m*d-^o9v?z^&Uq$hUMJgHcjaQixNI zQ;buJQ$SNjQ{1Mp2QpI_pMX=^fwh3Ug1dq>f_FmNfcrqMLcM-{guayTn()K(JMqf` zTL4oBR|gYGFXLGIgP_Y6Oc%Bd zW)W!-X7Q^VW)<}1SA8~pbbYc-lP;Jp89x`BlyXJuTfNGX2Vc}Gq)P~WhE4Y_M?Vff zGw@RIQZPF33F@>rb+Akrb1%C9`FP}o&9&XJl=irGhc-9gc8#pE1FoZoL!Pwt1)*Bu zh5Q$Qt1y+N!$2BGQ~QB=8YMq1`l9LdBdjrJ(>7U!8)$?wNr3T{Fo}$D6*Wm-r^98- znh{c&?Wy3aI8zwEnh)vS{uGxx7bKa?2ia?Rysl0jTrd$@zMQpgz$Rdm3@qtfre|0TL%+jF;fsM3)%7jCzf}^7THwrMGmcrr3^au z<{3yB6+8wF+XeQg#2&c|{19dpd==&usR{ZK(GLBRZWFsp2wVu#2CM?o2SOWC8(JIu z748vs6SnKYZ^Z8cED3A_f)Szv+zFf!tOMqiz>e?|b5o{k156L>{VO-@BfcG$9gH3B zC3Y80mzkeDcovu(gdmI;)Fa9z_@;N)moED*Pd~Y?RzFv;0We8$NibVTBuFH1BnTuh zUa&L2Mz9y~7cft7Yd^K`@LfoYkZ$Nz@Kxwlke4u<&RxI!&it(X%KaGp)WOog)4-S@ zIl*)x%3#~ze!{weS7BZ9Z}N2EcGddL`KkIP_?dyxfsOeUf{lR5fLDF#mjROp(}$11 z2FHTH0^5h&2gST-cUg7OcLBhxxUSg0lj+lD6EZ_H<1l|=Mr8(PCRBj^23rI@3swTI z>L>jjIvbxEiy4L)R{`c5G&M93Oad$nT-;COyC5<0C-4i70E+;L@QGv^LnwjMfZ-A2 z#6W!mtAcn2M+3X^YsmxkgvrosFw`q zzit?Zr_J#%k1bCa&TB_@ubYPd9XK%_eFbG?EDlX6N}${B$}Vn?-{jV~N;vCLpLCUX z0yBi7-|(^jcDU+oA-R~vZ2V5T(>`Dd>s4T4&mIG*+sfC7W4#m`m^5<@K)0F?Z7alv zAsM>DZAa>8HaP)T-=0*v4oiRDxF_v9{$TuJ$VzN|`h6U2r}zO5i4(fXj*yp22H*wZ zd$p$%MMQ9Lz3_H7q=;7oQ;w%`@1@fzFNaYeT!#26!IxHrKC&po{m zFWGqo?Cbz6+?C4@_0U``@~?5JNF&)_s-zth83(q*wZpd23XVkhV(KPbTQoSh)&r!2 z^99m3&(_vg_s*laKh7B$Ne{V|r|U2uD4i@9incL8Q5+X_jnupoW7U z#asx!RB6-1 z3D>PyOM}GRr7|fcVyp)p5WK3N`j_O!p5)NX(%D+=C0+w}*e|xZBgxL+Bgn*L<}2Dy zI&28~@DR^Xs9rx$J?AEXP~ zk9T=@bt20=s{v&Sgnhe`1%~D->Y==W>X%q==d6o?8$GIi~#OXO*Q(6t{ z)aZtw_Ujccuud!HG#^hk_^{-ce7?wQw-HPyILW(2{9bojuutTJnt@v^uRll~q>uW3 zP7MW3D8ftfcfHRX)4R>rPL{))Nv_kZ&a~Ts>LZMCjo%>aID*4ziRlE)6Nw(io@ zNS{eJs`gFxv`N154~(3I`Cl&H3U_92<6xkBzrgY$y{Z)7Z#YBDK$m+T(H4 zq1^>ZsvcY>S+DMaYob@Mf{GU2Z`&g6FbCg5IUimjIGUiWXus{_gFb|R>WpO5u2|t_ z(2G&rpSz4DU_+%RhUS1JmWr79m1P}GuX2GlQHtb`dV7OaWFo^mGpg-AW~U+ZTt;eK z)v$zg(bh|%aR_YzMCsTTDJTit&BUqkW4;%~-QdF8BvH+*$cXAs}7SNjJAw zs}Pw{2a=(^`oPQw+ZXRC$EUpFhx~X0MZ3;&^(v*_VVKUEkNSSD3%z$~H}cEV>i$h^ zl~_}w95)#~dUllJYTgNye2%6os1n~}Y>I7n2okY32@#-?n!xF3Y&9|xkcfbAebv8O zo^ru%=ILRJeAx)(ieBuT&?hd1GDK8x@z`l_&ADoBof>0lS%nt4 zDC^DooiK;Ah(9e@Qtu<4PW&hNF`nBnmAbbYMSJm3AsGygcc5h}xUzGSe)dnQSX^h3 za7s63Es$ss`})%Mt8>(e+6ftP zs_btQcPsg{>QB-cuKRIDj+FSi8p*t$c3R!@YRKhk5WCn1HmbzwoPH87aFsNO!m@O1 zLA+Q+Dz;B|d#;QDs;I2I)bKvkXm+QchDB1>VlC5D(qQXKwXLd9kmZ>)#|( ze!$*wgCUCVng1o(g~01lU`J?d!;A!OdEJ6_5Hv2%l0oE2{*j3OhDtDucL!@=lpck4 zCE1{F6xhEOo05?75lhd^mY(!C50FkX0#xlo=AIEMJk5Jt-BoT63)J9A!2l~ro%&O! zHl|u0NM92;1wT)3TB{+0Rd)xH@M2G6DFR}cs%A#x@ z`WcR+$Vgutw$?J@z0zwJt|QxD%biOl$>mv^UJ&H^YEA?5=- zN_wtB$ROv{H_Z_I_$(rJ%G9uVluX|SB;C6fnN8ts`$BAt{8UVw%dY1 zeWO5_)^`!DB@xfbnT(`N$?6iDGd~j`RP8C2Nkik@Wb$AmWiBV@^SE5TnrjhxzQ5Xc zu6czv&=fgk;k~wQ3Hw4$x2~+8Mu|!g14t5)BqFIn0VOL*k_{rDWCj~=G55Whp=#at-mh0bcb{{1`p(|F z*Q#%ou})!_`ehy2nn|nTxIT9Jq3vJQt{cilvsyaFy^R^Y^waCEv(KZ$ecdB`z-}(_ z2`E*mC8C~5*k1R#tEk+?uhlH?Ln}hgKQhqo3sMzQfZlk`HO^h7?VRwhsM#l5Ub!uB z{H9vl+1KJ4`cyEWqKDz%) z^?n|gg6w>g<^i%8=icoHX9ZI%@}o%F&daTyH9XPN`^U#p#^Q4A^4aJ&uShzPhYOYN zwMD!3KB@+_?+M0p9V2gd>%Fk1X=q%1djB39z$v!E*Kv?l=tN_ywype!B1VPYx!zGU(j{~=_Wn~&Aul(PTC%<8qE-SOQY*O3Iw$naQeXbEtY zrqmRR0$Byi`OC9SFI99I49b5~qmDyP9i7<7v@Xts+Gua)_o?SZee>wx8$x4 zvu2-2O!v!_rR%CY9bYS)39Vl!E6M1SlfU4!IGYsz5f>x>921^wWmq^ zES;a@(_aFtseX<}29@x{}{cjW$dD?iNU>EDH+0r0tTfz)isgdgPQ}vA^0p zJGxdfaIW!=mWxy*hNr}*=bBO7LT`O;yqLF-$;Ab28Y|hR?B$zy>X3|cMeC6KRP!rq zp@0C-#CP}?ueuvfmwpjVt8BAfUfRvRduhJNE-^Y*tPZot*cUc+!aPDvS4~hq^pr$r zWlL3d^6)8)CtF2U@8D=!#NoG^)~RyJQT8E5Hw%BVMje#gb1CR@`lz|@Rh*S#%LrrC z+djS1x`*_9VHG7QfNNAV!*g>gLt6_JWU=d+iPdT7fe?XXa=$)wXmg*X^6Y_jW~ySr z6JJYmjn{dSGR&*9-b;V`xCT$_Y_x)b?veb`IQ|5K!ckA{`=XtRd7qc}yloEY2vwSj zpY({(>=|09&M#}O=h5MQ>=UE)3~OHq89o*XqpA9E$1NXR(x~Zk!k-~Eo%@`UW?7t6 z$H6rB_2S80O540n%J+mwdroz|vy_;YQl)Dg#wSu$MdGpJqw2~rID$xy^>(4KO7R19 zAu-X|j>YW{4CHyWO!%!<&8Wtlz8_uderWHv7&ZApPPE=gJtuB4X%gZxV#&|)eT=QR zRE3d$B1qNefq9Aig_Qiq*>WfAGt4=o?$%Mqd2TJiz@YK6VGL} zi@QIy`#k&5{xQlTjqAV#2X2-tZBYOR?h;O+De7fY`hfXFXKz2TNA`)8Mn&z3zya&2 zUk9J}2jxb|>Wsgt~Z3%0W#0R*yE6SI>@ekmb7gx7SxuI^zbEpyXSh3}oSlbBp zsUP%Fy2Hfy+#h?R_a(O7T}T@@r*a=kb+I`ZI6n)?JXq)Vs$3_5{_uOnv*bB&y8NGiQqaq1D&K6 z(Hze)lSJ|x&WlU6zbpOR#mQU8@($HXwx&KtlS#Jix6V3m&33ZJ#oyjBr-wz~9gC4% zy-{|U>VGTLdO1e*(0;CH&XKWwF`QOfBB?i-S5?IBF+4i>I-YY%d33i|{EvjulNz@d z^DpqIUtP?P)>A7?60*NLZY#*rG{4I?ySsdyj(R541(^KeOL6w2TBdP zn$~o5en^Ovj*8>y>%Eu*F1LF4zq4;W`Wc>6*mVM}>5FwQ`-;Y>=58-;^Ot6tHR<+Q zSImw<8^-1$q$bS@5w7kbQ}#O-jcXS;OsdOw=2ocLswtaQF;MUHgcx<)0@8#rS5jUb z=4KkP0P>BmwMlZzxb~5IC2B5?^3sMe4n8DfvPV#n0$!rxV-T(WX9&zdg?`6Ek$!*`uA6Za=7-;3bjx3()G>xChKRkRohNC z&6bv3D}$DIWb^Qoi$t3rb~W9RUO6xsX8D{`j44}2en)8`=O2BdMSJsxKZ(_1CRbeg z<8d{IjbfkL;JHf2EG`vmK~6;hW|zryNd}1jp>9XF&&JF5{gGx4tPwp_%Zl~AZJw!x zBdyb}pSd<(N6}tYDPOgzQls3yb9{%b==uZY^{Ub#v*19vR}Lqwv()JNF|1QhD9Uon zmlR0?#aKx1;rqC@?wwQJj6M~{iPyF@mavH@@UBgJSvIUOdD1=Qe>8+Mz0I3Yjw0VS zF}0tG1IxZkfL@GktrT|raXl&@AREekY4hJ1<5YSrrXR?~#H+JC6r zzMHo6lZ8=&5S08SM?Q@Y=hSC#afkM;{zTh1{iabSF5o|f?r zZ;R<}$=544j79T)uU?TjJDU(qxBl#2q0;3+|L6)p0f(j~4Y@Zu-;n3@7qqo?m!mA@ z50^RGcBSW+z04XM))VNgsM_iBxNpE=tbyZ$TB(G$f$n^&uXEjzrmxpB6ADK&Sm znt{1H=S-7b$miP!K|TGqCTnH1r|g$po@tr%7F;oMbTCl)<@!{DL$V{tylS^|#84g! zdke36W8KvI{a3HKX-5B$P7h`Z+ZnS_YHZ#dBV)I>ZAi{qQAFpF7=izXf=8fdP{|ec z@!W8`VN;3ZYNp1Vd*dN{^AaPq934IhbukyH@N!56lCx0jSY)O_pg+~_ zRQCGggI6OX7WSww{)mV$R9~9g_xXcmJ{L26@!~#ajiTBHjo?zU3A17FF-LrfuE8jwB>Kw;tqwQj?DN}@&aMmq* z*5pz@gO-P`&BPXtH*UFhdV{HxNv21yKa~(TVa^}>sV2kH{M?GR;=QS<>y7cx^W^vP zoUlmW%QJ3UV)lr>bNr6f;UZn(A1dQs%`#u^UzuE)O)vT)DHCw#>2tI2kr0=J#T(hl z^wM4}-6zvJta5P^BEt6UdK%uV23!h-#`@PX7Zl=WJO>7j`7CEDFPyB6eUWIKpMOg; zt-QLzra#X^-M^-YC*Wsn%gJE3;?98Jl15ir6y@0q&Sw$%rpJ=G4F_A^oZ!pN?LU1r zf-!hUcaCU6E>nf~-lx0=^fqLI*5}VwfqfyIJ|8&^Eg~DrvVTfPzB5(`)69>fHza+# zy85j0%o>4VwwcT(4Gji9p&h9?9e<~uTJn2%{mg1E5Y<#DKNX^xQN<_HU~*@zG_LY( zd23u{jUX{J;!EbV0ASOe`*~(zafVH#v3FUK{ms#U%7vpQ;eHH_LaSXO&hB1oB5hR5 zyt$3%>z(4O+)9(besi*Bvp~NSk0%iSegpk~WqwZvF?~aAZ zIg0M*&O3WxK@vd*0AX&;e}6^X11n7+gEB+{i9mqAOzv_1(rK9WAwwa702zMAUD^7w z#(7732M;Vjq{zUZ0w+TlSxpaXC&zP&&h}2{v6~+chZ#CbN-o~mGtvZ{3jAQ|{qB4sPD2PU~7cs>8&!|9uv{w6eG{~ekwydG2l{^Ab& z|8sf>o4&&yQ*a~zf<0C-#=_rG-^}nP#{p0H2ixI)q7o2E!OJ~(&b$J#P2B%2FCVzP8dU6DnC|3L6b?X?9_@QZRZENOn3B6O2gQqlwCVKR$$j3zs_SeWqH=UXo zGy@I%RVmG$H>z(mDHF3yjiy&vI_rv?&=>DNk<0!<6pD?40^k3ciL!}zBok#59{*sX zc)Ojq!{A`d0~p+24;CPkiDaxD_AeP8-nRK*o&QS)fe;zy&25q4aCjU-h9{D7c$ob3 z&vke*2?P-`_;)-BsRM^25RvPM0Fel6Jr75u5D91*8G!HqKlQ@vKnP(UjtJq1sC5v5 zf;tZ(lVEP!*7G2kjf0SpaGPan>pBvSNJ8o*;Q$<5fw!CoQ3x~xRBwnApM0aB>@?GxN{Iu>&Qe@tYB6jOn%(zFPRL%w*Vo7 zd0Qy^0CWt<06;<60zfF-lR*L=r2{0vtVx7k7#qkOK@iM!MXUpeXiUP_h=kk=5Yd=~ z`!gy>00~b*VhD~D9vLeDHW_6L2_hqL0FVirRdMtAyS_kVR15%!2%>C;$PijaLETjl zu1&}sfjGFDAoPMT2@fr!P>`4e@pu#_K|BeCD-aK$Y7U$=5T%1aAR%iVNFd{p_X8w= z$QprzHZL{O4*2j0J}6`Ys=jQNXY@J{rn4h#25@B5Isn}VDF8efqxMoz{fz?S0O1=PKQgLs zL2xNS)*%RwNA_uWF9nB;9|RClc!A*m1Be{qH?JxJ_pl5PBJ{#C0uqz3j0p4Dx5NsM zBT#Ut^9U3WVIQ7IBqL`FSOy~R3?6R3Frj{{4k8(k?5lWqh9V=d0n0$-d;rfwL}Xup zWe~Ct;^Fpz?5ps6fCG@e0U!bTM=m|wtR0=syJ3zVl|AX`d;ZT^Pu9@I#RCiHZF3rg i|9UywxnN;a|C|inJ*?e4{+tWp(_uVfL`7Bg)&2$4o#Cti diff --git a/lib/morpho-blue-irm/lib/solmate/foundry.toml b/lib/morpho-blue-irm/lib/solmate/foundry.toml deleted file mode 100644 index ebdfa11..0000000 --- a/lib/morpho-blue-irm/lib/solmate/foundry.toml +++ /dev/null @@ -1,7 +0,0 @@ -[profile.default] -solc = "0.8.15" -bytecode_hash = "none" -optimizer_runs = 1000000 - -[profile.intense.fuzz] -runs = 10000 diff --git a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/.gitignore b/lib/morpho-blue-irm/lib/solmate/lib/ds-test/.gitignore deleted file mode 100644 index 63f0b2c..0000000 --- a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.dapple -/build -/out diff --git a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/LICENSE b/lib/morpho-blue-irm/lib/solmate/lib/ds-test/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/Makefile b/lib/morpho-blue-irm/lib/solmate/lib/ds-test/Makefile deleted file mode 100644 index 661dac4..0000000 --- a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all:; dapp build - -test: - -dapp --use solc:0.4.23 build - -dapp --use solc:0.4.26 build - -dapp --use solc:0.5.17 build - -dapp --use solc:0.6.12 build - -dapp --use solc:0.7.5 build - -demo: - DAPP_SRC=demo dapp --use solc:0.7.5 build - -hevm dapp-test --verbose 3 - -.PHONY: test demo diff --git a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/default.nix b/lib/morpho-blue-irm/lib/solmate/lib/ds-test/default.nix deleted file mode 100644 index cf65419..0000000 --- a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ solidityPackage, dappsys }: solidityPackage { - name = "ds-test"; - src = ./src; -} diff --git a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/demo/demo.sol b/lib/morpho-blue-irm/lib/solmate/lib/ds-test/demo/demo.sol deleted file mode 100644 index f3bb48e..0000000 --- a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/demo/demo.sol +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.5.0; - -import "../src/test.sol"; - -contract DemoTest is DSTest { - function test_this() public pure { - require(true); - } - function test_logs() public { - emit log("-- log(string)"); - emit log("a string"); - - emit log("-- log_named_uint(string, uint)"); - emit log_named_uint("uint", 512); - - emit log("-- log_named_int(string, int)"); - emit log_named_int("int", -512); - - emit log("-- log_named_address(string, address)"); - emit log_named_address("address", address(this)); - - emit log("-- log_named_bytes32(string, bytes32)"); - emit log_named_bytes32("bytes32", "a string"); - - emit log("-- log_named_bytes(string, bytes)"); - emit log_named_bytes("bytes", hex"cafefe"); - - emit log("-- log_named_string(string, string)"); - emit log_named_string("string", "a string"); - - emit log("-- log_named_decimal_uint(string, uint, uint)"); - emit log_named_decimal_uint("decimal uint", 1.0e18, 18); - - emit log("-- log_named_decimal_int(string, int, uint)"); - emit log_named_decimal_int("decimal int", -1.0e18, 18); - } - event log_old_named_uint(bytes32,uint); - function test_old_logs() public { - emit log_old_named_uint("key", 500); - emit log_named_bytes32("bkey", "val"); - } - function test_trace() public view { - this.echo("string 1", "string 2"); - } - function test_multiline() public { - emit log("a multiline\\nstring"); - emit log("a multiline string"); - emit log_bytes("a string"); - emit log_bytes("a multiline\nstring"); - emit log_bytes("a multiline\\nstring"); - emit logs(hex"0000"); - emit log_named_bytes("0x0000", hex"0000"); - emit logs(hex"ff"); - } - function echo(string memory s1, string memory s2) public pure - returns (string memory, string memory) - { - return (s1, s2); - } - - function prove_this(uint x) public { - emit log_named_uint("sym x", x); - assertGt(x + 1, 0); - } - - function test_logn() public { - assembly { - log0(0x01, 0x02) - log1(0x01, 0x02, 0x03) - log2(0x01, 0x02, 0x03, 0x04) - log3(0x01, 0x02, 0x03, 0x04, 0x05) - } - } - - event MyEvent(uint, uint indexed, uint, uint indexed); - function test_events() public { - emit MyEvent(1, 2, 3, 4); - } - - function test_asserts() public { - string memory err = "this test has failed!"; - emit log("## assertTrue(bool)\n"); - assertTrue(false); - emit log("\n"); - assertTrue(false, err); - - emit log("\n## assertEq(address,address)\n"); - assertEq(address(this), msg.sender); - emit log("\n"); - assertEq(address(this), msg.sender, err); - - emit log("\n## assertEq32(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(uint,uint)\n"); - assertEq(uint(0), 1); - emit log("\n"); - assertEq(uint(0), 1, err); - - emit log("\n## assertEq(int,int)\n"); - assertEq(-1, -2); - emit log("\n"); - assertEq(-1, -2, err); - - emit log("\n## assertEqDecimal(int,int,uint)\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertEqDecimal(uint,uint,uint)\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGt(uint,uint)\n"); - assertGt(uint(0), 0); - emit log("\n"); - assertGt(uint(0), 0, err); - - emit log("\n## assertGt(int,int)\n"); - assertGt(-1, -1); - emit log("\n"); - assertGt(-1, -1, err); - - emit log("\n## assertGtDecimal(int,int,uint)\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGtDecimal(uint,uint,uint)\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGe(uint,uint)\n"); - assertGe(uint(0), 1); - emit log("\n"); - assertGe(uint(0), 1, err); - - emit log("\n## assertGe(int,int)\n"); - assertGe(-1, 0); - emit log("\n"); - assertGe(-1, 0, err); - - emit log("\n## assertGeDecimal(int,int,uint)\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGeDecimal(uint,uint,uint)\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertLt(uint,uint)\n"); - assertLt(uint(0), 0); - emit log("\n"); - assertLt(uint(0), 0, err); - - emit log("\n## assertLt(int,int)\n"); - assertLt(-1, -1); - emit log("\n"); - assertLt(-1, -1, err); - - emit log("\n## assertLtDecimal(int,int,uint)\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLtDecimal(uint,uint,uint)\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertLe(uint,uint)\n"); - assertLe(uint(1), 0); - emit log("\n"); - assertLe(uint(1), 0, err); - - emit log("\n## assertLe(int,int)\n"); - assertLe(0, -1); - emit log("\n"); - assertLe(0, -1, err); - - emit log("\n## assertLeDecimal(int,int,uint)\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLeDecimal(uint,uint,uint)\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertEq(string,string)\n"); - string memory s1 = "string 1"; - string memory s2 = "string 2"; - assertEq(s1, s2); - emit log("\n"); - assertEq(s1, s2, err); - - emit log("\n## assertEq0(bytes,bytes)\n"); - assertEq0(hex"abcdef01", hex"abcdef02"); - emit log("\n"); - assertEq0(hex"abcdef01", hex"abcdef02", err); - } -} - -contract DemoTestWithSetUp { - function setUp() public { - } - function test_pass() public pure { - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/package.json b/lib/morpho-blue-irm/lib/solmate/lib/ds-test/package.json deleted file mode 100644 index 4802ada..0000000 --- a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ds-test", - "version": "1.0.0", - "description": "Assertions, equality checks and other test helpers ", - "bugs": "https://github.com/dapphub/ds-test/issues", - "license": "GPL-3.0", - "author": "Contributors to ds-test", - "files": [ - "src/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/dapphub/ds-test.git" - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/src/test.sol b/lib/morpho-blue-irm/lib/solmate/lib/ds-test/src/test.sol deleted file mode 100644 index 515a3bd..0000000 --- a/lib/morpho-blue-irm/lib/solmate/lib/ds-test/src/test.sol +++ /dev/null @@ -1,469 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pragma solidity >=0.5.0; - -contract DSTest { - event log (string); - event logs (bytes); - - event log_address (address); - event log_bytes32 (bytes32); - event log_int (int); - event log_uint (uint); - event log_bytes (bytes); - event log_string (string); - - event log_named_address (string key, address val); - event log_named_bytes32 (string key, bytes32 val); - event log_named_decimal_int (string key, int val, uint decimals); - event log_named_decimal_uint (string key, uint val, uint decimals); - event log_named_int (string key, int val); - event log_named_uint (string key, uint val); - event log_named_bytes (string key, bytes val); - event log_named_string (string key, string val); - - bool public IS_TEST = true; - bool private _failed; - - address constant HEVM_ADDRESS = - address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); - - modifier mayRevert() { _; } - modifier testopts(string memory) { _; } - - function failed() public returns (bool) { - if (_failed) { - return _failed; - } else { - bool globalFailed = false; - if (hasHEVMContext()) { - (, bytes memory retdata) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("load(address,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed")) - ) - ); - globalFailed = abi.decode(retdata, (bool)); - } - return globalFailed; - } - } - - function fail() internal { - if (hasHEVMContext()) { - (bool status, ) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("store(address,bytes32,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x01))) - ) - ); - status; // Silence compiler warnings - } - _failed = true; - } - - function hasHEVMContext() internal view returns (bool) { - uint256 hevmCodeSize = 0; - assembly { - hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) - } - return hevmCodeSize > 0; - } - - modifier logs_gas() { - uint startGas = gasleft(); - _; - uint endGas = gasleft(); - emit log_named_uint("gas", startGas - endGas); - } - - function assertTrue(bool condition) internal { - if (!condition) { - emit log("Error: Assertion Failed"); - fail(); - } - } - - function assertTrue(bool condition, string memory err) internal { - if (!condition) { - emit log_named_string("Error", err); - assertTrue(condition); - } - } - - function assertEq(address a, address b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [address]"); - emit log_named_address(" Expected", b); - emit log_named_address(" Actual", a); - fail(); - } - } - function assertEq(address a, address b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes32 a, bytes32 b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [bytes32]"); - emit log_named_bytes32(" Expected", b); - emit log_named_bytes32(" Actual", a); - fail(); - } - } - function assertEq(bytes32 a, bytes32 b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - function assertEq32(bytes32 a, bytes32 b) internal { - assertEq(a, b); - } - function assertEq32(bytes32 a, bytes32 b, string memory err) internal { - assertEq(a, b, err); - } - - function assertEq(int a, int b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [int]"); - emit log_named_int(" Expected", b); - emit log_named_int(" Actual", a); - fail(); - } - } - function assertEq(int a, int b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEq(uint a, uint b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [uint]"); - emit log_named_uint(" Expected", b); - emit log_named_uint(" Actual", a); - fail(); - } - } - function assertEq(uint a, uint b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEqDecimal(int a, int b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal int]"); - emit log_named_decimal_int(" Expected", b, decimals); - emit log_named_decimal_int(" Actual", a, decimals); - fail(); - } - } - function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - function assertEqDecimal(uint a, uint b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Expected", b, decimals); - emit log_named_decimal_uint(" Actual", a, decimals); - fail(); - } - } - function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - - function assertGt(uint a, uint b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGt(uint a, uint b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGt(int a, int b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGt(int a, int b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGtDecimal(int a, int b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - function assertGtDecimal(uint a, uint b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - - function assertGe(uint a, uint b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGe(uint a, uint b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGe(int a, int b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGe(int a, int b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGeDecimal(int a, int b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - function assertGeDecimal(uint a, uint b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertLt(uint a, uint b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLt(uint a, uint b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLt(int a, int b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLt(int a, int b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLtDecimal(int a, int b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - function assertLtDecimal(uint a, uint b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - - function assertLe(uint a, uint b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLe(uint a, uint b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLe(int a, int b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLe(int a, int b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLeDecimal(int a, int b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - function assertLeDecimal(uint a, uint b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertEq(string memory a, string memory b) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log("Error: a == b not satisfied [string]"); - emit log_named_string(" Expected", b); - emit log_named_string(" Actual", a); - fail(); - } - } - function assertEq(string memory a, string memory b, string memory err) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { - ok = true; - if (a.length == b.length) { - for (uint i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - ok = false; - } - } - } else { - ok = false; - } - } - function assertEq0(bytes memory a, bytes memory b) internal { - if (!checkEq0(a, b)) { - emit log("Error: a == b not satisfied [bytes]"); - emit log_named_bytes(" Expected", b); - emit log_named_bytes(" Actual", a); - fail(); - } - } - function assertEq0(bytes memory a, bytes memory b, string memory err) internal { - if (!checkEq0(a, b)) { - emit log_named_string("Error", err); - assertEq0(a, b); - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/package-lock.json b/lib/morpho-blue-irm/lib/solmate/package-lock.json deleted file mode 100644 index b99f283..0000000 --- a/lib/morpho-blue-irm/lib/solmate/package-lock.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "name": "solmate", - "version": "6.2.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@solidity-parser/parser": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.13.2.tgz", - "integrity": "sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", - "dev": true - }, - "prettier-plugin-solidity": { - "version": "1.0.0-beta.16", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.16.tgz", - "integrity": "sha512-xVBcnoWpe52dNnCCbqPHC9ZrTWXcNfldf852ZD0DBcHDqVMwjHTAPEdfBVy6FczbFpVa8bmxQil+G5XkEz5WHA==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.13.2", - "emoji-regex": "^9.2.2", - "escape-string-regexp": "^4.0.0", - "semver": "^7.3.5", - "solidity-comments-extractor": "^0.0.7", - "string-width": "^4.2.2" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - } - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/package.json b/lib/morpho-blue-irm/lib/solmate/package.json deleted file mode 100644 index e94cbdf..0000000 --- a/lib/morpho-blue-irm/lib/solmate/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "solmate", - "license": "AGPL-3.0-only", - "version": "6.2.0", - "description": "Modern, opinionated and gas optimized building blocks for smart contract development.", - "files": [ - "src/**/*.sol" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/transmissions11/solmate.git" - }, - "devDependencies": { - "prettier": "^2.3.1", - "prettier-plugin-solidity": "^1.0.0-beta.13" - }, - "scripts": { - "lint": "prettier --write **.sol" - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/auth/Auth.sol b/lib/morpho-blue-irm/lib/solmate/src/auth/Auth.sol deleted file mode 100644 index 3807ccd..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/auth/Auth.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) -/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) -abstract contract Auth { - event OwnershipTransferred(address indexed user, address indexed newOwner); - - event AuthorityUpdated(address indexed user, Authority indexed newAuthority); - - address public owner; - - Authority public authority; - - constructor(address _owner, Authority _authority) { - owner = _owner; - authority = _authority; - - emit OwnershipTransferred(msg.sender, _owner); - emit AuthorityUpdated(msg.sender, _authority); - } - - modifier requiresAuth() virtual { - require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED"); - - _; - } - - function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) { - Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas. - - // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be - // aware that this makes protected functions uncallable even to the owner if the authority is out of order. - return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner; - } - - function setAuthority(Authority newAuthority) public virtual { - // We check if the caller is the owner first because we want to ensure they can - // always swap out the authority even if it's reverting or using up a lot of gas. - require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig)); - - authority = newAuthority; - - emit AuthorityUpdated(msg.sender, newAuthority); - } - - function transferOwnership(address newOwner) public virtual requiresAuth { - owner = newOwner; - - emit OwnershipTransferred(msg.sender, newOwner); - } -} - -/// @notice A generic interface for a contract which provides authorization data to an Auth instance. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) -/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) -interface Authority { - function canCall( - address user, - address target, - bytes4 functionSig - ) external view returns (bool); -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/auth/Owned.sol b/lib/morpho-blue-irm/lib/solmate/src/auth/Owned.sol deleted file mode 100644 index e82b44d..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/auth/Owned.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Simple single owner authorization mixin. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol) -abstract contract Owned { - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event OwnershipTransferred(address indexed user, address indexed newOwner); - - /*////////////////////////////////////////////////////////////// - OWNERSHIP STORAGE - //////////////////////////////////////////////////////////////*/ - - address public owner; - - modifier onlyOwner() virtual { - require(msg.sender == owner, "UNAUTHORIZED"); - - _; - } - - /*////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor(address _owner) { - owner = _owner; - - emit OwnershipTransferred(address(0), _owner); - } - - /*////////////////////////////////////////////////////////////// - OWNERSHIP LOGIC - //////////////////////////////////////////////////////////////*/ - - function transferOwnership(address newOwner) public virtual onlyOwner { - owner = newOwner; - - emit OwnershipTransferred(msg.sender, newOwner); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/auth/authorities/MultiRolesAuthority.sol b/lib/morpho-blue-irm/lib/solmate/src/auth/authorities/MultiRolesAuthority.sol deleted file mode 100644 index 3ff80bb..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/auth/authorities/MultiRolesAuthority.sol +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {Auth, Authority} from "../Auth.sol"; - -/// @notice Flexible and target agnostic role based Authority that supports up to 256 roles. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/authorities/MultiRolesAuthority.sol) -contract MultiRolesAuthority is Auth, Authority { - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled); - - event PublicCapabilityUpdated(bytes4 indexed functionSig, bool enabled); - - event RoleCapabilityUpdated(uint8 indexed role, bytes4 indexed functionSig, bool enabled); - - event TargetCustomAuthorityUpdated(address indexed target, Authority indexed authority); - - /*////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor(address _owner, Authority _authority) Auth(_owner, _authority) {} - - /*////////////////////////////////////////////////////////////// - CUSTOM TARGET AUTHORITY STORAGE - //////////////////////////////////////////////////////////////*/ - - mapping(address => Authority) public getTargetCustomAuthority; - - /*////////////////////////////////////////////////////////////// - ROLE/USER STORAGE - //////////////////////////////////////////////////////////////*/ - - mapping(address => bytes32) public getUserRoles; - - mapping(bytes4 => bool) public isCapabilityPublic; - - mapping(bytes4 => bytes32) public getRolesWithCapability; - - function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) { - return (uint256(getUserRoles[user]) >> role) & 1 != 0; - } - - function doesRoleHaveCapability(uint8 role, bytes4 functionSig) public view virtual returns (bool) { - return (uint256(getRolesWithCapability[functionSig]) >> role) & 1 != 0; - } - - /*////////////////////////////////////////////////////////////// - AUTHORIZATION LOGIC - //////////////////////////////////////////////////////////////*/ - - function canCall( - address user, - address target, - bytes4 functionSig - ) public view virtual override returns (bool) { - Authority customAuthority = getTargetCustomAuthority[target]; - - if (address(customAuthority) != address(0)) return customAuthority.canCall(user, target, functionSig); - - return - isCapabilityPublic[functionSig] || bytes32(0) != getUserRoles[user] & getRolesWithCapability[functionSig]; - } - - /*/////////////////////////////////////////////////////////////// - CUSTOM TARGET AUTHORITY CONFIGURATION LOGIC - //////////////////////////////////////////////////////////////*/ - - function setTargetCustomAuthority(address target, Authority customAuthority) public virtual requiresAuth { - getTargetCustomAuthority[target] = customAuthority; - - emit TargetCustomAuthorityUpdated(target, customAuthority); - } - - /*////////////////////////////////////////////////////////////// - PUBLIC CAPABILITY CONFIGURATION LOGIC - //////////////////////////////////////////////////////////////*/ - - function setPublicCapability(bytes4 functionSig, bool enabled) public virtual requiresAuth { - isCapabilityPublic[functionSig] = enabled; - - emit PublicCapabilityUpdated(functionSig, enabled); - } - - /*////////////////////////////////////////////////////////////// - USER ROLE ASSIGNMENT LOGIC - //////////////////////////////////////////////////////////////*/ - - function setUserRole( - address user, - uint8 role, - bool enabled - ) public virtual requiresAuth { - if (enabled) { - getUserRoles[user] |= bytes32(1 << role); - } else { - getUserRoles[user] &= ~bytes32(1 << role); - } - - emit UserRoleUpdated(user, role, enabled); - } - - /*////////////////////////////////////////////////////////////// - ROLE CAPABILITY CONFIGURATION LOGIC - //////////////////////////////////////////////////////////////*/ - - function setRoleCapability( - uint8 role, - bytes4 functionSig, - bool enabled - ) public virtual requiresAuth { - if (enabled) { - getRolesWithCapability[functionSig] |= bytes32(1 << role); - } else { - getRolesWithCapability[functionSig] &= ~bytes32(1 << role); - } - - emit RoleCapabilityUpdated(role, functionSig, enabled); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/auth/authorities/RolesAuthority.sol b/lib/morpho-blue-irm/lib/solmate/src/auth/authorities/RolesAuthority.sol deleted file mode 100644 index aa5cc71..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/auth/authorities/RolesAuthority.sol +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {Auth, Authority} from "../Auth.sol"; - -/// @notice Role based Authority that supports up to 256 roles. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/authorities/RolesAuthority.sol) -/// @author Modified from Dappsys (https://github.com/dapphub/ds-roles/blob/master/src/roles.sol) -contract RolesAuthority is Auth, Authority { - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled); - - event PublicCapabilityUpdated(address indexed target, bytes4 indexed functionSig, bool enabled); - - event RoleCapabilityUpdated(uint8 indexed role, address indexed target, bytes4 indexed functionSig, bool enabled); - - /*////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor(address _owner, Authority _authority) Auth(_owner, _authority) {} - - /*////////////////////////////////////////////////////////////// - ROLE/USER STORAGE - //////////////////////////////////////////////////////////////*/ - - mapping(address => bytes32) public getUserRoles; - - mapping(address => mapping(bytes4 => bool)) public isCapabilityPublic; - - mapping(address => mapping(bytes4 => bytes32)) public getRolesWithCapability; - - function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) { - return (uint256(getUserRoles[user]) >> role) & 1 != 0; - } - - function doesRoleHaveCapability( - uint8 role, - address target, - bytes4 functionSig - ) public view virtual returns (bool) { - return (uint256(getRolesWithCapability[target][functionSig]) >> role) & 1 != 0; - } - - /*////////////////////////////////////////////////////////////// - AUTHORIZATION LOGIC - //////////////////////////////////////////////////////////////*/ - - function canCall( - address user, - address target, - bytes4 functionSig - ) public view virtual override returns (bool) { - return - isCapabilityPublic[target][functionSig] || - bytes32(0) != getUserRoles[user] & getRolesWithCapability[target][functionSig]; - } - - /*////////////////////////////////////////////////////////////// - ROLE CAPABILITY CONFIGURATION LOGIC - //////////////////////////////////////////////////////////////*/ - - function setPublicCapability( - address target, - bytes4 functionSig, - bool enabled - ) public virtual requiresAuth { - isCapabilityPublic[target][functionSig] = enabled; - - emit PublicCapabilityUpdated(target, functionSig, enabled); - } - - function setRoleCapability( - uint8 role, - address target, - bytes4 functionSig, - bool enabled - ) public virtual requiresAuth { - if (enabled) { - getRolesWithCapability[target][functionSig] |= bytes32(1 << role); - } else { - getRolesWithCapability[target][functionSig] &= ~bytes32(1 << role); - } - - emit RoleCapabilityUpdated(role, target, functionSig, enabled); - } - - /*////////////////////////////////////////////////////////////// - USER ROLE ASSIGNMENT LOGIC - //////////////////////////////////////////////////////////////*/ - - function setUserRole( - address user, - uint8 role, - bool enabled - ) public virtual requiresAuth { - if (enabled) { - getUserRoles[user] |= bytes32(1 << role); - } else { - getUserRoles[user] &= ~bytes32(1 << role); - } - - emit UserRoleUpdated(user, role, enabled); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/mixins/ERC4626.sol b/lib/morpho-blue-irm/lib/solmate/src/mixins/ERC4626.sol deleted file mode 100644 index af56c15..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/mixins/ERC4626.sol +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {ERC20} from "../tokens/ERC20.sol"; -import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; -import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol"; - -/// @notice Minimal ERC4626 tokenized Vault implementation. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol) -abstract contract ERC4626 is ERC20 { - using SafeTransferLib for ERC20; - using FixedPointMathLib for uint256; - - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed caller, - address indexed receiver, - address indexed owner, - uint256 assets, - uint256 shares - ); - - /*////////////////////////////////////////////////////////////// - IMMUTABLES - //////////////////////////////////////////////////////////////*/ - - ERC20 public immutable asset; - - constructor( - ERC20 _asset, - string memory _name, - string memory _symbol - ) ERC20(_name, _symbol, _asset.decimals()) { - asset = _asset; - } - - /*////////////////////////////////////////////////////////////// - DEPOSIT/WITHDRAWAL LOGIC - //////////////////////////////////////////////////////////////*/ - - function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) { - // Check for rounding error since we round down in previewDeposit. - require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES"); - - // Need to transfer before minting or ERC777s could reenter. - asset.safeTransferFrom(msg.sender, address(this), assets); - - _mint(receiver, shares); - - emit Deposit(msg.sender, receiver, assets, shares); - - afterDeposit(assets, shares); - } - - function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) { - assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up. - - // Need to transfer before minting or ERC777s could reenter. - asset.safeTransferFrom(msg.sender, address(this), assets); - - _mint(receiver, shares); - - emit Deposit(msg.sender, receiver, assets, shares); - - afterDeposit(assets, shares); - } - - function withdraw( - uint256 assets, - address receiver, - address owner - ) public virtual returns (uint256 shares) { - shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up. - - if (msg.sender != owner) { - uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; - } - - beforeWithdraw(assets, shares); - - _burn(owner, shares); - - emit Withdraw(msg.sender, receiver, owner, assets, shares); - - asset.safeTransfer(receiver, assets); - } - - function redeem( - uint256 shares, - address receiver, - address owner - ) public virtual returns (uint256 assets) { - if (msg.sender != owner) { - uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; - } - - // Check for rounding error since we round down in previewRedeem. - require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS"); - - beforeWithdraw(assets, shares); - - _burn(owner, shares); - - emit Withdraw(msg.sender, receiver, owner, assets, shares); - - asset.safeTransfer(receiver, assets); - } - - /*////////////////////////////////////////////////////////////// - ACCOUNTING LOGIC - //////////////////////////////////////////////////////////////*/ - - function totalAssets() public view virtual returns (uint256); - - function convertToShares(uint256 assets) public view virtual returns (uint256) { - uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. - - return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets()); - } - - function convertToAssets(uint256 shares) public view virtual returns (uint256) { - uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. - - return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply); - } - - function previewDeposit(uint256 assets) public view virtual returns (uint256) { - return convertToShares(assets); - } - - function previewMint(uint256 shares) public view virtual returns (uint256) { - uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. - - return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply); - } - - function previewWithdraw(uint256 assets) public view virtual returns (uint256) { - uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. - - return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets()); - } - - function previewRedeem(uint256 shares) public view virtual returns (uint256) { - return convertToAssets(shares); - } - - /*////////////////////////////////////////////////////////////// - DEPOSIT/WITHDRAWAL LIMIT LOGIC - //////////////////////////////////////////////////////////////*/ - - function maxDeposit(address) public view virtual returns (uint256) { - return type(uint256).max; - } - - function maxMint(address) public view virtual returns (uint256) { - return type(uint256).max; - } - - function maxWithdraw(address owner) public view virtual returns (uint256) { - return convertToAssets(balanceOf[owner]); - } - - function maxRedeem(address owner) public view virtual returns (uint256) { - return balanceOf[owner]; - } - - /*////////////////////////////////////////////////////////////// - INTERNAL HOOKS LOGIC - //////////////////////////////////////////////////////////////*/ - - function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {} - - function afterDeposit(uint256 assets, uint256 shares) internal virtual {} -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/Auth.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/Auth.t.sol deleted file mode 100644 index 9e31528..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/Auth.t.sol +++ /dev/null @@ -1,192 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol"; -import {MockAuthority} from "./utils/mocks/MockAuthority.sol"; - -import {Authority} from "../auth/Auth.sol"; - -contract OutOfOrderAuthority is Authority { - function canCall( - address, - address, - bytes4 - ) public pure override returns (bool) { - revert("OUT_OF_ORDER"); - } -} - -contract AuthTest is DSTestPlus { - MockAuthChild mockAuthChild; - - function setUp() public { - mockAuthChild = new MockAuthChild(); - } - - function testTransferOwnershipAsOwner() public { - mockAuthChild.transferOwnership(address(0xBEEF)); - assertEq(mockAuthChild.owner(), address(0xBEEF)); - } - - function testSetAuthorityAsOwner() public { - mockAuthChild.setAuthority(Authority(address(0xBEEF))); - assertEq(address(mockAuthChild.authority()), address(0xBEEF)); - } - - function testCallFunctionAsOwner() public { - mockAuthChild.updateFlag(); - } - - function testTransferOwnershipWithPermissiveAuthority() public { - mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.transferOwnership(address(this)); - } - - function testSetAuthorityWithPermissiveAuthority() public { - mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.setAuthority(Authority(address(0xBEEF))); - } - - function testCallFunctionWithPermissiveAuthority() public { - mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.updateFlag(); - } - - function testSetAuthorityAsOwnerWithOutOfOrderAuthority() public { - mockAuthChild.setAuthority(new OutOfOrderAuthority()); - mockAuthChild.setAuthority(new MockAuthority(true)); - } - - function testFailTransferOwnershipAsNonOwner() public { - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.transferOwnership(address(0xBEEF)); - } - - function testFailSetAuthorityAsNonOwner() public { - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.setAuthority(Authority(address(0xBEEF))); - } - - function testFailCallFunctionAsNonOwner() public { - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.updateFlag(); - } - - function testFailTransferOwnershipWithRestrictiveAuthority() public { - mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.transferOwnership(address(this)); - } - - function testFailSetAuthorityWithRestrictiveAuthority() public { - mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.setAuthority(Authority(address(0xBEEF))); - } - - function testFailCallFunctionWithRestrictiveAuthority() public { - mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.transferOwnership(address(0)); - mockAuthChild.updateFlag(); - } - - function testFailTransferOwnershipAsOwnerWithOutOfOrderAuthority() public { - mockAuthChild.setAuthority(new OutOfOrderAuthority()); - mockAuthChild.transferOwnership(address(0)); - } - - function testFailCallFunctionAsOwnerWithOutOfOrderAuthority() public { - mockAuthChild.setAuthority(new OutOfOrderAuthority()); - mockAuthChild.updateFlag(); - } - - function testTransferOwnershipAsOwner(address newOwner) public { - mockAuthChild.transferOwnership(newOwner); - assertEq(mockAuthChild.owner(), newOwner); - } - - function testSetAuthorityAsOwner(Authority newAuthority) public { - mockAuthChild.setAuthority(newAuthority); - assertEq(address(mockAuthChild.authority()), address(newAuthority)); - } - - function testTransferOwnershipWithPermissiveAuthority(address deadOwner, address newOwner) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.transferOwnership(newOwner); - } - - function testSetAuthorityWithPermissiveAuthority(address deadOwner, Authority newAuthority) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.setAuthority(newAuthority); - } - - function testCallFunctionWithPermissiveAuthority(address deadOwner) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.setAuthority(new MockAuthority(true)); - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.updateFlag(); - } - - function testFailTransferOwnershipAsNonOwner(address deadOwner, address newOwner) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.transferOwnership(newOwner); - } - - function testFailSetAuthorityAsNonOwner(address deadOwner, Authority newAuthority) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.setAuthority(newAuthority); - } - - function testFailCallFunctionAsNonOwner(address deadOwner) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.updateFlag(); - } - - function testFailTransferOwnershipWithRestrictiveAuthority(address deadOwner, address newOwner) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.transferOwnership(newOwner); - } - - function testFailSetAuthorityWithRestrictiveAuthority(address deadOwner, Authority newAuthority) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.setAuthority(newAuthority); - } - - function testFailCallFunctionWithRestrictiveAuthority(address deadOwner) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.setAuthority(new MockAuthority(false)); - mockAuthChild.transferOwnership(deadOwner); - mockAuthChild.updateFlag(); - } - - function testFailTransferOwnershipAsOwnerWithOutOfOrderAuthority(address deadOwner) public { - if (deadOwner == address(this)) deadOwner = address(0); - - mockAuthChild.setAuthority(new OutOfOrderAuthority()); - mockAuthChild.transferOwnership(deadOwner); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/Bytes32AddressLib.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/Bytes32AddressLib.t.sol deleted file mode 100644 index 6c0a3d8..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/Bytes32AddressLib.t.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {Bytes32AddressLib} from "../utils/Bytes32AddressLib.sol"; - -contract Bytes32AddressLibTest is DSTestPlus { - function testFillLast12Bytes() public { - assertEq( - Bytes32AddressLib.fillLast12Bytes(0xfEEDFaCEcaFeBEEFfEEDFACecaFEBeeFfeEdfAce), - 0xfeedfacecafebeeffeedfacecafebeeffeedface000000000000000000000000 - ); - } - - function testFromLast20Bytes() public { - assertEq( - Bytes32AddressLib.fromLast20Bytes(0xfeedfacecafebeeffeedfacecafebeeffeedfacecafebeeffeedfacecafebeef), - 0xCAfeBeefFeedfAceCAFeBEEffEEDfaCecafEBeeF - ); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/CREATE3.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/CREATE3.t.sol deleted file mode 100644 index b279eeb..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/CREATE3.t.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {WETH} from "../tokens/WETH.sol"; -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {MockERC20} from "./utils/mocks/MockERC20.sol"; -import {MockAuthChild} from "./utils/mocks/MockAuthChild.sol"; - -import {CREATE3} from "../utils/CREATE3.sol"; - -contract CREATE3Test is DSTestPlus { - function testDeployERC20() public { - bytes32 salt = keccak256(bytes("A salt!")); - - MockERC20 deployed = MockERC20( - CREATE3.deploy( - salt, - abi.encodePacked(type(MockERC20).creationCode, abi.encode("Mock Token", "MOCK", 18)), - 0 - ) - ); - - assertEq(address(deployed), CREATE3.getDeployed(salt)); - - assertEq(deployed.name(), "Mock Token"); - assertEq(deployed.symbol(), "MOCK"); - assertEq(deployed.decimals(), 18); - } - - function testFailDoubleDeploySameBytecode() public { - bytes32 salt = keccak256(bytes("Salty...")); - - CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0); - CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0); - } - - function testFailDoubleDeployDifferentBytecode() public { - bytes32 salt = keccak256(bytes("and sweet!")); - - CREATE3.deploy(salt, type(WETH).creationCode, 0); - CREATE3.deploy(salt, type(MockAuthChild).creationCode, 0); - } - - function testDeployERC20( - bytes32 salt, - string calldata name, - string calldata symbol, - uint8 decimals - ) public { - MockERC20 deployed = MockERC20( - CREATE3.deploy(salt, abi.encodePacked(type(MockERC20).creationCode, abi.encode(name, symbol, decimals)), 0) - ); - - assertEq(address(deployed), CREATE3.getDeployed(salt)); - - assertEq(deployed.name(), name); - assertEq(deployed.symbol(), symbol); - assertEq(deployed.decimals(), decimals); - } - - function testFailDoubleDeploySameBytecode(bytes32 salt, bytes calldata bytecode) public { - CREATE3.deploy(salt, bytecode, 0); - CREATE3.deploy(salt, bytecode, 0); - } - - function testFailDoubleDeployDifferentBytecode( - bytes32 salt, - bytes calldata bytecode1, - bytes calldata bytecode2 - ) public { - CREATE3.deploy(salt, bytecode1, 0); - CREATE3.deploy(salt, bytecode2, 0); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/DSTestPlus.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/DSTestPlus.t.sol deleted file mode 100644 index db10860..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/DSTestPlus.t.sol +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -contract DSTestPlusTest is DSTestPlus { - function testBound() public { - assertEq(bound(0, 69, 69), 69); - assertEq(bound(0, 68, 69), 68); - assertEq(bound(5, 0, 4), 0); - assertEq(bound(9999, 1337, 6666), 6006); - assertEq(bound(0, type(uint256).max - 6, type(uint256).max), type(uint256).max - 6); - assertEq(bound(6, type(uint256).max - 6, type(uint256).max), type(uint256).max); - } - - function testFailBoundMinBiggerThanMax() public { - bound(5, 100, 10); - } - - function testRelApproxEqBothZeroesPasses() public { - assertRelApproxEq(0, 0, 1e18); - assertRelApproxEq(0, 0, 0); - } - - function testBound( - uint256 num, - uint256 min, - uint256 max - ) public { - if (min > max) (min, max) = (max, min); - - uint256 bounded = bound(num, min, max); - - assertGe(bounded, min); - assertLe(bounded, max); - } - - function testFailBoundMinBiggerThanMax( - uint256 num, - uint256 min, - uint256 max - ) public { - if (max == min) { - unchecked { - min++; // Overflow is handled below. - } - } - - if (max > min) (min, max) = (max, min); - - bound(num, min, max); - } - - function testBrutalizeMemory() public brutalizeMemory("FEEDFACECAFEBEEFFEEDFACECAFEBEEF") { - bytes32 scratchSpace1; - bytes32 scratchSpace2; - bytes32 freeMem1; - bytes32 freeMem2; - - assembly { - scratchSpace1 := mload(0) - scratchSpace2 := mload(32) - freeMem1 := mload(mload(0x40)) - freeMem2 := mload(add(mload(0x40), 32)) - } - - assertGt(uint256(freeMem1), 0); - assertGt(uint256(freeMem2), 0); - assertGt(uint256(scratchSpace1), 0); - assertGt(uint256(scratchSpace2), 0); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/ERC1155.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/ERC1155.t.sol deleted file mode 100644 index 9e32d88..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/ERC1155.t.sol +++ /dev/null @@ -1,1777 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; - -import {MockERC1155} from "./utils/mocks/MockERC1155.sol"; - -import {ERC1155TokenReceiver} from "../tokens/ERC1155.sol"; - -contract ERC1155Recipient is ERC1155TokenReceiver { - address public operator; - address public from; - uint256 public id; - uint256 public amount; - bytes public mintData; - - function onERC1155Received( - address _operator, - address _from, - uint256 _id, - uint256 _amount, - bytes calldata _data - ) public override returns (bytes4) { - operator = _operator; - from = _from; - id = _id; - amount = _amount; - mintData = _data; - - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - address public batchOperator; - address public batchFrom; - uint256[] internal _batchIds; - uint256[] internal _batchAmounts; - bytes public batchData; - - function batchIds() external view returns (uint256[] memory) { - return _batchIds; - } - - function batchAmounts() external view returns (uint256[] memory) { - return _batchAmounts; - } - - function onERC1155BatchReceived( - address _operator, - address _from, - uint256[] calldata _ids, - uint256[] calldata _amounts, - bytes calldata _data - ) external override returns (bytes4) { - batchOperator = _operator; - batchFrom = _from; - _batchIds = _ids; - _batchAmounts = _amounts; - batchData = _data; - - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } -} - -contract RevertingERC1155Recipient is ERC1155TokenReceiver { - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes calldata - ) public pure override returns (bytes4) { - revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155Received.selector))); - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external pure override returns (bytes4) { - revert(string(abi.encodePacked(ERC1155TokenReceiver.onERC1155BatchReceived.selector))); - } -} - -contract WrongReturnDataERC1155Recipient is ERC1155TokenReceiver { - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes calldata - ) public pure override returns (bytes4) { - return 0xCAFEBEEF; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external pure override returns (bytes4) { - return 0xCAFEBEEF; - } -} - -contract NonERC1155Recipient {} - -contract ERC1155Test is DSTestPlus, ERC1155TokenReceiver { - MockERC1155 token; - - mapping(address => mapping(uint256 => uint256)) public userMintAmounts; - mapping(address => mapping(uint256 => uint256)) public userTransferOrBurnAmounts; - - function setUp() public { - token = new MockERC1155(); - } - - function testMintToEOA() public { - token.mint(address(0xBEEF), 1337, 1, ""); - - assertEq(token.balanceOf(address(0xBEEF), 1337), 1); - } - - function testMintToERC1155Recipient() public { - ERC1155Recipient to = new ERC1155Recipient(); - - token.mint(address(to), 1337, 1, "testing 123"); - - assertEq(token.balanceOf(address(to), 1337), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), 1337); - assertBytesEq(to.mintData(), "testing 123"); - } - - function testBatchMintToEOA() public { - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory amounts = new uint256[](5); - amounts[0] = 100; - amounts[1] = 200; - amounts[2] = 300; - amounts[3] = 400; - amounts[4] = 500; - - token.batchMint(address(0xBEEF), ids, amounts, ""); - - assertEq(token.balanceOf(address(0xBEEF), 1337), 100); - assertEq(token.balanceOf(address(0xBEEF), 1338), 200); - assertEq(token.balanceOf(address(0xBEEF), 1339), 300); - assertEq(token.balanceOf(address(0xBEEF), 1340), 400); - assertEq(token.balanceOf(address(0xBEEF), 1341), 500); - } - - function testBatchMintToERC1155Recipient() public { - ERC1155Recipient to = new ERC1155Recipient(); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory amounts = new uint256[](5); - amounts[0] = 100; - amounts[1] = 200; - amounts[2] = 300; - amounts[3] = 400; - amounts[4] = 500; - - token.batchMint(address(to), ids, amounts, "testing 123"); - - assertEq(to.batchOperator(), address(this)); - assertEq(to.batchFrom(), address(0)); - assertUintArrayEq(to.batchIds(), ids); - assertUintArrayEq(to.batchAmounts(), amounts); - assertBytesEq(to.batchData(), "testing 123"); - - assertEq(token.balanceOf(address(to), 1337), 100); - assertEq(token.balanceOf(address(to), 1338), 200); - assertEq(token.balanceOf(address(to), 1339), 300); - assertEq(token.balanceOf(address(to), 1340), 400); - assertEq(token.balanceOf(address(to), 1341), 500); - } - - function testBurn() public { - token.mint(address(0xBEEF), 1337, 100, ""); - - token.burn(address(0xBEEF), 1337, 70); - - assertEq(token.balanceOf(address(0xBEEF), 1337), 30); - } - - function testBatchBurn() public { - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory burnAmounts = new uint256[](5); - burnAmounts[0] = 50; - burnAmounts[1] = 100; - burnAmounts[2] = 150; - burnAmounts[3] = 200; - burnAmounts[4] = 250; - - token.batchMint(address(0xBEEF), ids, mintAmounts, ""); - - token.batchBurn(address(0xBEEF), ids, burnAmounts); - - assertEq(token.balanceOf(address(0xBEEF), 1337), 50); - assertEq(token.balanceOf(address(0xBEEF), 1338), 100); - assertEq(token.balanceOf(address(0xBEEF), 1339), 150); - assertEq(token.balanceOf(address(0xBEEF), 1340), 200); - assertEq(token.balanceOf(address(0xBEEF), 1341), 250); - } - - function testApproveAll() public { - token.setApprovalForAll(address(0xBEEF), true); - - assertTrue(token.isApprovedForAll(address(this), address(0xBEEF))); - } - - function testSafeTransferFromToEOA() public { - address from = address(0xABCD); - - token.mint(from, 1337, 100, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(0xBEEF), 1337, 70, ""); - - assertEq(token.balanceOf(address(0xBEEF), 1337), 70); - assertEq(token.balanceOf(from, 1337), 30); - } - - function testSafeTransferFromToERC1155Recipient() public { - ERC1155Recipient to = new ERC1155Recipient(); - - address from = address(0xABCD); - - token.mint(from, 1337, 100, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(to), 1337, 70, "testing 123"); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), from); - assertEq(to.id(), 1337); - assertBytesEq(to.mintData(), "testing 123"); - - assertEq(token.balanceOf(address(to), 1337), 70); - assertEq(token.balanceOf(from, 1337), 30); - } - - function testSafeTransferFromSelf() public { - token.mint(address(this), 1337, 100, ""); - - token.safeTransferFrom(address(this), address(0xBEEF), 1337, 70, ""); - - assertEq(token.balanceOf(address(0xBEEF), 1337), 70); - assertEq(token.balanceOf(address(this), 1337), 30); - } - - function testSafeBatchTransferFromToEOA() public { - address from = address(0xABCD); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory transferAmounts = new uint256[](5); - transferAmounts[0] = 50; - transferAmounts[1] = 100; - transferAmounts[2] = 150; - transferAmounts[3] = 200; - transferAmounts[4] = 250; - - token.batchMint(from, ids, mintAmounts, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(0xBEEF), ids, transferAmounts, ""); - - assertEq(token.balanceOf(from, 1337), 50); - assertEq(token.balanceOf(address(0xBEEF), 1337), 50); - - assertEq(token.balanceOf(from, 1338), 100); - assertEq(token.balanceOf(address(0xBEEF), 1338), 100); - - assertEq(token.balanceOf(from, 1339), 150); - assertEq(token.balanceOf(address(0xBEEF), 1339), 150); - - assertEq(token.balanceOf(from, 1340), 200); - assertEq(token.balanceOf(address(0xBEEF), 1340), 200); - - assertEq(token.balanceOf(from, 1341), 250); - assertEq(token.balanceOf(address(0xBEEF), 1341), 250); - } - - function testSafeBatchTransferFromToERC1155Recipient() public { - address from = address(0xABCD); - - ERC1155Recipient to = new ERC1155Recipient(); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory transferAmounts = new uint256[](5); - transferAmounts[0] = 50; - transferAmounts[1] = 100; - transferAmounts[2] = 150; - transferAmounts[3] = 200; - transferAmounts[4] = 250; - - token.batchMint(from, ids, mintAmounts, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(to), ids, transferAmounts, "testing 123"); - - assertEq(to.batchOperator(), address(this)); - assertEq(to.batchFrom(), from); - assertUintArrayEq(to.batchIds(), ids); - assertUintArrayEq(to.batchAmounts(), transferAmounts); - assertBytesEq(to.batchData(), "testing 123"); - - assertEq(token.balanceOf(from, 1337), 50); - assertEq(token.balanceOf(address(to), 1337), 50); - - assertEq(token.balanceOf(from, 1338), 100); - assertEq(token.balanceOf(address(to), 1338), 100); - - assertEq(token.balanceOf(from, 1339), 150); - assertEq(token.balanceOf(address(to), 1339), 150); - - assertEq(token.balanceOf(from, 1340), 200); - assertEq(token.balanceOf(address(to), 1340), 200); - - assertEq(token.balanceOf(from, 1341), 250); - assertEq(token.balanceOf(address(to), 1341), 250); - } - - function testBatchBalanceOf() public { - address[] memory tos = new address[](5); - tos[0] = address(0xBEEF); - tos[1] = address(0xCAFE); - tos[2] = address(0xFACE); - tos[3] = address(0xDEAD); - tos[4] = address(0xFEED); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - token.mint(address(0xBEEF), 1337, 100, ""); - token.mint(address(0xCAFE), 1338, 200, ""); - token.mint(address(0xFACE), 1339, 300, ""); - token.mint(address(0xDEAD), 1340, 400, ""); - token.mint(address(0xFEED), 1341, 500, ""); - - uint256[] memory balances = token.balanceOfBatch(tos, ids); - - assertEq(balances[0], 100); - assertEq(balances[1], 200); - assertEq(balances[2], 300); - assertEq(balances[3], 400); - assertEq(balances[4], 500); - } - - function testFailMintToZero() public { - token.mint(address(0), 1337, 1, ""); - } - - function testFailMintToNonERC155Recipient() public { - token.mint(address(new NonERC1155Recipient()), 1337, 1, ""); - } - - function testFailMintToRevertingERC155Recipient() public { - token.mint(address(new RevertingERC1155Recipient()), 1337, 1, ""); - } - - function testFailMintToWrongReturnDataERC155Recipient() public { - token.mint(address(new RevertingERC1155Recipient()), 1337, 1, ""); - } - - function testFailBurnInsufficientBalance() public { - token.mint(address(0xBEEF), 1337, 70, ""); - token.burn(address(0xBEEF), 1337, 100); - } - - function testFailSafeTransferFromInsufficientBalance() public { - address from = address(0xABCD); - - token.mint(from, 1337, 70, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(0xBEEF), 1337, 100, ""); - } - - function testFailSafeTransferFromSelfInsufficientBalance() public { - token.mint(address(this), 1337, 70, ""); - token.safeTransferFrom(address(this), address(0xBEEF), 1337, 100, ""); - } - - function testFailSafeTransferFromToZero() public { - token.mint(address(this), 1337, 100, ""); - token.safeTransferFrom(address(this), address(0), 1337, 70, ""); - } - - function testFailSafeTransferFromToNonERC155Recipient() public { - token.mint(address(this), 1337, 100, ""); - token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), 1337, 70, ""); - } - - function testFailSafeTransferFromToRevertingERC1155Recipient() public { - token.mint(address(this), 1337, 100, ""); - token.safeTransferFrom(address(this), address(new RevertingERC1155Recipient()), 1337, 70, ""); - } - - function testFailSafeTransferFromToWrongReturnDataERC1155Recipient() public { - token.mint(address(this), 1337, 100, ""); - token.safeTransferFrom(address(this), address(new WrongReturnDataERC1155Recipient()), 1337, 70, ""); - } - - function testFailSafeBatchTransferInsufficientBalance() public { - address from = address(0xABCD); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - - mintAmounts[0] = 50; - mintAmounts[1] = 100; - mintAmounts[2] = 150; - mintAmounts[3] = 200; - mintAmounts[4] = 250; - - uint256[] memory transferAmounts = new uint256[](5); - transferAmounts[0] = 100; - transferAmounts[1] = 200; - transferAmounts[2] = 300; - transferAmounts[3] = 400; - transferAmounts[4] = 500; - - token.batchMint(from, ids, mintAmounts, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(0xBEEF), ids, transferAmounts, ""); - } - - function testFailSafeBatchTransferFromToZero() public { - address from = address(0xABCD); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory transferAmounts = new uint256[](5); - transferAmounts[0] = 50; - transferAmounts[1] = 100; - transferAmounts[2] = 150; - transferAmounts[3] = 200; - transferAmounts[4] = 250; - - token.batchMint(from, ids, mintAmounts, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(0), ids, transferAmounts, ""); - } - - function testFailSafeBatchTransferFromToNonERC1155Recipient() public { - address from = address(0xABCD); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory transferAmounts = new uint256[](5); - transferAmounts[0] = 50; - transferAmounts[1] = 100; - transferAmounts[2] = 150; - transferAmounts[3] = 200; - transferAmounts[4] = 250; - - token.batchMint(from, ids, mintAmounts, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(new NonERC1155Recipient()), ids, transferAmounts, ""); - } - - function testFailSafeBatchTransferFromToRevertingERC1155Recipient() public { - address from = address(0xABCD); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory transferAmounts = new uint256[](5); - transferAmounts[0] = 50; - transferAmounts[1] = 100; - transferAmounts[2] = 150; - transferAmounts[3] = 200; - transferAmounts[4] = 250; - - token.batchMint(from, ids, mintAmounts, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(new RevertingERC1155Recipient()), ids, transferAmounts, ""); - } - - function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient() public { - address from = address(0xABCD); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory transferAmounts = new uint256[](5); - transferAmounts[0] = 50; - transferAmounts[1] = 100; - transferAmounts[2] = 150; - transferAmounts[3] = 200; - transferAmounts[4] = 250; - - token.batchMint(from, ids, mintAmounts, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(new WrongReturnDataERC1155Recipient()), ids, transferAmounts, ""); - } - - function testFailSafeBatchTransferFromWithArrayLengthMismatch() public { - address from = address(0xABCD); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory transferAmounts = new uint256[](4); - transferAmounts[0] = 50; - transferAmounts[1] = 100; - transferAmounts[2] = 150; - transferAmounts[3] = 200; - - token.batchMint(from, ids, mintAmounts, ""); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(0xBEEF), ids, transferAmounts, ""); - } - - function testFailBatchMintToZero() public { - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - token.batchMint(address(0), ids, mintAmounts, ""); - } - - function testFailBatchMintToNonERC1155Recipient() public { - NonERC1155Recipient to = new NonERC1155Recipient(); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - token.batchMint(address(to), ids, mintAmounts, ""); - } - - function testFailBatchMintToRevertingERC1155Recipient() public { - RevertingERC1155Recipient to = new RevertingERC1155Recipient(); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - token.batchMint(address(to), ids, mintAmounts, ""); - } - - function testFailBatchMintToWrongReturnDataERC1155Recipient() public { - WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient(); - - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - token.batchMint(address(to), ids, mintAmounts, ""); - } - - function testFailBatchMintWithArrayMismatch() public { - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory amounts = new uint256[](4); - amounts[0] = 100; - amounts[1] = 200; - amounts[2] = 300; - amounts[3] = 400; - - token.batchMint(address(0xBEEF), ids, amounts, ""); - } - - function testFailBatchBurnInsufficientBalance() public { - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 50; - mintAmounts[1] = 100; - mintAmounts[2] = 150; - mintAmounts[3] = 200; - mintAmounts[4] = 250; - - uint256[] memory burnAmounts = new uint256[](5); - burnAmounts[0] = 100; - burnAmounts[1] = 200; - burnAmounts[2] = 300; - burnAmounts[3] = 400; - burnAmounts[4] = 500; - - token.batchMint(address(0xBEEF), ids, mintAmounts, ""); - - token.batchBurn(address(0xBEEF), ids, burnAmounts); - } - - function testFailBatchBurnWithArrayLengthMismatch() public { - uint256[] memory ids = new uint256[](5); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - ids[4] = 1341; - - uint256[] memory mintAmounts = new uint256[](5); - mintAmounts[0] = 100; - mintAmounts[1] = 200; - mintAmounts[2] = 300; - mintAmounts[3] = 400; - mintAmounts[4] = 500; - - uint256[] memory burnAmounts = new uint256[](4); - burnAmounts[0] = 50; - burnAmounts[1] = 100; - burnAmounts[2] = 150; - burnAmounts[3] = 200; - - token.batchMint(address(0xBEEF), ids, mintAmounts, ""); - - token.batchBurn(address(0xBEEF), ids, burnAmounts); - } - - function testFailBalanceOfBatchWithArrayMismatch() public view { - address[] memory tos = new address[](5); - tos[0] = address(0xBEEF); - tos[1] = address(0xCAFE); - tos[2] = address(0xFACE); - tos[3] = address(0xDEAD); - tos[4] = address(0xFEED); - - uint256[] memory ids = new uint256[](4); - ids[0] = 1337; - ids[1] = 1338; - ids[2] = 1339; - ids[3] = 1340; - - token.balanceOfBatch(tos, ids); - } - - function testMintToEOA( - address to, - uint256 id, - uint256 amount, - bytes memory mintData - ) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - token.mint(to, id, amount, mintData); - - assertEq(token.balanceOf(to, id), amount); - } - - function testMintToERC1155Recipient( - uint256 id, - uint256 amount, - bytes memory mintData - ) public { - ERC1155Recipient to = new ERC1155Recipient(); - - token.mint(address(to), id, amount, mintData); - - assertEq(token.balanceOf(address(to), id), amount); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), id); - assertBytesEq(to.mintData(), mintData); - } - - function testBatchMintToEOA( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory mintData - ) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - uint256 minLength = min2(ids.length, amounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id]; - - uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId); - - normalizedIds[i] = id; - normalizedAmounts[i] = mintAmount; - - userMintAmounts[to][id] += mintAmount; - } - - token.batchMint(to, normalizedIds, normalizedAmounts, mintData); - - for (uint256 i = 0; i < normalizedIds.length; i++) { - uint256 id = normalizedIds[i]; - - assertEq(token.balanceOf(to, id), userMintAmounts[to][id]); - } - } - - function testBatchMintToERC1155Recipient( - uint256[] memory ids, - uint256[] memory amounts, - bytes memory mintData - ) public { - ERC1155Recipient to = new ERC1155Recipient(); - - uint256 minLength = min2(ids.length, amounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId); - - normalizedIds[i] = id; - normalizedAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - - token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData); - - assertEq(to.batchOperator(), address(this)); - assertEq(to.batchFrom(), address(0)); - assertUintArrayEq(to.batchIds(), normalizedIds); - assertUintArrayEq(to.batchAmounts(), normalizedAmounts); - assertBytesEq(to.batchData(), mintData); - - for (uint256 i = 0; i < normalizedIds.length; i++) { - uint256 id = normalizedIds[i]; - - assertEq(token.balanceOf(address(to), id), userMintAmounts[address(to)][id]); - } - } - - function testBurn( - address to, - uint256 id, - uint256 mintAmount, - bytes memory mintData, - uint256 burnAmount - ) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - burnAmount = bound(burnAmount, 0, mintAmount); - - token.mint(to, id, mintAmount, mintData); - - token.burn(to, id, burnAmount); - - assertEq(token.balanceOf(address(to), id), mintAmount - burnAmount); - } - - function testBatchBurn( - address to, - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory burnAmounts, - bytes memory mintData - ) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedBurnAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - normalizedIds[i] = id; - normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId); - normalizedBurnAmounts[i] = bound(burnAmounts[i], 0, normalizedMintAmounts[i]); - - userMintAmounts[address(to)][id] += normalizedMintAmounts[i]; - userTransferOrBurnAmounts[address(to)][id] += normalizedBurnAmounts[i]; - } - - token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData); - - token.batchBurn(to, normalizedIds, normalizedBurnAmounts); - - for (uint256 i = 0; i < normalizedIds.length; i++) { - uint256 id = normalizedIds[i]; - - assertEq(token.balanceOf(to, id), userMintAmounts[to][id] - userTransferOrBurnAmounts[to][id]); - } - } - - function testApproveAll(address to, bool approved) public { - token.setApprovalForAll(to, approved); - - assertBoolEq(token.isApprovedForAll(address(this), to), approved); - } - - function testSafeTransferFromToEOA( - uint256 id, - uint256 mintAmount, - bytes memory mintData, - uint256 transferAmount, - address to, - bytes memory transferData - ) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - transferAmount = bound(transferAmount, 0, mintAmount); - - address from = address(0xABCD); - - token.mint(from, id, mintAmount, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, to, id, transferAmount, transferData); - - if (to == from) { - assertEq(token.balanceOf(to, id), mintAmount); - } else { - assertEq(token.balanceOf(to, id), transferAmount); - assertEq(token.balanceOf(from, id), mintAmount - transferAmount); - } - } - - function testSafeTransferFromToERC1155Recipient( - uint256 id, - uint256 mintAmount, - bytes memory mintData, - uint256 transferAmount, - bytes memory transferData - ) public { - ERC1155Recipient to = new ERC1155Recipient(); - - address from = address(0xABCD); - - transferAmount = bound(transferAmount, 0, mintAmount); - - token.mint(from, id, mintAmount, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(to), id, transferAmount, transferData); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), from); - assertEq(to.id(), id); - assertBytesEq(to.mintData(), transferData); - - assertEq(token.balanceOf(address(to), id), transferAmount); - assertEq(token.balanceOf(from, id), mintAmount - transferAmount); - } - - function testSafeTransferFromSelf( - uint256 id, - uint256 mintAmount, - bytes memory mintData, - uint256 transferAmount, - address to, - bytes memory transferData - ) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - transferAmount = bound(transferAmount, 0, mintAmount); - - token.mint(address(this), id, mintAmount, mintData); - - token.safeTransferFrom(address(this), to, id, transferAmount, transferData); - - assertEq(token.balanceOf(to, id), transferAmount); - assertEq(token.balanceOf(address(this), id), mintAmount - transferAmount); - } - - function testSafeBatchTransferFromToEOA( - address to, - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory transferAmounts, - bytes memory mintData, - bytes memory transferData - ) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - address from = address(0xABCD); - - uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedTransferAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id]; - - uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount); - - normalizedIds[i] = id; - normalizedMintAmounts[i] = mintAmount; - normalizedTransferAmounts[i] = transferAmount; - - userMintAmounts[from][id] += mintAmount; - userTransferOrBurnAmounts[from][id] += transferAmount; - } - - token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, to, normalizedIds, normalizedTransferAmounts, transferData); - - for (uint256 i = 0; i < normalizedIds.length; i++) { - uint256 id = normalizedIds[i]; - - assertEq(token.balanceOf(address(to), id), userTransferOrBurnAmounts[from][id]); - assertEq(token.balanceOf(from, id), userMintAmounts[from][id] - userTransferOrBurnAmounts[from][id]); - } - } - - function testSafeBatchTransferFromToERC1155Recipient( - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory transferAmounts, - bytes memory mintData, - bytes memory transferData - ) public { - address from = address(0xABCD); - - ERC1155Recipient to = new ERC1155Recipient(); - - uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedTransferAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id]; - - uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount); - - normalizedIds[i] = id; - normalizedMintAmounts[i] = mintAmount; - normalizedTransferAmounts[i] = transferAmount; - - userMintAmounts[from][id] += mintAmount; - userTransferOrBurnAmounts[from][id] += transferAmount; - } - - token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(to), normalizedIds, normalizedTransferAmounts, transferData); - - assertEq(to.batchOperator(), address(this)); - assertEq(to.batchFrom(), from); - assertUintArrayEq(to.batchIds(), normalizedIds); - assertUintArrayEq(to.batchAmounts(), normalizedTransferAmounts); - assertBytesEq(to.batchData(), transferData); - - for (uint256 i = 0; i < normalizedIds.length; i++) { - uint256 id = normalizedIds[i]; - uint256 transferAmount = userTransferOrBurnAmounts[from][id]; - - assertEq(token.balanceOf(address(to), id), transferAmount); - assertEq(token.balanceOf(from, id), userMintAmounts[from][id] - transferAmount); - } - } - - function testBatchBalanceOf( - address[] memory tos, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory mintData - ) public { - uint256 minLength = min3(tos.length, ids.length, amounts.length); - - address[] memory normalizedTos = new address[](minLength); - uint256[] memory normalizedIds = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - address to = tos[i] == address(0) || tos[i].code.length > 0 ? address(0xBEEF) : tos[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id]; - - normalizedTos[i] = to; - normalizedIds[i] = id; - - uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId); - - token.mint(to, id, mintAmount, mintData); - - userMintAmounts[to][id] += mintAmount; - } - - uint256[] memory balances = token.balanceOfBatch(normalizedTos, normalizedIds); - - for (uint256 i = 0; i < normalizedTos.length; i++) { - assertEq(balances[i], token.balanceOf(normalizedTos[i], normalizedIds[i])); - } - } - - function testFailMintToZero( - uint256 id, - uint256 amount, - bytes memory data - ) public { - token.mint(address(0), id, amount, data); - } - - function testFailMintToNonERC155Recipient( - uint256 id, - uint256 mintAmount, - bytes memory mintData - ) public { - token.mint(address(new NonERC1155Recipient()), id, mintAmount, mintData); - } - - function testFailMintToRevertingERC155Recipient( - uint256 id, - uint256 mintAmount, - bytes memory mintData - ) public { - token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData); - } - - function testFailMintToWrongReturnDataERC155Recipient( - uint256 id, - uint256 mintAmount, - bytes memory mintData - ) public { - token.mint(address(new RevertingERC1155Recipient()), id, mintAmount, mintData); - } - - function testFailBurnInsufficientBalance( - address to, - uint256 id, - uint256 mintAmount, - uint256 burnAmount, - bytes memory mintData - ) public { - burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max); - - token.mint(to, id, mintAmount, mintData); - token.burn(to, id, burnAmount); - } - - function testFailSafeTransferFromInsufficientBalance( - address to, - uint256 id, - uint256 mintAmount, - uint256 transferAmount, - bytes memory mintData, - bytes memory transferData - ) public { - address from = address(0xABCD); - - transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max); - - token.mint(from, id, mintAmount, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, to, id, transferAmount, transferData); - } - - function testFailSafeTransferFromSelfInsufficientBalance( - address to, - uint256 id, - uint256 mintAmount, - uint256 transferAmount, - bytes memory mintData, - bytes memory transferData - ) public { - transferAmount = bound(transferAmount, mintAmount + 1, type(uint256).max); - - token.mint(address(this), id, mintAmount, mintData); - token.safeTransferFrom(address(this), to, id, transferAmount, transferData); - } - - function testFailSafeTransferFromToZero( - uint256 id, - uint256 mintAmount, - uint256 transferAmount, - bytes memory mintData, - bytes memory transferData - ) public { - transferAmount = bound(transferAmount, 0, mintAmount); - - token.mint(address(this), id, mintAmount, mintData); - token.safeTransferFrom(address(this), address(0), id, transferAmount, transferData); - } - - function testFailSafeTransferFromToNonERC155Recipient( - uint256 id, - uint256 mintAmount, - uint256 transferAmount, - bytes memory mintData, - bytes memory transferData - ) public { - transferAmount = bound(transferAmount, 0, mintAmount); - - token.mint(address(this), id, mintAmount, mintData); - token.safeTransferFrom(address(this), address(new NonERC1155Recipient()), id, transferAmount, transferData); - } - - function testFailSafeTransferFromToRevertingERC1155Recipient( - uint256 id, - uint256 mintAmount, - uint256 transferAmount, - bytes memory mintData, - bytes memory transferData - ) public { - transferAmount = bound(transferAmount, 0, mintAmount); - - token.mint(address(this), id, mintAmount, mintData); - token.safeTransferFrom( - address(this), - address(new RevertingERC1155Recipient()), - id, - transferAmount, - transferData - ); - } - - function testFailSafeTransferFromToWrongReturnDataERC1155Recipient( - uint256 id, - uint256 mintAmount, - uint256 transferAmount, - bytes memory mintData, - bytes memory transferData - ) public { - transferAmount = bound(transferAmount, 0, mintAmount); - - token.mint(address(this), id, mintAmount, mintData); - token.safeTransferFrom( - address(this), - address(new WrongReturnDataERC1155Recipient()), - id, - transferAmount, - transferData - ); - } - - function testFailSafeBatchTransferInsufficientBalance( - address to, - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory transferAmounts, - bytes memory mintData, - bytes memory transferData - ) public { - address from = address(0xABCD); - - uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); - - if (minLength == 0) revert(); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedTransferAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id]; - - uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = bound(transferAmounts[i], mintAmount + 1, type(uint256).max); - - normalizedIds[i] = id; - normalizedMintAmounts[i] = mintAmount; - normalizedTransferAmounts[i] = transferAmount; - - userMintAmounts[from][id] += mintAmount; - } - - token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, to, normalizedIds, normalizedTransferAmounts, transferData); - } - - function testFailSafeBatchTransferFromToZero( - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory transferAmounts, - bytes memory mintData, - bytes memory transferData - ) public { - address from = address(0xABCD); - - uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedTransferAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id]; - - uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount); - - normalizedIds[i] = id; - normalizedMintAmounts[i] = mintAmount; - normalizedTransferAmounts[i] = transferAmount; - - userMintAmounts[from][id] += mintAmount; - } - - token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, address(0), normalizedIds, normalizedTransferAmounts, transferData); - } - - function testFailSafeBatchTransferFromToNonERC1155Recipient( - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory transferAmounts, - bytes memory mintData, - bytes memory transferData - ) public { - address from = address(0xABCD); - - uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedTransferAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id]; - - uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount); - - normalizedIds[i] = id; - normalizedMintAmounts[i] = mintAmount; - normalizedTransferAmounts[i] = transferAmount; - - userMintAmounts[from][id] += mintAmount; - } - - token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom( - from, - address(new NonERC1155Recipient()), - normalizedIds, - normalizedTransferAmounts, - transferData - ); - } - - function testFailSafeBatchTransferFromToRevertingERC1155Recipient( - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory transferAmounts, - bytes memory mintData, - bytes memory transferData - ) public { - address from = address(0xABCD); - - uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedTransferAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id]; - - uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount); - - normalizedIds[i] = id; - normalizedMintAmounts[i] = mintAmount; - normalizedTransferAmounts[i] = transferAmount; - - userMintAmounts[from][id] += mintAmount; - } - - token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom( - from, - address(new RevertingERC1155Recipient()), - normalizedIds, - normalizedTransferAmounts, - transferData - ); - } - - function testFailSafeBatchTransferFromToWrongReturnDataERC1155Recipient( - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory transferAmounts, - bytes memory mintData, - bytes memory transferData - ) public { - address from = address(0xABCD); - - uint256 minLength = min3(ids.length, mintAmounts.length, transferAmounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedTransferAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[from][id]; - - uint256 mintAmount = bound(mintAmounts[i], 0, remainingMintAmountForId); - uint256 transferAmount = bound(transferAmounts[i], 0, mintAmount); - - normalizedIds[i] = id; - normalizedMintAmounts[i] = mintAmount; - normalizedTransferAmounts[i] = transferAmount; - - userMintAmounts[from][id] += mintAmount; - } - - token.batchMint(from, normalizedIds, normalizedMintAmounts, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom( - from, - address(new WrongReturnDataERC1155Recipient()), - normalizedIds, - normalizedTransferAmounts, - transferData - ); - } - - function testFailSafeBatchTransferFromWithArrayLengthMismatch( - address to, - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory transferAmounts, - bytes memory mintData, - bytes memory transferData - ) public { - address from = address(0xABCD); - - if (ids.length == transferAmounts.length) revert(); - - token.batchMint(from, ids, mintAmounts, mintData); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeBatchTransferFrom(from, to, ids, transferAmounts, transferData); - } - - function testFailBatchMintToZero( - uint256[] memory ids, - uint256[] memory amounts, - bytes memory mintData - ) public { - uint256 minLength = min2(ids.length, amounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(0)][id]; - - uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId); - - normalizedIds[i] = id; - normalizedAmounts[i] = mintAmount; - - userMintAmounts[address(0)][id] += mintAmount; - } - - token.batchMint(address(0), normalizedIds, normalizedAmounts, mintData); - } - - function testFailBatchMintToNonERC1155Recipient( - uint256[] memory ids, - uint256[] memory amounts, - bytes memory mintData - ) public { - NonERC1155Recipient to = new NonERC1155Recipient(); - - uint256 minLength = min2(ids.length, amounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId); - - normalizedIds[i] = id; - normalizedAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - - token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData); - } - - function testFailBatchMintToRevertingERC1155Recipient( - uint256[] memory ids, - uint256[] memory amounts, - bytes memory mintData - ) public { - RevertingERC1155Recipient to = new RevertingERC1155Recipient(); - - uint256 minLength = min2(ids.length, amounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId); - - normalizedIds[i] = id; - normalizedAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - - token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData); - } - - function testFailBatchMintToWrongReturnDataERC1155Recipient( - uint256[] memory ids, - uint256[] memory amounts, - bytes memory mintData - ) public { - WrongReturnDataERC1155Recipient to = new WrongReturnDataERC1155Recipient(); - - uint256 minLength = min2(ids.length, amounts.length); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[address(to)][id]; - - uint256 mintAmount = bound(amounts[i], 0, remainingMintAmountForId); - - normalizedIds[i] = id; - normalizedAmounts[i] = mintAmount; - - userMintAmounts[address(to)][id] += mintAmount; - } - - token.batchMint(address(to), normalizedIds, normalizedAmounts, mintData); - } - - function testFailBatchMintWithArrayMismatch( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory mintData - ) public { - if (ids.length == amounts.length) revert(); - - token.batchMint(address(to), ids, amounts, mintData); - } - - function testFailBatchBurnInsufficientBalance( - address to, - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory burnAmounts, - bytes memory mintData - ) public { - uint256 minLength = min3(ids.length, mintAmounts.length, burnAmounts.length); - - if (minLength == 0) revert(); - - uint256[] memory normalizedIds = new uint256[](minLength); - uint256[] memory normalizedMintAmounts = new uint256[](minLength); - uint256[] memory normalizedBurnAmounts = new uint256[](minLength); - - for (uint256 i = 0; i < minLength; i++) { - uint256 id = ids[i]; - - uint256 remainingMintAmountForId = type(uint256).max - userMintAmounts[to][id]; - - normalizedIds[i] = id; - normalizedMintAmounts[i] = bound(mintAmounts[i], 0, remainingMintAmountForId); - normalizedBurnAmounts[i] = bound(burnAmounts[i], normalizedMintAmounts[i] + 1, type(uint256).max); - - userMintAmounts[to][id] += normalizedMintAmounts[i]; - } - - token.batchMint(to, normalizedIds, normalizedMintAmounts, mintData); - - token.batchBurn(to, normalizedIds, normalizedBurnAmounts); - } - - function testFailBatchBurnWithArrayLengthMismatch( - address to, - uint256[] memory ids, - uint256[] memory mintAmounts, - uint256[] memory burnAmounts, - bytes memory mintData - ) public { - if (ids.length == burnAmounts.length) revert(); - - token.batchMint(to, ids, mintAmounts, mintData); - - token.batchBurn(to, ids, burnAmounts); - } - - function testFailBalanceOfBatchWithArrayMismatch(address[] memory tos, uint256[] memory ids) public view { - if (tos.length == ids.length) revert(); - - token.balanceOfBatch(tos, ids); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/ERC20.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/ERC20.t.sol deleted file mode 100644 index 1506d8c..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/ERC20.t.sol +++ /dev/null @@ -1,531 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; - -import {MockERC20} from "./utils/mocks/MockERC20.sol"; - -contract ERC20Test is DSTestPlus { - MockERC20 token; - - bytes32 constant PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - - function setUp() public { - token = new MockERC20("Token", "TKN", 18); - } - - function invariantMetadata() public { - assertEq(token.name(), "Token"); - assertEq(token.symbol(), "TKN"); - assertEq(token.decimals(), 18); - } - - function testMint() public { - token.mint(address(0xBEEF), 1e18); - - assertEq(token.totalSupply(), 1e18); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testBurn() public { - token.mint(address(0xBEEF), 1e18); - token.burn(address(0xBEEF), 0.9e18); - - assertEq(token.totalSupply(), 1e18 - 0.9e18); - assertEq(token.balanceOf(address(0xBEEF)), 0.1e18); - } - - function testApprove() public { - assertTrue(token.approve(address(0xBEEF), 1e18)); - - assertEq(token.allowance(address(this), address(0xBEEF)), 1e18); - } - - function testTransfer() public { - token.mint(address(this), 1e18); - - assertTrue(token.transfer(address(0xBEEF), 1e18)); - assertEq(token.totalSupply(), 1e18); - - assertEq(token.balanceOf(address(this)), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testTransferFrom() public { - address from = address(0xABCD); - - token.mint(from, 1e18); - - hevm.prank(from); - token.approve(address(this), 1e18); - - assertTrue(token.transferFrom(from, address(0xBEEF), 1e18)); - assertEq(token.totalSupply(), 1e18); - - assertEq(token.allowance(from, address(this)), 0); - - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testInfiniteApproveTransferFrom() public { - address from = address(0xABCD); - - token.mint(from, 1e18); - - hevm.prank(from); - token.approve(address(this), type(uint256).max); - - assertTrue(token.transferFrom(from, address(0xBEEF), 1e18)); - assertEq(token.totalSupply(), 1e18); - - assertEq(token.allowance(from, address(this)), type(uint256).max); - - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(address(0xBEEF)), 1e18); - } - - function testPermit() public { - uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp)) - ) - ) - ); - - token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); - - assertEq(token.allowance(owner, address(0xCAFE)), 1e18); - assertEq(token.nonces(owner), 1); - } - - function testFailTransferInsufficientBalance() public { - token.mint(address(this), 0.9e18); - token.transfer(address(0xBEEF), 1e18); - } - - function testFailTransferFromInsufficientAllowance() public { - address from = address(0xABCD); - - token.mint(from, 1e18); - - hevm.prank(from); - token.approve(address(this), 0.9e18); - - token.transferFrom(from, address(0xBEEF), 1e18); - } - - function testFailTransferFromInsufficientBalance() public { - address from = address(0xABCD); - - token.mint(from, 0.9e18); - - hevm.prank(from); - token.approve(address(this), 1e18); - - token.transferFrom(from, address(0xBEEF), 1e18); - } - - function testFailPermitBadNonce() public { - uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 1, block.timestamp)) - ) - ) - ); - - token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); - } - - function testFailPermitBadDeadline() public { - uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp)) - ) - ) - ); - - token.permit(owner, address(0xCAFE), 1e18, block.timestamp + 1, v, r, s); - } - - function testFailPermitPastDeadline() public { - uint256 oldTimestamp = block.timestamp; - uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, oldTimestamp)) - ) - ) - ); - - hevm.warp(block.timestamp + 1); - token.permit(owner, address(0xCAFE), 1e18, oldTimestamp, v, r, s); - } - - function testFailPermitReplay() public { - uint256 privateKey = 0xBEEF; - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp)) - ) - ) - ); - - token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); - token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s); - } - - function testMetadata( - string calldata name, - string calldata symbol, - uint8 decimals - ) public { - MockERC20 tkn = new MockERC20(name, symbol, decimals); - assertEq(tkn.name(), name); - assertEq(tkn.symbol(), symbol); - assertEq(tkn.decimals(), decimals); - } - - function testMint(address from, uint256 amount) public { - token.mint(from, amount); - - assertEq(token.totalSupply(), amount); - assertEq(token.balanceOf(from), amount); - } - - function testBurn( - address from, - uint256 mintAmount, - uint256 burnAmount - ) public { - burnAmount = bound(burnAmount, 0, mintAmount); - - token.mint(from, mintAmount); - token.burn(from, burnAmount); - - assertEq(token.totalSupply(), mintAmount - burnAmount); - assertEq(token.balanceOf(from), mintAmount - burnAmount); - } - - function testApprove(address to, uint256 amount) public { - assertTrue(token.approve(to, amount)); - - assertEq(token.allowance(address(this), to), amount); - } - - function testTransfer(address from, uint256 amount) public { - token.mint(address(this), amount); - - assertTrue(token.transfer(from, amount)); - assertEq(token.totalSupply(), amount); - - if (address(this) == from) { - assertEq(token.balanceOf(address(this)), amount); - } else { - assertEq(token.balanceOf(address(this)), 0); - assertEq(token.balanceOf(from), amount); - } - } - - function testTransferFrom( - address to, - uint256 approval, - uint256 amount - ) public { - amount = bound(amount, 0, approval); - - address from = address(0xABCD); - - token.mint(from, amount); - - hevm.prank(from); - token.approve(address(this), approval); - - assertTrue(token.transferFrom(from, to, amount)); - assertEq(token.totalSupply(), amount); - - uint256 app = from == address(this) || approval == type(uint256).max ? approval : approval - amount; - assertEq(token.allowance(from, address(this)), app); - - if (from == to) { - assertEq(token.balanceOf(from), amount); - } else { - assertEq(token.balanceOf(from), 0); - assertEq(token.balanceOf(to), amount); - } - } - - function testPermit( - uint248 privKey, - address to, - uint256 amount, - uint256 deadline - ) public { - uint256 privateKey = privKey; - if (deadline < block.timestamp) deadline = block.timestamp; - if (privateKey == 0) privateKey = 1; - - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) - ) - ) - ); - - token.permit(owner, to, amount, deadline, v, r, s); - - assertEq(token.allowance(owner, to), amount); - assertEq(token.nonces(owner), 1); - } - - function testFailBurnInsufficientBalance( - address to, - uint256 mintAmount, - uint256 burnAmount - ) public { - burnAmount = bound(burnAmount, mintAmount + 1, type(uint256).max); - - token.mint(to, mintAmount); - token.burn(to, burnAmount); - } - - function testFailTransferInsufficientBalance( - address to, - uint256 mintAmount, - uint256 sendAmount - ) public { - sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max); - - token.mint(address(this), mintAmount); - token.transfer(to, sendAmount); - } - - function testFailTransferFromInsufficientAllowance( - address to, - uint256 approval, - uint256 amount - ) public { - amount = bound(amount, approval + 1, type(uint256).max); - - address from = address(0xABCD); - - token.mint(from, amount); - - hevm.prank(from); - token.approve(address(this), approval); - - token.transferFrom(from, to, amount); - } - - function testFailTransferFromInsufficientBalance( - address to, - uint256 mintAmount, - uint256 sendAmount - ) public { - sendAmount = bound(sendAmount, mintAmount + 1, type(uint256).max); - - address from = address(0xABCD); - - token.mint(from, mintAmount); - - hevm.prank(from); - token.approve(address(this), sendAmount); - - token.transferFrom(from, to, sendAmount); - } - - function testFailPermitBadNonce( - uint256 privateKey, - address to, - uint256 amount, - uint256 deadline, - uint256 nonce - ) public { - if (deadline < block.timestamp) deadline = block.timestamp; - if (privateKey == 0) privateKey = 1; - if (nonce == 0) nonce = 1; - - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, nonce, deadline)) - ) - ) - ); - - token.permit(owner, to, amount, deadline, v, r, s); - } - - function testFailPermitBadDeadline( - uint256 privateKey, - address to, - uint256 amount, - uint256 deadline - ) public { - if (deadline < block.timestamp) deadline = block.timestamp; - if (privateKey == 0) privateKey = 1; - - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) - ) - ) - ); - - token.permit(owner, to, amount, deadline + 1, v, r, s); - } - - function testFailPermitPastDeadline( - uint256 privateKey, - address to, - uint256 amount, - uint256 deadline - ) public { - deadline = bound(deadline, 0, block.timestamp - 1); - if (privateKey == 0) privateKey = 1; - - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) - ) - ) - ); - - token.permit(owner, to, amount, deadline, v, r, s); - } - - function testFailPermitReplay( - uint256 privateKey, - address to, - uint256 amount, - uint256 deadline - ) public { - if (deadline < block.timestamp) deadline = block.timestamp; - if (privateKey == 0) privateKey = 1; - - address owner = hevm.addr(privateKey); - - (uint8 v, bytes32 r, bytes32 s) = hevm.sign( - privateKey, - keccak256( - abi.encodePacked( - "\x19\x01", - token.DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, to, amount, 0, deadline)) - ) - ) - ); - - token.permit(owner, to, amount, deadline, v, r, s); - token.permit(owner, to, amount, deadline, v, r, s); - } -} - -contract ERC20Invariants is DSTestPlus, DSInvariantTest { - BalanceSum balanceSum; - MockERC20 token; - - function setUp() public { - token = new MockERC20("Token", "TKN", 18); - balanceSum = new BalanceSum(token); - - addTargetContract(address(balanceSum)); - } - - function invariantBalanceSum() public { - assertEq(token.totalSupply(), balanceSum.sum()); - } -} - -contract BalanceSum { - MockERC20 token; - uint256 public sum; - - constructor(MockERC20 _token) { - token = _token; - } - - function mint(address from, uint256 amount) public { - token.mint(from, amount); - sum += amount; - } - - function burn(address from, uint256 amount) public { - token.burn(from, amount); - sum -= amount; - } - - function approve(address to, uint256 amount) public { - token.approve(to, amount); - } - - function transferFrom( - address from, - address to, - uint256 amount - ) public { - token.transferFrom(from, to, amount); - } - - function transfer(address to, uint256 amount) public { - token.transfer(to, amount); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/ERC4626.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/ERC4626.t.sol deleted file mode 100644 index 816c8e4..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/ERC4626.t.sol +++ /dev/null @@ -1,446 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {MockERC20} from "./utils/mocks/MockERC20.sol"; -import {MockERC4626} from "./utils/mocks/MockERC4626.sol"; - -contract ERC4626Test is DSTestPlus { - MockERC20 underlying; - MockERC4626 vault; - - function setUp() public { - underlying = new MockERC20("Mock Token", "TKN", 18); - vault = new MockERC4626(underlying, "Mock Token Vault", "vwTKN"); - } - - function invariantMetadata() public { - assertEq(vault.name(), "Mock Token Vault"); - assertEq(vault.symbol(), "vwTKN"); - assertEq(vault.decimals(), 18); - } - - function testMetadata(string calldata name, string calldata symbol) public { - MockERC4626 vlt = new MockERC4626(underlying, name, symbol); - assertEq(vlt.name(), name); - assertEq(vlt.symbol(), symbol); - assertEq(address(vlt.asset()), address(underlying)); - } - - function testSingleDepositWithdraw(uint128 amount) public { - if (amount == 0) amount = 1; - - uint256 aliceUnderlyingAmount = amount; - - address alice = address(0xABCD); - - underlying.mint(alice, aliceUnderlyingAmount); - - hevm.prank(alice); - underlying.approve(address(vault), aliceUnderlyingAmount); - assertEq(underlying.allowance(alice, address(vault)), aliceUnderlyingAmount); - - uint256 alicePreDepositBal = underlying.balanceOf(alice); - - hevm.prank(alice); - uint256 aliceShareAmount = vault.deposit(aliceUnderlyingAmount, alice); - - assertEq(vault.afterDepositHookCalledCounter(), 1); - - // Expect exchange rate to be 1:1 on initial deposit. - assertEq(aliceUnderlyingAmount, aliceShareAmount); - assertEq(vault.previewWithdraw(aliceShareAmount), aliceUnderlyingAmount); - assertEq(vault.previewDeposit(aliceUnderlyingAmount), aliceShareAmount); - assertEq(vault.totalSupply(), aliceShareAmount); - assertEq(vault.totalAssets(), aliceUnderlyingAmount); - assertEq(vault.balanceOf(alice), aliceShareAmount); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), aliceUnderlyingAmount); - assertEq(underlying.balanceOf(alice), alicePreDepositBal - aliceUnderlyingAmount); - - hevm.prank(alice); - vault.withdraw(aliceUnderlyingAmount, alice, alice); - - assertEq(vault.beforeWithdrawHookCalledCounter(), 1); - - assertEq(vault.totalAssets(), 0); - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 0); - assertEq(underlying.balanceOf(alice), alicePreDepositBal); - } - - function testSingleMintRedeem(uint128 amount) public { - if (amount == 0) amount = 1; - - uint256 aliceShareAmount = amount; - - address alice = address(0xABCD); - - underlying.mint(alice, aliceShareAmount); - - hevm.prank(alice); - underlying.approve(address(vault), aliceShareAmount); - assertEq(underlying.allowance(alice, address(vault)), aliceShareAmount); - - uint256 alicePreDepositBal = underlying.balanceOf(alice); - - hevm.prank(alice); - uint256 aliceUnderlyingAmount = vault.mint(aliceShareAmount, alice); - - assertEq(vault.afterDepositHookCalledCounter(), 1); - - // Expect exchange rate to be 1:1 on initial mint. - assertEq(aliceShareAmount, aliceUnderlyingAmount); - assertEq(vault.previewWithdraw(aliceShareAmount), aliceUnderlyingAmount); - assertEq(vault.previewDeposit(aliceUnderlyingAmount), aliceShareAmount); - assertEq(vault.totalSupply(), aliceShareAmount); - assertEq(vault.totalAssets(), aliceUnderlyingAmount); - assertEq(vault.balanceOf(alice), aliceUnderlyingAmount); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), aliceUnderlyingAmount); - assertEq(underlying.balanceOf(alice), alicePreDepositBal - aliceUnderlyingAmount); - - hevm.prank(alice); - vault.redeem(aliceShareAmount, alice, alice); - - assertEq(vault.beforeWithdrawHookCalledCounter(), 1); - - assertEq(vault.totalAssets(), 0); - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 0); - assertEq(underlying.balanceOf(alice), alicePreDepositBal); - } - - function testMultipleMintDepositRedeemWithdraw() public { - // Scenario: - // A = Alice, B = Bob - // ________________________________________________________ - // | Vault shares | A share | A assets | B share | B assets | - // |========================================================| - // | 1. Alice mints 2000 shares (costs 2000 tokens) | - // |--------------|---------|----------|---------|----------| - // | 2000 | 2000 | 2000 | 0 | 0 | - // |--------------|---------|----------|---------|----------| - // | 2. Bob deposits 4000 tokens (mints 4000 shares) | - // |--------------|---------|----------|---------|----------| - // | 6000 | 2000 | 2000 | 4000 | 4000 | - // |--------------|---------|----------|---------|----------| - // | 3. Vault mutates by +3000 tokens... | - // | (simulated yield returned from strategy)... | - // |--------------|---------|----------|---------|----------| - // | 6000 | 2000 | 3000 | 4000 | 6000 | - // |--------------|---------|----------|---------|----------| - // | 4. Alice deposits 2000 tokens (mints 1333 shares) | - // |--------------|---------|----------|---------|----------| - // | 7333 | 3333 | 4999 | 4000 | 6000 | - // |--------------|---------|----------|---------|----------| - // | 5. Bob mints 2000 shares (costs 3001 assets) | - // | NOTE: Bob's assets spent got rounded up | - // | NOTE: Alice's vault assets got rounded up | - // |--------------|---------|----------|---------|----------| - // | 9333 | 3333 | 5000 | 6000 | 9000 | - // |--------------|---------|----------|---------|----------| - // | 6. Vault mutates by +3000 tokens... | - // | (simulated yield returned from strategy) | - // | NOTE: Vault holds 17001 tokens, but sum of | - // | assetsOf() is 17000. | - // |--------------|---------|----------|---------|----------| - // | 9333 | 3333 | 6071 | 6000 | 10929 | - // |--------------|---------|----------|---------|----------| - // | 7. Alice redeem 1333 shares (2428 assets) | - // |--------------|---------|----------|---------|----------| - // | 8000 | 2000 | 3643 | 6000 | 10929 | - // |--------------|---------|----------|---------|----------| - // | 8. Bob withdraws 2928 assets (1608 shares) | - // |--------------|---------|----------|---------|----------| - // | 6392 | 2000 | 3643 | 4392 | 8000 | - // |--------------|---------|----------|---------|----------| - // | 9. Alice withdraws 3643 assets (2000 shares) | - // | NOTE: Bob's assets have been rounded back up | - // |--------------|---------|----------|---------|----------| - // | 4392 | 0 | 0 | 4392 | 8001 | - // |--------------|---------|----------|---------|----------| - // | 10. Bob redeem 4392 shares (8001 tokens) | - // |--------------|---------|----------|---------|----------| - // | 0 | 0 | 0 | 0 | 0 | - // |______________|_________|__________|_________|__________| - - address alice = address(0xABCD); - address bob = address(0xDCBA); - - uint256 mutationUnderlyingAmount = 3000; - - underlying.mint(alice, 4000); - - hevm.prank(alice); - underlying.approve(address(vault), 4000); - - assertEq(underlying.allowance(alice, address(vault)), 4000); - - underlying.mint(bob, 7001); - - hevm.prank(bob); - underlying.approve(address(vault), 7001); - - assertEq(underlying.allowance(bob, address(vault)), 7001); - - // 1. Alice mints 2000 shares (costs 2000 tokens) - hevm.prank(alice); - uint256 aliceUnderlyingAmount = vault.mint(2000, alice); - - uint256 aliceShareAmount = vault.previewDeposit(aliceUnderlyingAmount); - assertEq(vault.afterDepositHookCalledCounter(), 1); - - // Expect to have received the requested mint amount. - assertEq(aliceShareAmount, 2000); - assertEq(vault.balanceOf(alice), aliceShareAmount); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), aliceUnderlyingAmount); - assertEq(vault.convertToShares(aliceUnderlyingAmount), vault.balanceOf(alice)); - - // Expect a 1:1 ratio before mutation. - assertEq(aliceUnderlyingAmount, 2000); - - // Sanity check. - assertEq(vault.totalSupply(), aliceShareAmount); - assertEq(vault.totalAssets(), aliceUnderlyingAmount); - - // 2. Bob deposits 4000 tokens (mints 4000 shares) - hevm.prank(bob); - uint256 bobShareAmount = vault.deposit(4000, bob); - uint256 bobUnderlyingAmount = vault.previewWithdraw(bobShareAmount); - assertEq(vault.afterDepositHookCalledCounter(), 2); - - // Expect to have received the requested underlying amount. - assertEq(bobUnderlyingAmount, 4000); - assertEq(vault.balanceOf(bob), bobShareAmount); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), bobUnderlyingAmount); - assertEq(vault.convertToShares(bobUnderlyingAmount), vault.balanceOf(bob)); - - // Expect a 1:1 ratio before mutation. - assertEq(bobShareAmount, bobUnderlyingAmount); - - // Sanity check. - uint256 preMutationShareBal = aliceShareAmount + bobShareAmount; - uint256 preMutationBal = aliceUnderlyingAmount + bobUnderlyingAmount; - assertEq(vault.totalSupply(), preMutationShareBal); - assertEq(vault.totalAssets(), preMutationBal); - assertEq(vault.totalSupply(), 6000); - assertEq(vault.totalAssets(), 6000); - - // 3. Vault mutates by +3000 tokens... | - // (simulated yield returned from strategy)... - // The Vault now contains more tokens than deposited which causes the exchange rate to change. - // Alice share is 33.33% of the Vault, Bob 66.66% of the Vault. - // Alice's share count stays the same but the underlying amount changes from 2000 to 3000. - // Bob's share count stays the same but the underlying amount changes from 4000 to 6000. - underlying.mint(address(vault), mutationUnderlyingAmount); - assertEq(vault.totalSupply(), preMutationShareBal); - assertEq(vault.totalAssets(), preMutationBal + mutationUnderlyingAmount); - assertEq(vault.balanceOf(alice), aliceShareAmount); - assertEq( - vault.convertToAssets(vault.balanceOf(alice)), - aliceUnderlyingAmount + (mutationUnderlyingAmount / 3) * 1 - ); - assertEq(vault.balanceOf(bob), bobShareAmount); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), bobUnderlyingAmount + (mutationUnderlyingAmount / 3) * 2); - - // 4. Alice deposits 2000 tokens (mints 1333 shares) - hevm.prank(alice); - vault.deposit(2000, alice); - - assertEq(vault.totalSupply(), 7333); - assertEq(vault.balanceOf(alice), 3333); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 4999); - assertEq(vault.balanceOf(bob), 4000); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), 6000); - - // 5. Bob mints 2000 shares (costs 3001 assets) - // NOTE: Bob's assets spent got rounded up - // NOTE: Alices's vault assets got rounded up - hevm.prank(bob); - vault.mint(2000, bob); - - assertEq(vault.totalSupply(), 9333); - assertEq(vault.balanceOf(alice), 3333); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 5000); - assertEq(vault.balanceOf(bob), 6000); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), 9000); - - // Sanity checks: - // Alice and bob should have spent all their tokens now - assertEq(underlying.balanceOf(alice), 0); - assertEq(underlying.balanceOf(bob), 0); - // Assets in vault: 4k (alice) + 7k (bob) + 3k (yield) + 1 (round up) - assertEq(vault.totalAssets(), 14001); - - // 6. Vault mutates by +3000 tokens - // NOTE: Vault holds 17001 tokens, but sum of assetsOf() is 17000. - underlying.mint(address(vault), mutationUnderlyingAmount); - assertEq(vault.totalAssets(), 17001); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 6071); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), 10929); - - // 7. Alice redeem 1333 shares (2428 assets) - hevm.prank(alice); - vault.redeem(1333, alice, alice); - - assertEq(underlying.balanceOf(alice), 2428); - assertEq(vault.totalSupply(), 8000); - assertEq(vault.totalAssets(), 14573); - assertEq(vault.balanceOf(alice), 2000); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 3643); - assertEq(vault.balanceOf(bob), 6000); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), 10929); - - // 8. Bob withdraws 2929 assets (1608 shares) - hevm.prank(bob); - vault.withdraw(2929, bob, bob); - - assertEq(underlying.balanceOf(bob), 2929); - assertEq(vault.totalSupply(), 6392); - assertEq(vault.totalAssets(), 11644); - assertEq(vault.balanceOf(alice), 2000); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 3643); - assertEq(vault.balanceOf(bob), 4392); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), 8000); - - // 9. Alice withdraws 3643 assets (2000 shares) - // NOTE: Bob's assets have been rounded back up - hevm.prank(alice); - vault.withdraw(3643, alice, alice); - - assertEq(underlying.balanceOf(alice), 6071); - assertEq(vault.totalSupply(), 4392); - assertEq(vault.totalAssets(), 8001); - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 0); - assertEq(vault.balanceOf(bob), 4392); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), 8001); - - // 10. Bob redeem 4392 shares (8001 tokens) - hevm.prank(bob); - vault.redeem(4392, bob, bob); - assertEq(underlying.balanceOf(bob), 10930); - assertEq(vault.totalSupply(), 0); - assertEq(vault.totalAssets(), 0); - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.convertToAssets(vault.balanceOf(alice)), 0); - assertEq(vault.balanceOf(bob), 0); - assertEq(vault.convertToAssets(vault.balanceOf(bob)), 0); - - // Sanity check - assertEq(underlying.balanceOf(address(vault)), 0); - } - - function testFailDepositWithNotEnoughApproval() public { - underlying.mint(address(this), 0.5e18); - underlying.approve(address(vault), 0.5e18); - assertEq(underlying.allowance(address(this), address(vault)), 0.5e18); - - vault.deposit(1e18, address(this)); - } - - function testFailWithdrawWithNotEnoughUnderlyingAmount() public { - underlying.mint(address(this), 0.5e18); - underlying.approve(address(vault), 0.5e18); - - vault.deposit(0.5e18, address(this)); - - vault.withdraw(1e18, address(this), address(this)); - } - - function testFailRedeemWithNotEnoughShareAmount() public { - underlying.mint(address(this), 0.5e18); - underlying.approve(address(vault), 0.5e18); - - vault.deposit(0.5e18, address(this)); - - vault.redeem(1e18, address(this), address(this)); - } - - function testFailWithdrawWithNoUnderlyingAmount() public { - vault.withdraw(1e18, address(this), address(this)); - } - - function testFailRedeemWithNoShareAmount() public { - vault.redeem(1e18, address(this), address(this)); - } - - function testFailDepositWithNoApproval() public { - vault.deposit(1e18, address(this)); - } - - function testFailMintWithNoApproval() public { - vault.mint(1e18, address(this)); - } - - function testFailDepositZero() public { - vault.deposit(0, address(this)); - } - - function testMintZero() public { - vault.mint(0, address(this)); - - assertEq(vault.balanceOf(address(this)), 0); - assertEq(vault.convertToAssets(vault.balanceOf(address(this))), 0); - assertEq(vault.totalSupply(), 0); - assertEq(vault.totalAssets(), 0); - } - - function testFailRedeemZero() public { - vault.redeem(0, address(this), address(this)); - } - - function testWithdrawZero() public { - vault.withdraw(0, address(this), address(this)); - - assertEq(vault.balanceOf(address(this)), 0); - assertEq(vault.convertToAssets(vault.balanceOf(address(this))), 0); - assertEq(vault.totalSupply(), 0); - assertEq(vault.totalAssets(), 0); - } - - function testVaultInteractionsForSomeoneElse() public { - // init 2 users with a 1e18 balance - address alice = address(0xABCD); - address bob = address(0xDCBA); - underlying.mint(alice, 1e18); - underlying.mint(bob, 1e18); - - hevm.prank(alice); - underlying.approve(address(vault), 1e18); - - hevm.prank(bob); - underlying.approve(address(vault), 1e18); - - // alice deposits 1e18 for bob - hevm.prank(alice); - vault.deposit(1e18, bob); - - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.balanceOf(bob), 1e18); - assertEq(underlying.balanceOf(alice), 0); - - // bob mint 1e18 for alice - hevm.prank(bob); - vault.mint(1e18, alice); - assertEq(vault.balanceOf(alice), 1e18); - assertEq(vault.balanceOf(bob), 1e18); - assertEq(underlying.balanceOf(bob), 0); - - // alice redeem 1e18 for bob - hevm.prank(alice); - vault.redeem(1e18, bob, alice); - - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.balanceOf(bob), 1e18); - assertEq(underlying.balanceOf(bob), 1e18); - - // bob withdraw 1e18 for alice - hevm.prank(bob); - vault.withdraw(1e18, alice, bob); - - assertEq(vault.balanceOf(alice), 0); - assertEq(vault.balanceOf(bob), 0); - assertEq(underlying.balanceOf(alice), 1e18); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/ERC721.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/ERC721.t.sol deleted file mode 100644 index 81de0ff..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/ERC721.t.sol +++ /dev/null @@ -1,727 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; - -import {MockERC721} from "./utils/mocks/MockERC721.sol"; - -import {ERC721TokenReceiver} from "../tokens/ERC721.sol"; - -contract ERC721Recipient is ERC721TokenReceiver { - address public operator; - address public from; - uint256 public id; - bytes public data; - - function onERC721Received( - address _operator, - address _from, - uint256 _id, - bytes calldata _data - ) public virtual override returns (bytes4) { - operator = _operator; - from = _from; - id = _id; - data = _data; - - return ERC721TokenReceiver.onERC721Received.selector; - } -} - -contract RevertingERC721Recipient is ERC721TokenReceiver { - function onERC721Received( - address, - address, - uint256, - bytes calldata - ) public virtual override returns (bytes4) { - revert(string(abi.encodePacked(ERC721TokenReceiver.onERC721Received.selector))); - } -} - -contract WrongReturnDataERC721Recipient is ERC721TokenReceiver { - function onERC721Received( - address, - address, - uint256, - bytes calldata - ) public virtual override returns (bytes4) { - return 0xCAFEBEEF; - } -} - -contract NonERC721Recipient {} - -contract ERC721Test is DSTestPlus { - MockERC721 token; - - function setUp() public { - token = new MockERC721("Token", "TKN"); - } - - function invariantMetadata() public { - assertEq(token.name(), "Token"); - assertEq(token.symbol(), "TKN"); - } - - function testMint() public { - token.mint(address(0xBEEF), 1337); - - assertEq(token.balanceOf(address(0xBEEF)), 1); - assertEq(token.ownerOf(1337), address(0xBEEF)); - } - - function testBurn() public { - token.mint(address(0xBEEF), 1337); - token.burn(1337); - - assertEq(token.balanceOf(address(0xBEEF)), 0); - - hevm.expectRevert("NOT_MINTED"); - token.ownerOf(1337); - } - - function testApprove() public { - token.mint(address(this), 1337); - - token.approve(address(0xBEEF), 1337); - - assertEq(token.getApproved(1337), address(0xBEEF)); - } - - function testApproveBurn() public { - token.mint(address(this), 1337); - - token.approve(address(0xBEEF), 1337); - - token.burn(1337); - - assertEq(token.balanceOf(address(this)), 0); - assertEq(token.getApproved(1337), address(0)); - - hevm.expectRevert("NOT_MINTED"); - token.ownerOf(1337); - } - - function testApproveAll() public { - token.setApprovalForAll(address(0xBEEF), true); - - assertTrue(token.isApprovedForAll(address(this), address(0xBEEF))); - } - - function testTransferFrom() public { - address from = address(0xABCD); - - token.mint(from, 1337); - - hevm.prank(from); - token.approve(address(this), 1337); - - token.transferFrom(from, address(0xBEEF), 1337); - - assertEq(token.getApproved(1337), address(0)); - assertEq(token.ownerOf(1337), address(0xBEEF)); - assertEq(token.balanceOf(address(0xBEEF)), 1); - assertEq(token.balanceOf(from), 0); - } - - function testTransferFromSelf() public { - token.mint(address(this), 1337); - - token.transferFrom(address(this), address(0xBEEF), 1337); - - assertEq(token.getApproved(1337), address(0)); - assertEq(token.ownerOf(1337), address(0xBEEF)); - assertEq(token.balanceOf(address(0xBEEF)), 1); - assertEq(token.balanceOf(address(this)), 0); - } - - function testTransferFromApproveAll() public { - address from = address(0xABCD); - - token.mint(from, 1337); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.transferFrom(from, address(0xBEEF), 1337); - - assertEq(token.getApproved(1337), address(0)); - assertEq(token.ownerOf(1337), address(0xBEEF)); - assertEq(token.balanceOf(address(0xBEEF)), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeTransferFromToEOA() public { - address from = address(0xABCD); - - token.mint(from, 1337); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(0xBEEF), 1337); - - assertEq(token.getApproved(1337), address(0)); - assertEq(token.ownerOf(1337), address(0xBEEF)); - assertEq(token.balanceOf(address(0xBEEF)), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeTransferFromToERC721Recipient() public { - address from = address(0xABCD); - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, 1337); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(recipient), 1337); - - assertEq(token.getApproved(1337), address(0)); - assertEq(token.ownerOf(1337), address(recipient)); - assertEq(token.balanceOf(address(recipient)), 1); - assertEq(token.balanceOf(from), 0); - - assertEq(recipient.operator(), address(this)); - assertEq(recipient.from(), from); - assertEq(recipient.id(), 1337); - assertBytesEq(recipient.data(), ""); - } - - function testSafeTransferFromToERC721RecipientWithData() public { - address from = address(0xABCD); - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, 1337); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(recipient), 1337, "testing 123"); - - assertEq(token.getApproved(1337), address(0)); - assertEq(token.ownerOf(1337), address(recipient)); - assertEq(token.balanceOf(address(recipient)), 1); - assertEq(token.balanceOf(from), 0); - - assertEq(recipient.operator(), address(this)); - assertEq(recipient.from(), from); - assertEq(recipient.id(), 1337); - assertBytesEq(recipient.data(), "testing 123"); - } - - function testSafeMintToEOA() public { - token.safeMint(address(0xBEEF), 1337); - - assertEq(token.ownerOf(1337), address(address(0xBEEF))); - assertEq(token.balanceOf(address(address(0xBEEF))), 1); - } - - function testSafeMintToERC721Recipient() public { - ERC721Recipient to = new ERC721Recipient(); - - token.safeMint(address(to), 1337); - - assertEq(token.ownerOf(1337), address(to)); - assertEq(token.balanceOf(address(to)), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), 1337); - assertBytesEq(to.data(), ""); - } - - function testSafeMintToERC721RecipientWithData() public { - ERC721Recipient to = new ERC721Recipient(); - - token.safeMint(address(to), 1337, "testing 123"); - - assertEq(token.ownerOf(1337), address(to)); - assertEq(token.balanceOf(address(to)), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), 1337); - assertBytesEq(to.data(), "testing 123"); - } - - function testFailMintToZero() public { - token.mint(address(0), 1337); - } - - function testFailDoubleMint() public { - token.mint(address(0xBEEF), 1337); - token.mint(address(0xBEEF), 1337); - } - - function testFailBurnUnMinted() public { - token.burn(1337); - } - - function testFailDoubleBurn() public { - token.mint(address(0xBEEF), 1337); - - token.burn(1337); - token.burn(1337); - } - - function testFailApproveUnMinted() public { - token.approve(address(0xBEEF), 1337); - } - - function testFailApproveUnAuthorized() public { - token.mint(address(0xCAFE), 1337); - - token.approve(address(0xBEEF), 1337); - } - - function testFailTransferFromUnOwned() public { - token.transferFrom(address(0xFEED), address(0xBEEF), 1337); - } - - function testFailTransferFromWrongFrom() public { - token.mint(address(0xCAFE), 1337); - - token.transferFrom(address(0xFEED), address(0xBEEF), 1337); - } - - function testFailTransferFromToZero() public { - token.mint(address(this), 1337); - - token.transferFrom(address(this), address(0), 1337); - } - - function testFailTransferFromNotOwner() public { - token.mint(address(0xFEED), 1337); - - token.transferFrom(address(0xFEED), address(0xBEEF), 1337); - } - - function testFailSafeTransferFromToNonERC721Recipient() public { - token.mint(address(this), 1337); - - token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337); - } - - function testFailSafeTransferFromToNonERC721RecipientWithData() public { - token.mint(address(this), 1337); - - token.safeTransferFrom(address(this), address(new NonERC721Recipient()), 1337, "testing 123"); - } - - function testFailSafeTransferFromToRevertingERC721Recipient() public { - token.mint(address(this), 1337); - - token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337); - } - - function testFailSafeTransferFromToRevertingERC721RecipientWithData() public { - token.mint(address(this), 1337); - - token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), 1337, "testing 123"); - } - - function testFailSafeTransferFromToERC721RecipientWithWrongReturnData() public { - token.mint(address(this), 1337); - - token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337); - } - - function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData() public { - token.mint(address(this), 1337); - - token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), 1337, "testing 123"); - } - - function testFailSafeMintToNonERC721Recipient() public { - token.safeMint(address(new NonERC721Recipient()), 1337); - } - - function testFailSafeMintToNonERC721RecipientWithData() public { - token.safeMint(address(new NonERC721Recipient()), 1337, "testing 123"); - } - - function testFailSafeMintToRevertingERC721Recipient() public { - token.safeMint(address(new RevertingERC721Recipient()), 1337); - } - - function testFailSafeMintToRevertingERC721RecipientWithData() public { - token.safeMint(address(new RevertingERC721Recipient()), 1337, "testing 123"); - } - - function testFailSafeMintToERC721RecipientWithWrongReturnData() public { - token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337); - } - - function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData() public { - token.safeMint(address(new WrongReturnDataERC721Recipient()), 1337, "testing 123"); - } - - function testFailBalanceOfZeroAddress() public view { - token.balanceOf(address(0)); - } - - function testFailOwnerOfUnminted() public view { - token.ownerOf(1337); - } - - function testMetadata(string memory name, string memory symbol) public { - MockERC721 tkn = new MockERC721(name, symbol); - - assertEq(tkn.name(), name); - assertEq(tkn.symbol(), symbol); - } - - function testMint(address to, uint256 id) public { - if (to == address(0)) to = address(0xBEEF); - - token.mint(to, id); - - assertEq(token.balanceOf(to), 1); - assertEq(token.ownerOf(id), to); - } - - function testBurn(address to, uint256 id) public { - if (to == address(0)) to = address(0xBEEF); - - token.mint(to, id); - token.burn(id); - - assertEq(token.balanceOf(to), 0); - - hevm.expectRevert("NOT_MINTED"); - token.ownerOf(id); - } - - function testApprove(address to, uint256 id) public { - if (to == address(0)) to = address(0xBEEF); - - token.mint(address(this), id); - - token.approve(to, id); - - assertEq(token.getApproved(id), to); - } - - function testApproveBurn(address to, uint256 id) public { - token.mint(address(this), id); - - token.approve(address(to), id); - - token.burn(id); - - assertEq(token.balanceOf(address(this)), 0); - assertEq(token.getApproved(id), address(0)); - - hevm.expectRevert("NOT_MINTED"); - token.ownerOf(id); - } - - function testApproveAll(address to, bool approved) public { - token.setApprovalForAll(to, approved); - - assertBoolEq(token.isApprovedForAll(address(this), to), approved); - } - - function testTransferFrom(uint256 id, address to) public { - address from = address(0xABCD); - - if (to == address(0) || to == from) to = address(0xBEEF); - - token.mint(from, id); - - hevm.prank(from); - token.approve(address(this), id); - - token.transferFrom(from, to, id); - - assertEq(token.getApproved(id), address(0)); - assertEq(token.ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testTransferFromSelf(uint256 id, address to) public { - if (to == address(0) || to == address(this)) to = address(0xBEEF); - - token.mint(address(this), id); - - token.transferFrom(address(this), to, id); - - assertEq(token.getApproved(id), address(0)); - assertEq(token.ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(address(this)), 0); - } - - function testTransferFromApproveAll(uint256 id, address to) public { - address from = address(0xABCD); - - if (to == address(0) || to == from) to = address(0xBEEF); - - token.mint(from, id); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.transferFrom(from, to, id); - - assertEq(token.getApproved(id), address(0)); - assertEq(token.ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeTransferFromToEOA(uint256 id, address to) public { - address from = address(0xABCD); - - if (to == address(0) || to == from) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - token.mint(from, id); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, to, id); - - assertEq(token.getApproved(id), address(0)); - assertEq(token.ownerOf(id), to); - assertEq(token.balanceOf(to), 1); - assertEq(token.balanceOf(from), 0); - } - - function testSafeTransferFromToERC721Recipient(uint256 id) public { - address from = address(0xABCD); - - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, id); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(recipient), id); - - assertEq(token.getApproved(id), address(0)); - assertEq(token.ownerOf(id), address(recipient)); - assertEq(token.balanceOf(address(recipient)), 1); - assertEq(token.balanceOf(from), 0); - - assertEq(recipient.operator(), address(this)); - assertEq(recipient.from(), from); - assertEq(recipient.id(), id); - assertBytesEq(recipient.data(), ""); - } - - function testSafeTransferFromToERC721RecipientWithData(uint256 id, bytes calldata data) public { - address from = address(0xABCD); - ERC721Recipient recipient = new ERC721Recipient(); - - token.mint(from, id); - - hevm.prank(from); - token.setApprovalForAll(address(this), true); - - token.safeTransferFrom(from, address(recipient), id, data); - - assertEq(token.getApproved(id), address(0)); - assertEq(token.ownerOf(id), address(recipient)); - assertEq(token.balanceOf(address(recipient)), 1); - assertEq(token.balanceOf(from), 0); - - assertEq(recipient.operator(), address(this)); - assertEq(recipient.from(), from); - assertEq(recipient.id(), id); - assertBytesEq(recipient.data(), data); - } - - function testSafeMintToEOA(uint256 id, address to) public { - if (to == address(0)) to = address(0xBEEF); - - if (uint256(uint160(to)) <= 18 || to.code.length > 0) return; - - token.safeMint(to, id); - - assertEq(token.ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - } - - function testSafeMintToERC721Recipient(uint256 id) public { - ERC721Recipient to = new ERC721Recipient(); - - token.safeMint(address(to), id); - - assertEq(token.ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), id); - assertBytesEq(to.data(), ""); - } - - function testSafeMintToERC721RecipientWithData(uint256 id, bytes calldata data) public { - ERC721Recipient to = new ERC721Recipient(); - - token.safeMint(address(to), id, data); - - assertEq(token.ownerOf(id), address(to)); - assertEq(token.balanceOf(address(to)), 1); - - assertEq(to.operator(), address(this)); - assertEq(to.from(), address(0)); - assertEq(to.id(), id); - assertBytesEq(to.data(), data); - } - - function testFailMintToZero(uint256 id) public { - token.mint(address(0), id); - } - - function testFailDoubleMint(uint256 id, address to) public { - if (to == address(0)) to = address(0xBEEF); - - token.mint(to, id); - token.mint(to, id); - } - - function testFailBurnUnMinted(uint256 id) public { - token.burn(id); - } - - function testFailDoubleBurn(uint256 id, address to) public { - if (to == address(0)) to = address(0xBEEF); - - token.mint(to, id); - - token.burn(id); - token.burn(id); - } - - function testFailApproveUnMinted(uint256 id, address to) public { - token.approve(to, id); - } - - function testFailApproveUnAuthorized( - address owner, - uint256 id, - address to - ) public { - if (owner == address(0) || owner == address(this)) owner = address(0xBEEF); - - token.mint(owner, id); - - token.approve(to, id); - } - - function testFailTransferFromUnOwned( - address from, - address to, - uint256 id - ) public { - token.transferFrom(from, to, id); - } - - function testFailTransferFromWrongFrom( - address owner, - address from, - address to, - uint256 id - ) public { - if (owner == address(0)) to = address(0xBEEF); - if (from == owner) revert(); - - token.mint(owner, id); - - token.transferFrom(from, to, id); - } - - function testFailTransferFromToZero(uint256 id) public { - token.mint(address(this), id); - - token.transferFrom(address(this), address(0), id); - } - - function testFailTransferFromNotOwner( - address from, - address to, - uint256 id - ) public { - if (from == address(this)) from = address(0xBEEF); - - token.mint(from, id); - - token.transferFrom(from, to, id); - } - - function testFailSafeTransferFromToNonERC721Recipient(uint256 id) public { - token.mint(address(this), id); - - token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id); - } - - function testFailSafeTransferFromToNonERC721RecipientWithData(uint256 id, bytes calldata data) public { - token.mint(address(this), id); - - token.safeTransferFrom(address(this), address(new NonERC721Recipient()), id, data); - } - - function testFailSafeTransferFromToRevertingERC721Recipient(uint256 id) public { - token.mint(address(this), id); - - token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id); - } - - function testFailSafeTransferFromToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public { - token.mint(address(this), id); - - token.safeTransferFrom(address(this), address(new RevertingERC721Recipient()), id, data); - } - - function testFailSafeTransferFromToERC721RecipientWithWrongReturnData(uint256 id) public { - token.mint(address(this), id); - - token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id); - } - - function testFailSafeTransferFromToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) - public - { - token.mint(address(this), id); - - token.safeTransferFrom(address(this), address(new WrongReturnDataERC721Recipient()), id, data); - } - - function testFailSafeMintToNonERC721Recipient(uint256 id) public { - token.safeMint(address(new NonERC721Recipient()), id); - } - - function testFailSafeMintToNonERC721RecipientWithData(uint256 id, bytes calldata data) public { - token.safeMint(address(new NonERC721Recipient()), id, data); - } - - function testFailSafeMintToRevertingERC721Recipient(uint256 id) public { - token.safeMint(address(new RevertingERC721Recipient()), id); - } - - function testFailSafeMintToRevertingERC721RecipientWithData(uint256 id, bytes calldata data) public { - token.safeMint(address(new RevertingERC721Recipient()), id, data); - } - - function testFailSafeMintToERC721RecipientWithWrongReturnData(uint256 id) public { - token.safeMint(address(new WrongReturnDataERC721Recipient()), id); - } - - function testFailSafeMintToERC721RecipientWithWrongReturnDataWithData(uint256 id, bytes calldata data) public { - token.safeMint(address(new WrongReturnDataERC721Recipient()), id, data); - } - - function testFailOwnerOfUnminted(uint256 id) public view { - token.ownerOf(id); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/FixedPointMathLib.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/FixedPointMathLib.t.sol deleted file mode 100644 index 789f957..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/FixedPointMathLib.t.sol +++ /dev/null @@ -1,360 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol"; - -contract FixedPointMathLibTest is DSTestPlus { - function testMulWadDown() public { - assertEq(FixedPointMathLib.mulWadDown(2.5e18, 0.5e18), 1.25e18); - assertEq(FixedPointMathLib.mulWadDown(3e18, 1e18), 3e18); - assertEq(FixedPointMathLib.mulWadDown(369, 271), 0); - } - - function testMulWadDownEdgeCases() public { - assertEq(FixedPointMathLib.mulWadDown(0, 1e18), 0); - assertEq(FixedPointMathLib.mulWadDown(1e18, 0), 0); - assertEq(FixedPointMathLib.mulWadDown(0, 0), 0); - } - - function testMulWadUp() public { - assertEq(FixedPointMathLib.mulWadUp(2.5e18, 0.5e18), 1.25e18); - assertEq(FixedPointMathLib.mulWadUp(3e18, 1e18), 3e18); - assertEq(FixedPointMathLib.mulWadUp(369, 271), 1); - } - - function testMulWadUpEdgeCases() public { - assertEq(FixedPointMathLib.mulWadUp(0, 1e18), 0); - assertEq(FixedPointMathLib.mulWadUp(1e18, 0), 0); - assertEq(FixedPointMathLib.mulWadUp(0, 0), 0); - } - - function testDivWadDown() public { - assertEq(FixedPointMathLib.divWadDown(1.25e18, 0.5e18), 2.5e18); - assertEq(FixedPointMathLib.divWadDown(3e18, 1e18), 3e18); - assertEq(FixedPointMathLib.divWadDown(2, 100000000000000e18), 0); - } - - function testDivWadDownEdgeCases() public { - assertEq(FixedPointMathLib.divWadDown(0, 1e18), 0); - } - - function testFailDivWadDownZeroDenominator() public pure { - FixedPointMathLib.divWadDown(1e18, 0); - } - - function testDivWadUp() public { - assertEq(FixedPointMathLib.divWadUp(1.25e18, 0.5e18), 2.5e18); - assertEq(FixedPointMathLib.divWadUp(3e18, 1e18), 3e18); - assertEq(FixedPointMathLib.divWadUp(2, 100000000000000e18), 1); - } - - function testDivWadUpEdgeCases() public { - assertEq(FixedPointMathLib.divWadUp(0, 1e18), 0); - } - - function testFailDivWadUpZeroDenominator() public pure { - FixedPointMathLib.divWadUp(1e18, 0); - } - - function testMulDivDown() public { - assertEq(FixedPointMathLib.mulDivDown(2.5e27, 0.5e27, 1e27), 1.25e27); - assertEq(FixedPointMathLib.mulDivDown(2.5e18, 0.5e18, 1e18), 1.25e18); - assertEq(FixedPointMathLib.mulDivDown(2.5e8, 0.5e8, 1e8), 1.25e8); - assertEq(FixedPointMathLib.mulDivDown(369, 271, 1e2), 999); - - assertEq(FixedPointMathLib.mulDivDown(1e27, 1e27, 2e27), 0.5e27); - assertEq(FixedPointMathLib.mulDivDown(1e18, 1e18, 2e18), 0.5e18); - assertEq(FixedPointMathLib.mulDivDown(1e8, 1e8, 2e8), 0.5e8); - - assertEq(FixedPointMathLib.mulDivDown(2e27, 3e27, 2e27), 3e27); - assertEq(FixedPointMathLib.mulDivDown(3e18, 2e18, 3e18), 2e18); - assertEq(FixedPointMathLib.mulDivDown(2e8, 3e8, 2e8), 3e8); - } - - function testMulDivDownEdgeCases() public { - assertEq(FixedPointMathLib.mulDivDown(0, 1e18, 1e18), 0); - assertEq(FixedPointMathLib.mulDivDown(1e18, 0, 1e18), 0); - assertEq(FixedPointMathLib.mulDivDown(0, 0, 1e18), 0); - } - - function testFailMulDivDownZeroDenominator() public pure { - FixedPointMathLib.mulDivDown(1e18, 1e18, 0); - } - - function testMulDivUp() public { - assertEq(FixedPointMathLib.mulDivUp(2.5e27, 0.5e27, 1e27), 1.25e27); - assertEq(FixedPointMathLib.mulDivUp(2.5e18, 0.5e18, 1e18), 1.25e18); - assertEq(FixedPointMathLib.mulDivUp(2.5e8, 0.5e8, 1e8), 1.25e8); - assertEq(FixedPointMathLib.mulDivUp(369, 271, 1e2), 1000); - - assertEq(FixedPointMathLib.mulDivUp(1e27, 1e27, 2e27), 0.5e27); - assertEq(FixedPointMathLib.mulDivUp(1e18, 1e18, 2e18), 0.5e18); - assertEq(FixedPointMathLib.mulDivUp(1e8, 1e8, 2e8), 0.5e8); - - assertEq(FixedPointMathLib.mulDivUp(2e27, 3e27, 2e27), 3e27); - assertEq(FixedPointMathLib.mulDivUp(3e18, 2e18, 3e18), 2e18); - assertEq(FixedPointMathLib.mulDivUp(2e8, 3e8, 2e8), 3e8); - } - - function testMulDivUpEdgeCases() public { - assertEq(FixedPointMathLib.mulDivUp(0, 1e18, 1e18), 0); - assertEq(FixedPointMathLib.mulDivUp(1e18, 0, 1e18), 0); - assertEq(FixedPointMathLib.mulDivUp(0, 0, 1e18), 0); - } - - function testFailMulDivUpZeroDenominator() public pure { - FixedPointMathLib.mulDivUp(1e18, 1e18, 0); - } - - function testRPow() public { - assertEq(FixedPointMathLib.rpow(2e27, 2, 1e27), 4e27); - assertEq(FixedPointMathLib.rpow(2e18, 2, 1e18), 4e18); - assertEq(FixedPointMathLib.rpow(2e8, 2, 1e8), 4e8); - assertEq(FixedPointMathLib.rpow(8, 3, 1), 512); - } - - function testSqrt() public { - assertEq(FixedPointMathLib.sqrt(0), 0); - assertEq(FixedPointMathLib.sqrt(1), 1); - assertEq(FixedPointMathLib.sqrt(2704), 52); - assertEq(FixedPointMathLib.sqrt(110889), 333); - assertEq(FixedPointMathLib.sqrt(32239684), 5678); - assertEq(FixedPointMathLib.sqrt(type(uint256).max), 340282366920938463463374607431768211455); - } - - function testSqrtBackHashedSingle() public { - testSqrtBackHashed(123); - } - - function testMulWadDown(uint256 x, uint256 y) public { - // Ignore cases where x * y overflows. - unchecked { - if (x != 0 && (x * y) / x != y) return; - } - - assertEq(FixedPointMathLib.mulWadDown(x, y), (x * y) / 1e18); - } - - function testFailMulWadDownOverflow(uint256 x, uint256 y) public pure { - // Ignore cases where x * y does not overflow. - unchecked { - if ((x * y) / x == y) revert(); - } - - FixedPointMathLib.mulWadDown(x, y); - } - - function testMulWadUp(uint256 x, uint256 y) public { - // Ignore cases where x * y overflows. - unchecked { - if (x != 0 && (x * y) / x != y) return; - } - - assertEq(FixedPointMathLib.mulWadUp(x, y), x * y == 0 ? 0 : (x * y - 1) / 1e18 + 1); - } - - function testFailMulWadUpOverflow(uint256 x, uint256 y) public pure { - // Ignore cases where x * y does not overflow. - unchecked { - if ((x * y) / x == y) revert(); - } - - FixedPointMathLib.mulWadUp(x, y); - } - - function testDivWadDown(uint256 x, uint256 y) public { - // Ignore cases where x * WAD overflows or y is 0. - unchecked { - if (y == 0 || (x != 0 && (x * 1e18) / 1e18 != x)) return; - } - - assertEq(FixedPointMathLib.divWadDown(x, y), (x * 1e18) / y); - } - - function testFailDivWadDownOverflow(uint256 x, uint256 y) public pure { - // Ignore cases where x * WAD does not overflow or y is 0. - unchecked { - if (y == 0 || (x * 1e18) / 1e18 == x) revert(); - } - - FixedPointMathLib.divWadDown(x, y); - } - - function testFailDivWadDownZeroDenominator(uint256 x) public pure { - FixedPointMathLib.divWadDown(x, 0); - } - - function testDivWadUp(uint256 x, uint256 y) public { - // Ignore cases where x * WAD overflows or y is 0. - unchecked { - if (y == 0 || (x != 0 && (x * 1e18) / 1e18 != x)) return; - } - - assertEq(FixedPointMathLib.divWadUp(x, y), x == 0 ? 0 : (x * 1e18 - 1) / y + 1); - } - - function testFailDivWadUpOverflow(uint256 x, uint256 y) public pure { - // Ignore cases where x * WAD does not overflow or y is 0. - unchecked { - if (y == 0 || (x * 1e18) / 1e18 == x) revert(); - } - - FixedPointMathLib.divWadUp(x, y); - } - - function testFailDivWadUpZeroDenominator(uint256 x) public pure { - FixedPointMathLib.divWadUp(x, 0); - } - - function testMulDivDown( - uint256 x, - uint256 y, - uint256 denominator - ) public { - // Ignore cases where x * y overflows or denominator is 0. - unchecked { - if (denominator == 0 || (x != 0 && (x * y) / x != y)) return; - } - - assertEq(FixedPointMathLib.mulDivDown(x, y, denominator), (x * y) / denominator); - } - - function testFailMulDivDownOverflow( - uint256 x, - uint256 y, - uint256 denominator - ) public pure { - // Ignore cases where x * y does not overflow or denominator is 0. - unchecked { - if (denominator == 0 || (x * y) / x == y) revert(); - } - - FixedPointMathLib.mulDivDown(x, y, denominator); - } - - function testFailMulDivDownZeroDenominator(uint256 x, uint256 y) public pure { - FixedPointMathLib.mulDivDown(x, y, 0); - } - - function testMulDivUp( - uint256 x, - uint256 y, - uint256 denominator - ) public { - // Ignore cases where x * y overflows or denominator is 0. - unchecked { - if (denominator == 0 || (x != 0 && (x * y) / x != y)) return; - } - - assertEq(FixedPointMathLib.mulDivUp(x, y, denominator), x * y == 0 ? 0 : (x * y - 1) / denominator + 1); - } - - function testFailMulDivUpOverflow( - uint256 x, - uint256 y, - uint256 denominator - ) public pure { - // Ignore cases where x * y does not overflow or denominator is 0. - unchecked { - if (denominator == 0 || (x * y) / x == y) revert(); - } - - FixedPointMathLib.mulDivUp(x, y, denominator); - } - - function testFailMulDivUpZeroDenominator(uint256 x, uint256 y) public pure { - FixedPointMathLib.mulDivUp(x, y, 0); - } - - function testDifferentiallyFuzzSqrt(uint256 x) public { - assertEq(FixedPointMathLib.sqrt(x), uniswapSqrt(x)); - assertEq(FixedPointMathLib.sqrt(x), abdkSqrt(x)); - } - - function testSqrt(uint256 x) public { - uint256 root = FixedPointMathLib.sqrt(x); - uint256 next = root + 1; - - // Ignore cases where next * next overflows. - unchecked { - if (next * next < next) return; - } - - assertTrue(root * root <= x && next * next > x); - } - - function testSqrtBack(uint256 x) public { - unchecked { - x >>= 128; - while (x != 0) { - assertEq(FixedPointMathLib.sqrt(x * x), x); - x >>= 1; - } - } - } - - function testSqrtBackHashed(uint256 x) public { - testSqrtBack(uint256(keccak256(abi.encode(x)))); - } - - function uniswapSqrt(uint256 y) internal pure returns (uint256 z) { - if (y > 3) { - z = y; - uint256 x = y / 2 + 1; - while (x < z) { - z = x; - x = (y / x + x) / 2; - } - } else if (y != 0) { - z = 1; - } - } - - function abdkSqrt(uint256 x) private pure returns (uint256) { - unchecked { - if (x == 0) return 0; - else { - uint256 xx = x; - uint256 r = 1; - if (xx >= 0x100000000000000000000000000000000) { - xx >>= 128; - r <<= 64; - } - if (xx >= 0x10000000000000000) { - xx >>= 64; - r <<= 32; - } - if (xx >= 0x100000000) { - xx >>= 32; - r <<= 16; - } - if (xx >= 0x10000) { - xx >>= 16; - r <<= 8; - } - if (xx >= 0x100) { - xx >>= 8; - r <<= 4; - } - if (xx >= 0x10) { - xx >>= 4; - r <<= 2; - } - if (xx >= 0x8) { - r <<= 1; - } - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; - r = (r + x / r) >> 1; // Seven iterations should be enough - uint256 r1 = x / r; - return r < r1 ? r : r1; - } - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/LibString.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/LibString.t.sol deleted file mode 100644 index 36ed435..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/LibString.t.sol +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {LibString} from "../utils/LibString.sol"; - -contract LibStringTest is DSTestPlus { - function testToString() public { - assertEq(LibString.toString(uint256(0)), "0"); - assertEq(LibString.toString(uint256(1)), "1"); - assertEq(LibString.toString(uint256(17)), "17"); - assertEq(LibString.toString(uint256(99999999)), "99999999"); - assertEq(LibString.toString(uint256(99999999999)), "99999999999"); - assertEq(LibString.toString(uint256(2342343923423)), "2342343923423"); - assertEq(LibString.toString(uint256(98765685434567)), "98765685434567"); - } - - function testToStringIntPositive() public { - assertEq(LibString.toString(int256(0)), "0"); - assertEq(LibString.toString(int256(1)), "1"); - assertEq(LibString.toString(int256(17)), "17"); - assertEq(LibString.toString(int256(99999999)), "99999999"); - assertEq(LibString.toString(int256(99999999999)), "99999999999"); - assertEq(LibString.toString(int256(2342343923423)), "2342343923423"); - assertEq(LibString.toString(int256(98765685434567)), "98765685434567"); - } - - function testToStringIntNegative() public { - assertEq(LibString.toString(int256(-0)), "0"); - assertEq(LibString.toString(int256(-17)), "-17"); - assertEq(LibString.toString(int256(-99999999)), "-99999999"); - assertEq(LibString.toString(int256(-99999999999)), "-99999999999"); - assertEq(LibString.toString(int256(-2342343923423)), "-2342343923423"); - assertEq(LibString.toString(int256(-98765685434567)), "-98765685434567"); - } - - function testDifferentiallyFuzzToString(uint256 value, bytes calldata brutalizeWith) - public - brutalizeMemory(brutalizeWith) - { - string memory libString = LibString.toString(value); - string memory oz = toStringOZ(value); - - assertEq(bytes(libString).length, bytes(oz).length); - assertEq(libString, oz); - } - - function testDifferentiallyFuzzToStringInt(int256 value, bytes calldata brutalizeWith) - public - brutalizeMemory(brutalizeWith) - { - string memory libString = LibString.toString(value); - string memory oz = toStringOZ(value); - - assertEq(bytes(libString).length, bytes(oz).length); - assertEq(libString, oz); - } - - function testToStringOverwrite() public { - string memory str = LibString.toString(uint256(1)); - - bytes32 data; - bytes32 expected; - - assembly { - // Imagine a high level allocation writing something to the current free memory. - // Should have sufficient higher order bits for this to be visible - mstore(mload(0x40), not(0)) - // Correctly allocate 32 more bytes, to avoid more interference - mstore(0x40, add(mload(0x40), 32)) - data := mload(add(str, 32)) - - // the expected value should be the uft-8 encoding of 1 (49), - // followed by clean bits. We achieve this by taking the value and - // shifting left to the end of the 32 byte word - expected := shl(248, 49) - } - - assertEq(data, expected); - } - - function testToStringDirty() public { - uint256 freememptr; - // Make the next 4 bytes of the free memory dirty - assembly { - let dirty := not(0) - freememptr := mload(0x40) - mstore(freememptr, dirty) - mstore(add(freememptr, 32), dirty) - mstore(add(freememptr, 64), dirty) - mstore(add(freememptr, 96), dirty) - mstore(add(freememptr, 128), dirty) - } - string memory str = LibString.toString(uint256(1)); - uint256 len; - bytes32 data; - bytes32 expected; - assembly { - freememptr := str - len := mload(str) - data := mload(add(str, 32)) - // the expected value should be the uft-8 encoding of 1 (49), - // followed by clean bits. We achieve this by taking the value and - // shifting left to the end of the 32 byte word - expected := shl(248, 49) - } - emit log_named_uint("str: ", freememptr); - emit log_named_uint("len: ", len); - emit log_named_bytes32("data: ", data); - assembly { - freememptr := mload(0x40) - } - emit log_named_uint("memptr: ", freememptr); - - assertEq(data, expected); - } -} - -function toStringOZ(int256 value) pure returns (string memory) { - return string(abi.encodePacked(value < 0 ? "-" : "", toStringOZ(absOZ(value)))); -} - -function toStringOZ(uint256 value) pure returns (string memory) { - if (value == 0) { - return "0"; - } - uint256 temp = value; - uint256 digits; - while (temp != 0) { - digits++; - temp /= 10; - } - bytes memory buffer = new bytes(digits); - while (value != 0) { - digits -= 1; - buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); - value /= 10; - } - return string(buffer); -} - -function absOZ(int256 n) pure returns (uint256) { - unchecked { - // must be unchecked in order to support `n = type(int256).min` - return uint256(n >= 0 ? n : -n); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/MerkleProofLib.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/MerkleProofLib.t.sol deleted file mode 100644 index 5279679..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/MerkleProofLib.t.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {MerkleProofLib} from "../utils/MerkleProofLib.sol"; - -contract MerkleProofLibTest is DSTestPlus { - function testVerifyEmptyMerkleProofSuppliedLeafAndRootSame() public { - bytes32[] memory proof; - assertBoolEq(this.verify(proof, 0x00, 0x00), true); - } - - function testVerifyEmptyMerkleProofSuppliedLeafAndRootDifferent() public { - bytes32[] memory proof; - bytes32 leaf = "a"; - assertBoolEq(this.verify(proof, 0x00, leaf), false); - } - - function testValidProofSupplied() public { - // Merkle tree created from leaves ['a', 'b', 'c']. - // Leaf is 'a'. - bytes32[] memory proof = new bytes32[](2); - proof[0] = 0xb5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510; - proof[1] = 0x0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2; - bytes32 root = 0x5842148bc6ebeb52af882a317c765fccd3ae80589b21a9b8cbf21abb630e46a7; - bytes32 leaf = 0x3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb; - assertBoolEq(this.verify(proof, root, leaf), true); - } - - function testVerifyInvalidProofSupplied() public { - // Merkle tree created from leaves ['a', 'b', 'c']. - // Leaf is 'a'. - // Proof is same as testValidProofSupplied but last byte of first element is modified. - bytes32[] memory proof = new bytes32[](2); - proof[0] = 0xb5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5511; - proof[1] = 0x0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2; - bytes32 root = 0x5842148bc6ebeb52af882a317c765fccd3ae80589b21a9b8cbf21abb630e46a7; - bytes32 leaf = 0x3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb; - assertBoolEq(this.verify(proof, root, leaf), false); - } - - function verify( - bytes32[] calldata proof, - bytes32 root, - bytes32 leaf - ) external pure returns (bool) { - return MerkleProofLib.verify(proof, root, leaf); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/MultiRolesAuthority.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/MultiRolesAuthority.t.sol deleted file mode 100644 index eedf6a0..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/MultiRolesAuthority.t.sol +++ /dev/null @@ -1,321 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {MockAuthority} from "./utils/mocks/MockAuthority.sol"; - -import {Authority} from "../auth/Auth.sol"; - -import {MultiRolesAuthority} from "../auth/authorities/MultiRolesAuthority.sol"; - -contract MultiRolesAuthorityTest is DSTestPlus { - MultiRolesAuthority multiRolesAuthority; - - function setUp() public { - multiRolesAuthority = new MultiRolesAuthority(address(this), Authority(address(0))); - } - - function testSetRoles() public { - assertFalse(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0)); - - multiRolesAuthority.setUserRole(address(0xBEEF), 0, true); - assertTrue(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0)); - - multiRolesAuthority.setUserRole(address(0xBEEF), 0, false); - assertFalse(multiRolesAuthority.doesUserHaveRole(address(0xBEEF), 0)); - } - - function testSetRoleCapabilities() public { - assertFalse(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE)); - - multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true); - assertTrue(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE)); - - multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false); - assertFalse(multiRolesAuthority.doesRoleHaveCapability(0, 0xBEEFCAFE)); - } - - function testSetPublicCapabilities() public { - assertFalse(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE)); - - multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true); - assertTrue(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE)); - - multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false); - assertFalse(multiRolesAuthority.isCapabilityPublic(0xBEEFCAFE)); - } - - function testSetTargetCustomAuthority() public { - assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xBEEF), Authority(address(0xCAFE))); - assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0xCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xBEEF), Authority(address(0))); - assertEq(address(multiRolesAuthority.getTargetCustomAuthority(address(0xBEEF))), address(0)); - } - - function testCanCallWithAuthorizedRole() public { - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setUserRole(address(0xBEEF), 0, true); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setUserRole(address(0xBEEF), 0, false); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - } - - function testCanCallPublicCapability() public { - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - } - - function testCanCallWithCustomAuthority() public { - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false)); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true)); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false)); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0))); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true)); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - } - - function testCanCallWithCustomAuthorityOverridesPublicCapability() public { - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false)); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true)); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setPublicCapability(0xBEEFCAFE, false); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0))); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setPublicCapability(0xBEEFCAFE, true); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - } - - function testCanCallWithCustomAuthorityOverridesUserWithRole() public { - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setUserRole(address(0xBEEF), 0, true); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, true); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(false)); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), new MockAuthority(true)); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setUserRole(address(0xBEEF), 0, false); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setTargetCustomAuthority(address(0xCAFE), Authority(address(0))); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setUserRole(address(0xBEEF), 0, true); - assertTrue(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setRoleCapability(0, 0xBEEFCAFE, false); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - multiRolesAuthority.setUserRole(address(0xBEEF), 0, false); - assertFalse(multiRolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - } - - function testSetRoles(address user, uint8 role) public { - assertFalse(multiRolesAuthority.doesUserHaveRole(user, role)); - - multiRolesAuthority.setUserRole(user, role, true); - assertTrue(multiRolesAuthority.doesUserHaveRole(user, role)); - - multiRolesAuthority.setUserRole(user, role, false); - assertFalse(multiRolesAuthority.doesUserHaveRole(user, role)); - } - - function testSetRoleCapabilities(uint8 role, bytes4 functionSig) public { - assertFalse(multiRolesAuthority.doesRoleHaveCapability(role, functionSig)); - - multiRolesAuthority.setRoleCapability(role, functionSig, true); - assertTrue(multiRolesAuthority.doesRoleHaveCapability(role, functionSig)); - - multiRolesAuthority.setRoleCapability(role, functionSig, false); - assertFalse(multiRolesAuthority.doesRoleHaveCapability(role, functionSig)); - } - - function testSetPublicCapabilities(bytes4 functionSig) public { - assertFalse(multiRolesAuthority.isCapabilityPublic(functionSig)); - - multiRolesAuthority.setPublicCapability(functionSig, true); - assertTrue(multiRolesAuthority.isCapabilityPublic(functionSig)); - - multiRolesAuthority.setPublicCapability(functionSig, false); - assertFalse(multiRolesAuthority.isCapabilityPublic(functionSig)); - } - - function testSetTargetCustomAuthority(address user, Authority customAuthority) public { - assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(0)); - - multiRolesAuthority.setTargetCustomAuthority(user, customAuthority); - assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(customAuthority)); - - multiRolesAuthority.setTargetCustomAuthority(user, Authority(address(0))); - assertEq(address(multiRolesAuthority.getTargetCustomAuthority(user)), address(0)); - } - - function testCanCallWithAuthorizedRole( - address user, - uint8 role, - address target, - bytes4 functionSig - ) public { - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setUserRole(user, role, true); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setRoleCapability(role, functionSig, true); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setRoleCapability(role, functionSig, false); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setRoleCapability(role, functionSig, true); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setUserRole(user, role, false); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - } - - function testCanCallPublicCapability( - address user, - address target, - bytes4 functionSig - ) public { - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setPublicCapability(functionSig, true); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setPublicCapability(functionSig, false); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - } - - function testCanCallWithCustomAuthority( - address user, - address target, - bytes4 functionSig - ) public { - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false)); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true)); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false)); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0))); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true)); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - } - - function testCanCallWithCustomAuthorityOverridesPublicCapability( - address user, - address target, - bytes4 functionSig - ) public { - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setPublicCapability(functionSig, true); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false)); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true)); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setPublicCapability(functionSig, false); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0))); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setPublicCapability(functionSig, true); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - } - - function testCanCallWithCustomAuthorityOverridesUserWithRole( - address user, - uint8 role, - address target, - bytes4 functionSig - ) public { - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setUserRole(user, role, true); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setRoleCapability(role, functionSig, true); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(false)); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, new MockAuthority(true)); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setUserRole(user, role, false); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setTargetCustomAuthority(target, Authority(address(0))); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setUserRole(user, role, true); - assertTrue(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setRoleCapability(role, functionSig, false); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - - multiRolesAuthority.setUserRole(user, role, false); - assertFalse(multiRolesAuthority.canCall(user, target, functionSig)); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/Owned.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/Owned.t.sol deleted file mode 100644 index 08a0239..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/Owned.t.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {MockOwned} from "./utils/mocks/MockOwned.sol"; - -contract OwnedTest is DSTestPlus { - MockOwned mockOwned; - - function setUp() public { - mockOwned = new MockOwned(); - } - - function testTransferOwnership() public { - testTransferOwnership(address(0xBEEF)); - } - - function testCallFunctionAsNonOwner() public { - testCallFunctionAsNonOwner(address(0)); - } - - function testCallFunctionAsOwner() public { - mockOwned.updateFlag(); - } - - function testTransferOwnership(address newOwner) public { - mockOwned.transferOwnership(newOwner); - - assertEq(mockOwned.owner(), newOwner); - } - - function testCallFunctionAsNonOwner(address owner) public { - hevm.assume(owner != address(this)); - - mockOwned.transferOwnership(owner); - - hevm.expectRevert("UNAUTHORIZED"); - mockOwned.updateFlag(); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/ReentrancyGuard.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/ReentrancyGuard.t.sol deleted file mode 100644 index 842e367..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/ReentrancyGuard.t.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {ReentrancyGuard} from "../utils/ReentrancyGuard.sol"; - -contract RiskyContract is ReentrancyGuard { - uint256 public enterTimes; - - function unprotectedCall() public { - enterTimes++; - - if (enterTimes > 1) return; - - this.protectedCall(); - } - - function protectedCall() public nonReentrant { - enterTimes++; - - if (enterTimes > 1) return; - - this.protectedCall(); - } - - function overprotectedCall() public nonReentrant {} -} - -contract ReentrancyGuardTest is DSTestPlus { - RiskyContract riskyContract; - - function setUp() public { - riskyContract = new RiskyContract(); - } - - function invariantReentrancyStatusAlways1() public { - assertEq(uint256(hevm.load(address(riskyContract), 0)), 1); - } - - function testFailUnprotectedCall() public { - riskyContract.unprotectedCall(); - - assertEq(riskyContract.enterTimes(), 1); - } - - function testProtectedCall() public { - try riskyContract.protectedCall() { - fail("Reentrancy Guard Failed To Stop Attacker"); - } catch {} - } - - function testNoReentrancy() public { - riskyContract.overprotectedCall(); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/RolesAuthority.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/RolesAuthority.t.sol deleted file mode 100644 index e01db7e..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/RolesAuthority.t.sol +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {MockAuthority} from "./utils/mocks/MockAuthority.sol"; - -import {Authority} from "../auth/Auth.sol"; - -import {RolesAuthority} from "../auth/authorities/RolesAuthority.sol"; - -contract RolesAuthorityTest is DSTestPlus { - RolesAuthority rolesAuthority; - - function setUp() public { - rolesAuthority = new RolesAuthority(address(this), Authority(address(0))); - } - - function testSetRoles() public { - assertFalse(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0)); - - rolesAuthority.setUserRole(address(0xBEEF), 0, true); - assertTrue(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0)); - - rolesAuthority.setUserRole(address(0xBEEF), 0, false); - assertFalse(rolesAuthority.doesUserHaveRole(address(0xBEEF), 0)); - } - - function testSetRoleCapabilities() public { - assertFalse(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true); - assertTrue(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, false); - assertFalse(rolesAuthority.doesRoleHaveCapability(0, address(0xCAFE), 0xBEEFCAFE)); - } - - function testSetPublicCapabilities() public { - assertFalse(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, true); - assertTrue(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, false); - assertFalse(rolesAuthority.isCapabilityPublic(address(0xCAFE), 0xBEEFCAFE)); - } - - function testCanCallWithAuthorizedRole() public { - assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setUserRole(address(0xBEEF), 0, true); - assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true); - assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, false); - assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setRoleCapability(0, address(0xCAFE), 0xBEEFCAFE, true); - assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setUserRole(address(0xBEEF), 0, false); - assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - } - - function testCanCallPublicCapability() public { - assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, true); - assertTrue(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - - rolesAuthority.setPublicCapability(address(0xCAFE), 0xBEEFCAFE, false); - assertFalse(rolesAuthority.canCall(address(0xBEEF), address(0xCAFE), 0xBEEFCAFE)); - } - - function testSetRoles(address user, uint8 role) public { - assertFalse(rolesAuthority.doesUserHaveRole(user, role)); - - rolesAuthority.setUserRole(user, role, true); - assertTrue(rolesAuthority.doesUserHaveRole(user, role)); - - rolesAuthority.setUserRole(user, role, false); - assertFalse(rolesAuthority.doesUserHaveRole(user, role)); - } - - function testSetRoleCapabilities( - uint8 role, - address target, - bytes4 functionSig - ) public { - assertFalse(rolesAuthority.doesRoleHaveCapability(role, target, functionSig)); - - rolesAuthority.setRoleCapability(role, target, functionSig, true); - assertTrue(rolesAuthority.doesRoleHaveCapability(role, target, functionSig)); - - rolesAuthority.setRoleCapability(role, target, functionSig, false); - assertFalse(rolesAuthority.doesRoleHaveCapability(role, target, functionSig)); - } - - function testSetPublicCapabilities(address target, bytes4 functionSig) public { - assertFalse(rolesAuthority.isCapabilityPublic(target, functionSig)); - - rolesAuthority.setPublicCapability(target, functionSig, true); - assertTrue(rolesAuthority.isCapabilityPublic(target, functionSig)); - - rolesAuthority.setPublicCapability(target, functionSig, false); - assertFalse(rolesAuthority.isCapabilityPublic(target, functionSig)); - } - - function testCanCallWithAuthorizedRole( - address user, - uint8 role, - address target, - bytes4 functionSig - ) public { - assertFalse(rolesAuthority.canCall(user, target, functionSig)); - - rolesAuthority.setUserRole(user, role, true); - assertFalse(rolesAuthority.canCall(user, target, functionSig)); - - rolesAuthority.setRoleCapability(role, target, functionSig, true); - assertTrue(rolesAuthority.canCall(user, target, functionSig)); - - rolesAuthority.setRoleCapability(role, target, functionSig, false); - assertFalse(rolesAuthority.canCall(user, target, functionSig)); - - rolesAuthority.setRoleCapability(role, target, functionSig, true); - assertTrue(rolesAuthority.canCall(user, target, functionSig)); - - rolesAuthority.setUserRole(user, role, false); - assertFalse(rolesAuthority.canCall(user, target, functionSig)); - } - - function testCanCallPublicCapability( - address user, - address target, - bytes4 functionSig - ) public { - assertFalse(rolesAuthority.canCall(user, target, functionSig)); - - rolesAuthority.setPublicCapability(target, functionSig, true); - assertTrue(rolesAuthority.canCall(user, target, functionSig)); - - rolesAuthority.setPublicCapability(target, functionSig, false); - assertFalse(rolesAuthority.canCall(user, target, functionSig)); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/SSTORE2.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/SSTORE2.t.sol deleted file mode 100644 index 5d97ed7..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/SSTORE2.t.sol +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {SSTORE2} from "../utils/SSTORE2.sol"; - -contract SSTORE2Test is DSTestPlus { - function testWriteRead() public { - bytes memory testBytes = abi.encode("this is a test"); - - address pointer = SSTORE2.write(testBytes); - - assertBytesEq(SSTORE2.read(pointer), testBytes); - } - - function testWriteReadFullStartBound() public { - assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 0), hex"11223344"); - } - - function testWriteReadCustomStartBound() public { - assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1), hex"223344"); - } - - function testWriteReadFullBoundedRead() public { - bytes memory testBytes = abi.encode("this is a test"); - - assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), 0, testBytes.length), testBytes); - } - - function testWriteReadCustomBounds() public { - assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1, 3), hex"2233"); - } - - function testWriteReadEmptyBound() public { - SSTORE2.read(SSTORE2.write(hex"11223344"), 3, 3); - } - - function testFailReadInvalidPointer() public view { - SSTORE2.read(DEAD_ADDRESS); - } - - function testFailReadInvalidPointerCustomStartBound() public view { - SSTORE2.read(DEAD_ADDRESS, 1); - } - - function testFailReadInvalidPointerCustomBounds() public view { - SSTORE2.read(DEAD_ADDRESS, 2, 4); - } - - function testFailWriteReadOutOfStartBound() public { - SSTORE2.read(SSTORE2.write(hex"11223344"), 41000); - } - - function testFailWriteReadEmptyOutOfBounds() public { - SSTORE2.read(SSTORE2.write(hex"11223344"), 42000, 42000); - } - - function testFailWriteReadOutOfBounds() public { - SSTORE2.read(SSTORE2.write(hex"11223344"), 41000, 42000); - } - - function testWriteRead(bytes calldata testBytes, bytes calldata brutalizeWith) - public - brutalizeMemory(brutalizeWith) - { - assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes)), testBytes); - } - - function testWriteReadCustomStartBound( - bytes calldata testBytes, - uint256 startIndex, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - if (testBytes.length == 0) return; - - startIndex = bound(startIndex, 0, testBytes.length); - - assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), startIndex), bytes(testBytes[startIndex:])); - } - - function testWriteReadCustomBounds( - bytes calldata testBytes, - uint256 startIndex, - uint256 endIndex, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - if (testBytes.length == 0) return; - - endIndex = bound(endIndex, 0, testBytes.length); - startIndex = bound(startIndex, 0, testBytes.length); - - if (startIndex > endIndex) return; - - assertBytesEq( - SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex), - bytes(testBytes[startIndex:endIndex]) - ); - } - - function testFailReadInvalidPointer(address pointer, bytes calldata brutalizeWith) - public - view - brutalizeMemory(brutalizeWith) - { - if (pointer.code.length > 0) revert(); - - SSTORE2.read(pointer); - } - - function testFailReadInvalidPointerCustomStartBound( - address pointer, - uint256 startIndex, - bytes calldata brutalizeWith - ) public view brutalizeMemory(brutalizeWith) { - if (pointer.code.length > 0) revert(); - - SSTORE2.read(pointer, startIndex); - } - - function testFailReadInvalidPointerCustomBounds( - address pointer, - uint256 startIndex, - uint256 endIndex, - bytes calldata brutalizeWith - ) public view brutalizeMemory(brutalizeWith) { - if (pointer.code.length > 0) revert(); - - SSTORE2.read(pointer, startIndex, endIndex); - } - - function testFailWriteReadCustomStartBoundOutOfRange( - bytes calldata testBytes, - uint256 startIndex, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - startIndex = bound(startIndex, testBytes.length + 1, type(uint256).max); - - SSTORE2.read(SSTORE2.write(testBytes), startIndex); - } - - function testFailWriteReadCustomBoundsOutOfRange( - bytes calldata testBytes, - uint256 startIndex, - uint256 endIndex, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - endIndex = bound(endIndex, testBytes.length + 1, type(uint256).max); - - SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/SafeCastLib.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/SafeCastLib.t.sol deleted file mode 100644 index 52a6c07..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/SafeCastLib.t.sol +++ /dev/null @@ -1,644 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {SafeCastLib} from "../utils/SafeCastLib.sol"; - -contract SafeCastLibTest is DSTestPlus { - function testSafeCastTo248() public { - assertEq(SafeCastLib.safeCastTo248(2.5e45), 2.5e45); - assertEq(SafeCastLib.safeCastTo248(2.5e27), 2.5e27); - } - - function testSafeCastTo240() public { - assertEq(SafeCastLib.safeCastTo240(2.5e45), 2.5e45); - assertEq(SafeCastLib.safeCastTo240(2.5e27), 2.5e27); - } - - function testSafeCastTo232() public { - assertEq(SafeCastLib.safeCastTo232(2.5e45), 2.5e45); - assertEq(SafeCastLib.safeCastTo232(2.5e27), 2.5e27); - } - - function testSafeCastTo224() public { - assertEq(SafeCastLib.safeCastTo224(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo224(2.5e27), 2.5e27); - } - - function testSafeCastTo216() public { - assertEq(SafeCastLib.safeCastTo216(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo216(2.5e27), 2.5e27); - } - - function testSafeCastTo208() public { - assertEq(SafeCastLib.safeCastTo208(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo208(2.5e27), 2.5e27); - } - - function testSafeCastTo200() public { - assertEq(SafeCastLib.safeCastTo200(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo200(2.5e27), 2.5e27); - } - - function testSafeCastTo192() public { - assertEq(SafeCastLib.safeCastTo192(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo192(2.5e27), 2.5e27); - } - - function testSafeCastTo184() public { - assertEq(SafeCastLib.safeCastTo184(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo184(2.5e27), 2.5e27); - } - - function testSafeCastTo176() public { - assertEq(SafeCastLib.safeCastTo176(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo176(2.5e27), 2.5e27); - } - - function testSafeCastTo168() public { - assertEq(SafeCastLib.safeCastTo168(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo168(2.5e27), 2.5e27); - } - - function testSafeCastTo160() public { - assertEq(SafeCastLib.safeCastTo160(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo160(2.5e27), 2.5e27); - } - - function testSafeCastTo152() public { - assertEq(SafeCastLib.safeCastTo152(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo152(2.5e27), 2.5e27); - } - - function testSafeCastTo144() public { - assertEq(SafeCastLib.safeCastTo144(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo144(2.5e27), 2.5e27); - } - - function testSafeCastTo136() public { - assertEq(SafeCastLib.safeCastTo136(2.5e36), 2.5e36); - assertEq(SafeCastLib.safeCastTo136(2.5e27), 2.5e27); - } - - function testSafeCastTo128() public { - assertEq(SafeCastLib.safeCastTo128(2.5e27), 2.5e27); - assertEq(SafeCastLib.safeCastTo128(2.5e18), 2.5e18); - } - - function testSafeCastTo120() public { - assertEq(SafeCastLib.safeCastTo120(2.5e27), 2.5e27); - assertEq(SafeCastLib.safeCastTo120(2.5e18), 2.5e18); - } - - function testSafeCastTo112() public { - assertEq(SafeCastLib.safeCastTo112(2.5e27), 2.5e27); - assertEq(SafeCastLib.safeCastTo112(2.5e18), 2.5e18); - } - - function testSafeCastTo104() public { - assertEq(SafeCastLib.safeCastTo104(2.5e27), 2.5e27); - assertEq(SafeCastLib.safeCastTo104(2.5e18), 2.5e18); - } - - function testSafeCastTo96() public { - assertEq(SafeCastLib.safeCastTo96(2.5e18), 2.5e18); - assertEq(SafeCastLib.safeCastTo96(2.5e17), 2.5e17); - } - - function testSafeCastTo64() public { - assertEq(SafeCastLib.safeCastTo64(2.5e18), 2.5e18); - assertEq(SafeCastLib.safeCastTo64(2.5e17), 2.5e17); - } - - function testSafeCastTo56() public { - assertEq(SafeCastLib.safeCastTo56(2.5e16), 2.5e16); - assertEq(SafeCastLib.safeCastTo56(2.5e15), 2.5e15); - } - - function testSafeCastTo48() public { - assertEq(SafeCastLib.safeCastTo48(2.5e12), 2.5e12); - assertEq(SafeCastLib.safeCastTo48(2.5e11), 2.5e11); - } - - function testSafeCastTo40() public { - assertEq(SafeCastLib.safeCastTo40(2.5e10), 2.5e10); - assertEq(SafeCastLib.safeCastTo40(2.5e9), 2.5e9); - } - - function testSafeCastTo32() public { - assertEq(SafeCastLib.safeCastTo32(2.5e8), 2.5e8); - assertEq(SafeCastLib.safeCastTo32(2.5e7), 2.5e7); - } - - function testSafeCastTo24() public { - assertEq(SafeCastLib.safeCastTo24(2.5e4), 2.5e4); - assertEq(SafeCastLib.safeCastTo24(2.5e3), 2.5e3); - } - - function testSafeCastTo16() public { - assertEq(SafeCastLib.safeCastTo16(2.5e3), 2.5e3); - assertEq(SafeCastLib.safeCastTo16(2.5e2), 2.5e2); - } - - function testSafeCastTo8() public { - assertEq(SafeCastLib.safeCastTo8(100), 100); - assertEq(SafeCastLib.safeCastTo8(250), 250); - } - - function testFailSafeCastTo248() public pure { - SafeCastLib.safeCastTo248(type(uint248).max + 1); - } - - function testFailSafeCastTo240() public pure { - SafeCastLib.safeCastTo240(type(uint240).max + 1); - } - - function testFailSafeCastTo232() public pure { - SafeCastLib.safeCastTo232(type(uint232).max + 1); - } - - function testFailSafeCastTo224() public pure { - SafeCastLib.safeCastTo224(type(uint224).max + 1); - } - - function testFailSafeCastTo216() public pure { - SafeCastLib.safeCastTo216(type(uint216).max + 1); - } - - function testFailSafeCastTo208() public pure { - SafeCastLib.safeCastTo208(type(uint208).max + 1); - } - - function testFailSafeCastTo200() public pure { - SafeCastLib.safeCastTo200(type(uint200).max + 1); - } - - function testFailSafeCastTo192() public pure { - SafeCastLib.safeCastTo192(type(uint192).max + 1); - } - - function testFailSafeCastTo184() public pure { - SafeCastLib.safeCastTo184(type(uint184).max + 1); - } - - function testFailSafeCastTo176() public pure { - SafeCastLib.safeCastTo176(type(uint176).max + 1); - } - - function testFailSafeCastTo168() public pure { - SafeCastLib.safeCastTo168(type(uint168).max + 1); - } - - function testFailSafeCastTo160() public pure { - SafeCastLib.safeCastTo160(type(uint160).max + 1); - } - - function testFailSafeCastTo152() public pure { - SafeCastLib.safeCastTo152(type(uint152).max + 1); - } - - function testFailSafeCastTo144() public pure { - SafeCastLib.safeCastTo144(type(uint144).max + 1); - } - - function testFailSafeCastTo136() public pure { - SafeCastLib.safeCastTo136(type(uint136).max + 1); - } - - function testFailSafeCastTo128() public pure { - SafeCastLib.safeCastTo128(type(uint128).max + 1); - } - - function testFailSafeCastTo120() public pure { - SafeCastLib.safeCastTo120(type(uint120).max + 1); - } - - function testFailSafeCastTo112() public pure { - SafeCastLib.safeCastTo112(type(uint112).max + 1); - } - - function testFailSafeCastTo104() public pure { - SafeCastLib.safeCastTo104(type(uint104).max + 1); - } - - function testFailSafeCastTo96() public pure { - SafeCastLib.safeCastTo96(type(uint96).max + 1); - } - - function testFailSafeCastTo88() public pure { - SafeCastLib.safeCastTo88(type(uint88).max + 1); - } - - function testFailSafeCastTo80() public pure { - SafeCastLib.safeCastTo80(type(uint80).max + 1); - } - - function testFailSafeCastTo72() public pure { - SafeCastLib.safeCastTo72(type(uint72).max + 1); - } - - function testFailSafeCastTo64() public pure { - SafeCastLib.safeCastTo64(type(uint64).max + 1); - } - - function testFailSafeCastTo56() public pure { - SafeCastLib.safeCastTo56(type(uint56).max + 1); - } - - function testFailSafeCastTo48() public pure { - SafeCastLib.safeCastTo48(type(uint48).max + 1); - } - - function testFailSafeCastTo40() public pure { - SafeCastLib.safeCastTo40(type(uint40).max + 1); - } - - function testFailSafeCastTo32() public pure { - SafeCastLib.safeCastTo32(type(uint32).max + 1); - } - - function testFailSafeCastTo24() public pure { - SafeCastLib.safeCastTo24(type(uint24).max + 1); - } - - function testFailSafeCastTo16() public pure { - SafeCastLib.safeCastTo16(type(uint16).max + 1); - } - - function testFailSafeCastTo8() public pure { - SafeCastLib.safeCastTo8(type(uint8).max + 1); - } - - function testSafeCastTo248(uint256 x) public { - x = bound(x, 0, type(uint248).max); - - assertEq(SafeCastLib.safeCastTo248(x), x); - } - - function testSafeCastTo240(uint256 x) public { - x = bound(x, 0, type(uint240).max); - - assertEq(SafeCastLib.safeCastTo240(x), x); - } - - function testSafeCastTo232(uint256 x) public { - x = bound(x, 0, type(uint232).max); - - assertEq(SafeCastLib.safeCastTo232(x), x); - } - - function testSafeCastTo224(uint256 x) public { - x = bound(x, 0, type(uint224).max); - - assertEq(SafeCastLib.safeCastTo224(x), x); - } - - function testSafeCastTo216(uint256 x) public { - x = bound(x, 0, type(uint216).max); - - assertEq(SafeCastLib.safeCastTo216(x), x); - } - - function testSafeCastTo208(uint256 x) public { - x = bound(x, 0, type(uint208).max); - - assertEq(SafeCastLib.safeCastTo208(x), x); - } - - function testSafeCastTo200(uint256 x) public { - x = bound(x, 0, type(uint200).max); - - assertEq(SafeCastLib.safeCastTo200(x), x); - } - - function testSafeCastTo192(uint256 x) public { - x = bound(x, 0, type(uint192).max); - - assertEq(SafeCastLib.safeCastTo192(x), x); - } - - function testSafeCastTo184(uint256 x) public { - x = bound(x, 0, type(uint184).max); - - assertEq(SafeCastLib.safeCastTo184(x), x); - } - - function testSafeCastTo176(uint256 x) public { - x = bound(x, 0, type(uint176).max); - - assertEq(SafeCastLib.safeCastTo176(x), x); - } - - function testSafeCastTo168(uint256 x) public { - x = bound(x, 0, type(uint168).max); - - assertEq(SafeCastLib.safeCastTo168(x), x); - } - - function testSafeCastTo160(uint256 x) public { - x = bound(x, 0, type(uint160).max); - - assertEq(SafeCastLib.safeCastTo160(x), x); - } - - function testSafeCastTo152(uint256 x) public { - x = bound(x, 0, type(uint152).max); - - assertEq(SafeCastLib.safeCastTo152(x), x); - } - - function testSafeCastTo144(uint256 x) public { - x = bound(x, 0, type(uint144).max); - - assertEq(SafeCastLib.safeCastTo144(x), x); - } - - function testSafeCastTo136(uint256 x) public { - x = bound(x, 0, type(uint136).max); - - assertEq(SafeCastLib.safeCastTo136(x), x); - } - - function testSafeCastTo128(uint256 x) public { - x = bound(x, 0, type(uint128).max); - - assertEq(SafeCastLib.safeCastTo128(x), x); - } - - function testSafeCastTo120(uint256 x) public { - x = bound(x, 0, type(uint120).max); - - assertEq(SafeCastLib.safeCastTo120(x), x); - } - - function testSafeCastTo112(uint256 x) public { - x = bound(x, 0, type(uint112).max); - - assertEq(SafeCastLib.safeCastTo112(x), x); - } - - function testSafeCastTo104(uint256 x) public { - x = bound(x, 0, type(uint104).max); - - assertEq(SafeCastLib.safeCastTo104(x), x); - } - - function testSafeCastTo96(uint256 x) public { - x = bound(x, 0, type(uint96).max); - - assertEq(SafeCastLib.safeCastTo96(x), x); - } - - function testSafeCastTo88(uint256 x) public { - x = bound(x, 0, type(uint88).max); - - assertEq(SafeCastLib.safeCastTo88(x), x); - } - - function testSafeCastTo80(uint256 x) public { - x = bound(x, 0, type(uint80).max); - - assertEq(SafeCastLib.safeCastTo80(x), x); - } - - function testSafeCastTo72(uint256 x) public { - x = bound(x, 0, type(uint72).max); - - assertEq(SafeCastLib.safeCastTo72(x), x); - } - - function testSafeCastTo64(uint256 x) public { - x = bound(x, 0, type(uint64).max); - - assertEq(SafeCastLib.safeCastTo64(x), x); - } - - function testSafeCastTo56(uint256 x) public { - x = bound(x, 0, type(uint56).max); - - assertEq(SafeCastLib.safeCastTo56(x), x); - } - - function testSafeCastTo48(uint256 x) public { - x = bound(x, 0, type(uint48).max); - - assertEq(SafeCastLib.safeCastTo48(x), x); - } - - function testSafeCastTo40(uint256 x) public { - x = bound(x, 0, type(uint40).max); - - assertEq(SafeCastLib.safeCastTo40(x), x); - } - - function testSafeCastTo32(uint256 x) public { - x = bound(x, 0, type(uint32).max); - - assertEq(SafeCastLib.safeCastTo32(x), x); - } - - function testSafeCastTo24(uint256 x) public { - x = bound(x, 0, type(uint24).max); - - assertEq(SafeCastLib.safeCastTo24(x), x); - } - - function testSafeCastTo16(uint256 x) public { - x = bound(x, 0, type(uint16).max); - - assertEq(SafeCastLib.safeCastTo16(x), x); - } - - function testSafeCastTo8(uint256 x) public { - x = bound(x, 0, type(uint8).max); - - assertEq(SafeCastLib.safeCastTo8(x), x); - } - - function testFailSafeCastTo248(uint256 x) public { - x = bound(x, type(uint248).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo248(x); - } - - function testFailSafeCastTo240(uint256 x) public { - x = bound(x, type(uint240).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo240(x); - } - - function testFailSafeCastTo232(uint256 x) public { - x = bound(x, type(uint232).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo232(x); - } - - function testFailSafeCastTo224(uint256 x) public { - x = bound(x, type(uint224).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo224(x); - } - - function testFailSafeCastTo216(uint256 x) public { - x = bound(x, type(uint216).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo216(x); - } - - function testFailSafeCastTo208(uint256 x) public { - x = bound(x, type(uint208).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo208(x); - } - - function testFailSafeCastTo200(uint256 x) public { - x = bound(x, type(uint200).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo200(x); - } - - function testFailSafeCastTo192(uint256 x) public { - x = bound(x, type(uint192).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo192(x); - } - - function testFailSafeCastTo184(uint256 x) public { - x = bound(x, type(uint184).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo184(x); - } - - function testFailSafeCastTo176(uint256 x) public { - x = bound(x, type(uint176).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo176(x); - } - - function testFailSafeCastTo168(uint256 x) public { - x = bound(x, type(uint168).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo168(x); - } - - function testFailSafeCastTo160(uint256 x) public { - x = bound(x, type(uint160).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo160(x); - } - - function testFailSafeCastTo152(uint256 x) public { - x = bound(x, type(uint152).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo152(x); - } - - function testFailSafeCastTo144(uint256 x) public { - x = bound(x, type(uint144).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo144(x); - } - - function testFailSafeCastTo136(uint256 x) public { - x = bound(x, type(uint136).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo136(x); - } - - function testFailSafeCastTo128(uint256 x) public { - x = bound(x, type(uint128).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo128(x); - } - - function testFailSafeCastTo120(uint256 x) public { - x = bound(x, type(uint120).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo120(x); - } - - function testFailSafeCastTo112(uint256 x) public { - x = bound(x, type(uint112).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo112(x); - } - - function testFailSafeCastTo104(uint256 x) public { - x = bound(x, type(uint104).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo104(x); - } - - function testFailSafeCastTo96(uint256 x) public { - x = bound(x, type(uint96).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo96(x); - } - - function testFailSafeCastTo88(uint256 x) public { - x = bound(x, type(uint88).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo88(x); - } - - function testFailSafeCastTo80(uint256 x) public { - x = bound(x, type(uint80).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo80(x); - } - - function testFailSafeCastTo72(uint256 x) public { - x = bound(x, type(uint72).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo72(x); - } - - function testFailSafeCastTo64(uint256 x) public { - x = bound(x, type(uint64).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo64(x); - } - - function testFailSafeCastTo56(uint256 x) public { - x = bound(x, type(uint56).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo56(x); - } - - function testFailSafeCastTo48(uint256 x) public { - x = bound(x, type(uint48).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo48(x); - } - - function testFailSafeCastTo40(uint256 x) public { - x = bound(x, type(uint40).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo40(x); - } - - function testFailSafeCastTo32(uint256 x) public { - x = bound(x, type(uint32).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo32(x); - } - - function testFailSafeCastTo24(uint256 x) public { - x = bound(x, type(uint24).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo24(x); - } - - function testFailSafeCastTo16(uint256 x) public { - x = bound(x, type(uint16).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo16(x); - } - - function testFailSafeCastTo8(uint256 x) public { - x = bound(x, type(uint8).max + 1, type(uint256).max); - - SafeCastLib.safeCastTo8(x); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/SafeTransferLib.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/SafeTransferLib.t.sol deleted file mode 100644 index b976e9f..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/SafeTransferLib.t.sol +++ /dev/null @@ -1,610 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {MockERC20} from "./utils/mocks/MockERC20.sol"; -import {RevertingToken} from "./utils/weird-tokens/RevertingToken.sol"; -import {ReturnsTwoToken} from "./utils/weird-tokens/ReturnsTwoToken.sol"; -import {ReturnsFalseToken} from "./utils/weird-tokens/ReturnsFalseToken.sol"; -import {MissingReturnToken} from "./utils/weird-tokens/MissingReturnToken.sol"; -import {ReturnsTooMuchToken} from "./utils/weird-tokens/ReturnsTooMuchToken.sol"; -import {ReturnsGarbageToken} from "./utils/weird-tokens/ReturnsGarbageToken.sol"; -import {ReturnsTooLittleToken} from "./utils/weird-tokens/ReturnsTooLittleToken.sol"; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {ERC20} from "../tokens/ERC20.sol"; -import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; - -contract SafeTransferLibTest is DSTestPlus { - RevertingToken reverting; - ReturnsTwoToken returnsTwo; - ReturnsFalseToken returnsFalse; - MissingReturnToken missingReturn; - ReturnsTooMuchToken returnsTooMuch; - ReturnsGarbageToken returnsGarbage; - ReturnsTooLittleToken returnsTooLittle; - - MockERC20 erc20; - - function setUp() public { - reverting = new RevertingToken(); - returnsTwo = new ReturnsTwoToken(); - returnsFalse = new ReturnsFalseToken(); - missingReturn = new MissingReturnToken(); - returnsTooMuch = new ReturnsTooMuchToken(); - returnsGarbage = new ReturnsGarbageToken(); - returnsTooLittle = new ReturnsTooLittleToken(); - - erc20 = new MockERC20("StandardToken", "ST", 18); - erc20.mint(address(this), type(uint256).max); - } - - function testTransferWithMissingReturn() public { - verifySafeTransfer(address(missingReturn), address(0xBEEF), 1e18); - } - - function testTransferWithStandardERC20() public { - verifySafeTransfer(address(erc20), address(0xBEEF), 1e18); - } - - function testTransferWithReturnsTooMuch() public { - verifySafeTransfer(address(returnsTooMuch), address(0xBEEF), 1e18); - } - - function testTransferWithNonContract() public { - SafeTransferLib.safeTransfer(ERC20(address(0xBADBEEF)), address(0xBEEF), 1e18); - } - - function testTransferFromWithMissingReturn() public { - verifySafeTransferFrom(address(missingReturn), address(0xFEED), address(0xBEEF), 1e18); - } - - function testTransferFromWithStandardERC20() public { - verifySafeTransferFrom(address(erc20), address(0xFEED), address(0xBEEF), 1e18); - } - - function testTransferFromWithReturnsTooMuch() public { - verifySafeTransferFrom(address(returnsTooMuch), address(0xFEED), address(0xBEEF), 1e18); - } - - function testTransferFromWithNonContract() public { - SafeTransferLib.safeTransferFrom(ERC20(address(0xBADBEEF)), address(0xFEED), address(0xBEEF), 1e18); - } - - function testApproveWithMissingReturn() public { - verifySafeApprove(address(missingReturn), address(0xBEEF), 1e18); - } - - function testApproveWithStandardERC20() public { - verifySafeApprove(address(erc20), address(0xBEEF), 1e18); - } - - function testApproveWithReturnsTooMuch() public { - verifySafeApprove(address(returnsTooMuch), address(0xBEEF), 1e18); - } - - function testApproveWithNonContract() public { - SafeTransferLib.safeApprove(ERC20(address(0xBADBEEF)), address(0xBEEF), 1e18); - } - - function testTransferETH() public { - SafeTransferLib.safeTransferETH(address(0xBEEF), 1e18); - } - - function testFailTransferWithReturnsFalse() public { - verifySafeTransfer(address(returnsFalse), address(0xBEEF), 1e18); - } - - function testFailTransferWithReverting() public { - verifySafeTransfer(address(reverting), address(0xBEEF), 1e18); - } - - function testFailTransferWithReturnsTooLittle() public { - verifySafeTransfer(address(returnsTooLittle), address(0xBEEF), 1e18); - } - - function testFailTransferFromWithReturnsFalse() public { - verifySafeTransferFrom(address(returnsFalse), address(0xFEED), address(0xBEEF), 1e18); - } - - function testFailTransferFromWithReverting() public { - verifySafeTransferFrom(address(reverting), address(0xFEED), address(0xBEEF), 1e18); - } - - function testFailTransferFromWithReturnsTooLittle() public { - verifySafeTransferFrom(address(returnsTooLittle), address(0xFEED), address(0xBEEF), 1e18); - } - - function testFailApproveWithReturnsFalse() public { - verifySafeApprove(address(returnsFalse), address(0xBEEF), 1e18); - } - - function testFailApproveWithReverting() public { - verifySafeApprove(address(reverting), address(0xBEEF), 1e18); - } - - function testFailApproveWithReturnsTooLittle() public { - verifySafeApprove(address(returnsTooLittle), address(0xBEEF), 1e18); - } - - function testTransferWithMissingReturn( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransfer(address(missingReturn), to, amount); - } - - function testTransferWithStandardERC20( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransfer(address(erc20), to, amount); - } - - function testTransferWithReturnsTooMuch( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransfer(address(returnsTooMuch), to, amount); - } - - function testTransferWithGarbage( - address to, - uint256 amount, - bytes memory garbage, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - if ( - (garbage.length < 32 || - (garbage[0] != 0 || - garbage[1] != 0 || - garbage[2] != 0 || - garbage[3] != 0 || - garbage[4] != 0 || - garbage[5] != 0 || - garbage[6] != 0 || - garbage[7] != 0 || - garbage[8] != 0 || - garbage[9] != 0 || - garbage[10] != 0 || - garbage[11] != 0 || - garbage[12] != 0 || - garbage[13] != 0 || - garbage[14] != 0 || - garbage[15] != 0 || - garbage[16] != 0 || - garbage[17] != 0 || - garbage[18] != 0 || - garbage[19] != 0 || - garbage[20] != 0 || - garbage[21] != 0 || - garbage[22] != 0 || - garbage[23] != 0 || - garbage[24] != 0 || - garbage[25] != 0 || - garbage[26] != 0 || - garbage[27] != 0 || - garbage[28] != 0 || - garbage[29] != 0 || - garbage[30] != 0 || - garbage[31] != bytes1(0x01))) && garbage.length != 0 - ) return; - - returnsGarbage.setGarbage(garbage); - - verifySafeTransfer(address(returnsGarbage), to, amount); - } - - function testTransferWithNonContract( - address nonContract, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return; - - SafeTransferLib.safeTransfer(ERC20(nonContract), to, amount); - } - - function testFailTransferETHToContractWithoutFallback() public { - SafeTransferLib.safeTransferETH(address(this), 1e18); - } - - function testTransferFromWithMissingReturn( - address from, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransferFrom(address(missingReturn), from, to, amount); - } - - function testTransferFromWithStandardERC20( - address from, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransferFrom(address(erc20), from, to, amount); - } - - function testTransferFromWithReturnsTooMuch( - address from, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransferFrom(address(returnsTooMuch), from, to, amount); - } - - function testTransferFromWithGarbage( - address from, - address to, - uint256 amount, - bytes memory garbage, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - if ( - (garbage.length < 32 || - (garbage[0] != 0 || - garbage[1] != 0 || - garbage[2] != 0 || - garbage[3] != 0 || - garbage[4] != 0 || - garbage[5] != 0 || - garbage[6] != 0 || - garbage[7] != 0 || - garbage[8] != 0 || - garbage[9] != 0 || - garbage[10] != 0 || - garbage[11] != 0 || - garbage[12] != 0 || - garbage[13] != 0 || - garbage[14] != 0 || - garbage[15] != 0 || - garbage[16] != 0 || - garbage[17] != 0 || - garbage[18] != 0 || - garbage[19] != 0 || - garbage[20] != 0 || - garbage[21] != 0 || - garbage[22] != 0 || - garbage[23] != 0 || - garbage[24] != 0 || - garbage[25] != 0 || - garbage[26] != 0 || - garbage[27] != 0 || - garbage[28] != 0 || - garbage[29] != 0 || - garbage[30] != 0 || - garbage[31] != bytes1(0x01))) && garbage.length != 0 - ) return; - - returnsGarbage.setGarbage(garbage); - - verifySafeTransferFrom(address(returnsGarbage), from, to, amount); - } - - function testTransferFromWithNonContract( - address nonContract, - address from, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return; - - SafeTransferLib.safeTransferFrom(ERC20(nonContract), from, to, amount); - } - - function testApproveWithMissingReturn( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeApprove(address(missingReturn), to, amount); - } - - function testApproveWithStandardERC20( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeApprove(address(erc20), to, amount); - } - - function testApproveWithReturnsTooMuch( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeApprove(address(returnsTooMuch), to, amount); - } - - function testApproveWithGarbage( - address to, - uint256 amount, - bytes memory garbage, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - if ( - (garbage.length < 32 || - (garbage[0] != 0 || - garbage[1] != 0 || - garbage[2] != 0 || - garbage[3] != 0 || - garbage[4] != 0 || - garbage[5] != 0 || - garbage[6] != 0 || - garbage[7] != 0 || - garbage[8] != 0 || - garbage[9] != 0 || - garbage[10] != 0 || - garbage[11] != 0 || - garbage[12] != 0 || - garbage[13] != 0 || - garbage[14] != 0 || - garbage[15] != 0 || - garbage[16] != 0 || - garbage[17] != 0 || - garbage[18] != 0 || - garbage[19] != 0 || - garbage[20] != 0 || - garbage[21] != 0 || - garbage[22] != 0 || - garbage[23] != 0 || - garbage[24] != 0 || - garbage[25] != 0 || - garbage[26] != 0 || - garbage[27] != 0 || - garbage[28] != 0 || - garbage[29] != 0 || - garbage[30] != 0 || - garbage[31] != bytes1(0x01))) && garbage.length != 0 - ) return; - - returnsGarbage.setGarbage(garbage); - - verifySafeApprove(address(returnsGarbage), to, amount); - } - - function testApproveWithNonContract( - address nonContract, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - if (uint256(uint160(nonContract)) <= 18 || nonContract.code.length > 0) return; - - SafeTransferLib.safeApprove(ERC20(nonContract), to, amount); - } - - function testTransferETH( - address recipient, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - // Transferring to msg.sender can fail because it's possible to overflow their ETH balance as it begins non-zero. - if (recipient.code.length > 0 || uint256(uint160(recipient)) <= 18 || recipient == msg.sender) return; - - amount = bound(amount, 0, address(this).balance); - - SafeTransferLib.safeTransferETH(recipient, amount); - } - - function testFailTransferWithReturnsFalse( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransfer(address(returnsFalse), to, amount); - } - - function testFailTransferWithReverting( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransfer(address(reverting), to, amount); - } - - function testFailTransferWithReturnsTooLittle( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransfer(address(returnsTooLittle), to, amount); - } - - function testFailTransferWithReturnsTwo( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransfer(address(returnsTwo), to, amount); - } - - function testFailTransferWithGarbage( - address to, - uint256 amount, - bytes memory garbage, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - require(garbage.length != 0 && (garbage.length < 32 || garbage[31] != bytes1(0x01))); - - returnsGarbage.setGarbage(garbage); - - verifySafeTransfer(address(returnsGarbage), to, amount); - } - - function testFailTransferFromWithReturnsFalse( - address from, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransferFrom(address(returnsFalse), from, to, amount); - } - - function testFailTransferFromWithReverting( - address from, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransferFrom(address(reverting), from, to, amount); - } - - function testFailTransferFromWithReturnsTooLittle( - address from, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransferFrom(address(returnsTooLittle), from, to, amount); - } - - function testFailTransferFromWithReturnsTwo( - address from, - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeTransferFrom(address(returnsTwo), from, to, amount); - } - - function testFailTransferFromWithGarbage( - address from, - address to, - uint256 amount, - bytes memory garbage, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - require(garbage.length != 0 && (garbage.length < 32 || garbage[31] != bytes1(0x01))); - - returnsGarbage.setGarbage(garbage); - - verifySafeTransferFrom(address(returnsGarbage), from, to, amount); - } - - function testFailApproveWithReturnsFalse( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeApprove(address(returnsFalse), to, amount); - } - - function testFailApproveWithReverting( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeApprove(address(reverting), to, amount); - } - - function testFailApproveWithReturnsTooLittle( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeApprove(address(returnsTooLittle), to, amount); - } - - function testFailApproveWithReturnsTwo( - address to, - uint256 amount, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - verifySafeApprove(address(returnsTwo), to, amount); - } - - function testFailApproveWithGarbage( - address to, - uint256 amount, - bytes memory garbage, - bytes calldata brutalizeWith - ) public brutalizeMemory(brutalizeWith) { - require(garbage.length != 0 && (garbage.length < 32 || garbage[31] != bytes1(0x01))); - - returnsGarbage.setGarbage(garbage); - - verifySafeApprove(address(returnsGarbage), to, amount); - } - - function testFailTransferETHToContractWithoutFallback(uint256 amount, bytes calldata brutalizeWith) - public - brutalizeMemory(brutalizeWith) - { - SafeTransferLib.safeTransferETH(address(this), amount); - } - - function verifySafeTransfer( - address token, - address to, - uint256 amount - ) internal { - uint256 preBal = ERC20(token).balanceOf(to); - SafeTransferLib.safeTransfer(ERC20(address(token)), to, amount); - uint256 postBal = ERC20(token).balanceOf(to); - - if (to == address(this)) { - assertEq(preBal, postBal); - } else { - assertEq(postBal - preBal, amount); - } - } - - function verifySafeTransferFrom( - address token, - address from, - address to, - uint256 amount - ) internal { - forceApprove(token, from, address(this), amount); - - // We cast to MissingReturnToken here because it won't check - // that there was return data, which accommodates all tokens. - MissingReturnToken(token).transfer(from, amount); - - uint256 preBal = ERC20(token).balanceOf(to); - SafeTransferLib.safeTransferFrom(ERC20(token), from, to, amount); - uint256 postBal = ERC20(token).balanceOf(to); - - if (from == to) { - assertEq(preBal, postBal); - } else { - assertEq(postBal - preBal, amount); - } - } - - function verifySafeApprove( - address token, - address to, - uint256 amount - ) internal { - SafeTransferLib.safeApprove(ERC20(address(token)), to, amount); - - assertEq(ERC20(token).allowance(address(this), to), amount); - } - - function forceApprove( - address token, - address from, - address to, - uint256 amount - ) internal { - uint256 slot = token == address(erc20) ? 4 : 2; // Standard ERC20 name and symbol aren't constant. - - hevm.store( - token, - keccak256(abi.encode(to, keccak256(abi.encode(from, uint256(slot))))), - bytes32(uint256(amount)) - ); - - assertEq(ERC20(token).allowance(from, to), amount, "wrong allowance"); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/SignedWadMath.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/SignedWadMath.t.sol deleted file mode 100644 index 4849448..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/SignedWadMath.t.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; - -import {wadMul, wadDiv} from "../utils/SignedWadMath.sol"; - -contract SignedWadMathTest is DSTestPlus { - function testWadMul( - uint256 x, - uint256 y, - bool negX, - bool negY - ) public { - x = bound(x, 0, 99999999999999e18); - y = bound(x, 0, 99999999999999e18); - - int256 xPrime = negX ? -int256(x) : int256(x); - int256 yPrime = negY ? -int256(y) : int256(y); - - assertEq(wadMul(xPrime, yPrime), (xPrime * yPrime) / 1e18); - } - - function testFailWadMulEdgeCase() public pure { - int256 x = -1; - int256 y = type(int256).min; - - wadMul(x, y); - } - - function testFailWadMulEdgeCase2() public pure { - int256 x = type(int256).min; - int256 y = -1; - - wadMul(x, y); - } - - function testFailWadMulOverflow(int256 x, int256 y) public pure { - // Ignore cases where x * y does not overflow. - unchecked { - if ((x * y) / x == y) revert(); - } - - wadMul(x, y); - } - - function testWadDiv( - uint256 x, - uint256 y, - bool negX, - bool negY - ) public { - x = bound(x, 0, 99999999e18); - y = bound(x, 1, 99999999e18); - - int256 xPrime = negX ? -int256(x) : int256(x); - int256 yPrime = negY ? -int256(y) : int256(y); - - assertEq(wadDiv(xPrime, yPrime), (xPrime * 1e18) / yPrime); - } - - function testFailWadDivOverflow(int256 x, int256 y) public pure { - // Ignore cases where x * WAD does not overflow or y is 0. - unchecked { - if (y == 0 || (x * 1e18) / 1e18 == x) revert(); - } - - wadDiv(x, y); - } - - function testFailWadDivZeroDenominator(int256 x) public pure { - wadDiv(x, 0); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/WETH.t.sol b/lib/morpho-blue-irm/lib/solmate/src/test/WETH.t.sol deleted file mode 100644 index a13761e..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/WETH.t.sol +++ /dev/null @@ -1,146 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity 0.8.15; - -import {DSTestPlus} from "./utils/DSTestPlus.sol"; -import {DSInvariantTest} from "./utils/DSInvariantTest.sol"; - -import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; - -import {WETH} from "../tokens/WETH.sol"; - -contract WETHTest is DSTestPlus { - WETH weth; - - function setUp() public { - weth = new WETH(); - } - - function testFallbackDeposit() public { - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - - SafeTransferLib.safeTransferETH(address(weth), 1 ether); - - assertEq(weth.balanceOf(address(this)), 1 ether); - assertEq(weth.totalSupply(), 1 ether); - } - - function testDeposit() public { - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - - weth.deposit{value: 1 ether}(); - - assertEq(weth.balanceOf(address(this)), 1 ether); - assertEq(weth.totalSupply(), 1 ether); - } - - function testWithdraw() public { - uint256 startingBalance = address(this).balance; - - weth.deposit{value: 1 ether}(); - - weth.withdraw(1 ether); - - uint256 balanceAfterWithdraw = address(this).balance; - - assertEq(balanceAfterWithdraw, startingBalance); - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - } - - function testPartialWithdraw() public { - weth.deposit{value: 1 ether}(); - - uint256 balanceBeforeWithdraw = address(this).balance; - - weth.withdraw(0.5 ether); - - uint256 balanceAfterWithdraw = address(this).balance; - - assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + 0.5 ether); - assertEq(weth.balanceOf(address(this)), 0.5 ether); - assertEq(weth.totalSupply(), 0.5 ether); - } - - function testFallbackDeposit(uint256 amount) public { - amount = bound(amount, 0, address(this).balance); - - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - - SafeTransferLib.safeTransferETH(address(weth), amount); - - assertEq(weth.balanceOf(address(this)), amount); - assertEq(weth.totalSupply(), amount); - } - - function testDeposit(uint256 amount) public { - amount = bound(amount, 0, address(this).balance); - - assertEq(weth.balanceOf(address(this)), 0); - assertEq(weth.totalSupply(), 0); - - weth.deposit{value: amount}(); - - assertEq(weth.balanceOf(address(this)), amount); - assertEq(weth.totalSupply(), amount); - } - - function testWithdraw(uint256 depositAmount, uint256 withdrawAmount) public { - depositAmount = bound(depositAmount, 0, address(this).balance); - withdrawAmount = bound(withdrawAmount, 0, depositAmount); - - weth.deposit{value: depositAmount}(); - - uint256 balanceBeforeWithdraw = address(this).balance; - - weth.withdraw(withdrawAmount); - - uint256 balanceAfterWithdraw = address(this).balance; - - assertEq(balanceAfterWithdraw, balanceBeforeWithdraw + withdrawAmount); - assertEq(weth.balanceOf(address(this)), depositAmount - withdrawAmount); - assertEq(weth.totalSupply(), depositAmount - withdrawAmount); - } - - receive() external payable {} -} - -contract WETHInvariants is DSTestPlus, DSInvariantTest { - WETHTester wethTester; - WETH weth; - - function setUp() public { - weth = new WETH(); - wethTester = new WETHTester{value: address(this).balance}(weth); - - addTargetContract(address(wethTester)); - } - - function invariantTotalSupplyEqualsBalance() public { - assertEq(address(weth).balance, weth.totalSupply()); - } -} - -contract WETHTester { - WETH weth; - - constructor(WETH _weth) payable { - weth = _weth; - } - - function deposit(uint256 amount) public { - weth.deposit{value: amount}(); - } - - function fallbackDeposit(uint256 amount) public { - SafeTransferLib.safeTransferETH(address(weth), amount); - } - - function withdraw(uint256 amount) public { - weth.withdraw(amount); - } - - receive() external payable {} -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/DSInvariantTest.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/DSInvariantTest.sol deleted file mode 100644 index 820775c..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/DSInvariantTest.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -contract DSInvariantTest { - address[] private targets; - - function targetContracts() public view virtual returns (address[] memory) { - require(targets.length > 0, "NO_TARGET_CONTRACTS"); - - return targets; - } - - function addTargetContract(address newTargetContract) internal virtual { - targets.push(newTargetContract); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/DSTestPlus.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/DSTestPlus.sol deleted file mode 100644 index b56d4c9..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/DSTestPlus.sol +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {DSTest} from "ds-test/test.sol"; - -import {Hevm} from "./Hevm.sol"; - -/// @notice Extended testing framework for DappTools projects. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/test/utils/DSTestPlus.sol) -contract DSTestPlus is DSTest { - Hevm internal constant hevm = Hevm(HEVM_ADDRESS); - - address internal constant DEAD_ADDRESS = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; - - string private checkpointLabel; - uint256 private checkpointGasLeft = 1; // Start the slot warm. - - modifier brutalizeMemory(bytes memory brutalizeWith) { - /// @solidity memory-safe-assembly - assembly { - // Fill the 64 bytes of scratch space with the data. - pop( - staticcall( - gas(), // Pass along all the gas in the call. - 0x04, // Call the identity precompile address. - brutalizeWith, // Offset is the bytes' pointer. - 64, // Copy enough to only fill the scratch space. - 0, // Store the return value in the scratch space. - 64 // Scratch space is only 64 bytes in size, we don't want to write further. - ) - ) - - let size := add(mload(brutalizeWith), 32) // Add 32 to include the 32 byte length slot. - - // Fill the free memory pointer's destination with the data. - pop( - staticcall( - gas(), // Pass along all the gas in the call. - 0x04, // Call the identity precompile address. - brutalizeWith, // Offset is the bytes' pointer. - size, // We want to pass the length of the bytes. - mload(0x40), // Store the return value at the free memory pointer. - size // Since the precompile just returns its input, we reuse size. - ) - ) - } - - _; - } - - function startMeasuringGas(string memory label) internal virtual { - checkpointLabel = label; - - checkpointGasLeft = gasleft(); - } - - function stopMeasuringGas() internal virtual { - uint256 checkpointGasLeft2 = gasleft(); - - // Subtract 100 to account for the warm SLOAD in startMeasuringGas. - uint256 gasDelta = checkpointGasLeft - checkpointGasLeft2 - 100; - - emit log_named_uint(string(abi.encodePacked(checkpointLabel, " Gas")), gasDelta); - } - - function fail(string memory err) internal virtual { - emit log_named_string("Error", err); - fail(); - } - - function assertFalse(bool data) internal virtual { - assertTrue(!data); - } - - function assertUint128Eq(uint128 a, uint128 b) internal virtual { - assertEq(uint256(a), uint256(b)); - } - - function assertUint64Eq(uint64 a, uint64 b) internal virtual { - assertEq(uint256(a), uint256(b)); - } - - function assertUint96Eq(uint96 a, uint96 b) internal virtual { - assertEq(uint256(a), uint256(b)); - } - - function assertUint32Eq(uint32 a, uint32 b) internal virtual { - assertEq(uint256(a), uint256(b)); - } - - function assertBoolEq(bool a, bool b) internal virtual { - b ? assertTrue(a) : assertFalse(a); - } - - function assertApproxEq( - uint256 a, - uint256 b, - uint256 maxDelta - ) internal virtual { - uint256 delta = a > b ? a - b : b - a; - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Expected", b); - emit log_named_uint(" Actual", a); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertRelApproxEq( - uint256 a, - uint256 b, - uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% - ) internal virtual { - if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too. - - uint256 percentDelta = ((a > b ? a - b : b - a) * 1e18) / b; - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Expected", b); - emit log_named_uint(" Actual", a); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta, 18); - emit log_named_decimal_uint(" % Delta", percentDelta, 18); - fail(); - } - } - - function assertBytesEq(bytes memory a, bytes memory b) internal virtual { - if (keccak256(a) != keccak256(b)) { - emit log("Error: a == b not satisfied [bytes]"); - emit log_named_bytes(" Expected", b); - emit log_named_bytes(" Actual", a); - fail(); - } - } - - function assertUintArrayEq(uint256[] memory a, uint256[] memory b) internal virtual { - require(a.length == b.length, "LENGTH_MISMATCH"); - - for (uint256 i = 0; i < a.length; i++) { - assertEq(a[i], b[i]); - } - } - - function bound( - uint256 x, - uint256 min, - uint256 max - ) internal virtual returns (uint256 result) { - require(max >= min, "MAX_LESS_THAN_MIN"); - - uint256 size = max - min; - - if (size == 0) result = min; - else if (size == type(uint256).max) result = x; - else { - ++size; // Make max inclusive. - uint256 mod = x % size; - result = min + mod; - } - - emit log_named_uint("Bound Result", result); - } - - function min3( - uint256 a, - uint256 b, - uint256 c - ) internal pure returns (uint256) { - return a > b ? (b > c ? c : b) : (a > c ? c : a); - } - - function min2(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? b : a; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/Hevm.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/Hevm.sol deleted file mode 100644 index 8ca0eff..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/Hevm.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -interface Hevm { - /// @notice Sets the block timestamp. - function warp(uint256) external; - - /// @notice Sets the block height. - function roll(uint256) external; - - /// @notice Sets the block base fee. - function fee(uint256) external; - - /// @notice Loads a storage slot from an address. - function load(address, bytes32) external returns (bytes32); - - /// @notice Stores a value to an address' storage slot. - function store( - address, - bytes32, - bytes32 - ) external; - - /// @notice Signs a digest with a private key, returns v r s. - function sign(uint256, bytes32) - external - returns ( - uint8, - bytes32, - bytes32 - ); - - /// @notice Gets address for a given private key. - function addr(uint256) external returns (address); - - /// @notice Performs a foreign function call via a terminal call. - function ffi(string[] calldata) external returns (bytes memory); - - /// @notice Sets the next call's msg.sender to be the input address. - function prank(address) external; - - /// @notice Sets all subsequent calls' msg.sender to be the input address until stopPrank is called. - function startPrank(address) external; - - /// @notice Sets the next call's msg.sender to be the input address and the tx.origin to be the second input. - function prank(address, address) external; - - /// @notice Sets all subsequent calls' msg.sender to be the input address and - /// sets tx.origin to be the second address inputted until stopPrank is called. - function startPrank(address, address) external; - - /// @notice Resets msg.sender to its original value before a prank. - function stopPrank() external; - - /// @notice Sets an address' balance. - function deal(address, uint256) external; - - /// @notice Sets an address' code. - function etch(address, bytes calldata) external; - - /// @notice Expects an error from the next call. - function expectRevert(bytes calldata) external; - - /// @notice Expects a revert from the next call. - function expectRevert(bytes4) external; - - /// @notice Record all storage reads and writes. - function record() external; - - /// @notice Gets all accessed reads and write slots from a recording session, for a given address. - function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes); - - /// @notice Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). - /// @notice Call this function, then emit an event, then call a function. Internally after the call, we check - /// if logs were emitted in the expected order with the expected topics and data as specified by the booleans. - function expectEmit( - bool, - bool, - bool, - bool - ) external; - - /// @notice Mocks the behavior of a contract call, setting the input and output for a function. - /// @notice Calldata can either be strict or a partial match, e.g. if only passed - /// a selector to the expected calldata, then the entire function will be mocked. - function mockCall( - address, - bytes calldata, - bytes calldata - ) external; - - /// @notice Clears all mocked calls. - function clearMockedCalls() external; - - /// @notice Expect a call to an address with the specified calldata. - /// @notice Calldata can either be strict or a partial match. - function expectCall(address, bytes calldata) external; - - /// @notice Fetches the contract bytecode from its artifact file. - function getCode(string calldata) external returns (bytes memory); - - /// @notice Label an address in test traces. - function label(address addr, string calldata label) external; - - /// @notice When fuzzing, generate new inputs if the input conditional is not met. - function assume(bool) external; -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockAuthChild.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockAuthChild.sol deleted file mode 100644 index d2c3276..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockAuthChild.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {Auth, Authority} from "../../../auth/Auth.sol"; - -contract MockAuthChild is Auth(msg.sender, Authority(address(0))) { - bool public flag; - - function updateFlag() public virtual requiresAuth { - flag = true; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockAuthority.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockAuthority.sol deleted file mode 100644 index acb3689..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockAuthority.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {Authority} from "../../../auth/Auth.sol"; - -contract MockAuthority is Authority { - bool immutable allowCalls; - - constructor(bool _allowCalls) { - allowCalls = _allowCalls; - } - - function canCall( - address, - address, - bytes4 - ) public view override returns (bool) { - return allowCalls; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC1155.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC1155.sol deleted file mode 100644 index ede086d..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC1155.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {ERC1155} from "../../../tokens/ERC1155.sol"; - -contract MockERC1155 is ERC1155 { - function uri(uint256) public pure virtual override returns (string memory) {} - - function mint( - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual { - _mint(to, id, amount, data); - } - - function batchMint( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - _batchMint(to, ids, amounts, data); - } - - function burn( - address from, - uint256 id, - uint256 amount - ) public virtual { - _burn(from, id, amount); - } - - function batchBurn( - address from, - uint256[] memory ids, - uint256[] memory amounts - ) public virtual { - _batchBurn(from, ids, amounts); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC20.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC20.sol deleted file mode 100644 index fbbaef5..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC20.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {ERC20} from "../../../tokens/ERC20.sol"; - -contract MockERC20 is ERC20 { - constructor( - string memory _name, - string memory _symbol, - uint8 _decimals - ) ERC20(_name, _symbol, _decimals) {} - - function mint(address to, uint256 value) public virtual { - _mint(to, value); - } - - function burn(address from, uint256 value) public virtual { - _burn(from, value); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC4626.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC4626.sol deleted file mode 100644 index edc7d5f..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC4626.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {ERC20} from "../../../tokens/ERC20.sol"; -import {ERC4626} from "../../../mixins/ERC4626.sol"; - -contract MockERC4626 is ERC4626 { - uint256 public beforeWithdrawHookCalledCounter = 0; - uint256 public afterDepositHookCalledCounter = 0; - - constructor( - ERC20 _underlying, - string memory _name, - string memory _symbol - ) ERC4626(_underlying, _name, _symbol) {} - - function totalAssets() public view override returns (uint256) { - return asset.balanceOf(address(this)); - } - - function beforeWithdraw(uint256, uint256) internal override { - beforeWithdrawHookCalledCounter++; - } - - function afterDeposit(uint256, uint256) internal override { - afterDepositHookCalledCounter++; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC721.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC721.sol deleted file mode 100644 index 51227c0..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockERC721.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {ERC721} from "../../../tokens/ERC721.sol"; - -contract MockERC721 is ERC721 { - constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {} - - function tokenURI(uint256) public pure virtual override returns (string memory) {} - - function mint(address to, uint256 tokenId) public virtual { - _mint(to, tokenId); - } - - function burn(uint256 tokenId) public virtual { - _burn(tokenId); - } - - function safeMint(address to, uint256 tokenId) public virtual { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory data - ) public virtual { - _safeMint(to, tokenId, data); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockOwned.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockOwned.sol deleted file mode 100644 index 52ef918..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/mocks/MockOwned.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {Owned} from "../../../auth/Owned.sol"; - -contract MockOwned is Owned(msg.sender) { - bool public flag; - - function updateFlag() public virtual onlyOwner { - flag = true; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/MissingReturnToken.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/MissingReturnToken.sol deleted file mode 100644 index 23f4633..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/MissingReturnToken.sol +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -contract MissingReturnToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "MissingReturnToken"; - - string public constant symbol = "MRT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 amount) public virtual { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - } - - function transfer(address to, uint256 amount) public virtual { - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - } - - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual { - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; - - balanceOf[from] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsFalseToken.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsFalseToken.sol deleted file mode 100644 index 8139efe..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsFalseToken.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -contract ReturnsFalseToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsFalseToken"; - - string public constant symbol = "RFT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address, uint256) public virtual returns (bool) { - return false; - } - - function transfer(address, uint256) public virtual returns (bool) { - return false; - } - - function transferFrom( - address, - address, - uint256 - ) public virtual returns (bool) { - return false; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsGarbageToken.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsGarbageToken.sol deleted file mode 100644 index 77c9575..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsGarbageToken.sol +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -contract ReturnsGarbageToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsGarbageToken"; - - string public constant symbol = "RGT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - MOCK STORAGE - //////////////////////////////////////////////////////////////*/ - - bytes garbage; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 amount) public virtual { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - - bytes memory _garbage = garbage; - - assembly { - return(add(_garbage, 32), mload(_garbage)) - } - } - - function transfer(address to, uint256 amount) public virtual { - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - - bytes memory _garbage = garbage; - - assembly { - return(add(_garbage, 32), mload(_garbage)) - } - } - - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual { - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; - - balanceOf[from] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - - bytes memory _garbage = garbage; - - assembly { - return(add(_garbage, 32), mload(_garbage)) - } - } - - /*/////////////////////////////////////////////////////////////// - MOCK LOGIC - //////////////////////////////////////////////////////////////*/ - - function setGarbage(bytes memory _garbage) public virtual { - garbage = _garbage; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTooLittleToken.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTooLittleToken.sol deleted file mode 100644 index 69947c3..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTooLittleToken.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -contract ReturnsTooLittleToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsTooLittleToken"; - - string public constant symbol = "RTLT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address, uint256) public virtual { - assembly { - mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) - return(0, 8) - } - } - - function transfer(address, uint256) public virtual { - assembly { - mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) - return(0, 8) - } - } - - function transferFrom( - address, - address, - uint256 - ) public virtual { - assembly { - mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) - return(0, 8) - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTooMuchToken.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTooMuchToken.sol deleted file mode 100644 index 8774cbb..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTooMuchToken.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -contract ReturnsTooMuchToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsTooMuchToken"; - - string public constant symbol = "RTMT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 amount) public virtual { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - - assembly { - mstore(0, 1) - return(0, 4096) - } - } - - function transfer(address to, uint256 amount) public virtual { - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - - assembly { - mstore(0, 1) - return(0, 4096) - } - } - - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual { - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; - - balanceOf[from] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - - assembly { - mstore(0, 1) - return(0, 4096) - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTwoToken.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTwoToken.sol deleted file mode 100644 index ac980f8..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/ReturnsTwoToken.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -contract ReturnsTwoToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "ReturnsFalseToken"; - - string public constant symbol = "RTT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address, uint256) public virtual returns (uint256) { - return 2; - } - - function transfer(address, uint256) public virtual returns (uint256) { - return 2; - } - - function transferFrom( - address, - address, - uint256 - ) public virtual returns (uint256) { - return 2; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/RevertingToken.sol b/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/RevertingToken.sol deleted file mode 100644 index 48ac1fa..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/test/utils/weird-tokens/RevertingToken.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -contract RevertingToken { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*/////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public constant name = "RevertingToken"; - - string public constant symbol = "RT"; - - uint8 public constant decimals = 18; - - /*/////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*/////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor() { - totalSupply = type(uint256).max; - balanceOf[msg.sender] = type(uint256).max; - } - - /*/////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address, uint256) public virtual { - revert(); - } - - function transfer(address, uint256) public virtual { - revert(); - } - - function transferFrom( - address, - address, - uint256 - ) public virtual { - revert(); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC1155.sol b/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC1155.sol deleted file mode 100644 index cff0f02..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC1155.sol +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Minimalist and gas efficient standard ERC1155 implementation. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) -abstract contract ERC1155 { - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event TransferSingle( - address indexed operator, - address indexed from, - address indexed to, - uint256 id, - uint256 amount - ); - - event TransferBatch( - address indexed operator, - address indexed from, - address indexed to, - uint256[] ids, - uint256[] amounts - ); - - event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - - event URI(string value, uint256 indexed id); - - /*////////////////////////////////////////////////////////////// - ERC1155 STORAGE - //////////////////////////////////////////////////////////////*/ - - mapping(address => mapping(uint256 => uint256)) public balanceOf; - - mapping(address => mapping(address => bool)) public isApprovedForAll; - - /*////////////////////////////////////////////////////////////// - METADATA LOGIC - //////////////////////////////////////////////////////////////*/ - - function uri(uint256 id) public view virtual returns (string memory); - - /*////////////////////////////////////////////////////////////// - ERC1155 LOGIC - //////////////////////////////////////////////////////////////*/ - - function setApprovalForAll(address operator, bool approved) public virtual { - isApprovedForAll[msg.sender][operator] = approved; - - emit ApprovalForAll(msg.sender, operator, approved); - } - - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) public virtual { - require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); - - balanceOf[from][id] -= amount; - balanceOf[to][id] += amount; - - emit TransferSingle(msg.sender, from, to, id, amount); - - require( - to.code.length == 0 - ? to != address(0) - : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == - ERC1155TokenReceiver.onERC1155Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - function safeBatchTransferFrom( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) public virtual { - require(ids.length == amounts.length, "LENGTH_MISMATCH"); - - require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); - - // Storing these outside the loop saves ~15 gas per iteration. - uint256 id; - uint256 amount; - - for (uint256 i = 0; i < ids.length; ) { - id = ids[i]; - amount = amounts[i]; - - balanceOf[from][id] -= amount; - balanceOf[to][id] += amount; - - // An array can't have a total length - // larger than the max uint256 value. - unchecked { - ++i; - } - } - - emit TransferBatch(msg.sender, from, to, ids, amounts); - - require( - to.code.length == 0 - ? to != address(0) - : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == - ERC1155TokenReceiver.onERC1155BatchReceived.selector, - "UNSAFE_RECIPIENT" - ); - } - - function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) - public - view - virtual - returns (uint256[] memory balances) - { - require(owners.length == ids.length, "LENGTH_MISMATCH"); - - balances = new uint256[](owners.length); - - // Unchecked because the only math done is incrementing - // the array index counter which cannot possibly overflow. - unchecked { - for (uint256 i = 0; i < owners.length; ++i) { - balances[i] = balanceOf[owners[i]][ids[i]]; - } - } - } - - /*////////////////////////////////////////////////////////////// - ERC165 LOGIC - //////////////////////////////////////////////////////////////*/ - - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { - return - interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 - interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 - interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI - } - - /*////////////////////////////////////////////////////////////// - INTERNAL MINT/BURN LOGIC - //////////////////////////////////////////////////////////////*/ - - function _mint( - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - balanceOf[to][id] += amount; - - emit TransferSingle(msg.sender, address(0), to, id, amount); - - require( - to.code.length == 0 - ? to != address(0) - : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) == - ERC1155TokenReceiver.onERC1155Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - function _batchMint( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - uint256 idsLength = ids.length; // Saves MLOADs. - - require(idsLength == amounts.length, "LENGTH_MISMATCH"); - - for (uint256 i = 0; i < idsLength; ) { - balanceOf[to][ids[i]] += amounts[i]; - - // An array can't have a total length - // larger than the max uint256 value. - unchecked { - ++i; - } - } - - emit TransferBatch(msg.sender, address(0), to, ids, amounts); - - require( - to.code.length == 0 - ? to != address(0) - : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == - ERC1155TokenReceiver.onERC1155BatchReceived.selector, - "UNSAFE_RECIPIENT" - ); - } - - function _batchBurn( - address from, - uint256[] memory ids, - uint256[] memory amounts - ) internal virtual { - uint256 idsLength = ids.length; // Saves MLOADs. - - require(idsLength == amounts.length, "LENGTH_MISMATCH"); - - for (uint256 i = 0; i < idsLength; ) { - balanceOf[from][ids[i]] -= amounts[i]; - - // An array can't have a total length - // larger than the max uint256 value. - unchecked { - ++i; - } - } - - emit TransferBatch(msg.sender, from, address(0), ids, amounts); - } - - function _burn( - address from, - uint256 id, - uint256 amount - ) internal virtual { - balanceOf[from][id] -= amount; - - emit TransferSingle(msg.sender, from, address(0), id, amount); - } -} - -/// @notice A generic interface for a contract which properly accepts ERC1155 tokens. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) -abstract contract ERC1155TokenReceiver { - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes calldata - ) external virtual returns (bytes4) { - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external virtual returns (bytes4) { - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC20.sol b/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC20.sol deleted file mode 100644 index 9657044..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC20.sol +++ /dev/null @@ -1,206 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) -/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) -/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. -abstract contract ERC20 { - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 amount); - - event Approval(address indexed owner, address indexed spender, uint256 amount); - - /*////////////////////////////////////////////////////////////// - METADATA STORAGE - //////////////////////////////////////////////////////////////*/ - - string public name; - - string public symbol; - - uint8 public immutable decimals; - - /*////////////////////////////////////////////////////////////// - ERC20 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 public totalSupply; - - mapping(address => uint256) public balanceOf; - - mapping(address => mapping(address => uint256)) public allowance; - - /*////////////////////////////////////////////////////////////// - EIP-2612 STORAGE - //////////////////////////////////////////////////////////////*/ - - uint256 internal immutable INITIAL_CHAIN_ID; - - bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; - - mapping(address => uint256) public nonces; - - /*////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor( - string memory _name, - string memory _symbol, - uint8 _decimals - ) { - name = _name; - symbol = _symbol; - decimals = _decimals; - - INITIAL_CHAIN_ID = block.chainid; - INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); - } - - /*////////////////////////////////////////////////////////////// - ERC20 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 amount) public virtual returns (bool) { - allowance[msg.sender][spender] = amount; - - emit Approval(msg.sender, spender, amount); - - return true; - } - - function transfer(address to, uint256 amount) public virtual returns (bool) { - balanceOf[msg.sender] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(msg.sender, to, amount); - - return true; - } - - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual returns (bool) { - uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. - - if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; - - balanceOf[from] -= amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(from, to, amount); - - return true; - } - - /*////////////////////////////////////////////////////////////// - EIP-2612 LOGIC - //////////////////////////////////////////////////////////////*/ - - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual { - require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); - - // Unchecked because the only math done is incrementing - // the owner's nonce which cannot realistically overflow. - unchecked { - address recoveredAddress = ecrecover( - keccak256( - abi.encodePacked( - "\x19\x01", - DOMAIN_SEPARATOR(), - keccak256( - abi.encode( - keccak256( - "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" - ), - owner, - spender, - value, - nonces[owner]++, - deadline - ) - ) - ) - ), - v, - r, - s - ); - - require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); - - allowance[recoveredAddress][spender] = value; - } - - emit Approval(owner, spender, value); - } - - function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { - return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); - } - - function computeDomainSeparator() internal view virtual returns (bytes32) { - return - keccak256( - abi.encode( - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), - keccak256(bytes(name)), - keccak256("1"), - block.chainid, - address(this) - ) - ); - } - - /*////////////////////////////////////////////////////////////// - INTERNAL MINT/BURN LOGIC - //////////////////////////////////////////////////////////////*/ - - function _mint(address to, uint256 amount) internal virtual { - totalSupply += amount; - - // Cannot overflow because the sum of all user - // balances can't exceed the max uint256 value. - unchecked { - balanceOf[to] += amount; - } - - emit Transfer(address(0), to, amount); - } - - function _burn(address from, uint256 amount) internal virtual { - balanceOf[from] -= amount; - - // Cannot underflow because a user's balance - // will never be larger than the total supply. - unchecked { - totalSupply -= amount; - } - - emit Transfer(from, address(0), amount); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC721.sol b/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC721.sol deleted file mode 100644 index b47f271..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/tokens/ERC721.sol +++ /dev/null @@ -1,231 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Modern, minimalist, and gas efficient ERC-721 implementation. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) -abstract contract ERC721 { - /*////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - event Transfer(address indexed from, address indexed to, uint256 indexed id); - - event Approval(address indexed owner, address indexed spender, uint256 indexed id); - - event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - - /*////////////////////////////////////////////////////////////// - METADATA STORAGE/LOGIC - //////////////////////////////////////////////////////////////*/ - - string public name; - - string public symbol; - - function tokenURI(uint256 id) public view virtual returns (string memory); - - /*////////////////////////////////////////////////////////////// - ERC721 BALANCE/OWNER STORAGE - //////////////////////////////////////////////////////////////*/ - - mapping(uint256 => address) internal _ownerOf; - - mapping(address => uint256) internal _balanceOf; - - function ownerOf(uint256 id) public view virtual returns (address owner) { - require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); - } - - function balanceOf(address owner) public view virtual returns (uint256) { - require(owner != address(0), "ZERO_ADDRESS"); - - return _balanceOf[owner]; - } - - /*////////////////////////////////////////////////////////////// - ERC721 APPROVAL STORAGE - //////////////////////////////////////////////////////////////*/ - - mapping(uint256 => address) public getApproved; - - mapping(address => mapping(address => bool)) public isApprovedForAll; - - /*////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////*/ - - constructor(string memory _name, string memory _symbol) { - name = _name; - symbol = _symbol; - } - - /*////////////////////////////////////////////////////////////// - ERC721 LOGIC - //////////////////////////////////////////////////////////////*/ - - function approve(address spender, uint256 id) public virtual { - address owner = _ownerOf[id]; - - require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); - - getApproved[id] = spender; - - emit Approval(owner, spender, id); - } - - function setApprovalForAll(address operator, bool approved) public virtual { - isApprovedForAll[msg.sender][operator] = approved; - - emit ApprovalForAll(msg.sender, operator, approved); - } - - function transferFrom( - address from, - address to, - uint256 id - ) public virtual { - require(from == _ownerOf[id], "WRONG_FROM"); - - require(to != address(0), "INVALID_RECIPIENT"); - - require( - msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], - "NOT_AUTHORIZED" - ); - - // Underflow of the sender's balance is impossible because we check for - // ownership above and the recipient's balance can't realistically overflow. - unchecked { - _balanceOf[from]--; - - _balanceOf[to]++; - } - - _ownerOf[id] = to; - - delete getApproved[id]; - - emit Transfer(from, to, id); - } - - function safeTransferFrom( - address from, - address to, - uint256 id - ) public virtual { - transferFrom(from, to, id); - - require( - to.code.length == 0 || - ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == - ERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - function safeTransferFrom( - address from, - address to, - uint256 id, - bytes calldata data - ) public virtual { - transferFrom(from, to, id); - - require( - to.code.length == 0 || - ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == - ERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - /*////////////////////////////////////////////////////////////// - ERC165 LOGIC - //////////////////////////////////////////////////////////////*/ - - function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { - return - interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 - interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 - interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata - } - - /*////////////////////////////////////////////////////////////// - INTERNAL MINT/BURN LOGIC - //////////////////////////////////////////////////////////////*/ - - function _mint(address to, uint256 id) internal virtual { - require(to != address(0), "INVALID_RECIPIENT"); - - require(_ownerOf[id] == address(0), "ALREADY_MINTED"); - - // Counter overflow is incredibly unrealistic. - unchecked { - _balanceOf[to]++; - } - - _ownerOf[id] = to; - - emit Transfer(address(0), to, id); - } - - function _burn(uint256 id) internal virtual { - address owner = _ownerOf[id]; - - require(owner != address(0), "NOT_MINTED"); - - // Ownership check above ensures no underflow. - unchecked { - _balanceOf[owner]--; - } - - delete _ownerOf[id]; - - delete getApproved[id]; - - emit Transfer(owner, address(0), id); - } - - /*////////////////////////////////////////////////////////////// - INTERNAL SAFE MINT LOGIC - //////////////////////////////////////////////////////////////*/ - - function _safeMint(address to, uint256 id) internal virtual { - _mint(to, id); - - require( - to.code.length == 0 || - ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == - ERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } - - function _safeMint( - address to, - uint256 id, - bytes memory data - ) internal virtual { - _mint(to, id); - - require( - to.code.length == 0 || - ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == - ERC721TokenReceiver.onERC721Received.selector, - "UNSAFE_RECIPIENT" - ); - } -} - -/// @notice A generic interface for a contract which properly accepts ERC721 tokens. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol) -abstract contract ERC721TokenReceiver { - function onERC721Received( - address, - address, - uint256, - bytes calldata - ) external virtual returns (bytes4) { - return ERC721TokenReceiver.onERC721Received.selector; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/tokens/WETH.sol b/lib/morpho-blue-irm/lib/solmate/src/tokens/WETH.sol deleted file mode 100644 index ddf9647..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/tokens/WETH.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {ERC20} from "./ERC20.sol"; - -import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; - -/// @notice Minimalist and modern Wrapped Ether implementation. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/WETH.sol) -/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol) -contract WETH is ERC20("Wrapped Ether", "WETH", 18) { - using SafeTransferLib for address; - - event Deposit(address indexed from, uint256 amount); - - event Withdrawal(address indexed to, uint256 amount); - - function deposit() public payable virtual { - _mint(msg.sender, msg.value); - - emit Deposit(msg.sender, msg.value); - } - - function withdraw(uint256 amount) public virtual { - _burn(msg.sender, amount); - - emit Withdrawal(msg.sender, amount); - - msg.sender.safeTransferETH(amount); - } - - receive() external payable virtual { - deposit(); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/Bytes32AddressLib.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/Bytes32AddressLib.sol deleted file mode 100644 index 448fb75..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/Bytes32AddressLib.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Library for converting between addresses and bytes32 values. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Bytes32AddressLib.sol) -library Bytes32AddressLib { - function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) { - return address(uint160(uint256(bytesValue))); - } - - function fillLast12Bytes(address addressValue) internal pure returns (bytes32) { - return bytes32(bytes20(addressValue)); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/CREATE3.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/CREATE3.sol deleted file mode 100644 index 0d5b341..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/CREATE3.sol +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {Bytes32AddressLib} from "./Bytes32AddressLib.sol"; - -/// @notice Deploy to deterministic addresses without an initcode factor. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol) -/// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol) -library CREATE3 { - using Bytes32AddressLib for bytes32; - - //--------------------------------------------------------------------------------// - // Opcode | Opcode + Arguments | Description | Stack View // - //--------------------------------------------------------------------------------// - // 0x36 | 0x36 | CALLDATASIZE | size // - // 0x3d | 0x3d | RETURNDATASIZE | 0 size // - // 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // - // 0x37 | 0x37 | CALLDATACOPY | // - // 0x36 | 0x36 | CALLDATASIZE | size // - // 0x3d | 0x3d | RETURNDATASIZE | 0 size // - // 0x34 | 0x34 | CALLVALUE | value 0 size // - // 0xf0 | 0xf0 | CREATE | newContract // - //--------------------------------------------------------------------------------// - // Opcode | Opcode + Arguments | Description | Stack View // - //--------------------------------------------------------------------------------// - // 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode // - // 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode // - // 0x52 | 0x52 | MSTORE | // - // 0x60 | 0x6008 | PUSH1 08 | 8 // - // 0x60 | 0x6018 | PUSH1 18 | 24 8 // - // 0xf3 | 0xf3 | RETURN | // - //--------------------------------------------------------------------------------// - bytes internal constant PROXY_BYTECODE = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3"; - - bytes32 internal constant PROXY_BYTECODE_HASH = keccak256(PROXY_BYTECODE); - - function deploy( - bytes32 salt, - bytes memory creationCode, - uint256 value - ) internal returns (address deployed) { - bytes memory proxyChildBytecode = PROXY_BYTECODE; - - address proxy; - /// @solidity memory-safe-assembly - assembly { - // Deploy a new contract with our pre-made bytecode via CREATE2. - // We start 32 bytes into the code to avoid copying the byte length. - proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt) - } - require(proxy != address(0), "DEPLOYMENT_FAILED"); - - deployed = getDeployed(salt); - (bool success, ) = proxy.call{value: value}(creationCode); - require(success && deployed.code.length != 0, "INITIALIZATION_FAILED"); - } - - function getDeployed(bytes32 salt) internal view returns (address) { - address proxy = keccak256( - abi.encodePacked( - // Prefix: - bytes1(0xFF), - // Creator: - address(this), - // Salt: - salt, - // Bytecode hash: - PROXY_BYTECODE_HASH - ) - ).fromLast20Bytes(); - - return - keccak256( - abi.encodePacked( - // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - hex"d6_94", - proxy, - hex"01" // Nonce of the proxy contract (1) - ) - ).fromLast20Bytes(); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/FixedPointMathLib.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/FixedPointMathLib.sol deleted file mode 100644 index 6887722..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/FixedPointMathLib.sol +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Arithmetic library with operations for fixed-point numbers. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) -/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) -library FixedPointMathLib { - /*////////////////////////////////////////////////////////////// - SIMPLIFIED FIXED POINT OPERATIONS - //////////////////////////////////////////////////////////////*/ - - uint256 internal constant MAX_UINT256 = 2**256 - 1; - - uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. - - function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { - return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. - } - - function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { - return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. - } - - function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { - return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. - } - - function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { - return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. - } - - /*////////////////////////////////////////////////////////////// - LOW LEVEL FIXED POINT OPERATIONS - //////////////////////////////////////////////////////////////*/ - - function mulDivDown( - uint256 x, - uint256 y, - uint256 denominator - ) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) - if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { - revert(0, 0) - } - - // Divide x * y by the denominator. - z := div(mul(x, y), denominator) - } - } - - function mulDivUp( - uint256 x, - uint256 y, - uint256 denominator - ) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) - if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { - revert(0, 0) - } - - // If x * y modulo the denominator is strictly greater than 0, - // 1 is added to round up the division of x * y by the denominator. - z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator)) - } - } - - function rpow( - uint256 x, - uint256 n, - uint256 scalar - ) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - switch x - case 0 { - switch n - case 0 { - // 0 ** 0 = 1 - z := scalar - } - default { - // 0 ** n = 0 - z := 0 - } - } - default { - switch mod(n, 2) - case 0 { - // If n is even, store scalar in z for now. - z := scalar - } - default { - // If n is odd, store x in z for now. - z := x - } - - // Shifting right by 1 is like dividing by 2. - let half := shr(1, scalar) - - for { - // Shift n right by 1 before looping to halve it. - n := shr(1, n) - } n { - // Shift n right by 1 each iteration to halve it. - n := shr(1, n) - } { - // Revert immediately if x ** 2 would overflow. - // Equivalent to iszero(eq(div(xx, x), x)) here. - if shr(128, x) { - revert(0, 0) - } - - // Store x squared. - let xx := mul(x, x) - - // Round to the nearest number. - let xxRound := add(xx, half) - - // Revert if xx + half overflowed. - if lt(xxRound, xx) { - revert(0, 0) - } - - // Set x to scaled xxRound. - x := div(xxRound, scalar) - - // If n is even: - if mod(n, 2) { - // Compute z * x. - let zx := mul(z, x) - - // If z * x overflowed: - if iszero(eq(div(zx, x), z)) { - // Revert if x is non-zero. - if iszero(iszero(x)) { - revert(0, 0) - } - } - - // Round to the nearest number. - let zxRound := add(zx, half) - - // Revert if zx + half overflowed. - if lt(zxRound, zx) { - revert(0, 0) - } - - // Return properly scaled zxRound. - z := div(zxRound, scalar) - } - } - } - } - } - - /*////////////////////////////////////////////////////////////// - GENERAL NUMBER UTILITIES - //////////////////////////////////////////////////////////////*/ - - function sqrt(uint256 x) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - let y := x // We start y at x, which will help us make our initial estimate. - - z := 181 // The "correct" value is 1, but this saves a multiplication later. - - // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad - // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. - - // We check y >= 2^(k + 8) but shift right by k bits - // each branch to ensure that if x >= 256, then y >= 256. - if iszero(lt(y, 0x10000000000000000000000000000000000)) { - y := shr(128, y) - z := shl(64, z) - } - if iszero(lt(y, 0x1000000000000000000)) { - y := shr(64, y) - z := shl(32, z) - } - if iszero(lt(y, 0x10000000000)) { - y := shr(32, y) - z := shl(16, z) - } - if iszero(lt(y, 0x1000000)) { - y := shr(16, y) - z := shl(8, z) - } - - // Goal was to get z*z*y within a small factor of x. More iterations could - // get y in a tighter range. Currently, we will have y in [256, 256*2^16). - // We ensured y >= 256 so that the relative difference between y and y+1 is small. - // That's not possible if x < 256 but we can just verify those cases exhaustively. - - // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. - // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. - // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. - - // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range - // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. - - // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate - // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. - - // There is no overflow risk here since y < 2^136 after the first branch above. - z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. - - // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - z := shr(1, add(z, div(x, z))) - - // If x+1 is a perfect square, the Babylonian method cycles between - // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. - // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division - // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. - // If you don't care whether the floor or ceil square root is returned, you can remove this statement. - z := sub(z, lt(div(x, z), z)) - } - } - - function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // Mod x by y. Note this will return - // 0 instead of reverting if y is zero. - z := mod(x, y) - } - } - - function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - // Divide x by y. Note this will return - // 0 instead of reverting if y is zero. - r := div(x, y) - } - } - - function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - /// @solidity memory-safe-assembly - assembly { - // Add 1 to x * y if x % y > 0. Note this will - // return 0 instead of reverting if y is zero. - z := add(gt(mod(x, y), 0), div(x, y)) - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/LibString.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/LibString.sol deleted file mode 100644 index 97c89e0..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/LibString.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -/// @notice Efficient library for creating string representations of integers. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) -/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) -library LibString { - function toString(int256 value) internal pure returns (string memory str) { - if (value >= 0) return toString(uint256(value)); - - unchecked { - str = toString(uint256(-value)); - - /// @solidity memory-safe-assembly - assembly { - // Note: This is only safe because we over-allocate memory - // and write the string from right to left in toString(uint256), - // and thus can be sure that sub(str, 1) is an unused memory location. - - let length := mload(str) // Load the string length. - // Put the - character at the start of the string contents. - mstore(str, 45) // 45 is the ASCII code for the - character. - str := sub(str, 1) // Move back the string pointer by a byte. - mstore(str, add(length, 1)) // Update the string length. - } - } - } - - function toString(uint256 value) internal pure returns (string memory str) { - /// @solidity memory-safe-assembly - assembly { - // The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes - // to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the - // trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes. - let newFreeMemoryPointer := add(mload(0x40), 160) - - // Update the free memory pointer to avoid overriding our string. - mstore(0x40, newFreeMemoryPointer) - - // Assign str to the end of the zone of newly allocated memory. - str := sub(newFreeMemoryPointer, 32) - - // Clean the last word of memory it may not be overwritten. - mstore(str, 0) - - // Cache the end of the memory to calculate the length later. - let end := str - - // We write the string from rightmost digit to leftmost digit. - // The following is essentially a do-while loop that also handles the zero case. - // prettier-ignore - for { let temp := value } 1 {} { - // Move the pointer 1 byte to the left. - str := sub(str, 1) - - // Write the character to the pointer. - // The ASCII index of the '0' character is 48. - mstore8(str, add(48, mod(temp, 10))) - - // Keep dividing temp until zero. - temp := div(temp, 10) - - // prettier-ignore - if iszero(temp) { break } - } - - // Compute and cache the final total length of the string. - let length := sub(end, str) - - // Move the pointer 32 bytes leftwards to make room for the length. - str := sub(str, 32) - - // Store the string's length at the start of memory allocated for our string. - mstore(str, length) - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/MerkleProofLib.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/MerkleProofLib.sol deleted file mode 100644 index 8fd7cbd..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/MerkleProofLib.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -/// @notice Gas optimized merkle proof verification library. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol) -/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol) -library MerkleProofLib { - function verify( - bytes32[] calldata proof, - bytes32 root, - bytes32 leaf - ) internal pure returns (bool isValid) { - /// @solidity memory-safe-assembly - assembly { - if proof.length { - // Left shifting by 5 is like multiplying by 32. - let end := add(proof.offset, shl(5, proof.length)) - - // Initialize offset to the offset of the proof in calldata. - let offset := proof.offset - - // Iterate over proof elements to compute root hash. - // prettier-ignore - for {} 1 {} { - // Slot where the leaf should be put in scratch space. If - // leaf > calldataload(offset): slot 32, otherwise: slot 0. - let leafSlot := shl(5, gt(leaf, calldataload(offset))) - - // Store elements to hash contiguously in scratch space. - // The xor puts calldataload(offset) in whichever slot leaf - // is not occupying, so 0 if leafSlot is 32, and 32 otherwise. - mstore(leafSlot, leaf) - mstore(xor(leafSlot, 32), calldataload(offset)) - - // Reuse leaf to store the hash to reduce stack operations. - leaf := keccak256(0, 64) // Hash both slots of scratch space. - - offset := add(offset, 32) // Shift 1 word per cycle. - - // prettier-ignore - if iszero(lt(offset, end)) { break } - } - } - - isValid := eq(leaf, root) // The proof is valid if the roots match. - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/ReentrancyGuard.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/ReentrancyGuard.sol deleted file mode 100644 index 1453e24..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/ReentrancyGuard.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Gas optimized reentrancy protection for smart contracts. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) -abstract contract ReentrancyGuard { - uint256 private locked = 1; - - modifier nonReentrant() virtual { - require(locked == 1, "REENTRANCY"); - - locked = 2; - - _; - - locked = 1; - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/SSTORE2.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/SSTORE2.sol deleted file mode 100644 index 23d6980..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/SSTORE2.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Read and write to persistent storage at a fraction of the cost. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol) -/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol) -library SSTORE2 { - uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called. - - /*////////////////////////////////////////////////////////////// - WRITE LOGIC - //////////////////////////////////////////////////////////////*/ - - function write(bytes memory data) internal returns (address pointer) { - // Prefix the bytecode with a STOP opcode to ensure it cannot be called. - bytes memory runtimeCode = abi.encodePacked(hex"00", data); - - bytes memory creationCode = abi.encodePacked( - //---------------------------------------------------------------------------------------------------------------// - // Opcode | Opcode + Arguments | Description | Stack View // - //---------------------------------------------------------------------------------------------------------------// - // 0x60 | 0x600B | PUSH1 11 | codeOffset // - // 0x59 | 0x59 | MSIZE | 0 codeOffset // - // 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset // - // 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset // - // 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset // - // 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset // - // 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // - // 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // - // 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) // - // 0xf3 | 0xf3 | RETURN | // - //---------------------------------------------------------------------------------------------------------------// - hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes. - runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit. - ); - - /// @solidity memory-safe-assembly - assembly { - // Deploy a new contract with the generated creation code. - // We start 32 bytes into the code to avoid copying the byte length. - pointer := create(0, add(creationCode, 32), mload(creationCode)) - } - - require(pointer != address(0), "DEPLOYMENT_FAILED"); - } - - /*////////////////////////////////////////////////////////////// - READ LOGIC - //////////////////////////////////////////////////////////////*/ - - function read(address pointer) internal view returns (bytes memory) { - return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET); - } - - function read(address pointer, uint256 start) internal view returns (bytes memory) { - start += DATA_OFFSET; - - return readBytecode(pointer, start, pointer.code.length - start); - } - - function read( - address pointer, - uint256 start, - uint256 end - ) internal view returns (bytes memory) { - start += DATA_OFFSET; - end += DATA_OFFSET; - - require(pointer.code.length >= end, "OUT_OF_BOUNDS"); - - return readBytecode(pointer, start, end - start); - } - - /*////////////////////////////////////////////////////////////// - INTERNAL HELPER LOGIC - //////////////////////////////////////////////////////////////*/ - - function readBytecode( - address pointer, - uint256 start, - uint256 size - ) private view returns (bytes memory data) { - /// @solidity memory-safe-assembly - assembly { - // Get a pointer to some free memory. - data := mload(0x40) - - // Update the free memory pointer to prevent overriding our data. - // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)). - // Adding 31 to size and running the result through the logic above ensures - // the memory pointer remains word-aligned, following the Solidity convention. - mstore(0x40, add(data, and(add(add(size, 32), 31), not(31)))) - - // Store the size of the data in the first 32 byte chunk of free memory. - mstore(data, size) - - // Copy the code into memory right after the 32 bytes we used to store the size. - extcodecopy(pointer, add(data, 32), start, size) - } - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/SafeCastLib.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/SafeCastLib.sol deleted file mode 100644 index 9e8a2af..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/SafeCastLib.sol +++ /dev/null @@ -1,193 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -/// @notice Safe unsigned integer casting library that reverts on overflow. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeCastLib.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol) -library SafeCastLib { - function safeCastTo248(uint256 x) internal pure returns (uint248 y) { - require(x < 1 << 248); - - y = uint248(x); - } - - function safeCastTo240(uint256 x) internal pure returns (uint240 y) { - require(x < 1 << 240); - - y = uint240(x); - } - - function safeCastTo232(uint256 x) internal pure returns (uint232 y) { - require(x < 1 << 232); - - y = uint232(x); - } - - function safeCastTo224(uint256 x) internal pure returns (uint224 y) { - require(x < 1 << 224); - - y = uint224(x); - } - - function safeCastTo216(uint256 x) internal pure returns (uint216 y) { - require(x < 1 << 216); - - y = uint216(x); - } - - function safeCastTo208(uint256 x) internal pure returns (uint208 y) { - require(x < 1 << 208); - - y = uint208(x); - } - - function safeCastTo200(uint256 x) internal pure returns (uint200 y) { - require(x < 1 << 200); - - y = uint200(x); - } - - function safeCastTo192(uint256 x) internal pure returns (uint192 y) { - require(x < 1 << 192); - - y = uint192(x); - } - - function safeCastTo184(uint256 x) internal pure returns (uint184 y) { - require(x < 1 << 184); - - y = uint184(x); - } - - function safeCastTo176(uint256 x) internal pure returns (uint176 y) { - require(x < 1 << 176); - - y = uint176(x); - } - - function safeCastTo168(uint256 x) internal pure returns (uint168 y) { - require(x < 1 << 168); - - y = uint168(x); - } - - function safeCastTo160(uint256 x) internal pure returns (uint160 y) { - require(x < 1 << 160); - - y = uint160(x); - } - - function safeCastTo152(uint256 x) internal pure returns (uint152 y) { - require(x < 1 << 152); - - y = uint152(x); - } - - function safeCastTo144(uint256 x) internal pure returns (uint144 y) { - require(x < 1 << 144); - - y = uint144(x); - } - - function safeCastTo136(uint256 x) internal pure returns (uint136 y) { - require(x < 1 << 136); - - y = uint136(x); - } - - function safeCastTo128(uint256 x) internal pure returns (uint128 y) { - require(x < 1 << 128); - - y = uint128(x); - } - - function safeCastTo120(uint256 x) internal pure returns (uint120 y) { - require(x < 1 << 120); - - y = uint120(x); - } - - function safeCastTo112(uint256 x) internal pure returns (uint112 y) { - require(x < 1 << 112); - - y = uint112(x); - } - - function safeCastTo104(uint256 x) internal pure returns (uint104 y) { - require(x < 1 << 104); - - y = uint104(x); - } - - function safeCastTo96(uint256 x) internal pure returns (uint96 y) { - require(x < 1 << 96); - - y = uint96(x); - } - - function safeCastTo88(uint256 x) internal pure returns (uint88 y) { - require(x < 1 << 88); - - y = uint88(x); - } - - function safeCastTo80(uint256 x) internal pure returns (uint80 y) { - require(x < 1 << 80); - - y = uint80(x); - } - - function safeCastTo72(uint256 x) internal pure returns (uint72 y) { - require(x < 1 << 72); - - y = uint72(x); - } - - function safeCastTo64(uint256 x) internal pure returns (uint64 y) { - require(x < 1 << 64); - - y = uint64(x); - } - - function safeCastTo56(uint256 x) internal pure returns (uint56 y) { - require(x < 1 << 56); - - y = uint56(x); - } - - function safeCastTo48(uint256 x) internal pure returns (uint48 y) { - require(x < 1 << 48); - - y = uint48(x); - } - - function safeCastTo40(uint256 x) internal pure returns (uint40 y) { - require(x < 1 << 40); - - y = uint40(x); - } - - function safeCastTo32(uint256 x) internal pure returns (uint32 y) { - require(x < 1 << 32); - - y = uint32(x); - } - - function safeCastTo24(uint256 x) internal pure returns (uint24 y) { - require(x < 1 << 24); - - y = uint24(x); - } - - function safeCastTo16(uint256 x) internal pure returns (uint16 y) { - require(x < 1 << 16); - - y = uint16(x); - } - - function safeCastTo8(uint256 x) internal pure returns (uint8 y) { - require(x < 1 << 8); - - y = uint8(x); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/SafeTransferLib.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/SafeTransferLib.sol deleted file mode 100644 index 93ef5a9..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/SafeTransferLib.sol +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity >=0.8.0; - -import {ERC20} from "../tokens/ERC20.sol"; - -/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) -/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. -/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. -library SafeTransferLib { - /*////////////////////////////////////////////////////////////// - ETH OPERATIONS - //////////////////////////////////////////////////////////////*/ - - function safeTransferETH(address to, uint256 amount) internal { - bool success; - - /// @solidity memory-safe-assembly - assembly { - // Transfer the ETH and store if it succeeded or not. - success := call(gas(), to, amount, 0, 0, 0, 0) - } - - require(success, "ETH_TRANSFER_FAILED"); - } - - /*////////////////////////////////////////////////////////////// - ERC20 OPERATIONS - //////////////////////////////////////////////////////////////*/ - - function safeTransferFrom( - ERC20 token, - address from, - address to, - uint256 amount - ) internal { - bool success; - - /// @solidity memory-safe-assembly - assembly { - // Get a pointer to some free memory. - let freeMemoryPointer := mload(0x40) - - // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. - mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. - mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - - success := and( - // Set success to whether the call reverted, if not we check it either - // returned exactly 1 (can't just be non-zero data), or had no return data. - or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), - // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - // Counterintuitively, this call must be positioned second to the or() call in the - // surrounding and() call or else returndatasize() will be zero during the computation. - call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) - ) - } - - require(success, "TRANSFER_FROM_FAILED"); - } - - function safeTransfer( - ERC20 token, - address to, - uint256 amount - ) internal { - bool success; - - /// @solidity memory-safe-assembly - assembly { - // Get a pointer to some free memory. - let freeMemoryPointer := mload(0x40) - - // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. - mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - - success := and( - // Set success to whether the call reverted, if not we check it either - // returned exactly 1 (can't just be non-zero data), or had no return data. - or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), - // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - // Counterintuitively, this call must be positioned second to the or() call in the - // surrounding and() call or else returndatasize() will be zero during the computation. - call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) - ) - } - - require(success, "TRANSFER_FAILED"); - } - - function safeApprove( - ERC20 token, - address to, - uint256 amount - ) internal { - bool success; - - /// @solidity memory-safe-assembly - assembly { - // Get a pointer to some free memory. - let freeMemoryPointer := mload(0x40) - - // Write the abi-encoded calldata into memory, beginning with the function selector. - mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) - mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. - mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. - - success := and( - // Set success to whether the call reverted, if not we check it either - // returned exactly 1 (can't just be non-zero data), or had no return data. - or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), - // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. - // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. - // Counterintuitively, this call must be positioned second to the or() call in the - // surrounding and() call or else returndatasize() will be zero during the computation. - call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) - ) - } - - require(success, "APPROVE_FAILED"); - } -} diff --git a/lib/morpho-blue-irm/lib/solmate/src/utils/SignedWadMath.sol b/lib/morpho-blue-irm/lib/solmate/src/utils/SignedWadMath.sol deleted file mode 100644 index e7d30a4..0000000 --- a/lib/morpho-blue-irm/lib/solmate/src/utils/SignedWadMath.sol +++ /dev/null @@ -1,245 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -/// @notice Signed 18 decimal fixed point (wad) arithmetic library. -/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SignedWadMath.sol) -/// @author Modified from Remco Bloemen (https://xn--2-umb.com/22/exp-ln/index.html) - -/// @dev Will not revert on overflow, only use where overflow is not possible. -function toWadUnsafe(uint256 x) pure returns (int256 r) { - /// @solidity memory-safe-assembly - assembly { - // Multiply x by 1e18. - r := mul(x, 1000000000000000000) - } -} - -/// @dev Takes an integer amount of seconds and converts it to a wad amount of days. -/// @dev Will not revert on overflow, only use where overflow is not possible. -/// @dev Not meant for negative second amounts, it assumes x is positive. -function toDaysWadUnsafe(uint256 x) pure returns (int256 r) { - /// @solidity memory-safe-assembly - assembly { - // Multiply x by 1e18 and then divide it by 86400. - r := div(mul(x, 1000000000000000000), 86400) - } -} - -/// @dev Takes a wad amount of days and converts it to an integer amount of seconds. -/// @dev Will not revert on overflow, only use where overflow is not possible. -/// @dev Not meant for negative day amounts, it assumes x is positive. -function fromDaysWadUnsafe(int256 x) pure returns (uint256 r) { - /// @solidity memory-safe-assembly - assembly { - // Multiply x by 86400 and then divide it by 1e18. - r := div(mul(x, 86400), 1000000000000000000) - } -} - -/// @dev Will not revert on overflow, only use where overflow is not possible. -function unsafeWadMul(int256 x, int256 y) pure returns (int256 r) { - /// @solidity memory-safe-assembly - assembly { - // Multiply x by y and divide by 1e18. - r := sdiv(mul(x, y), 1000000000000000000) - } -} - -/// @dev Will return 0 instead of reverting if y is zero and will -/// not revert on overflow, only use where overflow is not possible. -function unsafeWadDiv(int256 x, int256 y) pure returns (int256 r) { - /// @solidity memory-safe-assembly - assembly { - // Multiply x by 1e18 and divide it by y. - r := sdiv(mul(x, 1000000000000000000), y) - } -} - -function wadMul(int256 x, int256 y) pure returns (int256 r) { - /// @solidity memory-safe-assembly - assembly { - // Store x * y in r for now. - r := mul(x, y) - - // Combined overflow check (`x == 0 || (x * y) / x == y`) and edge case check - // where x == -1 and y == type(int256).min, for y == -1 and x == min int256, - // the second overflow check will catch this. - // See: https://secure-contracts.com/learn_evm/arithmetic-checks.html#arithmetic-checks-for-int256-multiplication - // Combining into 1 expression saves gas as resulting bytecode will only have 1 `JUMPI` - // rather than 2. - if iszero( - and( - or(iszero(x), eq(sdiv(r, x), y)), - or(lt(x, not(0)), sgt(y, 0x8000000000000000000000000000000000000000000000000000000000000000)) - ) - ) { - revert(0, 0) - } - - // Scale the result down by 1e18. - r := sdiv(r, 1000000000000000000) - } -} - -function wadDiv(int256 x, int256 y) pure returns (int256 r) { - /// @solidity memory-safe-assembly - assembly { - // Store x * 1e18 in r for now. - r := mul(x, 1000000000000000000) - - // Equivalent to require(y != 0 && ((x * 1e18) / 1e18 == x)) - if iszero(and(iszero(iszero(y)), eq(sdiv(r, 1000000000000000000), x))) { - revert(0, 0) - } - - // Divide r by y. - r := sdiv(r, y) - } -} - -/// @dev Will not work with negative bases, only use when x is positive. -function wadPow(int256 x, int256 y) pure returns (int256) { - // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y) - return wadExp((wadLn(x) * y) / 1e18); // Using ln(x) means x must be greater than 0. -} - -function wadExp(int256 x) pure returns (int256 r) { - unchecked { - // When the result is < 0.5 we return zero. This happens when - // x <= floor(log(0.5e18) * 1e18) ~ -42e18 - if (x <= -42139678854452767551) return 0; - - // When the result is > (2**255 - 1) / 1e18 we can not represent it as an - // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. - if (x >= 135305999368893231589) revert("EXP_OVERFLOW"); - - // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 - // for more intermediate precision and a binary basis. This base conversion - // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. - x = (x << 78) / 5**18; - - // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers - // of two such that exp(x) = exp(x') * 2**k, where k is an integer. - // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). - int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96; - x = x - k * 54916777467707473351141471128; - - // k is in the range [-61, 195]. - - // Evaluate using a (6, 7)-term rational approximation. - // p is made monic, we'll multiply by a scale factor later. - int256 y = x + 1346386616545796478920950773328; - y = ((y * x) >> 96) + 57155421227552351082224309758442; - int256 p = y + x - 94201549194550492254356042504812; - p = ((p * y) >> 96) + 28719021644029726153956944680412240; - p = p * x + (4385272521454847904659076985693276 << 96); - - // We leave p in 2**192 basis so we don't need to scale it back up for the division. - int256 q = x - 2855989394907223263936484059900; - q = ((q * x) >> 96) + 50020603652535783019961831881945; - q = ((q * x) >> 96) - 533845033583426703283633433725380; - q = ((q * x) >> 96) + 3604857256930695427073651918091429; - q = ((q * x) >> 96) - 14423608567350463180887372962807573; - q = ((q * x) >> 96) + 26449188498355588339934803723976023; - - /// @solidity memory-safe-assembly - assembly { - // Div in assembly because solidity adds a zero check despite the unchecked. - // The q polynomial won't have zeros in the domain as all its roots are complex. - // No scaling is necessary because p is already 2**96 too large. - r := sdiv(p, q) - } - - // r should be in the range (0.09, 0.25) * 2**96. - - // We now need to multiply r by: - // * the scale factor s = ~6.031367120. - // * the 2**k factor from the range reduction. - // * the 1e18 / 2**96 factor for base conversion. - // We do this all at once, with an intermediate result in 2**213 - // basis, so the final right shift is always by a positive amount. - r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)); - } -} - -function wadLn(int256 x) pure returns (int256 r) { - unchecked { - require(x > 0, "UNDEFINED"); - - // We want to convert x from 10**18 fixed point to 2**96 fixed point. - // We do this by multiplying by 2**96 / 10**18. But since - // ln(x * C) = ln(x) + ln(C), we can simply do nothing here - // and add ln(2**96 / 10**18) at the end. - - /// @solidity memory-safe-assembly - assembly { - r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - r := or(r, shl(2, lt(0xf, shr(r, x)))) - r := or(r, shl(1, lt(0x3, shr(r, x)))) - r := or(r, lt(0x1, shr(r, x))) - } - - // Reduce range of x to (1, 2) * 2**96 - // ln(2^k * x) = k * ln(2) + ln(x) - int256 k = r - 96; - x <<= uint256(159 - k); - x = int256(uint256(x) >> 159); - - // Evaluate using a (8, 8)-term rational approximation. - // p is made monic, we will multiply by a scale factor later. - int256 p = x + 3273285459638523848632254066296; - p = ((p * x) >> 96) + 24828157081833163892658089445524; - p = ((p * x) >> 96) + 43456485725739037958740375743393; - p = ((p * x) >> 96) - 11111509109440967052023855526967; - p = ((p * x) >> 96) - 45023709667254063763336534515857; - p = ((p * x) >> 96) - 14706773417378608786704636184526; - p = p * x - (795164235651350426258249787498 << 96); - - // We leave p in 2**192 basis so we don't need to scale it back up for the division. - // q is monic by convention. - int256 q = x + 5573035233440673466300451813936; - q = ((q * x) >> 96) + 71694874799317883764090561454958; - q = ((q * x) >> 96) + 283447036172924575727196451306956; - q = ((q * x) >> 96) + 401686690394027663651624208769553; - q = ((q * x) >> 96) + 204048457590392012362485061816622; - q = ((q * x) >> 96) + 31853899698501571402653359427138; - q = ((q * x) >> 96) + 909429971244387300277376558375; - /// @solidity memory-safe-assembly - assembly { - // Div in assembly because solidity adds a zero check despite the unchecked. - // The q polynomial is known not to have zeros in the domain. - // No scaling required because p is already 2**96 too large. - r := sdiv(p, q) - } - - // r is in the range (0, 0.125) * 2**96 - - // Finalization, we need to: - // * multiply by the scale factor s = 5.549… - // * add ln(2**96 / 10**18) - // * add k * ln(2) - // * multiply by 10**18 / 2**96 = 5**18 >> 78 - - // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 - r *= 1677202110996718588342820967067443963516166; - // add ln(2) * k * 5e18 * 2**192 - r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k; - // add ln(2**96 / 10**18) * 5e18 * 2**192 - r += 600920179829731861736702779321621459595472258049074101567377883020018308; - // base conversion: mul 2**18 / 2**192 - r >>= 174; - } -} - -/// @dev Will return 0 instead of reverting if y is zero. -function unsafeDiv(int256 x, int256 y) pure returns (int256 r) { - /// @solidity memory-safe-assembly - assembly { - // Divide x by y. - r := sdiv(x, y) - } -} diff --git a/lib/morpho-blue-irm/src/SpeedJumpIrm.sol b/lib/morpho-blue-irm/src/SpeedJumpIrm.sol deleted file mode 100644 index 0bea8c1..0000000 --- a/lib/morpho-blue-irm/src/SpeedJumpIrm.sol +++ /dev/null @@ -1,155 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.19; - -import {IIrm} from "../lib/morpho-blue/src/interfaces/IIrm.sol"; - -import {MathLib} from "./libraries/MathLib.sol"; -import {UtilsLib} from "./libraries/UtilsLib.sol"; -import {ErrorsLib} from "./libraries/ErrorsLib.sol"; -import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol"; -import {Id, MarketParams, Market} from "../lib/morpho-blue/src/interfaces/IMorpho.sol"; -import {WAD, MathLib as MorphoMathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol"; - -struct MarketIrm { - // Previous final borrow rate. Scaled by WAD. - uint128 prevBorrowRate; - // Previous error. Scaled by WAD. - int128 prevErr; -} - -/// @title SpeedJumpIrm -/// @author Morpho Labs -/// @custom:contact security@morpho.xyz -/// @notice Interest rate model. -contract SpeedJumpIrm is IIrm { - using MathLib for int256; - using MathLib for uint256; - using UtilsLib for uint256; - using MorphoMathLib for uint128; - using MorphoMathLib for uint256; - using MarketParamsLib for MarketParams; - - /* EVENTS */ - - /// @notice Emitted when a borrow rate is updated. - event BorrowRateUpdate(Id indexed id, int128 err, uint128 newBorrowRate, uint256 avgBorrowRate); - - /* CONSTANTS */ - - /// @notice Maximum rate per second (scaled by WAD) (1B% APR). - uint256 public constant MAX_RATE = uint256(1e7 ether) / 365 days; - /// @notice Mininimum rate per second (scaled by WAD) (0.1% APR). - uint256 public constant MIN_RATE = uint256(0.001 ether) / 365 days; - /// @notice Address of Morpho. - address public immutable MORPHO; - /// @notice Ln of the jump factor (scaled by WAD). - uint256 public immutable LN_JUMP_FACTOR; - /// @notice Speed factor (scaled by WAD). - /// @dev The speed is per second, so the rate moves at a speed of SPEED_FACTOR * err each second (while being - /// continuously compounded). A typical value for the SPEED_FACTOR would be 10 ethers / 365 days. - uint256 public immutable SPEED_FACTOR; - /// @notice Target utilization (scaled by WAD). - uint256 public immutable TARGET_UTILIZATION; - /// @notice Initial rate (scaled by WAD). - uint128 public immutable INITIAL_RATE; - - /* STORAGE */ - - /// @notice IRM storage for each market. - mapping(Id => MarketIrm) public marketIrm; - - /* CONSTRUCTOR */ - - /// @notice Constructor. - /// @param morpho The address of Morpho. - /// @param lnJumpFactor The log of the jump factor (scaled by WAD). - /// @param speedFactor The speed factor (scaled by WAD). - /// @param targetUtilization The target utilization (scaled by WAD). Should be strictly between 0 and 1. - /// @param initialRate The initial rate (scaled by WAD). - constructor( - address morpho, - uint256 lnJumpFactor, - uint256 speedFactor, - uint256 targetUtilization, - uint128 initialRate - ) { - require(lnJumpFactor <= uint256(type(int256).max), ErrorsLib.INPUT_TOO_LARGE); - require(speedFactor <= uint256(type(int256).max), ErrorsLib.INPUT_TOO_LARGE); - require(targetUtilization < WAD, ErrorsLib.INPUT_TOO_LARGE); - require(targetUtilization > 0, ErrorsLib.ZERO_INPUT); - - MORPHO = morpho; - LN_JUMP_FACTOR = lnJumpFactor; - SPEED_FACTOR = speedFactor; - TARGET_UTILIZATION = targetUtilization; - INITIAL_RATE = initialRate; - } - - /* BORROW RATES */ - - /// @inheritdoc IIrm - function borrowRateView(MarketParams memory marketParams, Market memory market) external view returns (uint256) { - (,, uint256 avgBorrowRate) = _borrowRate(marketParams.id(), market); - return avgBorrowRate; - } - - /// @inheritdoc IIrm - function borrowRate(MarketParams memory marketParams, Market memory market) external returns (uint256) { - require(msg.sender == MORPHO, ErrorsLib.NOT_MORPHO); - - Id id = marketParams.id(); - - (int128 err, uint128 newBorrowRate, uint256 avgBorrowRate) = _borrowRate(id, market); - - marketIrm[id].prevErr = err; - marketIrm[id].prevBorrowRate = newBorrowRate; - - emit BorrowRateUpdate(id, err, newBorrowRate, avgBorrowRate); - - return avgBorrowRate; - } - - /// @dev Returns err, newBorrowRate and avgBorrowRate. - function _borrowRate(Id id, Market memory market) private view returns (int128, uint128, uint128) { - uint256 utilization = - market.totalSupplyAssets > 0 ? market.totalBorrowAssets.wDivDown(market.totalSupplyAssets) : 0; - - uint256 errNormFactor = utilization > TARGET_UTILIZATION ? WAD - TARGET_UTILIZATION : TARGET_UTILIZATION; - // Safe "unchecked" int128 cast because |err| <= WAD. - // Safe "unchecked" int256 casts because utilization <= WAD, TARGET_UTILIZATION < WAD and errNormFactor <= WAD. - int128 err = int128((int256(utilization) - int256(TARGET_UTILIZATION)).wDivDown(int256(errNormFactor))); - - MarketIrm storage irm = marketIrm[id]; - if (irm.prevBorrowRate == 0) return (err, INITIAL_RATE, INITIAL_RATE); - - // errDelta = err - prevErr. - // errDelta is between -1 and 1, scaled by WAD. - int256 errDelta = err - irm.prevErr; - - // Safe "unchecked" cast because LN_JUMP_FACTOR <= type(int256).max. - uint256 jumpMultiplier = MathLib.wExp(errDelta.wMulDown(int256(LN_JUMP_FACTOR))); - // Safe "unchecked" cast because SPEED_FACTOR <= type(int256).max. - int256 speed = int256(SPEED_FACTOR).wMulDown(err); - uint256 elapsed = block.timestamp - market.lastUpdate; - // Safe "unchecked" cast because elapsed <= block.timestamp. - int256 linearVariation = speed * int256(elapsed); - uint256 variationMultiplier = MathLib.wExp(linearVariation); - - // newBorrowRate = prevBorrowRate * jumpMultiplier * variationMultiplier. - uint256 borrowRateAfterJump = irm.prevBorrowRate.wMulDown(jumpMultiplier); - uint256 newBorrowRate = borrowRateAfterJump.wMulDown(variationMultiplier); - - // Then we compute the average rate over the period (this is what Morpho needs to accrue the interest). - // avgBorrowRate = 1 / elapsed * ∫ borrowRateAfterJump * exp(speed * t) dt between 0 and elapsed - // = borrowRateAfterJump * (exp(linearVariation) - 1) / linearVariation - // = (newBorrowRate - borrowRateAfterJump) / linearVariation - // And avgBorrowRate ~ borrowRateAfterJump for linearVariation around zero. - uint256 avgBorrowRate; - if (linearVariation == 0) avgBorrowRate = borrowRateAfterJump; - // Safe "unchecked" cast to uint256 because linearVariation < 0 <=> newBorrowRate <= borrowRateAfterJump. - else avgBorrowRate = uint256((int256(newBorrowRate) - int256(borrowRateAfterJump)).wDivDown(linearVariation)); - - // We bound both newBorrowRate and avgBorrowRate between MIN_RATE and MAX_RATE. - return (err, uint128(newBorrowRate.bound(MIN_RATE, MAX_RATE)), uint128(avgBorrowRate.bound(MIN_RATE, MAX_RATE))); - } -} diff --git a/lib/morpho-blue-irm/src/libraries/ErrorsLib.sol b/lib/morpho-blue-irm/src/libraries/ErrorsLib.sol deleted file mode 100644 index 0f6c614..0000000 --- a/lib/morpho-blue-irm/src/libraries/ErrorsLib.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; - -/// @title ErrorsLib -/// @author Morpho Labs -/// @custom:contact security@morpho.xyz -/// @notice Library exposing error messages. -library ErrorsLib { - /// @dev Thrown when the input is too large to fit in the expected type. - string internal constant INPUT_TOO_LARGE = "input too large"; - - /// @dev Thrown when passing the zero input. - string internal constant ZERO_INPUT = "zero input"; - - /// @dev Thrown when wExp underflows. - string internal constant WEXP_UNDERFLOW = "wExp underflow"; - - /// @dev Thrown when wExp overflows. - string internal constant WEXP_OVERFLOW = "wExp overflow"; - - /// @dev Thrown when the caller is not Morpho. - string internal constant NOT_MORPHO = "not Morpho"; -} diff --git a/lib/morpho-blue-irm/src/libraries/MathLib.sol b/lib/morpho-blue-irm/src/libraries/MathLib.sol deleted file mode 100644 index f076274..0000000 --- a/lib/morpho-blue-irm/src/libraries/MathLib.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; - -import {ErrorsLib} from "./ErrorsLib.sol"; -import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol"; - -int256 constant WAD_INT = int256(WAD); - -/// @title MathLib -/// @author Morpho Labs -/// @custom:contact security@morpho.xyz -/// @notice Library to manage fixed-point arithmetic and approximate the exponential function. -library MathLib { - using MathLib for uint128; - using MathLib for uint256; - using {wDivDown} for int256; - using {wMulDown} for int256; - - /// @dev ln(2). - int256 private constant LN2_INT = 0.693147180559945309 ether; - - /// @dev Returns an approximation of exp. - function wExp(int256 x) internal pure returns (uint256) { - unchecked { - // Revert if x > ln(2^256-1) ~ 177. - require(x <= 177.44567822334599921 ether, ErrorsLib.WEXP_OVERFLOW); - // Revert if x < -(2**255-1) + (ln(2)/2). - require(x >= type(int256).min + LN2_INT / 2, ErrorsLib.WEXP_UNDERFLOW); - - // Decompose x as x = q * ln(2) + r with q an integer and -ln(2)/2 <= r <= ln(2)/2. - // q = x / ln(2) rounded half toward zero. - int256 roundingAdjustment = (x < 0) ? -(LN2_INT / 2) : (LN2_INT / 2); - // Safe unchecked because x is bounded. - int256 q = (x + roundingAdjustment) / LN2_INT; - // Safe unchecked because |q * LN2_INT| <= |x|. - int256 r = x - q * LN2_INT; - - // Compute e^r with a 2nd-order Taylor polynomial. - // Safe unchecked because |r| < 1, expR < 2 and the sum is positive. - uint256 expR = uint256(WAD_INT + r + r.wMulDown(r) / 2); - - // Return e^x = 2^q * e^r. - if (q >= 0) return expR << uint256(q); - else return expR >> uint256(-q); - } - } - - function wMulDown(int256 a, int256 b) internal pure returns (int256) { - return a * b / WAD_INT; - } - - function wDivDown(int256 a, int256 b) internal pure returns (int256) { - return a * WAD_INT / b; - } -} diff --git a/lib/morpho-blue-irm/src/libraries/UtilsLib.sol b/lib/morpho-blue-irm/src/libraries/UtilsLib.sol deleted file mode 100644 index 3d4f03a..0000000 --- a/lib/morpho-blue-irm/src/libraries/UtilsLib.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; - -/// @title UtilsLib -/// @author Morpho Labs -/// @custom:contact security@morpho.xyz -/// @notice Library exposing helpers. -library UtilsLib { - /// @dev Bounds `x` between `low` and `high`. - /// @dev Assumes that `low` <= `high`. If it is not the case it returns `low`. - function bound(uint256 x, uint256 low, uint256 high) internal pure returns (uint256 z) { - assembly { - // z = min(x, high). - z := xor(x, mul(xor(x, high), lt(high, x))) - // z = max(z, low). - z := xor(z, mul(xor(z, low), gt(low, z))) - } - } -} diff --git a/lib/morpho-blue-irm/test/MathLibTest.sol b/lib/morpho-blue-irm/test/MathLibTest.sol deleted file mode 100644 index aff12bd..0000000 --- a/lib/morpho-blue-irm/test/MathLibTest.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; - -import {MathLib} from "../src/libraries/MathLib.sol"; -import {ErrorsLib} from "../src/libraries/ErrorsLib.sol"; -import {wadExp} from "../lib/solmate/src/utils/SignedWadMath.sol"; - -import "../lib/forge-std/src/Test.sol"; - -contract MathLibTest is Test { - using MathLib for uint128; - using MathLib for uint256; - - int256 private constant LN2_INT = 0.693147180559945309 ether; - - function testWExp(int256 x) public { - // Bound between ln(1e-9) ~ -27 and ln(max / 1e18 / 1e18) ~ 94, to be able to use `assertApproxEqRel`. - x = bound(x, -27 ether, 94 ether); - assertApproxEqRel(MathLib.wExp(x), uint256(wadExp(x)), 0.01 ether); - } - - function testWExpSmall(int256 x) public { - // Bound between -(2**255-1) + ln(2)/2 and ln(1e-18). - x = bound(x, type(int256).min + LN2_INT / 2, -178 ether); - assertEq(MathLib.wExp(x), 0); - } - - function testWExpTooSmall(int256 x) public { - // Bound between -(2**255-1) and -(2**255-1) + ln(2)/2 - 1. - x = bound(x, type(int256).min, type(int256).min + LN2_INT / 2 - 1); - vm.expectRevert(bytes(ErrorsLib.WEXP_UNDERFLOW)); - assertEq(MathLib.wExp(x), 0); - } - - function testWExpTooLarge(int256 x) public { - // Bound between ln(2**256-1) ~ 177 and 2**255-1. - x = bound(x, 178 ether, type(int256).max); - vm.expectRevert(bytes(ErrorsLib.WEXP_OVERFLOW)); - MathLib.wExp(x); - } -} diff --git a/lib/morpho-blue-irm/test/SpeedJumpIrmTest.sol b/lib/morpho-blue-irm/test/SpeedJumpIrmTest.sol deleted file mode 100644 index 366b78d..0000000 --- a/lib/morpho-blue-irm/test/SpeedJumpIrmTest.sol +++ /dev/null @@ -1,219 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; - -import "../src/SpeedJumpIrm.sol"; - -import "../lib/forge-std/src/Test.sol"; - -contract SpeedJumpIrmTest is Test { - using MathLib for int256; - using MathLib for int256; - using MathLib for uint256; - using UtilsLib for uint256; - using MorphoMathLib for uint128; - using MorphoMathLib for uint256; - using MarketParamsLib for MarketParams; - - event BorrowRateUpdate(Id indexed id, int128 err, uint128 newBorrowRate, uint256 avgBorrowRate); - - uint256 internal constant LN2 = 0.69314718056 ether; - uint256 internal constant TARGET_UTILIZATION = 0.8 ether; - uint256 internal constant SPEED_FACTOR = uint256(0.01 ether) / uint256(10 hours); - uint128 internal constant INITIAL_RATE = uint128(0.01 ether) / uint128(365 days); - - SpeedJumpIrm internal irm; - MarketParams internal marketParams = MarketParams(address(0), address(0), address(0), address(0), 0); - - function setUp() public { - irm = new SpeedJumpIrm(address(this), LN2, SPEED_FACTOR, TARGET_UTILIZATION, INITIAL_RATE); - vm.warp(90 days); - } - - function testFirstBorrowRate(Market memory market) public { - vm.assume(market.totalBorrowAssets > 0); - vm.assume(market.totalSupplyAssets >= market.totalBorrowAssets); - - uint256 avgBorrowRate = irm.borrowRate(marketParams, market); - (uint256 prevBorrowRate, int256 prevErr) = irm.marketIrm(marketParams.id()); - - assertEq(avgBorrowRate, INITIAL_RATE, "avgBorrowRate"); - assertEq(prevBorrowRate, INITIAL_RATE, "prevBorrowRate"); - assertEq(prevErr, _err(market), "prevErr"); - } - - function testBorrowRateEventEmission(Market memory market) public { - vm.assume(market.totalBorrowAssets > 0); - vm.assume(market.totalSupplyAssets >= market.totalBorrowAssets); - - vm.expectEmit(address(irm)); - emit BorrowRateUpdate(marketParams.id(), int128(_err(market)), INITIAL_RATE, INITIAL_RATE); - irm.borrowRate(marketParams, market); - } - - function testFirstBorrowRateView(Market memory market) public { - vm.assume(market.totalBorrowAssets > 0); - vm.assume(market.totalSupplyAssets >= market.totalBorrowAssets); - - uint256 avgBorrowRate = irm.borrowRateView(marketParams, market); - (uint256 prevBorrowRate, int256 prevErr) = irm.marketIrm(marketParams.id()); - - assertEq(avgBorrowRate, INITIAL_RATE, "avgBorrowRate"); - assertEq(prevBorrowRate, 0, "prevBorrowRate"); - assertEq(prevErr, 0, "prevErr"); - } - - function testBorrowRate(Market memory market0, Market memory market1) public { - vm.assume(market0.totalBorrowAssets > 0); - vm.assume(market0.totalSupplyAssets >= market0.totalBorrowAssets); - irm.borrowRate(marketParams, market0); - - vm.assume(market1.totalBorrowAssets > 0); - vm.assume(market1.totalSupplyAssets >= market1.totalBorrowAssets); - market1.lastUpdate = uint128(bound(market1.lastUpdate, 0, block.timestamp - 1)); - - uint256 avgBorrowRate = irm.borrowRate(marketParams, market1); - (uint256 prevBorrowRate,) = irm.marketIrm(marketParams.id()); - - (uint256 expectedAvgBorrowRate, uint256 expectedPrevBorrowRate) = _expectedBorrowRates(market0, market1); - - assertEq(prevBorrowRate, expectedPrevBorrowRate, "prevBorrowRate"); - assertEq(avgBorrowRate, expectedAvgBorrowRate, "avgBorrowRate"); - } - - function testBorrowRateView(Market memory market0, Market memory market1) public { - vm.assume(market0.totalBorrowAssets > 0); - vm.assume(market0.totalSupplyAssets >= market0.totalBorrowAssets); - irm.borrowRate(marketParams, market0); - - vm.assume(market1.totalBorrowAssets > 0); - vm.assume(market1.totalSupplyAssets >= market1.totalBorrowAssets); - market1.lastUpdate = uint128(bound(market1.lastUpdate, 0, block.timestamp - 1)); - - uint256 avgBorrowRate = irm.borrowRateView(marketParams, market1); - (uint256 prevBorrowRate,) = irm.marketIrm(marketParams.id()); - - (uint256 expectedAvgBorrowRate,) = _expectedBorrowRates(market0, market1); - - assertEq(prevBorrowRate, INITIAL_RATE, "prevBorrowRate"); - assertEq(avgBorrowRate, expectedAvgBorrowRate, "avgBorrowRate"); - } - - function testBorrowRateJumpOnly(Market memory market0, Market memory market1) public { - vm.assume(market0.totalBorrowAssets > 0); - vm.assume(market0.totalSupplyAssets >= market0.totalBorrowAssets); - irm.borrowRate(marketParams, market0); - - vm.assume(market1.totalBorrowAssets > 0); - vm.assume(market1.totalSupplyAssets >= market1.totalBorrowAssets); - market1.lastUpdate = uint128(block.timestamp); - - uint256 avgBorrowRate = irm.borrowRate(marketParams, market1); - (uint256 prevBorrowRate,) = irm.marketIrm(marketParams.id()); - - (uint256 expectedAvgBorrowRate, uint256 expectedPrevBorrowRate) = _expectedBorrowRates(market0, market1); - - assertEq(expectedAvgBorrowRate, expectedPrevBorrowRate, "expectedAvgBorrowRate"); - assertEq(avgBorrowRate, expectedAvgBorrowRate, "avgBorrowRate"); - assertEq(prevBorrowRate, expectedPrevBorrowRate, "prevBorrowRate"); - } - - function testBorrowRateViewJumpOnly(Market memory market0, Market memory market1) public { - vm.assume(market0.totalBorrowAssets > 0); - vm.assume(market0.totalSupplyAssets >= market0.totalBorrowAssets); - irm.borrowRate(marketParams, market0); - - vm.assume(market1.totalBorrowAssets > 0); - vm.assume(market1.totalSupplyAssets >= market1.totalBorrowAssets); - market1.lastUpdate = uint128(block.timestamp); - - uint256 avgBorrowRate = irm.borrowRateView(marketParams, market1); - (uint256 prevBorrowRate,) = irm.marketIrm(marketParams.id()); - - (uint256 expectedAvgBorrowRate,) = _expectedBorrowRates(market0, market1); - - assertEq(prevBorrowRate, INITIAL_RATE, "prevBorrowRate"); - assertEq(avgBorrowRate, expectedAvgBorrowRate, "avgBorrowRate"); - } - - function testBorrowRateSpeedOnly(Market memory market0, Market memory market1) public { - vm.assume(market0.totalBorrowAssets > 0); - vm.assume(market0.totalSupplyAssets >= market0.totalBorrowAssets); - irm.borrowRate(marketParams, market0); - - market1.totalBorrowAssets = market0.totalBorrowAssets; - market1.totalSupplyAssets = market0.totalSupplyAssets; - market1.lastUpdate = uint128(bound(market1.lastUpdate, 0, block.timestamp - 1)); - - uint256 avgBorrowRate = irm.borrowRate(marketParams, market1); - (uint256 prevBorrowRate,) = irm.marketIrm(marketParams.id()); - - (uint256 expectedAvgBorrowRate, uint256 expectedPrevBorrowRate) = _expectedBorrowRates(market0, market1); - - assertEq(prevBorrowRate, expectedPrevBorrowRate, "prevBorrowRate"); - assertEq(avgBorrowRate, expectedAvgBorrowRate, "avgBorrowRate"); - } - - function testBorrowRateViewSpeedOnly(Market memory market0, Market memory market1) public { - vm.assume(market0.totalBorrowAssets > 0); - vm.assume(market0.totalSupplyAssets >= market0.totalBorrowAssets); - irm.borrowRate(marketParams, market0); - - market1.totalBorrowAssets = market0.totalBorrowAssets; - market1.totalSupplyAssets = market0.totalSupplyAssets; - market1.lastUpdate = uint128(bound(market1.lastUpdate, 0, block.timestamp - 1)); - - uint256 avgBorrowRate = irm.borrowRateView(marketParams, market1); - (uint256 prevBorrowRate,) = irm.marketIrm(marketParams.id()); - - (uint256 expectedAvgBorrowRate,) = _expectedBorrowRates(market0, market1); - - assertEq(prevBorrowRate, INITIAL_RATE, "prevBorrowRate"); - assertEq(avgBorrowRate, expectedAvgBorrowRate, "avgBorrowRate"); - } - - /// @dev Returns the expected `avgBorrowRate` and `prevBorrowRate`. - function _expectedBorrowRates(Market memory market0, Market memory market1) - internal - view - returns (uint256, uint256) - { - int256 err = _err(market1); - int256 prevErr = _err(market0); - int256 errDelta = err - prevErr; - uint256 elapsed = block.timestamp - market1.lastUpdate; - - uint256 jumpMultiplier = MathLib.wExp(errDelta.wMulDown(int256(LN2))); - int256 speed = int256(SPEED_FACTOR).wMulDown(err); - uint256 variationMultiplier = MathLib.wExp(speed * int256(elapsed)); - uint256 expectedBorrowRateAfterJump = INITIAL_RATE.wMulDown(jumpMultiplier); - uint256 expectedNewBorrowRate = INITIAL_RATE.wMulDown(jumpMultiplier).wMulDown(variationMultiplier); - - uint256 expectedAvgBorrowRate; - if (speed * int256(elapsed) == 0) { - expectedAvgBorrowRate = INITIAL_RATE.wMulDown(jumpMultiplier); - } else { - expectedAvgBorrowRate = uint256( - (int256(expectedNewBorrowRate) - int256(expectedBorrowRateAfterJump)).wDivDown(speed * int256(elapsed)) - ); - } - - return ( - expectedAvgBorrowRate.bound(irm.MIN_RATE(), irm.MAX_RATE()), - expectedNewBorrowRate.bound(irm.MIN_RATE(), irm.MAX_RATE()) - ); - } - - function _err(Market memory market) internal pure returns (int256) { - uint256 utilization = market.totalBorrowAssets.wDivDown(market.totalSupplyAssets); - - int256 err; - if (utilization > TARGET_UTILIZATION) { - // Safe "unchecked" cast because |err| <= WAD. - err = int256((utilization - TARGET_UTILIZATION).wDivDown(WAD - TARGET_UTILIZATION)); - } else { - // Safe "unchecked" casts because utilization <= WAD and TARGET_UTILIZATION <= WAD. - err = (int256(utilization) - int256(TARGET_UTILIZATION)).wDivDown(int256(TARGET_UTILIZATION)); - } - return err; - } -} diff --git a/lib/morpho-blue-irm/test/UtilsLibTest.sol b/lib/morpho-blue-irm/test/UtilsLibTest.sol deleted file mode 100644 index e542bb9..0000000 --- a/lib/morpho-blue-irm/test/UtilsLibTest.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; - -import "../src/libraries/UtilsLib.sol"; - -import "../lib/forge-std/src/Test.sol"; - -contract UtilsTest is Test { - using UtilsLib for uint256; - - function testBound(uint256 x, uint256 low, uint256 high) public { - if (x <= high) { - if (x >= low) assertEq(x.bound(low, high), x); - else assertEq(x.bound(low, high), low); - } else { - if (low <= high) assertEq(x.bound(low, high), high); - else assertEq(x.bound(low, high), low); - } - } -} diff --git a/lib/morpho-utils/.github/workflows/certora.yml b/lib/morpho-utils/.github/workflows/certora.yml deleted file mode 100644 index 29466ac..0000000 --- a/lib/morpho-utils/.github/workflows/certora.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Certora - -on: - push: - -jobs: - verify: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Install python - uses: actions/setup-python@v4 - - - name: Install certora - run: pip install certora-cli - - - name: Install solc - run: | - wget https://github.com/ethereum/solidity/releases/download/v0.8.17/solc-static-linux - chmod +x solc-static-linux - sudo mv solc-static-linux /usr/local/bin/solc8.17 - - name: Verify rule ${{ matrix.script }} - run: | - echo "key length" ${#CERTORAKEY} - bash certora/scripts/${{ matrix.script }} --solc solc8.17 - env: - CERTORAKEY: ${{ secrets.CERTORAKEY }} - - strategy: - fail-fast: false - max-parallel: 4 - - matrix: - script: - - verifyAll.sh diff --git a/lib/morpho-utils/.github/workflows/foundry-gas-diff.yml b/lib/morpho-utils/.github/workflows/foundry-gas-diff.yml deleted file mode 100644 index 8e528a4..0000000 --- a/lib/morpho-utils/.github/workflows/foundry-gas-diff.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Foundry tests - -on: - push: - branches: - - main - pull_request: - paths: - - src/** - - test/** - - lib/** - - yarn.lock - - foundry.toml - - remappings.txt - - .github/workflows/foundry-gas-diff.yml - -jobs: - compare_gas_reports: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Run tests & create gas report - run: forge test --gas-report > gasreport.ansi - env: - # make fuzzing semi-deterministic to avoid noisy gas cost estimation - # due to non-deterministic fuzzing, but keep it not always deterministic - FOUNDRY_FUZZ_SEED: 0x${{ github.event.pull_request.base.sha || github.sha }} - - - name: Compare gas reports - uses: Rubilmax/foundry-gas-diff@v3.13 - id: gas_diff - - - name: Add gas diff to sticky comment - if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target' - uses: marocchino/sticky-pull-request-comment@v2 - with: - delete: ${{ !steps.gas_diff.outputs.markdown }} # delete the comment in case changes no longer impacts gas costs - message: ${{ steps.gas_diff.outputs.markdown }} diff --git a/lib/morpho-utils/.gitignore b/lib/morpho-utils/.gitignore deleted file mode 100644 index b1dc42a..0000000 --- a/lib/morpho-utils/.gitignore +++ /dev/null @@ -1,53 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# IDE -.vscode - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage -*.html - -# production -/build -/out - -# hardhat -/artifacts -/cache -/coverage.json - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local -*.ansi - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# traces -*.ansi -*.html -lcov.* - -# foundry -.gas-snapshot - -# docs -/docs/* -!/docs/*.pdf -!/docs/*.tex - -# certora -.certora* -.last_confs -certora_debug* -resource_errors.json diff --git a/lib/morpho-utils/.gitmodules b/lib/morpho-utils/.gitmodules deleted file mode 100644 index 6dcad44..0000000 --- a/lib/morpho-utils/.gitmodules +++ /dev/null @@ -1,13 +0,0 @@ -[submodule "lib/forge-std"] - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "lib/openzeppelin-contracts"] - path = lib/openzeppelin-contracts - url = https://github.com/OpenZeppelin/openzeppelin-contracts -[submodule "lib/aave-v3-core"] - path = lib/aave-v3-core - url = https://github.com/aave/aave-v3-core -[submodule "lib/openzeppelin-contracts-upgradeable"] - path = lib/openzeppelin-contracts-upgradeable - url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable - branch = v4.8.3 diff --git a/lib/morpho-utils/.husky/post-checkout b/lib/morpho-utils/.husky/post-checkout deleted file mode 100755 index a531ca6..0000000 --- a/lib/morpho-utils/.husky/post-checkout +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -git submodule update --init --recursive -yarn diff --git a/lib/morpho-utils/.husky/post-merge b/lib/morpho-utils/.husky/post-merge deleted file mode 100755 index a531ca6..0000000 --- a/lib/morpho-utils/.husky/post-merge +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -git submodule update --init --recursive -yarn diff --git a/lib/morpho-utils/.husky/pre-commit b/lib/morpho-utils/.husky/pre-commit deleted file mode 100755 index d2ae35e..0000000 --- a/lib/morpho-utils/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -yarn lint-staged diff --git a/lib/morpho-utils/.prettierignore b/lib/morpho-utils/.prettierignore deleted file mode 100644 index a65b417..0000000 --- a/lib/morpho-utils/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -lib diff --git a/lib/morpho-utils/.prettierrc.json b/lib/morpho-utils/.prettierrc.json deleted file mode 100644 index 9ee6899..0000000 --- a/lib/morpho-utils/.prettierrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "tabWidth": 2, - "printWidth": 100, - "overrides": [ - { - "files": "*.sol", - "options": { - "tabWidth": 4, - "printWidth": 120 - } - } - ] -} diff --git a/lib/morpho-utils/ISSUES.md b/lib/morpho-utils/ISSUES.md deleted file mode 100644 index ca62f9b..0000000 --- a/lib/morpho-utils/ISSUES.md +++ /dev/null @@ -1,44 +0,0 @@ -# Known Issues - -Libraries released within this repository have some known issues that can't be fixed because of the way they are defined. Here is listed all the known issues the dev team could identify. - -## [CompoundMath](./src/math/CompoundMath.sol) - -Given the following operations: - -```solidity -function mul(uint256 x, uint256 y) internal pure returns (uint256) { - return (x * y) / 1e18; -} - -function div(uint256 x, uint256 y) internal pure returns (uint256) { - return ((1e18 * x * 1e18) / y) / 1e18; -} -``` - -The following theorem does not hold: -$\forall x,y, \forall \mu,\nu, (x.mul(\mu) + y.mul(\nu)).div(\mu + \nu) = x.mul(\mu.div(\mu + \nu)) + y.mul(\nu.div(\mu + \nu))$ - -for values: -$x < 10^{18}, \mu < 10^{18 - \log10(x)}$ and $y < 10^{18}, \nu < 10^{18 - \log10(y)}$ - -### Example - -$x = 10, y = 10, \mu = 10^{16}, \nu = 10^{16}$ - -$(x.mul(\mu) + y.mul(\nu)).div(\mu + \nu) = 0 + 0 = 0$ - -$x.mul(\mu.div(\mu + \nu)) + y.mul(\nu.div(\mu + \nu)) = 10.mul(0.5e18) + 10.mul(0.5e18) = 5 + 5 = 10$ - -### Proof - -Because $x \times \mu < 10^{18}$ and $y \times \nu < 10^{18}$ which leads the operation `mul` to truncate to 0 - -This issue leads rounding errors with values: -$x < 10^{18}, \mu < 10^{18}, \log10(x \times \mu) \geqslant 18$ or $y < 10^{18}, \nu < 10^{18}, \log10(y \times \nu) \geqslant 18$ -**[needs a proof]** - -But the theorem (at least) holds for values: -$\mu \geqslant 10^{18}$ and $y \geqslant 10^{18}$ - ---- diff --git a/lib/morpho-utils/LICENSE b/lib/morpho-utils/LICENSE deleted file mode 100644 index 0ad25db..0000000 --- a/lib/morpho-utils/LICENSE +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. diff --git a/lib/morpho-utils/README.md b/lib/morpho-utils/README.md deleted file mode 100644 index d0b9889..0000000 --- a/lib/morpho-utils/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# Morpho Utils - -[![Foundry Tests](https://github.com/morpho-dao/morpho-utils/actions/workflows/foundry-gas-diff.yml/badge.svg)](https://github.com/morpho-dao/morpho-utils/actions/workflows/foundry-gas-diff.yml) -[![Certora Tests](https://github.com/morpho-dao/morpho-utils/actions/workflows/certora.yml/badge.svg)](https://github.com/morpho-dao/morpho-utils/actions/workflows/certora.yml) - - - - - - -Repository gathering useful libraries and contracts. - -## Getting started - -Install this repository as a forge dependency: - -```bash -forge install morpho-dao/morpho-utils -``` - -Then add a remapping to your `remappings.txt`: - -```txt -@morpho-utils/=lib/morpho-utils/src/ -``` - -You're good to go! Just import libraries with `@morpho-utils/math/Math.sol` for example. - ---- - -## Known Issues - -Please be aware that some [known issues](./ISSUES.md) are inherent to the way some libraries work in this repository. - ---- - -## Development - -After cloning this repository, run: - -```bash -git submodule update --init --recursive -``` - -Configure your VSCode to automatically format a file on save, using `forge fmt`: - -- Install [emeraldwalk.runonsave](https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave) -- Update your `settings.json`: - -```json -{ - "[solidity]": { - "editor.formatOnSave": false - }, - "emeraldwalk.runonsave": { - "commands": [ - { - "match": ".sol", - "isAsync": true, - "cmd": "forge fmt ${file}" - } - ] - } -} -``` - ---- - -## Testing - -For testing, run: - -```bash -forge test -``` - ---- - -## Formal verification - -To run the Certora prover, run (with a CERTORAKEY in your environment): - -```bash -./certora/scripts/verifyAll.sh -``` - ---- - -## External contributors - -We thank the MEP team for their help on code optimization: - -- [@AtomicAzzaz](https://github.com/AtomicAzzaz) -- [@ewile](https://github.com/wile) -- [@makcandrov](https://github.com/makcandrov) - ---- - -## Acknowledgements - -This repository is inspired by several sources: - -- [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) -- [Compound](https://github.com/compound-finance/compound-protocol) -- [Aave V2](https://github.com/aave/protocol-v2) -- [Aave V3](https://github.com/aave/aave-v3-core) diff --git a/lib/morpho-utils/certora/scripts/verifyAll.sh b/lib/morpho-utils/certora/scripts/verifyAll.sh deleted file mode 100755 index 89c11c9..0000000 --- a/lib/morpho-utils/certora/scripts/verifyAll.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -certora/scripts/verifyCompoundMath.sh $@ -certora/scripts/verifyMath.sh $@ -certora/scripts/verifyPercentageMath.sh $@ -certora/scripts/verifyWadRayMath.sh $@ diff --git a/lib/morpho-utils/certora/scripts/verifyCompoundMath.sh b/lib/morpho-utils/certora/scripts/verifyCompoundMath.sh deleted file mode 100755 index f465fb2..0000000 --- a/lib/morpho-utils/certora/scripts/verifyCompoundMath.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -certoraRun \ - test/mocks/CompoundMathMock.sol \ - --verify CompoundMathMock:certora/specs/compoundMath.spec \ - --msg "CompoundMath" \ - $@ diff --git a/lib/morpho-utils/certora/scripts/verifyMath.sh b/lib/morpho-utils/certora/scripts/verifyMath.sh deleted file mode 100755 index 96c80e0..0000000 --- a/lib/morpho-utils/certora/scripts/verifyMath.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -certoraRun \ - test/mocks/MathMock.sol \ - --verify MathMock:certora/specs/math.spec \ - --settings -useBitVectorTheory \ - --msg "Math" \ - $@ - - diff --git a/lib/morpho-utils/certora/scripts/verifyPercentageMath.sh b/lib/morpho-utils/certora/scripts/verifyPercentageMath.sh deleted file mode 100755 index e5128dc..0000000 --- a/lib/morpho-utils/certora/scripts/verifyPercentageMath.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -certoraRun \ - test/mocks/PercentageMathMock.sol \ - --verify PercentageMathMock:certora/specs/percentageMath.spec \ - --msg "PercentageMath" \ - $@ diff --git a/lib/morpho-utils/certora/scripts/verifyWadRayMath.sh b/lib/morpho-utils/certora/scripts/verifyWadRayMath.sh deleted file mode 100755 index 6fac463..0000000 --- a/lib/morpho-utils/certora/scripts/verifyWadRayMath.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -certoraRun \ - test/mocks/WadRayMathMock.sol \ - --verify WadRayMathMock:certora/specs/wadRayMath.spec \ - --msg "WadRayMath" \ - $@ - diff --git a/lib/morpho-utils/certora/specs/compoundMath.spec b/lib/morpho-utils/certora/specs/compoundMath.spec deleted file mode 100644 index d62a0e9..0000000 --- a/lib/morpho-utils/certora/specs/compoundMath.spec +++ /dev/null @@ -1,34 +0,0 @@ -methods { - mul(uint256, uint256) returns (uint256) envfree - div(uint256, uint256) returns (uint256) envfree -} - -definition WAD() returns uint = 10^18; - -/// mul /// - -rule mulSafety(uint256 x, uint256 y) { - uint res = mul(x, y); - - assert res == x * y / WAD(); -} - -rule mulLiveness(uint256 x, uint256 y) { - mul@withrevert(x, y); - - assert lastReverted <=> x * y >= 2^256; -} - -/// div /// - -rule divSafety(uint256 x, uint256 y) { - uint res = div(x, y); - - assert res == x * WAD() / y; -} - -rule divLiveness(uint256 x, uint256 y) { - div@withrevert(x, y); - - assert lastReverted <=> x * WAD() >= 2^256 || y == 0; -} diff --git a/lib/morpho-utils/certora/specs/math.spec b/lib/morpho-utils/certora/specs/math.spec deleted file mode 100644 index 120b1ff..0000000 --- a/lib/morpho-utils/certora/specs/math.spec +++ /dev/null @@ -1,67 +0,0 @@ - -methods { - min(uint256, uint256) returns (uint256) envfree - max(uint256, uint256) returns (uint256) envfree - zeroFloorSub(uint256, uint256) returns (uint256) envfree - divUp(uint256, uint256) returns (uint256) envfree -} - -/// min /// - -rule minSafety(uint256 a, uint256 b) { - uint res = min(a, b); - - assert a <= b => res == a; - assert a > b => res == b; -} - -rule minLiveness(uint256 a, uint256 b) { - min@withrevert(a, b); - - assert lastReverted <=> false; -} - -/// max /// - -rule maxSafety(uint256 a, uint256 b) { - uint res = max(a, b); - - assert a >= b => res == a; - assert a < b => res == b; -} - -rule maxLiveness(uint256 a, uint256 b) { - max@withrevert(a, b); - - assert lastReverted <=> false; -} - -/// zeroFloorSub /// - -rule zeroFloorSubSafety(uint256 a, uint256 b) { - uint res = zeroFloorSub(a, b); - - assert a >= b => res == a - b; - assert a < b => res == 0; -} - -rule zeroFloorSubLiveness(uint256 a, uint256 b) { - zeroFloorSub@withrevert(a, b); - - assert lastReverted <=> false; -} - -/// divUp /// - -rule divUpSafety(uint256 a, uint256 b) { - uint res = divUp(a, b); - - assert a % b == 0 => res == a / b; - assert a % b != 0 => res == a / b + 1; -} - -rule divUpLiveness(uint256 a, uint256 b) { - divUp@withrevert(a, b); - - assert lastReverted <=> b == 0; -} diff --git a/lib/morpho-utils/certora/specs/percentageMath.spec b/lib/morpho-utils/certora/specs/percentageMath.spec deleted file mode 100644 index 8257485..0000000 --- a/lib/morpho-utils/certora/specs/percentageMath.spec +++ /dev/null @@ -1,140 +0,0 @@ -methods { - percentAdd(uint256, uint256) returns (uint256) envfree - percentSub(uint256, uint256) returns (uint256) envfree - percentMul(uint256, uint256) returns (uint256) envfree - percentMulDown(uint256, uint256) returns (uint256) envfree - percentMulUp(uint256, uint256) returns (uint256) envfree - percentDiv(uint256, uint256) returns (uint256) envfree - percentDivDown(uint256, uint256) returns (uint256) envfree - percentDivUp(uint256, uint256) returns (uint256) envfree - weightedAvg(uint256, uint256, uint256) returns (uint256) envfree -} - -definition PERCENTAGE_FACTOR() returns uint = 10^4; - -/// percentAdd /// - -rule percentAddSafety(uint256 x, uint256 p) { - uint res = percentAdd(x, p); - - assert res == (x * (PERCENTAGE_FACTOR() + p) + PERCENTAGE_FACTOR() / 2) / PERCENTAGE_FACTOR(); -} - -rule percentAddLiveness(uint256 x, uint256 p) { - percentAdd@withrevert(x, p); - - // The first condition does not imply the second one because x can be zero. - assert lastReverted <=> PERCENTAGE_FACTOR() + p >= 2^256 || x * (PERCENTAGE_FACTOR() + p) + PERCENTAGE_FACTOR() / 2 >= 2^256; -} - -/// percentSub /// - -rule percentSubSafety(uint256 x, uint256 p) { - uint res = percentSub(x, p); - - assert res == (x * (PERCENTAGE_FACTOR() - p) + PERCENTAGE_FACTOR() / 2) / PERCENTAGE_FACTOR(); -} - -rule percentSubLiveness(uint256 x, uint256 p) { - percentSub@withrevert(x, p); - - assert lastReverted <=> x * (PERCENTAGE_FACTOR() - p) + PERCENTAGE_FACTOR() / 2 >= 2^256 || p > PERCENTAGE_FACTOR(); -} - -/// percentMul /// - -rule percentMulSafety(uint256 x, uint256 p) { - uint res = percentMul(x, p); - - assert res == (x * p + PERCENTAGE_FACTOR() / 2) / PERCENTAGE_FACTOR(); -} - -rule percentMulLiveness(uint256 x, uint256 p) { - percentMul@withrevert(x, p); - - assert lastReverted <=> x * p + PERCENTAGE_FACTOR() / 2 >= 2^256; -} - -/// percentMulDown /// - -rule percentMulDownSafety(uint256 a, uint256 p) { - uint res = percentMulDown(a, p); - - assert res == (a * p) / PERCENTAGE_FACTOR(); -} - -rule percentMulDownLiveness(uint256 a, uint256 p) { - percentMulDown@withrevert(a, p); - - assert lastReverted <=> a * p >= 2^256; -} - -/// percentMulUp /// - -rule percentMulUpSafety(uint256 a, uint256 p) { - uint res = percentMulUp(a, p); - - assert res == (a * p + (PERCENTAGE_FACTOR() - 1)) / PERCENTAGE_FACTOR(); -} - -rule percentMulUpLiveness(uint256 a, uint256 p) { - percentMulUp@withrevert(a, p); - - assert lastReverted <=> a * p + PERCENTAGE_FACTOR() - 1 >= 2^256; -} - -/// percentDiv /// - -rule percentDivSafety(uint256 x, uint256 p) { - uint res = percentDiv(x, p); - - assert res == (x * PERCENTAGE_FACTOR() + p / 2) / p; -} - -rule percentDivLiveness(uint256 x, uint256 p) { - percentDiv@withrevert(x, p); - - assert lastReverted <=> x * PERCENTAGE_FACTOR() + p / 2 >= 2^256 || p == 0; -} - -/// percentDivDown /// - -rule percentDivDownSafety(uint256 a, uint256 p) { - uint res = percentDivDown(a, p); - - assert res == (a * PERCENTAGE_FACTOR()) / p; -} - -rule percentDivDownLiveness(uint256 a, uint256 p) { - percentDivDown@withrevert(a, p); - - assert lastReverted <=> a * PERCENTAGE_FACTOR() >= 2^256 || p == 0; -} - -/// percentDivUp /// - -rule percentDivUpSafety(uint256 a, uint256 p) { - uint res = percentDivUp(a, p); - - assert res == (a * PERCENTAGE_FACTOR() + (p - 1)) / p; -} - -rule percentDivUpLiveness(uint256 a, uint256 p) { - percentDivUp@withrevert(a, p); - - assert lastReverted <=> a * PERCENTAGE_FACTOR() + (p - 1) >= 2^256 || p == 0; -} - -/// weightedAvg /// - -rule weightedAvgSafety(uint256 x, uint256 y, uint256 p) { - uint res = weightedAvg(x, y, p); - - assert res == (x * (PERCENTAGE_FACTOR() - p) + y * p + PERCENTAGE_FACTOR() / 2) / PERCENTAGE_FACTOR(); -} - -rule weightedAvgLiveness(uint256 x, uint256 y, uint256 p) { - weightedAvg@withrevert(x, y, p); - - assert lastReverted <=> x * (PERCENTAGE_FACTOR() - p) + y * p + PERCENTAGE_FACTOR() / 2 >= 2^256 || p > PERCENTAGE_FACTOR(); -} diff --git a/lib/morpho-utils/certora/specs/wadRayMath.spec b/lib/morpho-utils/certora/specs/wadRayMath.spec deleted file mode 100644 index 103cef1..0000000 --- a/lib/morpho-utils/certora/specs/wadRayMath.spec +++ /dev/null @@ -1,246 +0,0 @@ -methods { - wadMul(uint256, uint256) returns (uint256) envfree - wadMulDown(uint256, uint256) returns (uint256) envfree - wadMulUp(uint256, uint256) returns (uint256) envfree - wadDiv(uint256, uint256) returns (uint256) envfree - wadDivDown(uint256, uint256) returns (uint256) envfree - wadDivUp(uint256, uint256) returns (uint256) envfree - rayMul(uint256, uint256) returns (uint256) envfree - rayMulDown(uint256, uint256) returns (uint256) envfree - rayMulUp(uint256, uint256) returns (uint256) envfree - rayDiv(uint256, uint256) returns (uint256) envfree - rayDivDown(uint256, uint256) returns (uint256) envfree - rayDivUp(uint256, uint256) returns (uint256) envfree - rayToWad(uint256) returns (uint256) envfree - wadToRay(uint256) returns (uint256) envfree - wadWeightedAvg(uint256, uint256, uint256) returns (uint256) envfree - rayWeightedAvg(uint256, uint256, uint256) returns (uint256) envfree -} - -definition WAD() returns uint = 10^18; -definition RAY() returns uint = 10^27; -definition WADTORAY() returns uint = 10^9; - -/// wadMul /// - -rule wadMulSafety(uint256 a, uint256 b) { - uint res = wadMul(a, b); - - assert res == (a * b + (WAD() / 2)) / WAD(); -} - -rule wadMulLiveness(uint256 a, uint256 b) { - wadMul@withrevert(a, b); - - assert lastReverted <=> a * b + WAD() / 2 >= 2^256; -} - -/// wadMulDown /// - -rule wadMulDownSafety(uint256 a, uint256 b) { - uint res = wadMulDown(a, b); - - assert res == (a * b) / WAD(); -} - -rule wadMulDownLiveness(uint256 a, uint256 b) { - wadMulDown@withrevert(a, b); - - assert lastReverted <=> a * b >= 2^256; -} - -/// wadMulUp /// - -rule wadMulUpSafety(uint256 a, uint256 b) { - uint res = wadMulUp(a, b); - - assert res == (a * b + (WAD() - 1)) / WAD(); -} - -rule wadMulUpLiveness(uint256 a, uint256 b) { - wadMulUp@withrevert(a, b); - - assert lastReverted <=> a * b + WAD() - 1 >= 2^256; -} - -/// wadDiv /// - -rule wadDivSafety(uint256 a, uint256 b) { - uint res = wadDiv(a, b); - - assert res == (a * WAD() + (b / 2)) / b; -} - -rule wadDivLiveness(uint256 a, uint256 b) { - wadDiv@withrevert(a, b); - - assert lastReverted <=> a * WAD() + b / 2 >= 2^256 || b == 0; -} - -/// wadDivDown /// - -rule wadDivDownSafety(uint256 a, uint256 b) { - uint res = wadDivDown(a, b); - - assert res == (a * WAD()) / b; -} - -rule wadDivDownLiveness(uint256 a, uint256 b) { - wadDivDown@withrevert(a, b); - - assert lastReverted <=> a * WAD() >= 2^256 || b == 0; -} - -/// wadDivUp /// - -rule wadDivUpSafety(uint256 a, uint256 b) { - uint res = wadDivUp(a, b); - - assert res == (a * WAD() + (b - 1)) / b; -} - -rule wadDivUpLiveness(uint256 a, uint256 b) { - wadDivUp@withrevert(a, b); - - assert lastReverted <=> a * WAD() + (b - 1) >= 2^256 || b == 0; -} - -/// rayMul /// - -rule rayMulSafety(uint256 a, uint256 b) { - uint res = rayMul(a, b); - - assert res == (a * b + (RAY() / 2)) / RAY(); -} - -rule rayMulLiveness(uint256 a, uint256 b) { - rayMul@withrevert(a, b); - - assert lastReverted <=> a * b + RAY() / 2 >= 2^256; -} - -/// rayMulDown /// - -rule rayMulDownSafety(uint256 a, uint256 b) { - uint res = rayMulDown(a, b); - - assert res == (a * b) / RAY(); -} - -rule rayMulDownLiveness(uint256 a, uint256 b) { - rayMulDown@withrevert(a, b); - - assert lastReverted <=> a * b >= 2^256; -} - -/// rayMulUp /// - -rule rayMulUpSafety(uint256 a, uint256 b) { - uint res = rayMulUp(a, b); - - assert res == (a * b + (RAY() - 1)) / RAY(); -} - -rule rayMulUpLiveness(uint256 a, uint256 b) { - rayMulUp@withrevert(a, b); - - assert lastReverted <=> a * b + RAY() - 1 >= 2^256; -} - -/// rayDiv /// - -rule rayDivSafety(uint256 a, uint256 b) { - uint res = rayDiv(a, b); - - assert res == (a * RAY() + (b / 2)) / b; -} - -rule rayDivLiveness(uint256 a, uint256 b) { - rayDiv@withrevert(a, b); - - assert lastReverted <=> a * RAY() + b / 2 >= 2^256 || b == 0; -} - -/// rayDivDown /// - -rule rayDivDownSafety(uint256 a, uint256 b) { - uint res = rayDivDown(a, b); - - assert res == (a * RAY()) / b; -} - -rule rayDivDownLiveness(uint256 a, uint256 b) { - rayDivDown@withrevert(a, b); - - assert lastReverted <=> a * RAY() >= 2^256 || b == 0; -} - -/// rayDivUp /// - -rule rayDivUpSafety(uint256 a, uint256 b) { - uint res = rayDivUp(a, b); - - assert res == (a * RAY() + (b - 1)) / b; -} - -rule rayDivUpLiveness(uint256 a, uint256 b) { - rayDivUp@withrevert(a, b); - - assert lastReverted <=> a * RAY() + (b - 1) >= 2^256 || b == 0; -} - -/// rayToWad /// - -rule rayToWadSafety(uint256 a) { - uint res = rayToWad(a); - - assert res == (a + (WADTORAY() / 2)) / WADTORAY(); -} - -rule rayToWadLiveness(uint256 a) { - rayToWad@withrevert(a); - - assert lastReverted <=> false; -} - -/// wadToRay /// - -rule wadToRaySafety(uint256 a) { - uint res = wadToRay(a); - - assert res == a * WADTORAY(); -} - -rule wadToRayLiveness(uint256 a) { - wadToRay@withrevert(a); - - assert lastReverted <=> a * WADTORAY() > 2^256; -} - -/// wadWeightedAvg /// - -rule wadWeightedAvgSafety(uint256 x, uint256 y, uint256 w) { - uint res = wadWeightedAvg(x, y, w); - - assert res == (x * (WAD() - w) + y * w + WAD() / 2) / WAD(); -} - -rule wadWeightedAvgLiveness(uint256 x, uint256 y, uint256 w) { - wadWeightedAvg@withrevert(x, y, w); - - assert lastReverted <=> x * (WAD() - w) + y * w + WAD() / 2 >= 2^256 || w > WAD(); -} - -/// rayWeightedAvg /// - -rule rayWeightedAvgSafety(uint256 x, uint256 y, uint256 w) { - uint res = rayWeightedAvg(x, y, w); - - assert res == (x * (RAY() - w) + y * w + RAY() / 2) / RAY(); -} - -rule rayWeightedAvgLiveness(uint256 x, uint256 y, uint256 w) { - rayWeightedAvg@withrevert(x, y, w); - - assert lastReverted <=> x * (RAY() - w) + y * w + RAY() / 2 >= 2^256 || w > RAY(); -} diff --git a/lib/morpho-utils/foundry.toml b/lib/morpho-utils/foundry.toml deleted file mode 100644 index ac84fdb..0000000 --- a/lib/morpho-utils/foundry.toml +++ /dev/null @@ -1,4 +0,0 @@ -[fuzz] -runs = 2048 - -# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/lib/morpho-utils/lib/aave-v3-core/.giatattributes b/lib/morpho-utils/lib/aave-v3-core/.giatattributes deleted file mode 100644 index 7cc88f0..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.giatattributes +++ /dev/null @@ -1 +0,0 @@ -*.sol linguist-language=Solidity \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/.github/CODEOWNERS b/lib/morpho-utils/lib/aave-v3-core/.github/CODEOWNERS deleted file mode 100644 index 89828dd..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @The-3D @miguelmtzinf @stevenvaleri @foodaka @kartojal @Zer0dot @donosonaumczuk @BenSparksCode \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/.github/workflows/node.js.yml b/lib/morpho-utils/lib/aave-v3-core/.github/workflows/node.js.yml deleted file mode 100644 index 88dc8b3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.github/workflows/node.js.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Build - -on: - push: - branches: [master] - pull_request: - branches: [master] - -jobs: - build: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [14.x] - - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://npm.pkg.github.com/ - scope: '@aave' - env: - NODE_AUTH_TOKEN: ${{ secrets.PAT_PACKAGES_REGISTRY_READ_ONLY }} - - uses: actions/cache@v2 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - name: Install dependencies - run: npm ci - env: - NODE_AUTH_TOKEN: ${{ secrets.PAT_PACKAGES_REGISTRY_READ_ONLY }} - - name: Test - run: npm run ci:test - - name: Coverage - run: npm run coverage - - name: Publish coverage - uses: codecov/codecov-action@v1 - with: - fail_ci_if_error: true - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/lib/morpho-utils/lib/aave-v3-core/.github/workflows/release.yml b/lib/morpho-utils/lib/aave-v3-core/.github/workflows/release.yml deleted file mode 100644 index 4448905..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.github/workflows/release.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: release-please -on: - push: - branches: - - master -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: GoogleCloudPlatform/release-please-action@v2 - id: release - with: - release-type: node - package-name: ${{ github.event.repository.name }} - # The logic below handles the npm publication: - - uses: actions/checkout@v2 - # these if statements ensure that a publication only occurs when - # a new release is created: - if: ${{ steps.release.outputs.release_created }} - - uses: actions/setup-node@v1 - if: ${{ steps.release.outputs.release_created }} - with: - node-version: ${{ matrix.node-version }} - # Use the Github Package registry - registry-url: https://npm.pkg.github.com/ - scope: '@aave' - - run: npm ci - env: - NODE_AUTH_TOKEN: ${{ secrets.PAT_PACKAGES_REGISTRY_READ_ONLY }} - if: ${{ steps.release.outputs.release_created }} - - run: npm run ci:test - env: - NODE_AUTH_TOKEN: ${{ secrets.PAT_PACKAGES_REGISTRY_READ_ONLY }} - if: ${{ steps.release.outputs.release_created }} - - run: npm publish - if: ${{ steps.release.outputs.release_created }} - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/lib/morpho-utils/lib/aave-v3-core/.gitignore b/lib/morpho-utils/lib/aave-v3-core/.gitignore deleted file mode 100644 index 0b724ca..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -.env -#Hardhat files -cache -artifacts -temp-artifacts -node_modules -dist/ -build/ -.vscode -.idea -/types -contracts/hardhat-dependency-compiler - -deployed-contracts.json - -coverage -.coverage_artifacts -.coverage_cache -.coverage_contracts -coverage.json -deployments/ \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/.gitlab-ci.yml b/lib/morpho-utils/lib/aave-v3-core/.gitlab-ci.yml deleted file mode 100644 index 23de908..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.gitlab-ci.yml +++ /dev/null @@ -1,92 +0,0 @@ -stages: - - checks - - prepare - - publish - -variables: - IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA} - -lint: - stage: checks - tags: - - aave-build-runner - before_script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml build - script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run prettier:check - after_script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down - -test: - stage: checks - tags: - - aave-build-runner - before_script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml build - script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:test - after_script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down - only: - - master - - merge_requests -deploy-mainnet-fork: - tags: - - aave-build-runner - stage: checks - before_script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml build - script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run aave:fork:main - after_script: - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean - - docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down - only: - - master - - merge_requests - -certora-test: - stage: checks - image: python:latest - before_script: - - apt-get update || apt-get update - - apt-get install -y software-properties-common - - pip3 install certora-cli - - wget https://github.com/ethereum/solidity/releases/download/v0.6.12/solc-static-linux - - chmod +x solc-static-linux - - mv solc-static-linux /usr/bin/solc - - export PATH=$PATH:/usr/bin/solc/solc-static-linux - script: - - certoraRun specs/harness/StableDebtTokenHarness.sol:StableDebtTokenHarness --solc_args "['--optimize']" --verify StableDebtTokenHarness:specs/StableDebtToken.spec --settings -assumeUnwindCond,-b=4 --cache StableDebtToken --cloud - - certoraRun specs/harness/UserConfigurationHarness.sol --verify UserConfigurationHarness:specs/UserConfiguration.spec --solc_args "['--optimize']" --settings -useBitVectorTheory --cache UserConfiguration --cloud - - certoraRun contracts/protocol/tokenization/VariableDebtToken.sol:VariableDebtToken specs/harness/PoolHarnessForVariableDebtToken.sol --solc_args "['--optimize']" --link VariableDebtToken:POOL=PoolHarnessForVariableDebtToken --verify VariableDebtToken:specs/VariableDebtToken.spec --settings -assumeUnwindCond,-useNonLinearArithmetic,-b=4 --cache VariableDebtToken --cloud - only: - - master - - merge_requests - -prepare: - stage: prepare - tags: - - docker-builder - script: - - docker build -t ${IMAGE} . - - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY - - docker push ${IMAGE} - only: - - master - -publish: - image: ${IMAGE} - tags: - - docker - stage: publish - script: - - npm ci - - echo //registry.npmjs.org/:_authToken=${NPM_V2_PACKAGES_TOKEN} > .npmrc - - npm run compile - - ${VERSION} - - npm publish --access public - only: - - master diff --git a/lib/morpho-utils/lib/aave-v3-core/.npmrc b/lib/morpho-utils/lib/aave-v3-core/.npmrc deleted file mode 100644 index 7a78c8a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -@aave:registry=https://npm.pkg.github.com -engine-strict=true \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/.nvmrc b/lib/morpho-utils/lib/aave-v3-core/.nvmrc deleted file mode 100644 index ff65059..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v16.13.0 diff --git a/lib/morpho-utils/lib/aave-v3-core/.prettierignore b/lib/morpho-utils/lib/aave-v3-core/.prettierignore deleted file mode 100644 index ba02554..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -artifacts -cache -node_modules diff --git a/lib/morpho-utils/lib/aave-v3-core/.prettierrc b/lib/morpho-utils/lib/aave-v3-core/.prettierrc deleted file mode 100644 index 2caa982..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.prettierrc +++ /dev/null @@ -1,16 +0,0 @@ -{ - "printWidth": 100, - "trailingComma": "es5", - "semi": true, - "singleQuote": true, - "tabWidth": 2, - "overrides": [ - { - "files": "*.sol", - "options": { - "semi": true, - "printWidth": 100 - } - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/.solcover.js b/lib/morpho-utils/lib/aave-v3-core/.solcover.js deleted file mode 100644 index 71bbe81..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/.solcover.js +++ /dev/null @@ -1,17 +0,0 @@ -const accounts = require(`./test-wallets.js`).accounts; -const cp = require('child_process'); - -module.exports = { - client: require('ganache-cli'), - skipFiles: ['./mocks', './interfaces', './dependencies'], - mocha: { - enableTimeouts: false, - }, - providerOptions: { - accounts, - }, - onCompileComplete: function () { - console.log('onCompileComplete hook'); - cp.execSync('. ./setup-test-env.sh', { stdio: 'inherit' }); - }, -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/CHANGELOG.md b/lib/morpho-utils/lib/aave-v3-core/CHANGELOG.md deleted file mode 100644 index 7190ab3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/CHANGELOG.md +++ /dev/null @@ -1,820 +0,0 @@ -# Changelog - -### [1.16.1](https://www.github.com/aave/aave-v3-core/compare/v1.16.0...v1.16.1) (2022-04-05) - - -### Bug Fixes - -* add comment for undocumentted parameter ([ba0e4ee](https://www.github.com/aave/aave-v3-core/commit/ba0e4ee72cc3060fc55294aeac0a7bbb9caf3087)) -* Add helpers for proxy contracts (eip1967 slots) ([d82be43](https://www.github.com/aave/aave-v3-core/commit/d82be4350d1778c269b5f7d875bdf5025fcff0bd)) -* Fix ts type of contract in tests ([12373ca](https://www.github.com/aave/aave-v3-core/commit/12373ca09d4e2cec32546dc87285d516c1d9f261)) - -## [1.16.0](https://www.github.com/aave/aave-v3-core/compare/v1.15.0...v1.16.0) (2022-03-15) - - -### Features - -* updated price oracle sentinel interface ([f6b71f5](https://www.github.com/aave/aave-v3-core/commit/f6b71f508db2a9a6f966bc6d606198eebaaefbb9)) - - -### Bug Fixes - -* Fix docstrings of ISequencerOracle ([4391fd4](https://www.github.com/aave/aave-v3-core/commit/4391fd4c8f29fb81c966fd4510df89d0acdb8404)) - -## [1.15.0](https://www.github.com/aave/aave-v3-core/compare/v1.14.2...v1.15.0) (2022-03-04) - - -### Features - -* add owner constructor parameter to contracts that inherits Ownable to support CREATE2 factory deployment ([b6cc245](https://www.github.com/aave/aave-v3-core/commit/b6cc245b7e78e7d27b7af3e045cceff58e477231)) -* bump beta deploy package ([fbcf885](https://www.github.com/aave/aave-v3-core/commit/fbcf885269285b36b54cc741da7922d257255a44)) -* refactored executeLiquidationCall function ([63e43ef](https://www.github.com/aave/aave-v3-core/commit/63e43eff1c36a8d7e96c86f9655e7af31fe7e81f)) - - -### Bug Fixes - -* add owner parameters to test suites ([6e96821](https://www.github.com/aave/aave-v3-core/commit/6e968212d088ab6c9911b85dc454e4b989db7d6f)) -* Move reservesData param to the beginning of the param list ([0872cb4](https://www.github.com/aave/aave-v3-core/commit/0872cb4c30e79566f09a0320168d0bd1f5111a29)) - -### [1.14.2](https://www.github.com/aave/aave-v3-core/compare/v1.14.1...v1.14.2) (2022-03-02) - - -### Bug Fixes - -* Replace `...PriceAddress` with `...PriceSource` ([10a8667](https://www.github.com/aave/aave-v3-core/commit/10a8667b08c2e3daa1d87b1a7348154081c3903d)) -* Use `EModeLogic::isInEModeCategory` in `executeLiquidationCall` ([28f72fe](https://www.github.com/aave/aave-v3-core/commit/28f72fe82496044d23d4ea3f20298cec9918404b)) - -### [1.14.1](https://www.github.com/aave/aave-v3-core/compare/v1.14.0...v1.14.1) (2022-03-01) - - -### Bug Fixes - -* Improve consistency of function naming of CalldataLogic ([1a5517d](https://www.github.com/aave/aave-v3-core/commit/1a5517d28b531d673e6ac81e59b552d1280e7d7e)) -* Use memory instead of storage in `getLiquidationBonus` ([deccf52](https://www.github.com/aave/aave-v3-core/commit/deccf529ad8d300f8a0e768cc8d9bf6d48b7699f)) - -## [1.14.0](https://www.github.com/aave/aave-v3-core/compare/v1.13.1...v1.14.0) (2022-02-21) - - -### Features - -* clean dependencies and upgrade child dependencies ([7ca97ca](https://www.github.com/aave/aave-v3-core/commit/7ca97ca4cd6e9aad74583a4a1ca5ebe3fae44c64)) -* removed obsolete files for the certora tools ([d7e0e7c](https://www.github.com/aave/aave-v3-core/commit/d7e0e7c37c0741b54afde3354d0be4a619fafde5)) - - -### Bug Fixes - -* `reserves` renamed to `reservesData` or `reservesList` when fitting ([3a6b928](https://www.github.com/aave/aave-v3-core/commit/3a6b928abb9ad6920582064704673e84f4b543dd)) -* Cleanup naming and remove duplicate tests ([6ed5891](https://www.github.com/aave/aave-v3-core/commit/6ed589163ae30b235206dc571b98091f08dc5bad)) -* Fix typo in package contributors tag ([14a3b6d](https://www.github.com/aave/aave-v3-core/commit/14a3b6d503d71d080c145e7fbcdacbe68b2b11ba)) -* Moved getUserAccountData logic to PoolLogic to minimize contract size ([b07bdab](https://www.github.com/aave/aave-v3-core/commit/b07bdab921705788f38e130f75a10a1444cbc6b1)) -* Natspec for `IPool::swapBorrowRateMode()` ([5b016fc](https://www.github.com/aave/aave-v3-core/commit/5b016fc699ef816204cf1e0fe1178285f53cf83c)) -* Place interface extension declaration at the end ([19c015e](https://www.github.com/aave/aave-v3-core/commit/19c015ec76efc229da6b59fafa9f640d56e7f157)) -* Rename reserves to reservesList ([4b0af0b](https://www.github.com/aave/aave-v3-core/commit/4b0af0bbb200e76dfedc7adf923c80e74fae37cb)) -* Revert dependencies to last working state ([ff4d987](https://www.github.com/aave/aave-v3-core/commit/ff4d98765cea9b07f3e61f5b5e0efc472a06addc)) -* typo in tech paper ([d6b9cbc](https://www.github.com/aave/aave-v3-core/commit/d6b9cbc55adf88c4cb7dd6df11941167fd119b3d)) -* Update contributors etc in package.json ([60fc967](https://www.github.com/aave/aave-v3-core/commit/60fc967fa8037bb856c0c39c1e433fabafab255c)) -* Update gas optimization numbers ([8719929](https://www.github.com/aave/aave-v3-core/commit/8719929597742e697cd8824cd29d9a786f3ec0eb)) - -### [1.13.1](https://www.github.com/aave/aave-v3-core/compare/v1.13.0...v1.13.1) (2022-01-27) - - -### Bug Fixes - -* Add virtual to getReserveNormalizedIncome function ([bc10fd2](https://www.github.com/aave/aave-v3-core/commit/bc10fd24750680e83e3d4abb54bf452998fa0e0d)) -* Mark all functions as virtual ([f6932b3](https://www.github.com/aave/aave-v3-core/commit/f6932b3d8c0055caf4ed1a191ec64676f4e68ad1)) - -## [1.13.0](https://www.github.com/aave/aave-v3-core/compare/v1.12.0...v1.13.0) (2022-01-25) - - -### Features - -* bump @aave/deploy-v3 ([430c9d3](https://www.github.com/aave/aave-v3-core/commit/430c9d3eebfafc6349ead5860016e25ff43fb547)) - -## [1.12.0](https://www.github.com/aave/aave-v3-core/compare/v1.11.1...v1.12.0) (2022-01-25) - - -### Features - -* bump @aave/deploy-v3 version ([85ec0fe](https://www.github.com/aave/aave-v3-core/commit/85ec0fe7cb45ae227b74ceb53c9088612034a3dc)) - - -### Bug Fixes - -* missing library at test, add updated deploy beta package ([67a5c80](https://www.github.com/aave/aave-v3-core/commit/67a5c80f04d0bcdd2dfa01c4b2d18a8a82dd222e)) - -### [1.11.1](https://www.github.com/aave/aave-v3-core/compare/v1.11.0...v1.11.1) (2022-01-25) - - -### Bug Fixes - -* Add natspec and handle naming ([1f5c8a9](https://www.github.com/aave/aave-v3-core/commit/1f5c8a9daeeb58e25049d315127c37b3b92cee74)) -* Adding literal params struct to initReserve ([43cced7](https://www.github.com/aave/aave-v3-core/commit/43cced7b155fa8cd714f5a088f5bf0b24ba6dc4e)) -* Change function modifier of MAX_NUMBER_RESERVES to pure ([dc34a67](https://www.github.com/aave/aave-v3-core/commit/dc34a67d390e66ce77622d0c8ce80edd572fe9c6)) -* Error library ([475eb1d](https://www.github.com/aave/aave-v3-core/commit/475eb1d73755d1ab8eb997feb0ebfa7f15f9893a)) -* fix comments ([b90b888](https://www.github.com/aave/aave-v3-core/commit/b90b888726beed2032b6c0ba84d797cf90aef2e5)) -* Move `dropReserve` logic to PoolLogic ([169d72c](https://www.github.com/aave/aave-v3-core/commit/169d72c58135b49b1236fd7fe9478adf1053efe9)) -* Move `initReserve` and `getReservesList` to PoolLogic ([b0ef5e4](https://www.github.com/aave/aave-v3-core/commit/b0ef5e4ed8ff4aa2d1a872f23899a1e81476b6ba)) -* Move availableLiqudity assignment in DefaultReserveInterestRateStrategy ([8c82d9d](https://www.github.com/aave/aave-v3-core/commit/8c82d9d87566ec2bacb705e2918ebb6e916d13b6)) -* Move comment up in validationlogic ([cbdaa30](https://www.github.com/aave/aave-v3-core/commit/cbdaa3080f43ea53bcc4afa9636735eff1deb175)) -* Move getters back to Pool, rename execute for functions called by pool ([106b617](https://www.github.com/aave/aave-v3-core/commit/106b6174c40086347de907f17dbf65f7535d69f3)) -* Naming Atoken to AToken ([0d50841](https://www.github.com/aave/aave-v3-core/commit/0d508413f9ddba280ff32db6898d3927f1219bda)) -* Remove unneeded comment ([1cb2324](https://www.github.com/aave/aave-v3-core/commit/1cb2324e11138c08d908d8cda7460f8598005cd1)) -* Remove unneeded comment ([4134d89](https://www.github.com/aave/aave-v3-core/commit/4134d89707e5dec310fcb1f6945d1692d7a9cf5c)) -* Remove unneeded fields in FlashLoanLocalVars struct ([9cb3a05](https://www.github.com/aave/aave-v3-core/commit/9cb3a05efdcb388ff7329480f26de8b3cc38d249)) -* Remove unneeded import of interface in Pool ([cc49160](https://www.github.com/aave/aave-v3-core/commit/cc4916049d394fbadf63568b3ddaef74b531d087)) -* Rename flashloanRepayment internal funciton to _flashloanRepayment ([3e18b8a](https://www.github.com/aave/aave-v3-core/commit/3e18b8ad2a80776f47f72c6c9bb5dfe620400e82)) -* Replace > 0 with != 0 ([7bc9926](https://www.github.com/aave/aave-v3-core/commit/7bc99264a76453f04ac7754595ec643317b0763e)) -* Simplify `executeRepay` ([6ab4a44](https://www.github.com/aave/aave-v3-core/commit/6ab4a44d601c71784a3af47d0d3f2c1d0f09b3f4)) -* update comments ([5f09cf9](https://www.github.com/aave/aave-v3-core/commit/5f09cf90792d1e8aa71168de4822f4f4b29da0a8)) -* Update deploy version ([a99e5b4](https://www.github.com/aave/aave-v3-core/commit/a99e5b458e4264ec1b583d7bbeafc12fde9a0ba5)) -* Update import order in PoolLogic ([40447cd](https://www.github.com/aave/aave-v3-core/commit/40447cd10c1925ce5daea74f0d201c571128cab6)) -* Update natspec ([f60a451](https://www.github.com/aave/aave-v3-core/commit/f60a451508f8c96a6c9dad55a2f5b43812feb721)) -* Update ordering in `FlashLoanRepaymentParams` ([93dd9ea](https://www.github.com/aave/aave-v3-core/commit/93dd9eadd3f8e0deef5b91ff36f038d14b89e8f6)) - -## [1.11.0](https://www.github.com/aave/aave-v3-core/compare/v1.10.0...v1.11.0) (2022-01-23) - - -### Features - -* Add rescueTokens functionality for Pool and AToken ([047edf8](https://www.github.com/aave/aave-v3-core/commit/047edf8a3cbb93d2d61f25b7954be9599ee96fd7)) - - -### Bug Fixes - -* Add getter for `_stableRateExcessOffset` ([3586ebb](https://www.github.com/aave/aave-v3-core/commit/3586ebbe2df893332c791ad9aa1bf049240d8c25)) -* Fix contract docstrings ([802a4bd](https://www.github.com/aave/aave-v3-core/commit/802a4bd428edeff446cf0fca2696f4f7ad2a97cd)) -* Fix imports order ([5d237a4](https://www.github.com/aave/aave-v3-core/commit/5d237a4e7e4259b28a50052ba106961a38911220)) -* Re-add the abstract modifier to base tokenization contracts ([52abb3f](https://www.github.com/aave/aave-v3-core/commit/52abb3f81a420ed233422d7caee87beda8e8f31e)) -* Remove blank space ([0c208fa](https://www.github.com/aave/aave-v3-core/commit/0c208fa3555c481667fa507ebfec1863a9bc39f9)) -* Remove rescueTokensFromAToken from Pool ([1a32301](https://www.github.com/aave/aave-v3-core/commit/1a32301881993888b880e077236de90493338cde)) -* Revert chainId renaming ([c4283d5](https://www.github.com/aave/aave-v3-core/commit/c4283d5fe062c4af5a6c37effa95df67efd7bd57)) -* Update comment ([94c4cfb](https://www.github.com/aave/aave-v3-core/commit/94c4cfbd95d45e772d6348bdcde7e212a5651ea6)) -* Update natspec and test ([39363e4](https://www.github.com/aave/aave-v3-core/commit/39363e4dd659899163619b62ef4fd2818a58f620)) -* Update natspec for `calculateInterestRates()` ([b22150b](https://www.github.com/aave/aave-v3-core/commit/b22150b8da8ba0a51845264e367b1935456b0ba7)) -* Update test name ([f6319b9](https://www.github.com/aave/aave-v3-core/commit/f6319b94d0db7a65ca7763115b29845f78dd5ae4)) - -## [1.10.0](https://www.github.com/aave/aave-v3-core/compare/v1.9.0...v1.10.0) (2022-01-12) - - -### Features - -* fix tests missing module. add deployments dir to gitignore ([4e2c5e8](https://www.github.com/aave/aave-v3-core/commit/4e2c5e8334060941741375053ee2da4e6de3ed98)) -* moved IncentivizedERC20 to the base folder ([1d5ed55](https://www.github.com/aave/aave-v3-core/commit/1d5ed55a613d52290263a87f863e423d054871f2)) -* refactored premium to protocol in updateFlashloanPremiumTotal ([6349f4b](https://www.github.com/aave/aave-v3-core/commit/6349f4bdc16665350f421d535ac1e8126ba6741e)) -* refactored premiumTotal in updateFlashloanPremiumToProtocol ([6b9f82c](https://www.github.com/aave/aave-v3-core/commit/6b9f82cb7cc267b932b92afce124e22cc22e523a)) -* update comment ([7d6ccfb](https://www.github.com/aave/aave-v3-core/commit/7d6ccfb1b2ee35e59177d5bd289bce1bbe167b14)) - - -### Bug Fixes - -* Add `userTotalDebt` variable and refactor fix ([f9794f1](https://www.github.com/aave/aave-v3-core/commit/f9794f1f2494b7a4d569b947c14c01d6d6f678f6)) -* Add amount cache in premium calc of executeFlashLoan ([785ba09](https://www.github.com/aave/aave-v3-core/commit/785ba097f930d35fe98fb52888bc43939a5ab356)) -* Add checks to turn off borrowing. ([f9ec711](https://www.github.com/aave/aave-v3-core/commit/f9ec71142186d2d3abc6d9d090920cb2abd03d20)) -* Add error message ([18ae21f](https://www.github.com/aave/aave-v3-core/commit/18ae21f2d345de64f5c7272c2023ac3c4d3eadb6)) -* add failing tests ([254a021](https://www.github.com/aave/aave-v3-core/commit/254a0212dfd083dad58aadd0f9081b503d1f1eee)) -* Add id to register and unregister events ([c196b71](https://www.github.com/aave/aave-v3-core/commit/c196b71241833db95205925c42ef29afc6f5b343)) -* Add indexed params to MarketIdSet event ([74062fc](https://www.github.com/aave/aave-v3-core/commit/74062fcfb3e735b3430723d2d8e15ac67347a502)) -* Add new event AddressSetAsProxy for imple address updates ([e4a15fb](https://www.github.com/aave/aave-v3-core/commit/e4a15fbecdfcaa2bc6a988b02af33ea43c99508d)) -* Add override modifier to underlyingAsset getter ([be4702c](https://www.github.com/aave/aave-v3-core/commit/be4702c0ca9e3f310bf25875f574162cb2f4f153)) -* Add percentage range check of liquidationFee in Configurator ([2d5330b](https://www.github.com/aave/aave-v3-core/commit/2d5330b37b248aa3f7e36713588eeff2c961cace)) -* Add range check for new reserve factor ([9863a47](https://www.github.com/aave/aave-v3-core/commit/9863a47eac0a84e8b64469f5a597759b8c542633)) -* add test for setting interest rate on unlistest asset ([09c04d2](https://www.github.com/aave/aave-v3-core/commit/09c04d241c087ea084f69701fca004adf282d165)) -* Add underlying getter in debtToken interfaces ([498b860](https://www.github.com/aave/aave-v3-core/commit/498b860f7ff0588b9e58b793376d3b132bbcf498)) -* add validation to set interest rates ([f623d9a](https://www.github.com/aave/aave-v3-core/commit/f623d9afe64035ef45d1f75b8693bb51e5a967cf)) -* Add visibility accessors to StableDebtToken state variables ([9faa22f](https://www.github.com/aave/aave-v3-core/commit/9faa22f91343cbfd2eac5d3ac917432692871f07)) -* Add visibility accessors to state variables of mocks ([b76dcb7](https://www.github.com/aave/aave-v3-core/commit/b76dcb731fc473aaef91141580ae4fd3d479deed)) -* address provider staticcall get implementation ([d2b1a32](https://www.github.com/aave/aave-v3-core/commit/d2b1a322b34ab7e055f5c60142db917367e629fe)) -* Change order of condition in validateHFAndLtv for gas saving ([34145bf](https://www.github.com/aave/aave-v3-core/commit/34145bf33225f6185a558a9eff965aac87803fb4)) -* check asset for zero address ([cdaa90c](https://www.github.com/aave/aave-v3-core/commit/cdaa90cb231e2799513d1bf20125dbf8de1f973b)) -* Clean tests ([d47b777](https://www.github.com/aave/aave-v3-core/commit/d47b777f9459ca8d55983096305cf78e4ccf59c6)) -* consistent get, set order ([ccb634a](https://www.github.com/aave/aave-v3-core/commit/ccb634ae26d12ecdb15ed4a50b906a089089ab0c)) -* Enhance reserves listing function in Pool ([2303871](https://www.github.com/aave/aave-v3-core/commit/2303871378a9ef5f123fc64756d30f6f9c2c2002)) -* failing test ([82758e9](https://www.github.com/aave/aave-v3-core/commit/82758e96c6ae97745cd76558139a67b88eae4fb7)) -* Fix ChainlinkAggregator intergration in AaveOracle ([44af5fe](https://www.github.com/aave/aave-v3-core/commit/44af5fe4b0b1378ca0767f821d443275b1bc6875)) -* Fix docstrings ([a6b1a02](https://www.github.com/aave/aave-v3-core/commit/a6b1a0286980814dc7ba8c7f4f326a6c4bda3d64)) -* Fix error from merge conflicts ([b0bea4c](https://www.github.com/aave/aave-v3-core/commit/b0bea4c8e4e4b62795f823d796a45418df786ed9)) -* Fix error in a revert message of test cases ([abaaa2c](https://www.github.com/aave/aave-v3-core/commit/abaaa2c71b191c5637f97f5c9d0d637b33141ef7)) -* Fix error in docstring ([a9aec4a](https://www.github.com/aave/aave-v3-core/commit/a9aec4a582875979e8d5271a67c45a72e8297b78)) -* Fix error in test case ([4fb8037](https://www.github.com/aave/aave-v3-core/commit/4fb80372bf68c6740b8d5dc143719d4efb0585c7)) -* Fix error in test from merge conflicts ([c7512ed](https://www.github.com/aave/aave-v3-core/commit/c7512ed0ea3d8b5932df461475292fa4b86ac14d)) -* Fix error name INVALID_RESERVE_FACTOR ([3785b38](https://www.github.com/aave/aave-v3-core/commit/3785b389db2588ff731e9eeab234fa96e498024d)) -* Fix errors constants in types.ts ([cdc6b26](https://www.github.com/aave/aave-v3-core/commit/cdc6b2663ac4798d46894a36473ff751223d811e)) -* Fix errors in constants from merge conflicts ([4831638](https://www.github.com/aave/aave-v3-core/commit/4831638687daf4567bf825e4ee0ff905ae6b426a)) -* Fix errors of merge conflicts ([b684547](https://www.github.com/aave/aave-v3-core/commit/b684547f2517397fe4dade7f30b050186f4d3d94)) -* Fix grammar spell typos in docstrings ([3868ead](https://www.github.com/aave/aave-v3-core/commit/3868eadd9c6c01fcfd407247e718737bfef9d608)) -* Fix MockAggregator code ([67d29f5](https://www.github.com/aave/aave-v3-core/commit/67d29f553f9ad7d53435aea0c40221372efa5bf2)) -* Fix test, fetching artifact from local typechain ([da07b87](https://www.github.com/aave/aave-v3-core/commit/da07b87b3073ade16312f30935b46459a3859082)) -* Fix typo in constant value ([71dc37c](https://www.github.com/aave/aave-v3-core/commit/71dc37cb70113aca1d9d0450a833786ac22d8237)) -* Fix typo in docstring ([70a4a51](https://www.github.com/aave/aave-v3-core/commit/70a4a512caad3e83a462eac79d84c9dec3060ef3)) -* Fix typos in docstrings ([51b95e0](https://www.github.com/aave/aave-v3-core/commit/51b95e0f1d26f61a16480e773fb65f3881fc663c)) -* Fix typos in docstrings ([80ad248](https://www.github.com/aave/aave-v3-core/commit/80ad248732c1b9377955b811b2f3b2515c22b6eb)) -* Fix typos in docstrings ([d3aa941](https://www.github.com/aave/aave-v3-core/commit/d3aa9413ae29010385f02d878ef4450f6fb8fd0e)) -* Improve readability of LiquidationLogic constants ([79896d5](https://www.github.com/aave/aave-v3-core/commit/79896d5292aeef177eedda5dabd287988d3b8c45)) -* improve set config readability ([a9dd99f](https://www.github.com/aave/aave-v3-core/commit/a9dd99fc69b960594261420152e0c5e4a979a0be)) -* interest-rate-strategy-range-checks ([adf2f4c](https://www.github.com/aave/aave-v3-core/commit/adf2f4c341c36c559c555897162f34991824a008)) -* Make flashloan premium to protocol a fraction of total premium ([d24c962](https://www.github.com/aave/aave-v3-core/commit/d24c96297013c122380b115a1ad5e8552a655097)) -* Mark proxyAddress as indexed in AddressSetAsProxy event ([bddabad](https://www.github.com/aave/aave-v3-core/commit/bddabadb50bfee7f4d2f050a05893f1edcd7d07f)) -* Move IChainlinkAggregator to dependencies and rename it to official name ([6099f84](https://www.github.com/aave/aave-v3-core/commit/6099f84733fbfe8c4738e0cd8c7b4637d8e8f0a9)) -* Move up validation of executeFlashloan ([4b64705](https://www.github.com/aave/aave-v3-core/commit/4b6470574c81d2da10937bf2922a9bed9cf762f6)) -* Naming of excess variables + introduction of constant for stable ratio ([37c2a63](https://www.github.com/aave/aave-v3-core/commit/37c2a63063b74bacf47a1f7059b1978f61b59750)) -* Remove .solhint.json ([972ec21](https://www.github.com/aave/aave-v3-core/commit/972ec21552400b2ca29beb9a7e4b4680f742f82b)) -* remove console logs ([2cd4dcc](https://www.github.com/aave/aave-v3-core/commit/2cd4dccdb0d6994dfbad60a4d3e18678dfd0fe96)) -* Remove external hacky getProxyImplementation function ([62a25c8](https://www.github.com/aave/aave-v3-core/commit/62a25c8f4d50a5ff38c960a00962d5ec220b94f8)) -* Remove getUserCurrentDebtMemory() helper function ([f2dc371](https://www.github.com/aave/aave-v3-core/commit/f2dc37148d13e7d217bcc3458c703fc98c7c90ca)) -* Remove not needed ProxyImplementationSet event ([002ebda](https://www.github.com/aave/aave-v3-core/commit/002ebdac6a6665529886149765f550c46bf4c589)) -* Remove redundant functions in WadRayMath lib ([5f0f035](https://www.github.com/aave/aave-v3-core/commit/5f0f0352efc69c19751b58b0dbcfc61370296992)) -* Remove references to DataTypes inside itself ([e5abd90](https://www.github.com/aave/aave-v3-core/commit/e5abd90f36594f0bce3d5303a7a870ca0f98afad)) -* Remove unneeded _getUnderlyingAsset() ([f2af600](https://www.github.com/aave/aave-v3-core/commit/f2af60004d4be0bb0ef6fd69070723f3f2527d69)) -* Remove unneeded constants for tests ([27130ac](https://www.github.com/aave/aave-v3-core/commit/27130ac8e9d61303f8723e24f442d662e957eb54)) -* Remove unneeded debug console ([4654be0](https://www.github.com/aave/aave-v3-core/commit/4654be065b270150456a1d7b06d217d15ef3d521)) -* Remove unneeded import in PoolStorage ([361cc39](https://www.github.com/aave/aave-v3-core/commit/361cc390f540a029df6fc587802581d2dc616fac)) -* Remove unneeded local variables ([a718549](https://www.github.com/aave/aave-v3-core/commit/a718549425f45cd6bc5bce52381fadefa80fa5ac)) -* Remove unneeded vars for validateHFAndLtv ([8b32e45](https://www.github.com/aave/aave-v3-core/commit/8b32e45867405e8792ae1c50f08d4eb18272c032)) -* Remove unused commented value ([9179670](https://www.github.com/aave/aave-v3-core/commit/917967002858662cd2164699f3852610dbc5ea97)) -* Removes not needed BytesLib library ([43db2f6](https://www.github.com/aave/aave-v3-core/commit/43db2f6479d8e10629fc5f8b213d4cbc9be430f5)) -* Rename last test helper with utilizationRate naming ([8acfc1a](https://www.github.com/aave/aave-v3-core/commit/8acfc1a40683bb6a051de7a4c7784baf24f1c209)) -* Rename utilizationRate for usageRation in contracts ([b9e46eb](https://www.github.com/aave/aave-v3-core/commit/b9e46ebd1ac1e9144cc0db70bd9bfcbcb70725e5)) -* Replace INCORRECT_ADDRESSES_PROVIDER for INVALID_ADDRESSES_PROVIDER ([be99a3c](https://www.github.com/aave/aave-v3-core/commit/be99a3ca8e150f749739838f7d058108ee07c56d)) -* Replace INVALID_PARAMS_EMODE_CATEGORY for INVALID_EMODE_CATEGORY_PARAMS ([e4e922b](https://www.github.com/aave/aave-v3-core/commit/e4e922b52ec9f4a3b57d746830b02d636c07c19d)) -* Replace INVALID_PARAMS_RESERVE for INVALID_RESERVE_PARAMS ([b6bb1cc](https://www.github.com/aave/aave-v3-core/commit/b6bb1ccbd3def686f90b32ae0e2685fbb304f696)) -* Replace NO_STABLE_RATE_LOAN_IN_RESERVE for NO_STABLE_RATE_DEBT ([43cf2a1](https://www.github.com/aave/aave-v3-core/commit/43cf2a1d3634282073a3a7671443434587eb5f28)) -* Replace NO_VARIABLE_RATE_LOAN_IN_RESERVE for NO_VARIABLE_RATE_DEBT ([df9658f](https://www.github.com/aave/aave-v3-core/commit/df9658f0e4bc663b7bc89e4f818f75a46a76f8b3)) -* Replace unneeded inline if with expect ([d0d24b8](https://www.github.com/aave/aave-v3-core/commit/d0d24b8474c9c9ca0a28131f3a9a7aed6f618db0)) -* Replace updateIsolationModeTotalDebt with a reset function ([35b4346](https://www.github.com/aave/aave-v3-core/commit/35b4346d5cf3f8054ce13ff8c69e369311f68f7e)) -* Revert renaming of ValidationLogic constants ([b6fc891](https://www.github.com/aave/aave-v3-core/commit/b6fc891b211698db7d2b0d615d28ace84f47b5f7)) -* Revert renaming of ValidationLogic constants ([52fc81a](https://www.github.com/aave/aave-v3-core/commit/52fc81ab447de19437e614535b027f409845fe8f)) -* Revert variable rename of usageRatio ([66f51fd](https://www.github.com/aave/aave-v3-core/commit/66f51fd4fa18c7ffa1e9f98fe72aa50c3db22ee1)) -* Simplify test using object destructuring ([98b7d73](https://www.github.com/aave/aave-v3-core/commit/98b7d73e2d766606148278ca94b3bb3ad44ea9eb)) -* Simplify updateImpl logic ([da14cbf](https://www.github.com/aave/aave-v3-core/commit/da14cbf3ddfc7afcf590a4df95f3c81c411f4097)) -* Update naming of EXCESS constants ([064a4d4](https://www.github.com/aave/aave-v3-core/commit/064a4d4131f53ba9e3be457ecf86bd902af769a6)) - - -### Miscellaneous Chores - -* release 1.10.0 ([734f83a](https://www.github.com/aave/aave-v3-core/commit/734f83abe0385760489185aa7fb7e773a41ab8b8)) - -## [1.9.0](https://www.github.com/aave/aave-v3-core/compare/v1.8.0...v1.9.0) (2021-12-26) - - -### Features - -* add event test ([d5fe4bb](https://www.github.com/aave/aave-v3-core/commit/d5fe4bb5afd7d5cc1dfe47ef0700c5dd4cfce5ea)) -* added additional functions to IAToken for EIP2612 ([df8ee61](https://www.github.com/aave/aave-v3-core/commit/df8ee614e460cf804fcaf1dcd8b9e5f1de0ef406)) -* added event to DelegationAwareAToken ([f5fd1b6](https://www.github.com/aave/aave-v3-core/commit/f5fd1b654d598ff9b2170dafcba6d28f88a391ae)) -* added indexed to the ICreditDelegation event ([0a3d365](https://www.github.com/aave/aave-v3-core/commit/0a3d36546683949a6dc8002db814827507847abc)) -* replaced SafeERC20 with GPv2SafeERC20 ([fe4ae41](https://www.github.com/aave/aave-v3-core/commit/fe4ae41aa2bb1583b430595decc4fddd6e60d137)) - - -### Bug Fixes - -* Add comment to BorrowLogic ([2ae309d](https://www.github.com/aave/aave-v3-core/commit/2ae309dbad85dedf1313a898a0bd558eeb447b64)) -* add else ([4bdbd7f](https://www.github.com/aave/aave-v3-core/commit/4bdbd7f56b4bdf7d3fdf421a7a2f21a0cdcb7b31)) -* Add explicit access level for variables ([8fb2e3c](https://www.github.com/aave/aave-v3-core/commit/8fb2e3c3102bc42aab9aaec8f77a1bea6463b6da)) -* Add mode to FlashLoan event ([956c809](https://www.github.com/aave/aave-v3-core/commit/956c809749a83d4fa79ffa1cfc8d7bd06348b442)) -* Add natspec to `executeLiquidationCall` ([9bb5289](https://www.github.com/aave/aave-v3-core/commit/9bb5289465ffaf0edc32c6f733f4c7eccecf2f5a)) -* Add repay with atoken ux issue ([b464cf5](https://www.github.com/aave/aave-v3-core/commit/b464cf55fe9dbfa918b3832f033e635595212247)) -* Avoid finalizeTransfer with 0 value transfer ([d6bf261](https://www.github.com/aave/aave-v3-core/commit/d6bf261f4fc08bfd8bd1a4b3e3b4ed140430a01a)) -* Cache result to not recompute for event ([b342d2f](https://www.github.com/aave/aave-v3-core/commit/b342d2f7f0f9fc05b5e7d9dc21e17183219b6d19)) -* Change to in Pool for V2 compatibility ([932c5a0](https://www.github.com/aave/aave-v3-core/commit/932c5a0dc02c22f4a9c20384a9912e2780fcbae8)) -* Clean cumulateToLiqIndex and add comments ([d6e90dc](https://www.github.com/aave/aave-v3-core/commit/d6e90dcd92e2f1536323648fb66c018a8811d97d)) -* Fix `income` -> `debt` in `getNormalizedDebt` natspec. ([9e6b183](https://www.github.com/aave/aave-v3-core/commit/9e6b1831f3f814fca46e19d6761bda9a7cd07f66)) -* Fix differences between IPool and Pool ([8beefda](https://www.github.com/aave/aave-v3-core/commit/8beefda3d19c3814196052575332342a5b23be08)) -* Fix docstrings ([93c2d95](https://www.github.com/aave/aave-v3-core/commit/93c2d954937172dedd3a794a0e58627b7aaa1dc0)) -* Fix docstrings ([c55bb04](https://www.github.com/aave/aave-v3-core/commit/c55bb04725b4a1ed6c87a0f5092669d55e306afc)) -* Fix typo ([df40063](https://www.github.com/aave/aave-v3-core/commit/df400636ac915f19b642a830b8ba86969837ac2d)) -* Fix typo in setReserveFreeze function name ([da72c39](https://www.github.com/aave/aave-v3-core/commit/da72c391f8ddef9a200e5b9203c1cfbd29986ca6)) -* Fix variable name of event in ReserveLogic ([40b9bb8](https://www.github.com/aave/aave-v3-core/commit/40b9bb814e5b89e19b50cb73a274646901dd2a00)) -* Gas optimization UserConfiguration ([af00927](https://www.github.com/aave/aave-v3-core/commit/af009272000e82aa2af78ec871373a57e2f1dbf5)) -* Handle code style issues ([af3743b](https://www.github.com/aave/aave-v3-core/commit/af3743b108ebeca4f7185a79b6ce6d7ca988075c)) -* Improve code readability of ReserveLogic ([ae1476d](https://www.github.com/aave/aave-v3-core/commit/ae1476daf53cf24262fdd9628e0fa4df9bf15a47)) -* Improve readability of initial values of variables ([592b21d](https://www.github.com/aave/aave-v3-core/commit/592b21d831b0dc2a6e3e998701ea4e3a4b13c401)) -* Include 100% as valid premiums ([c6b3347](https://www.github.com/aave/aave-v3-core/commit/c6b33472ed4f2ba6ebcf5a0b1aa3826c066aa7bd)) -* Make test engine not stop at first failure ([84eaf29](https://www.github.com/aave/aave-v3-core/commit/84eaf29afeffb720194d95b6ed86cb91273bf763)) -* Move up event in IVariableDebtToken ([f536538](https://www.github.com/aave/aave-v3-core/commit/f536538e6b7d6f97b24ff353c32e301c1b11d1ec)) -* move up require ([d47afa2](https://www.github.com/aave/aave-v3-core/commit/d47afa2da264bb4ec81957ebdc787052ce7d0079)) -* Re-add `getUserCurrentDebtMemory()` ([7742985](https://www.github.com/aave/aave-v3-core/commit/7742985319be5df5a11d6740a712c2017f64dcf6)) -* Refactor variable calc in StableDebtToken ([4ed69b4](https://www.github.com/aave/aave-v3-core/commit/4ed69b4a8ad17cfc8defe19e7049db88f1cd0cf8)) -* Remove case, created separate issue ([0082fd8](https://www.github.com/aave/aave-v3-core/commit/0082fd82eacfe61f32efce03fe99f464a3992eec)) -* remove IAaveIncentivesController casting ([9805add](https://www.github.com/aave/aave-v3-core/commit/9805add3405965badb9803ab68c8b7f73b0989ab)) -* Remove redundant casting for block.timestamp ([941539f](https://www.github.com/aave/aave-v3-core/commit/941539f0a3b72598a0ff556ba2b5889cfe0f08ff)) -* Remove redundant unneeded variable ([703782c](https://www.github.com/aave/aave-v3-core/commit/703782cb7c1d353239bec219b474f3ee30b0c063)) -* Remove unneeded `delegator` param from delegationWithSig typehash ([dcf7c36](https://www.github.com/aave/aave-v3-core/commit/dcf7c36dc2df66283f29c72738872c1e3e992a43)) -* Remove unneeded imports in contracts ([48f9e89](https://www.github.com/aave/aave-v3-core/commit/48f9e89ee21fe0637e970fd1bbcd662c74ab5147)) -* Remove unneededv variable in cumulateToLiqIndex ([75e7fdc](https://www.github.com/aave/aave-v3-core/commit/75e7fdcd4cf9b5112bb22fb3c4e6b03b33db4907)) -* removed invalid imports ([659b82c](https://www.github.com/aave/aave-v3-core/commit/659b82cf93d3a032a9ad746a7f0fdf02f06ecd60)) -* rename admin variable ([5199283](https://www.github.com/aave/aave-v3-core/commit/5199283c5ac4e93260ad416920fb28aa8896ce5a)) -* Replace `rateMode` with `interestRateMode` and precise dataype ([806f161](https://www.github.com/aave/aave-v3-core/commit/806f16172bb718366417ef9e519b0fe5b9d04595)) -* Replace factor with multiplier for clarity ([085ad0c](https://www.github.com/aave/aave-v3-core/commit/085ad0c8df62ac60a25f74c722fcd822c1f09107)) -* Replace HALF_PERCENT with HALF_PERCENTAGE_FACTOR ([4fb45ec](https://www.github.com/aave/aave-v3-core/commit/4fb45ec34d4d86f75b94e2d284942ac69d62e8db)) -* Replace Helper.toUint128 with OZ SafeCast ([3916735](https://www.github.com/aave/aave-v3-core/commit/391673546fbf7de6199822b60a49787498a26978)) -* Rever simplification of cumulateToLiqIndex due to precision loss ([585c9c4](https://www.github.com/aave/aave-v3-core/commit/585c9c41525a8df7c6b13aa37fa07c860a03bd27)) -* set config map to zero on init ([ea40ee1](https://www.github.com/aave/aave-v3-core/commit/ea40ee1608b7ffe60ae03154403b77fdc20933de)) -* Simplify condition in SupplyLogic ([6487f29](https://www.github.com/aave/aave-v3-core/commit/6487f29892706390cae8fd46b10de24ca67281db)) -* Simplify cumulateToLiqIndex in ReserveLogic ([53a95c8](https://www.github.com/aave/aave-v3-core/commit/53a95c809764a3acdb6f6e5d1845aea0d7de5a27)) -* swap name ([ebd3622](https://www.github.com/aave/aave-v3-core/commit/ebd3622b28b18d8d7adbcd5f285a3c13a180db8f)) -* Typo in liquidation-emode.spec.ts ([97e0acc](https://www.github.com/aave/aave-v3-core/commit/97e0acc5515641ef936cbb3284b4e2f9811a27f6)) -* update admin to internal ([7d19d29](https://www.github.com/aave/aave-v3-core/commit/7d19d295c66c5e19c58cec87082e1905116dc196)) -* Update test with new delegationWithSig typehash ([fea83f3](https://www.github.com/aave/aave-v3-core/commit/fea83f39d433ff1e624a39878686ddf661eb66fe)) -* Use `next` prefix for isolation mode total debt ([5ffeecd](https://www.github.com/aave/aave-v3-core/commit/5ffeecdd6e376ff341d6f633e36be53c2cbc43b1)) - -## [1.8.0](https://www.github.com/aave/aave-v3-core/compare/v1.7.0...v1.8.0) (2021-12-16) - - -### Features - -* added natspec comments, changed function param names to uniform with the other functions ([dda5bde](https://www.github.com/aave/aave-v3-core/commit/dda5bde0b901df2fdadd41cba332652f20dc3796)) -* clarify mint and burn comment in interface ([03041ef](https://www.github.com/aave/aave-v3-core/commit/03041ef2189dbd5ed5344df09a6d3acf5caff0b6)) -* refactored setReserveBorrowing, setReserveStableRateBorrowing, fixed tests ([6749233](https://www.github.com/aave/aave-v3-core/commit/6749233881b49e7f1d93b991ce1b8f850382c5b7)) - - -### Bug Fixes - -* Add 0 division check to wadDiv and rayDiv. ([ea80f22](https://www.github.com/aave/aave-v3-core/commit/ea80f22e6aeb51d0eab96785113aa5b802346e9d)) -* Add better natspec for ConfiguratorLogic ([5cdfcdf](https://www.github.com/aave/aave-v3-core/commit/5cdfcdfe67ffbaccaf565385ad13588f99865145)) -* Add better natspec for EModeLogic ([816d566](https://www.github.com/aave/aave-v3-core/commit/816d566224b4df116016e60a7e841cb0c5826949)) -* Add comments about BaseCurrency to IPriceOracleGetter ([60ff953](https://www.github.com/aave/aave-v3-core/commit/60ff953ba9b4bdacb9a2acf5bbfcefd69e87e84d)) -* Add docstrings for SequencerOracle ([9557272](https://www.github.com/aave/aave-v3-core/commit/955727288ef62e0a1e59ffdd3babb0b211a70a40)) -* Add docstrings to PriceOracleSentinel ([368c77f](https://www.github.com/aave/aave-v3-core/commit/368c77f15e644e00e53a73f92294cf52a17d91b7)) -* Add event emission to natspec ([ec28a38](https://www.github.com/aave/aave-v3-core/commit/ec28a384fad9d42cc308c5a894358f81f11034bd)) -* Add explicit error message for LTV == 0 before division. ([d8d1694](https://www.github.com/aave/aave-v3-core/commit/d8d1694deb12a24f0638fb5990951f0daa574731)) -* Add functions docs of `IPoolAddressesProvider` ([36a543b](https://www.github.com/aave/aave-v3-core/commit/36a543b3856a075d197e108717f4aa020f06fa1c)) -* Add IAaveOracle interface ([ed03e30](https://www.github.com/aave/aave-v3-core/commit/ed03e3097aaae33c202d042bd6bb0f1d9a03eb26)) -* Add literal syntax to setEModeCategory ([4ab27c3](https://www.github.com/aave/aave-v3-core/commit/4ab27c3a78f882175032417019073b6574e28d91)) -* Add missing docstrings of the IACLManager ([84bcffc](https://www.github.com/aave/aave-v3-core/commit/84bcffce40ecfec73b43ce0f4263b60629fa9d87)) -* Add test and zero div check to percentageDiv ([d914c9d](https://www.github.com/aave/aave-v3-core/commit/d914c9dc4502e1f166d0c1cc26c7c95628d34db6)) -* Added `first` to natspec `_getFirstAssetAsCollateralId()` ([1b6a1df](https://www.github.com/aave/aave-v3-core/commit/1b6a1dfb80b6a254753af01fcfa60b9d8a891d62)) -* additional check in isUsingAsCollateralOne() to avoid revert if collateralData == 0 ([49638cb](https://www.github.com/aave/aave-v3-core/commit/49638cb0874050443281c6cb30959891b6d32268)) -* Change access control to setGracePeriod ([d9c2630](https://www.github.com/aave/aave-v3-core/commit/d9c26306b4f573422584453437c8f8d1b777f484)) -* Clean code style of FlashLoan mocks ([6fe84b6](https://www.github.com/aave/aave-v3-core/commit/6fe84b6bd385195e5d5cac299a1458e33489f643)) -* Clean code style of mocks ([60a03e3](https://www.github.com/aave/aave-v3-core/commit/60a03e38157ed8c64fab8efd073d72e183f17a7b)) -* Consolidate BorrowingOnReserve events into 1 ([110c5d0](https://www.github.com/aave/aave-v3-core/commit/110c5d01bd321be8f101202c5ca3c38822928701)) -* Enhance clarity of WadRayMath constants ([b7244c1](https://www.github.com/aave/aave-v3-core/commit/b7244c181f3649e94a6c8a085c1d3156556883f7)) -* Fix and clean halfWad and halfRay values ([5f5dff4](https://www.github.com/aave/aave-v3-core/commit/5f5dff43a826209bc22a8a4562dbbb40c782e06a)) -* Fix BridgeLogic natspec ([71be75e](https://www.github.com/aave/aave-v3-core/commit/71be75eb0362c214b4a28292455d9faaf473d24a)) -* Fix PoolAddresesProvider docstrings ([30d757f](https://www.github.com/aave/aave-v3-core/commit/30d757f45d4eec26285df513e9b914aa4964985d)) -* Fix typo in `IAaveOracle` natspec ([1f02c09](https://www.github.com/aave/aave-v3-core/commit/1f02c090b7922f9a08ad6e5bc29d350b2736060b)) -* Fix typo in `LiquidationLogic` natspec ([3729466](https://www.github.com/aave/aave-v3-core/commit/37294662bbb6a8ff77c0c48ad3d0d09e554ade8f)) -* Fix typos in docstrings ([167da26](https://www.github.com/aave/aave-v3-core/commit/167da26e4db23a9ca6b30940d633d4472a1348e4)) -* Fix typos in natspec docs ([e29d46f](https://www.github.com/aave/aave-v3-core/commit/e29d46f9ff816f085140a70fcb41d4785a1c85fd)) -* Format public immutable variable name with MACRO case ([c90b040](https://www.github.com/aave/aave-v3-core/commit/c90b04093f770e32febb3fb88e26a199c0b2316b)) -* increased the data size of id and i to uint16 ([3d7fc2b](https://www.github.com/aave/aave-v3-core/commit/3d7fc2bf8ff001d203e64bde826f3f77da552cea)) -* Make `_pool` public of AToken and DebtToken ([014da25](https://www.github.com/aave/aave-v3-core/commit/014da25b4f13ea9c83b468099e71b5eceff2f98c)) -* Make addressesProvider of AaveOracle public ([69b3eca](https://www.github.com/aave/aave-v3-core/commit/69b3ecacc7e953c43a32764b4bcaad0da1c822cb)) -* Make gracePeriod and sequencerOracle configurables ([3c6352f](https://www.github.com/aave/aave-v3-core/commit/3c6352fa3907407e46c1df6d9338cd638d974ece)) -* Make Pool `_addressesProvider` public ([762d79e](https://www.github.com/aave/aave-v3-core/commit/762d79e033be02a0a67dbf47447688de1cd08167)) -* Merge conflict in stable-debt-token.spec.ts ([78a6198](https://www.github.com/aave/aave-v3-core/commit/78a61982db5d58e0ee6a5ee0b3bcf2173a264a07)) -* Minor merge conflict ([0df5e80](https://www.github.com/aave/aave-v3-core/commit/0df5e80a4a7e983231b7cb23be458f53b3f572b6)) -* Move the optimization after the operation condition ([c6a785f](https://www.github.com/aave/aave-v3-core/commit/c6a785f2cd1f93f147a9c5a799648b61f4381541)) -* naming consistency and stable debt event fix ([7f17123](https://www.github.com/aave/aave-v3-core/commit/7f17123ee4c59157a1a6f02746dd9790e4420db8)) -* Optimize setUseReserveAsCollateral whenthere is no state change ([55445f2](https://www.github.com/aave/aave-v3-core/commit/55445f21ea27d8248ecad60a3230d28c48c9581a)) -* remove console.log ([e279cda](https://www.github.com/aave/aave-v3-core/commit/e279cda79676b2c6d92a4ccbb737d71dc062fee9)) -* Remove duplicated code in LiquidationLogic ([2189ba4](https://www.github.com/aave/aave-v3-core/commit/2189ba4446e843645ed3b2add8153881088bfbb4)) -* Remove unneeded comments ([9ec0ec4](https://www.github.com/aave/aave-v3-core/commit/9ec0ec4b79a29b060743bbdd700559d6d7159469)) -* Remove unneeded contract file ([6f480ec](https://www.github.com/aave/aave-v3-core/commit/6f480ecb2eb0325aabab25e6b902e83d22f77755)) -* remove unused variable ([87fc0bb](https://www.github.com/aave/aave-v3-core/commit/87fc0bb492df1ef82b71a765f48b9913024d2875)) -* Rename PoolConfigurator setter events ([53b40ce](https://www.github.com/aave/aave-v3-core/commit/53b40ce81d0b539be6b415ed75d1e419137b9fbc)) -* Rename setter functions names ([449f42d](https://www.github.com/aave/aave-v3-core/commit/449f42d91fd0c08342412f08e3e3b1f3638ba953)) -* set package-lock.json ([299d2f9](https://www.github.com/aave/aave-v3-core/commit/299d2f9ea3d62190004caca0dafa243089a262b3)) -* Typo in flashloanlogic natspec ([4e36f6f](https://www.github.com/aave/aave-v3-core/commit/4e36f6f2d58411c9bc51f59058a80349a171a3de)) -* Unify reserveCount and maxReserve to uint16 ([b6e2b35](https://www.github.com/aave/aave-v3-core/commit/b6e2b351f15cad9de45dcd3cf1e6a0686b64aad9)) -* update .npmrc ([9cfe79c](https://www.github.com/aave/aave-v3-core/commit/9cfe79c3752959c7a22fcfb07b74d4c960c8ccf2)) -* Update comments in validation-logic.spec.ts ([3b5c039](https://www.github.com/aave/aave-v3-core/commit/3b5c03973446c817860401ef255bcb5455d2676b)) -* Update executeRepay to compute interest correctly for repaying with aTokens ([abf0e0c](https://www.github.com/aave/aave-v3-core/commit/abf0e0cf6da5bd9f6d91c505fda3580e4467c87e)) -* Update function naming ([594b929](https://www.github.com/aave/aave-v3-core/commit/594b92985fb62831e8b4ee72a6ad4dfd5730eb05)) -* Update natspec docs for FlashLoanLogic ([4b02b3e](https://www.github.com/aave/aave-v3-core/commit/4b02b3e6cf2f4f1c3f7f583652b3b9ff3a41b94e)) -* Update variable packing of `ReserveData` ([7765624](https://www.github.com/aave/aave-v3-core/commit/77656242fd9e61c2080f938e7514d719c0015a91)) -* Update wording of token update functions in ConfiguratorLogic ([2dd1551](https://www.github.com/aave/aave-v3-core/commit/2dd15513c1930d739aff0b14e2c94770b0e38004)) -* use @aave/deploy-v3@1.7.1 library and load typechain locally instead of deploy-v3, to fix unsynced artifacts ([6904746](https://www.github.com/aave/aave-v3-core/commit/690474641fef8efa0dd95f645cb3e9b8d4eab3e5)) -* Use `checkNoSuppliers` instead of `CheckNoDepositors` ([88aff43](https://www.github.com/aave/aave-v3-core/commit/88aff43cebb660689c6fcdd84560a5ebe9f98911)) -* use already calculated value instead of re-calculating ([c0743f9](https://www.github.com/aave/aave-v3-core/commit/c0743f95890eb6e6c0ee873775b81aa952b55753)) -* Use cache to get `aTokenAddress` in bridge logic ([e41ec39](https://www.github.com/aave/aave-v3-core/commit/e41ec395182296ee1226ed4b57914abdd3321fa0)) -* Use literal syntax for struct params ([7baf196](https://www.github.com/aave/aave-v3-core/commit/7baf196bf51ad60a09d477e325537fdffe6f8465)) - -## [1.7.0](https://www.github.com/aave/aave-v3-core/compare/v1.6.0...v1.7.0) (2021-12-01) - - -### Features - -* Add decimals to MockAggregator to match Chainlink Aggregator interface ([4cf1dac](https://www.github.com/aave/aave-v3-core/commit/4cf1dacd70f11a0c7103ade68bb05c907e846b2d)) -* added handleRepayment() in flashloan and liqCall ([6c43820](https://www.github.com/aave/aave-v3-core/commit/6c438201c6ee95b6dc3895b904213b975ce3905d)) - - -### Bug Fixes - -* fixed handleRepayment() in flashloan ([80a19bb](https://www.github.com/aave/aave-v3-core/commit/80a19bb7e0d92af0604e67dc6586a0f376bf91a4)) - -## [1.6.0](https://www.github.com/aave/aave-v3-core/compare/v1.5.2...v1.6.0) (2021-11-27) - - -### Features - -* reduced the number of optimizer runs ([8562a91](https://www.github.com/aave/aave-v3-core/commit/8562a911d04ede756a703be60f985d1916805d46)) -* reorganized PoolStorage for gas savings ([87776f7](https://www.github.com/aave/aave-v3-core/commit/87776f757d58ddf20b99cdce752e068602f38389)) - - -### Bug Fixes - -* Add `useATokens` param to `Repay` event ([beec3f8](https://www.github.com/aave/aave-v3-core/commit/beec3f86bf1e4024dc74583bb386851b3d212963)) -* Add additional constraint to use `eModeAssetPrice` ([ec42295](https://www.github.com/aave/aave-v3-core/commit/ec422953ca60110d98aa3c7c8930f70d88d5b294)) -* Add check to `Pool::initializer()` ([8f2b426](https://www.github.com/aave/aave-v3-core/commit/8f2b426962a11c3e289301a341bcdf170b3e763f)) -* Add clean ups to VariableDebtToken test ([bc4f314](https://www.github.com/aave/aave-v3-core/commit/bc4f314c85ac59ea84244108e6fc6f7c22d3fb74)) -* Add cleanup to StableDebtToken test ([d1eeaa5](https://www.github.com/aave/aave-v3-core/commit/d1eeaa51d19b1e45bfa564fb51e5bd69623450db)) -* Add cleanups in eMode tests ([fbf80a8](https://www.github.com/aave/aave-v3-core/commit/fbf80a8092c5807a281ab95b6e54f85790dda9b4)) -* Add extra input to MockPoolInherited test deployment ([e7944dc](https://www.github.com/aave/aave-v3-core/commit/e7944dc1f92ea6fada5a31031d3628c7682da0d7)) -* Add minor gas optimization for executeFlashLoan ([0d737f5](https://www.github.com/aave/aave-v3-core/commit/0d737f5041649a27a2d97148e625e1d3b211d0e3)) -* Add natspec comments to IncentivizedERC20 ([722a8e7](https://www.github.com/aave/aave-v3-core/commit/722a8e7b5c3a2e14f639e6491cb264b8d305508a)) -* Add precision to debt ceiling comment ([3d43c02](https://www.github.com/aave/aave-v3-core/commit/3d43c02a8d014e33619ad5d375d1baeac4448cb8)) -* Add test exploiting pricing issue ([3457fb8](https://www.github.com/aave/aave-v3-core/commit/3457fb829d094a45f6d056c9893ad0c3b1bef465)) -* Add test for incorrect init of pool ([b3cebaf](https://www.github.com/aave/aave-v3-core/commit/b3cebaf6180340378e37257c6ac4e4adab444e2f)) -* Bumped Node JS version of Dockerfile to 16 stable version. Update package-lock. ([f0c8787](https://www.github.com/aave/aave-v3-core/commit/f0c8787725ff3fc77b02cf92928f6e79207a93ff)) -* Change visibility of `name()` in IncentivizedERC20 ([467a5c1](https://www.github.com/aave/aave-v3-core/commit/467a5c110552bf4ec71449cccc2bb8fd9201806b)) -* Do multiplication before devision for `currentStableBorrowRate` ([ca177fb](https://www.github.com/aave/aave-v3-core/commit/ca177fbe5860ae360e4ebf8e93712fa84b1ab2e4)) -* Fix typo on credit delegation test case ([0b6a65b](https://www.github.com/aave/aave-v3-core/commit/0b6a65bb109665b1d74bcdc5c5fd04c38dfa4721)) -* Handle minor merge issue ([36488c9](https://www.github.com/aave/aave-v3-core/commit/36488c9e86a15bc66047ddf09505dbcf29f79324)) -* Make `_addressesProvider` immutable in `Pool` ([b41feab](https://www.github.com/aave/aave-v3-core/commit/b41feabd504c8da527db7fc1e3867519b2c7334e)) -* Make `_nonces` internal and add `nonces` getter ([f3d1817](https://www.github.com/aave/aave-v3-core/commit/f3d18176f6250ac255287acaf86aae8f04c22e77)) -* Make `MAX_RESERVES_COUNT` constant ([04ced7f](https://www.github.com/aave/aave-v3-core/commit/04ced7fd5582af588ebdcf4d2f755db8998d1b75)) -* MockPoolInherited wrong return value on `MAX_NUMBER_RESERVES` ([b724a73](https://www.github.com/aave/aave-v3-core/commit/b724a73790b8fcad67e33df10217da448a4cf953)) -* Move `_nonces` to IncentivizedERC20 ([54eb024](https://www.github.com/aave/aave-v3-core/commit/54eb024bef45a8d77a5f856cf1866024d282da7e)) -* Move list length check to front of `validateFlashloan` function ([f485be5](https://www.github.com/aave/aave-v3-core/commit/f485be5d9f87d85cef65d816e708741437586280)) -* Pair `_avgStableBorrowRate` and `_totalSupplyTimestamp` ([b6c9372](https://www.github.com/aave/aave-v3-core/commit/b6c937292dd7bb2c91eec05940170ac902701a09)) -* Refactor tokens, move domain separator function to IncentivizedERC20 ([c033f9d](https://www.github.com/aave/aave-v3-core/commit/c033f9d4d83c08f75b63b972ca02fca27d6afc45)) -* Removal of unneeded struct ([262dc7a](https://www.github.com/aave/aave-v3-core/commit/262dc7a525b3e6794b96b904189696773e3787c5)) -* Remove unneeded fields from `AvailableCollateralToLiquidateLocalVars` ([f9088b6](https://www.github.com/aave/aave-v3-core/commit/f9088b65a6b3a5c6875f0176f32bda99caf63ee9)) -* setup npm registry without file ([91fdc99](https://www.github.com/aave/aave-v3-core/commit/91fdc99b02dffb4924c5078d894f2ca180d8e23c)) -* Simplify `_getFirstAssetAsCollateralId()` ([dffc2f6](https://www.github.com/aave/aave-v3-core/commit/dffc2f63275c6d4be780dc4199adace662afb585)) -* source setup env for coverage ([fd7de34](https://www.github.com/aave/aave-v3-core/commit/fd7de34862f678aeac426634ba48b1c0afd65f7d)) -* Update `user` to `onBehalfOf` for VariabelDebtToken ([7ff840f](https://www.github.com/aave/aave-v3-core/commit/7ff840f36a12ae19372c1f83b9d2ee01ae30de5b)) -* Update package.json ([49a8c39](https://www.github.com/aave/aave-v3-core/commit/49a8c39e6137f31aa7a4e05a6ca2556532ddab20)) -* update v3 deploy dev dependency to latest deployment scripts ([2aa8f5c](https://www.github.com/aave/aave-v3-core/commit/2aa8f5c3364c518890a12366f4ed6c8747dfe4bc)) -* update v3 dev dependencies ([9cb6a47](https://www.github.com/aave/aave-v3-core/commit/9cb6a47393d676d16bd928e8cce5f90db14892ad)) -* Use cached value for asset unit instead of recomputation ([335927c](https://www.github.com/aave/aave-v3-core/commit/335927c0493772f68968feb0477d0fad348e5b59)) - -### [1.5.2](https://www.github.com/aave/aave-v3-core/compare/v1.5.1...v1.5.2) (2021-11-12) - - -### Bug Fixes - -* fix releasepipeline ([5dc309d](https://www.github.com/aave/aave-v3-core/commit/5dc309d08120d3cf2ddea44e53f56b6c29fdfca6)) - -### [1.5.1](https://www.github.com/aave/aave-v3-core/compare/v1.5.0...v1.5.1) (2021-11-12) - - -### Bug Fixes - -* fix ci workflow file ([5520c8f](https://www.github.com/aave/aave-v3-core/commit/5520c8fb3ab959f3167755cee7642e3ea184eac9)) - -## [1.5.0](https://www.github.com/aave/aave-v3-core/compare/v1.4.0...v1.5.0) (2021-11-12) - - -### Features - -* updated solidity version ([7891ac6](https://www.github.com/aave/aave-v3-core/commit/7891ac6a9063e9d042333aa16589126e10fcb67d)) - - -### Bug Fixes - -* Add comment + gasoptimization for flashloans ([546fe84](https://www.github.com/aave/aave-v3-core/commit/546fe84771345d612d42a91ef434188194b26a3b)) -* Add comment to elaborate on unusual flow in flashloan simple ([5f41c07](https://www.github.com/aave/aave-v3-core/commit/5f41c07c19e36e195114c63702808607de6a5f9c)) -* Add configuration cache to save gas ([e5b9c2a](https://www.github.com/aave/aave-v3-core/commit/e5b9c2a8e52084f58548d11609ccebdf0e40bf52)) -* Fix reentrance attack in `flashLoanSimple` ([1e98320](https://www.github.com/aave/aave-v3-core/commit/1e98320efce9e4a2de8da59c6c416e49a10d9ce5)) -* Move `interestRateMode` cast below state update ([9732e6f](https://www.github.com/aave/aave-v3-core/commit/9732e6f1e61fa010401126651c615e911da2af57)) -* Simplify flow for `mintToTreasury` ([8385f6b](https://www.github.com/aave/aave-v3-core/commit/8385f6b6c6dfd2e3e0b02b09ca7a8b6970ba6868)) - -## [1.4.0](https://www.github.com/aave/aave-v3-core/compare/v1.3.0...v1.4.0) (2021-11-09) - - -### Features - -* added public debt ceiling decimal constant, added getter to DataProvider ([52918e2](https://www.github.com/aave/aave-v3-core/commit/52918e2f98e3e9ce65fca8df19596ec577213b26)) - -## [1.3.0](https://www.github.com/aave/aave-v3-core/compare/v1.2.1...v1.3.0) (2021-11-09) - - -### Features - -* added borrowable in isolation configuration, fixed tests ([8755279](https://www.github.com/aave/aave-v3-core/commit/87552797a8776f38e869aff7e0c3a1f9d70a7950)) -* Added missing legacy methods ([3a2fc3f](https://www.github.com/aave/aave-v3-core/commit/3a2fc3f50dbcc7f3552554b04f6b33f51657a107)) -* finalized implementation, fixed tests ([c9bb800](https://www.github.com/aave/aave-v3-core/commit/c9bb8002498e8638b63528d63cea4d8fefcbcdb2)) -* initial implementation ([043bcde](https://www.github.com/aave/aave-v3-core/commit/043bcdec992a7196348881fa3bfef1ac8cb9e0b7)) - - -### Bug Fixes - -* improved condition in rayToWad() ([3eec7b3](https://www.github.com/aave/aave-v3-core/commit/3eec7b3093249e6d07861434298ff0e9716c3c44)) - -### [1.2.1](https://www.github.com/aave/aave-v3-core/compare/v1.2.0...v1.2.1) (2021-10-19) - - -### Bug Fixes - -* Added view to getEModeCategoryData method in pool interface ([b3ebdcc](https://www.github.com/aave/aave-v3-core/commit/b3ebdcc53fe0220285cbd42ada2240ffbbaf9158)) - -## [1.2.0](https://www.github.com/aave/aave-v3-core/compare/v1.1.0...v1.2.0) (2021-10-18) - - -### Features - -* Add `onlyAssetListingOrPoolAdmins` modifier to `setAssetSources` ([6bb8a1c](https://www.github.com/aave/aave-v3-core/commit/6bb8a1c06a1167941068656fec64bfd9ea18c0ce)) -* Add bridge protocol fee + fix tests for update ([bc4b554](https://www.github.com/aave/aave-v3-core/commit/bc4b554403b245bbcb1be3d2b4546d001a9175e7)) -* Add simple flashloan of 1 asset ([dbc5c9e](https://www.github.com/aave/aave-v3-core/commit/dbc5c9e1a9f3f8913ab8f1da16844ac4e62caf86)) -* added setIncentivesController ([8c027f4](https://www.github.com/aave/aave-v3-core/commit/8c027f4048bfa8c0bd859296e441906e9f3c0de3)) -* added the data provider to the addresses provider ([5f3abbc](https://www.github.com/aave/aave-v3-core/commit/5f3abbc8eaf216603ba2dfbd007ef5452905e50d)) -* finalize implementation ([1e72d0b](https://www.github.com/aave/aave-v3-core/commit/1e72d0bcf5dd4a4facefa716f095fc3d97c02f22)) -* fixed calculations in ValidationLogic and BorrowLogic ([5b507bd](https://www.github.com/aave/aave-v3-core/commit/5b507bd8b911e1a3a5cd8529413a3c6071a0ebb7)) -* fixed setDebtCeiling, added tests ([6ef9683](https://www.github.com/aave/aave-v3-core/commit/6ef968352655ac9e958ddf53ab0748e68e2160a6)) -* increased debt ceiling field capacity ([541f970](https://www.github.com/aave/aave-v3-core/commit/541f97056bb7e4fdb1f8645c386b68b9818ae7a4)) -* refactored PoolDataProvider functions in the addresses provider, fixed _checkNoLiquidity ([10300d4](https://www.github.com/aave/aave-v3-core/commit/10300d40832cfb94df83064879036e36994b57a4)) -* refactored the pool variable to immutable in atoken/debt tokens ([8e4d226](https://www.github.com/aave/aave-v3-core/commit/8e4d2265edd7f322e785a10ae61f67ded93d6fcb)) -* renamed simpleFlashloan and data structure ([9cc4d0c](https://www.github.com/aave/aave-v3-core/commit/9cc4d0c301325d1b113fb6ebaa51a0087d811c75)) -* Uniform permission of `AaveOracle` ([f471b0f](https://www.github.com/aave/aave-v3-core/commit/f471b0f9156cb93f1ec70fc94961d900a3b6927c)) - - -### Bug Fixes - -* Add `getActive` check on assets in flashloan. ([740aeaf](https://www.github.com/aave/aave-v3-core/commit/740aeafdee25cb48fbf7a6a170ccc7893857c6ab)) -* added public vars to interface for periphery usage ([8af6d0a](https://www.github.com/aave/aave-v3-core/commit/8af6d0aed5de659676db5b920267596454d8678d)) -* added view to the getDataProvider function interface ([0e6ee36](https://www.github.com/aave/aave-v3-core/commit/0e6ee361604ad0309a1cf83abd40c82d41bb9611)) -* correct package lock ([7965e0e](https://www.github.com/aave/aave-v3-core/commit/7965e0e4c264d63b71fc357b8de16cd06d6615a4)) -* Fix 0.8.7 version throughout the contracts ([6d97be8](https://www.github.com/aave/aave-v3-core/commit/6d97be80c2ba3c9d608bb690e4b5e1dacb174c07)) -* fix calculation bug in isolation mode ([8de2424](https://www.github.com/aave/aave-v3-core/commit/8de2424d475ac707c4b51e0b7bec5674746f5049)) -* Fix convention naming for constants ([193e3ab](https://www.github.com/aave/aave-v3-core/commit/193e3ab8b4255b0f152bae2a98530b812d2b3c53)) -* Fix declaration shadowing of mock contract ([7872ecb](https://www.github.com/aave/aave-v3-core/commit/7872ecbf67db4ed2e0e2314aebdb2919b692974a)) -* Fix doc in `StableDebtToken` ([9494299](https://www.github.com/aave/aave-v3-core/commit/9494299d7f9652e2c20adf5e03f42f8dcc4cfaf1)) -* Fix inheritance of mock contracts ([5bb62ad](https://www.github.com/aave/aave-v3-core/commit/5bb62ad59ddd97c1444d6d28f9b8764889238c08)) -* Fix simple flash loan test to use new function name ([9036580](https://www.github.com/aave/aave-v3-core/commit/9036580d7e1e6d5302d984f1fc6e82ff01ee3bfe)) -* Fix stack too deep for unoptimized compile of PoolConfigurator ([ef14f03](https://www.github.com/aave/aave-v3-core/commit/ef14f031e0a20bd7284e0a5ff96c889d3a005925)) -* fixed condition on supply and transfer, added tests ([6081003](https://www.github.com/aave/aave-v3-core/commit/6081003fd6bc09c27aa5dfb7642dea3a1051b122)) -* fixed isolation mode condition ([9672442](https://www.github.com/aave/aave-v3-core/commit/96724422b59517b0307d746a71c8f609208a4317)) -* fixed the calculation for isolationModeTotalDebt ([68bf644](https://www.github.com/aave/aave-v3-core/commit/68bf644803a1d89ac5f650b2031a1896bf7fd5e0)) -* Follow `check-effects-interactions` pattern more strictly ([7e7980a](https://www.github.com/aave/aave-v3-core/commit/7e7980a19dee98ecca7f13767fcc192ae0629bfb)) -* Mark the initialization functions as `external` ([e037467](https://www.github.com/aave/aave-v3-core/commit/e037467b555dd83a3419ee0bd8f1743bfa4b1551)) -* Move flashloans to separate library ([9308e97](https://www.github.com/aave/aave-v3-core/commit/9308e9797b1097334df7cf4745a335804b229dd0)) -* package lock with correct node version ([3d2f5b6](https://www.github.com/aave/aave-v3-core/commit/3d2f5b61057f06f3990951e86cd8017b1b4fa6bf)) -* Reintroduced check for max repayment on behalf ([c351627](https://www.github.com/aave/aave-v3-core/commit/c351627cfc218b99c9f0354c58cefb9edb2e68a2)) -* Remove comment from `FlashLoanLogic` ([774c326](https://www.github.com/aave/aave-v3-core/commit/774c326a4b128f3816e6c2f4a924f6f8a5adc460)) -* Remove old call ([a82d303](https://www.github.com/aave/aave-v3-core/commit/a82d3039653ec9574a6c9ae1637307fcfb1a63da)) -* Remove unneded return value of `AToken.transferUnderlyingTo` ([5f30b38](https://www.github.com/aave/aave-v3-core/commit/5f30b38dd5b5a719c72da466ac56aac3a407fd7c)) -* Remove unneded use of `SafeMath` ([a9584f8](https://www.github.com/aave/aave-v3-core/commit/a9584f84e2acf11ec1b7cdb09b6f5fe0b1ff5873)) -* Remove unneeded check at validateRepay ([6d3d73f](https://www.github.com/aave/aave-v3-core/commit/6d3d73ff6cbde45ac13065cae1af799888ef524a)) -* Remove unneeded storage variable from PoolConfigurator ([af8f695](https://www.github.com/aave/aave-v3-core/commit/af8f695aa371cb8e6d7a3a9ac0fac53da07a412e)) -* Remove unneeded use of function params ([d0d8980](https://www.github.com/aave/aave-v3-core/commit/d0d898003791c8f3df184a12e070f25e4dbad9ff)) -* Remove unused `PC_INVALID_DEBT_CEILING_ASSET_ALREADY_SUPPLIED` ([c68b67a](https://www.github.com/aave/aave-v3-core/commit/c68b67a8843e12da02b762cff4e73935e2d42d5f)) -* Remove unused imports from BorrowLogic ([7b019c0](https://www.github.com/aave/aave-v3-core/commit/7b019c0fdbc1e5daf6e9214a03bcf43b979343c6)) -* Remove unused inports from FlashLoanLogic ([0aa3a39](https://www.github.com/aave/aave-v3-core/commit/0aa3a3926e5a0e3bc97c31d72643dd51fbdd17f1)) -* Remove unused variable + readability ([00c2e66](https://www.github.com/aave/aave-v3-core/commit/00c2e66d78451be2f0874586e9357915359ad682)) -* Rename `_checkNoLiquidity` to `_checkNoDepositors` ([95fb785](https://www.github.com/aave/aave-v3-core/commit/95fb7853a0e216e2716a5ed3cdd14eb134120ad5)) -* Rename arguments for `backUnbacked` in library ([6ca57a1](https://www.github.com/aave/aave-v3-core/commit/6ca57a1fb0067c265b2697f52721e412a2342961)) -* Rename Percentage to BPs for argument in `backUnbacked` ([94eaf83](https://www.github.com/aave/aave-v3-core/commit/94eaf83df951a134a70add4c5fdc326db806a356)) -* Replace assembly for chainId ([777d04a](https://www.github.com/aave/aave-v3-core/commit/777d04a1bd1790e768f474e9ae68590d1adf7e6e)) -* Set `MAX_VALID_DEBT_CEILING` = `2^40 - 1` ([fa4c485](https://www.github.com/aave/aave-v3-core/commit/fa4c485a53cd497cf58e5a772a171ee0fb5ecbe2)) -* Update `calculateCompoundedInterest` to increase precision ([dcbb583](https://www.github.com/aave/aave-v3-core/commit/dcbb583231d57790c1decceaa6a5f73d852734ad)) -* Update comments in FlashLoanLogic ([7fee95c](https://www.github.com/aave/aave-v3-core/commit/7fee95c0608bdf87a7535b62e5495585af2840b4)) -* Update doc for `getDebtCeiling` ([3d0e0cb](https://www.github.com/aave/aave-v3-core/commit/3d0e0cb742ec9a36782db24c0b976377c71506ce)) -* Update IPool doc for `backUnbacked` ([6ffc157](https://www.github.com/aave/aave-v3-core/commit/6ffc15703175de2974b957c98d5663f001f71251)) -* Update precision in isolationDebt check ([7fbf7b6](https://www.github.com/aave/aave-v3-core/commit/7fbf7b67080ffe54d0d235ff1a686f45ec9c530b)) -* update the max MAX_VALID_DEBT_CEILING ([16d9aa8](https://www.github.com/aave/aave-v3-core/commit/16d9aa8a0e7dae3edd59ca3012523b7eefe2ef9b)) -* Update visibility of tokenization ([128a947](https://www.github.com/aave/aave-v3-core/commit/128a947d91ccca05645e6f2a40f2917c977e7d8f)) -* updated hardhat config ([2129dc0](https://www.github.com/aave/aave-v3-core/commit/2129dc0cc45de1895a0a030e5abf9174730fd303)) - -## [1.1.0](https://www.github.com/aave/aave-v3-core/compare/v1.0.3...v1.1.0) (2021-09-28) - - -### Features - -* Add `unbackedMintCap` to control unbacked atokens minting ([bde09e3](https://www.github.com/aave/aave-v3-core/commit/bde09e30dea092f442c2bbf14a94bb04e15dea62)) -* Add asset listing admin role ([3c3cd50](https://www.github.com/aave/aave-v3-core/commit/3c3cd50873c379d1b126c523039a36532ae16f1c)) -* Add eMode category getters on Pool ([1e5a4e2](https://www.github.com/aave/aave-v3-core/commit/1e5a4e26e1c9d6b2084dbbe9936d1c60db485249)) -* Add flag for OperationValidator at ReserveConfig, add renaming ([6515d1d](https://www.github.com/aave/aave-v3-core/commit/6515d1de492f9532363b6f303ffd6c6a810bd175)) -* Add getReserveEModeCategory at DataProvider ([268dac1](https://www.github.com/aave/aave-v3-core/commit/268dac16779745fc54bbef9b7a11f5c563cdae37)) -* Add initial contract to validate operations ([d6af2e5](https://www.github.com/aave/aave-v3-core/commit/d6af2e5caa9ab714bb7091ee5553a8582ec9cf2c)) -* Add new onlyAssetListingOrPoolAdmin for initReserves ([9d36fa5](https://www.github.com/aave/aave-v3-core/commit/9d36fa56327e110c1d954b183046e1ea983b55a6)) -* Add test cases ([0814ac2](https://www.github.com/aave/aave-v3-core/commit/0814ac29f5318e0f7eca0a02cf523c684c1bc74b)) -* Add test cases for category emode registration ([31ab296](https://www.github.com/aave/aave-v3-core/commit/31ab296db37e0e934b761cf5527c609c0e7d90fc)) -* Add tests for edge cases of `supply` function ([30d5f83](https://www.github.com/aave/aave-v3-core/commit/30d5f83d1478925865d175824fafd0fef20e9d89)) -* Add tests for the new unbackedMint cap control ([ad92076](https://www.github.com/aave/aave-v3-core/commit/ad9207672a66f0e9c9bff5c43b77ee84ba96aadc)) -* added optimal stable to variable debt ratio ([e0a9756](https://www.github.com/aave/aave-v3-core/commit/e0a9756822a42f8d990ee4ce466b9300b1f3f6eb)) -* added validation and events on eMode categories configuration ([fdf483b](https://www.github.com/aave/aave-v3-core/commit/fdf483bd70d95146e12d781bf55875e72b0137e3)) -* Initial OperationalValidator integration ([5088148](https://www.github.com/aave/aave-v3-core/commit/5088148abd402153535180ddd6a3841b8e6b9198)) -* refactored InterestRateStrategy, fixed conditions ([5196636](https://www.github.com/aave/aave-v3-core/commit/51966363ae3ce6cab7a532d3f2b3ab5180295046)) -* removal of the rate oracle, initial implementation, tests fixed ([1f5b953](https://www.github.com/aave/aave-v3-core/commit/1f5b9530b39a6c5ea1f8edbdfdf3d34b5c43192f)) -* Rename `OperationalValidator` to `PriceOracleSentinel` ([9004f49](https://www.github.com/aave/aave-v3-core/commit/9004f49775fa4c57b07a259f3b660298cdef855c)) - - -### Bug Fixes - -* Add additional checks to liquidation tests ([e06c74f](https://www.github.com/aave/aave-v3-core/commit/e06c74fceeeb33211363e0cb1cf0e2f5549933f4)) -* Add check for previous index ([3cfc67c](https://www.github.com/aave/aave-v3-core/commit/3cfc67c9c9a9dffb78ee63aed9e2c48fa9c8a75b)) -* Add checks for avaiable liquidity in liqudations ([80cb24d](https://www.github.com/aave/aave-v3-core/commit/80cb24ddd72cd075c488f16f1a697e907ece6d30)) -* Add cleanups and fixes to tests ([ccd5a96](https://www.github.com/aave/aave-v3-core/commit/ccd5a961e2e0eb6d73d5f0e696383b762daf1f3e)) -* Add fixes to OperationalValidator contracts ([829be88](https://www.github.com/aave/aave-v3-core/commit/829be8826c84fa67fce6745b5768dbee5127e5e4)) -* Add tests for `ASSET_LISTING_ADMIN` role ([84aa268](https://www.github.com/aave/aave-v3-core/commit/84aa26830124fee2fa4479e8ed3fc16ccbd38024)) -* Cap supply utilization at borrow utilization ([5e79c48](https://www.github.com/aave/aave-v3-core/commit/5e79c48f9d9d10492166a8801f34f0a73114affb)) -* Fix `supply` function error at `SupplyLogic` lib. ([6c112e8](https://www.github.com/aave/aave-v3-core/commit/6c112e89a271003acb8ed3a33fcb6a9f9bc2c196)) -* Fix docs of `ACLManager` contract ([acfebe8](https://www.github.com/aave/aave-v3-core/commit/acfebe8e685e1b980fc74be5f9f16d73ea4aeeec)) -* Fix docs of OperationValidator contract ([213094c](https://www.github.com/aave/aave-v3-core/commit/213094cebf281c3d2e84affcfc448b74677cca0c)) -* Fix duplicated code at `validateHF` ([6a30bbb](https://www.github.com/aave/aave-v3-core/commit/6a30bbb46cad3d1330db5174f47dcc0dc7b169c2)) -* Fix liquidityAdded in BridgeLogic backUnbacked ([68764ee](https://www.github.com/aave/aave-v3-core/commit/68764ee1d539495f6beaf3df545806f466e710fd)) -* Fix package-lock ([5e37eeb](https://www.github.com/aave/aave-v3-core/commit/5e37eeba93ee371261286322d757f1a6fb113d01)) -* Fix some comments on contracts ([973e644](https://www.github.com/aave/aave-v3-core/commit/973e6447bb49981f66791fa3be48475a9c0e4b25)) -* Fix tests ([506d339](https://www.github.com/aave/aave-v3-core/commit/506d339f6fc958484b3b09095bb5bebb6ee5a230)) -* fixed borrow condition, removed conditions on transfer/deposit/use as collateral ([8dbe7e4](https://www.github.com/aave/aave-v3-core/commit/8dbe7e4d186c834eca1a80e3d01d9d939ddd2038)) -* fixed calculation of the avg ltv/liq threshold in eMode ([0534f47](https://www.github.com/aave/aave-v3-core/commit/0534f47dfc16ba3a3f7f1c274b80de662ca54b72)) -* fixed error after merging the main branch ([83f385f](https://www.github.com/aave/aave-v3-core/commit/83f385fc1fdcac9f87aaa94614bcda3020578fb0)) -* fixed logic for the stable rate offset, fixed tests ([c319929](https://www.github.com/aave/aave-v3-core/commit/c31992993519a5b964656093b034de6b4fa91a3d)) -* fixed validateSetUserEMode ([750fd34](https://www.github.com/aave/aave-v3-core/commit/750fd349e8c52726d505844fa47376c8784d7109)) -* Improve readability and fix docs of `BridgeLogic` ([2c48e7e](https://www.github.com/aave/aave-v3-core/commit/2c48e7e64cc7a2de53e54865b11ecefbe0acedea)) -* Initial interest rate fix ([350c528](https://www.github.com/aave/aave-v3-core/commit/350c528354d3cbb55f66458b812395d31fc12d95)) -* Move `isBorrowAllowed` higher up in `validateBorrow` ([93a447c](https://www.github.com/aave/aave-v3-core/commit/93a447c2a18e17a5067b47dbe7e724970d9eff9b)) -* npm dependencies ([2a366f7](https://www.github.com/aave/aave-v3-core/commit/2a366f7f708803137c7dab2916e524709a7afc83)) -* refactored PriceOracleSentinel, valdiation conditions, removed reserve config ([e112db9](https://www.github.com/aave/aave-v3-core/commit/e112db92acbaf3a41f2197a7b270b5b42d1586b7)) -* Remove AToken totalSupply from interest computation ([9b779e9](https://www.github.com/aave/aave-v3-core/commit/9b779e9ead03fc919f7fa6f38c6dbe361d47198f)) -* Remove deployOperationalValidator import ([3152285](https://www.github.com/aave/aave-v3-core/commit/3152285ae7e7bbb126ff41a403bd6f7a13767607)) -* Remove deprecated code of contracts ([282b629](https://www.github.com/aave/aave-v3-core/commit/282b6297e7276b579cd59ff182d670ebf9aeca12)) -* removed unnecessary overflow check ([4d9861d](https://www.github.com/aave/aave-v3-core/commit/4d9861d94d5531104f95af625cffead15f603d4d)) -* removed useAsCollateral flag in supply ([891da9b](https://www.github.com/aave/aave-v3-core/commit/891da9bdeccc6c09e8b65472618370725030fbc9)) -* Rename variable `rate-strategy.spec.ts` ([f7fbdac](https://www.github.com/aave/aave-v3-core/commit/f7fbdac5fa0eea659ba4da6c5f87eae6e82fec51)) -* Revert renaming back to SequencerOracle ([53ab533](https://www.github.com/aave/aave-v3-core/commit/53ab533d0c4c56d59002e4efcc8f3c4ae5c44f10)) -* Update `rate-strategy.spec.ts` to use strategy two ([31335e0](https://www.github.com/aave/aave-v3-core/commit/31335e0ff373d343b7bb2887a499e66ea2b7cff4)) -* Update and fix contracts docs ([171acdf](https://www.github.com/aave/aave-v3-core/commit/171acdf711b243234c1baa350c30485e58f9f4f3)) -* Update comments in IPool ([3e32f07](https://www.github.com/aave/aave-v3-core/commit/3e32f07f9966c97242035580f1f6672bba27cd7a)) -* Update operation-validator reserve getters ([bcdc91d](https://www.github.com/aave/aave-v3-core/commit/bcdc91d134403f49b15f13a07c996e22ff7da844)) -* Update tests for new interest rate calculation ([a37d9a1](https://www.github.com/aave/aave-v3-core/commit/a37d9a10591b5b39f63731a3d8257d024a540538)) -* Upgrade library to make it work with london hf. ([c1e6fec](https://www.github.com/aave/aave-v3-core/commit/c1e6fecbcffa7d6160a896ec00d3cedb248cfa8c)) -* use nextVariableBorrowIndex instead of nextLiquidityIndex on repayValidation ([cf9007c](https://www.github.com/aave/aave-v3-core/commit/cf9007c78d6e2eaaa9816309ebc44f160c53ed3c)) - -### [1.0.3](https://www.github.com/aave/aave-v3-core/compare/v1.0.2...v1.0.3) (2021-09-17) - - -### Miscellaneous Chores - -* release 1.0.3 ([003569a](https://www.github.com/aave/aave-v3-core/commit/003569a1c336f9396715c306be78f1973348ca5c)) - -### [1.0.2](https://www.github.com/aave/aave-v3-core/compare/v1.0.1...v1.0.2) (2021-09-15) - - -### Bug Fixes - -* add repository field and fix publishConfig at package.json ([76b90e7](https://www.github.com/aave/aave-v3-core/commit/76b90e7780b602a48cbbd388a99a742dc24978a5)) - -### [1.0.1](https://www.github.com/aave/aave-v3-core/compare/v1.0.0...v1.0.1) (2021-09-15) - - -### Bug Fixes - -* set release please to run at master ([599fe87](https://www.github.com/aave/aave-v3-core/commit/599fe870a95ab46b1db6869b8339a65871e10e57)) - -## 1.0.0 (2021-09-14) - - -### Features - -* Add `virtual` on Pool and Configurator `getRevision` functions ([ddd4ac5](https://www.github.com/aave/aave-v3-core/commit/ddd4ac5f76e3dc5b99c58068e823c1a7930e2d8c)) -* Add `wadraymath.ts` to support wad and ray math on ethers bignumber ([cc468df](https://www.github.com/aave/aave-v3-core/commit/cc468df58ca1408279ec32a69c8feadc1d63d4d9)) -* add coverage, fix merge issues ([cfd2afd](https://www.github.com/aave/aave-v3-core/commit/cfd2afdc1a32d53317a65b50e48df82b4e97540a)) -* add coverage.json to gitignore ([8613ddd](https://www.github.com/aave/aave-v3-core/commit/8613ddd9d2d72e46ed76511e9a54f1c479f78b19)) -* Add fix in WETH9Mocked ([615ca0b](https://www.github.com/aave/aave-v3-core/commit/615ca0be8da2f80e9d5420f65af65a3954ca2786)) -* add liquidation protocol fee to configuration ([1207d63](https://www.github.com/aave/aave-v3-core/commit/1207d63ea6080039be63067894af25cc6e203d47)) -* Add missing cases for `DefaultReserveInterestRateStrategy` ([08d6c63](https://www.github.com/aave/aave-v3-core/commit/08d6c636c561df8727a36e25a810a1613242f982)) -* Add missing cases for `LiqudationLogic` ([5fa09f5](https://www.github.com/aave/aave-v3-core/commit/5fa09f5a7cced188fa6cbc459b6c6ec3ecb34af2)) -* Add missing cases for `ValidationLogic` ([c8703d4](https://www.github.com/aave/aave-v3-core/commit/c8703d423070720cd8abbaca2db69275cb39a4b9)) -* Add receive function as fallback in Proxy contract ([9bf567e](https://www.github.com/aave/aave-v3-core/commit/9bf567ece620b3a5f58fd55c175446c40b0f57a9)) -* Change lendingpool path to pool ([f344193](https://www.github.com/aave/aave-v3-core/commit/f344193cfa7ef1b3a041267763b51ace6bc489d1)) -* Fix small compiler warnings ([6f86981](https://www.github.com/aave/aave-v3-core/commit/6f86981447cdc64d4607de3efb0ac423dce2b060)) -* initial implementation ([34786a9](https://www.github.com/aave/aave-v3-core/commit/34786a9ec9b80de21252db608455a17600915143)) -* liquidation fee based on bonus amount ([6ca1b1e](https://www.github.com/aave/aave-v3-core/commit/6ca1b1ec759bd7e5eadb137e385c872ebf980120)) -* liquidation protocol fee and tests ([1a86b77](https://www.github.com/aave/aave-v3-core/commit/1a86b77652f2af4ff4bc21be1c9dce923df313e2)) -* re-add temporary test script ([7ddeb7a](https://www.github.com/aave/aave-v3-core/commit/7ddeb7ad26e11ea90d2f71cde9ffad8940b6b879)) -* refactor and simplify the market configuration ([eeb9e7a](https://www.github.com/aave/aave-v3-core/commit/eeb9e7a4a09afbbfa34737d6057875675ea68e7e)) -* Remove `LendingPool` references of contracts ([702a8d3](https://www.github.com/aave/aave-v3-core/commit/702a8d374e0cd91dc0eea03a8225444aca502385)) -* Remove `LendingPool` references of tasks, helpers and tests ([6fdde99](https://www.github.com/aave/aave-v3-core/commit/6fdde99e042062d20edae46b1e75863b5657f777)) -* remove adapter scripts ([259c2cb](https://www.github.com/aave/aave-v3-core/commit/259c2cb010da2b7a3fcec1d489e73da6501e4d1f)) -* remove adapters ([253c63e](https://www.github.com/aave/aave-v3-core/commit/253c63e339bc0d75319869b344cb9e3accd470c6)) -* remove amm test scripts ([9f00d44](https://www.github.com/aave/aave-v3-core/commit/9f00d44927c373757721017b43a89eb6e46328c9)) -* remove dev tasks ([3693feb](https://www.github.com/aave/aave-v3-core/commit/3693febe46786b755503d6116de7deca69c8790d)) -* Remove LendingPoolCollateralManager references ([270f1fe](https://www.github.com/aave/aave-v3-core/commit/270f1fe1d881531385a21f5f00e2b369711ea524)) -* remove multi market support ([3b6e9c5](https://www.github.com/aave/aave-v3-core/commit/3b6e9c5212795f17c3d99b1a4a8945be1575fb30)) -* Remove references to `LENDING_POOL` of Errors lib ([59b5104](https://www.github.com/aave/aave-v3-core/commit/59b510494880bb134812c6ecf4e0c796ed360477)) -* Remove references to `LendingPool` of `Pool` contract ([9919194](https://www.github.com/aave/aave-v3-core/commit/9919194ce6735cfea33ca77df7f6633f5c6fb297)) -* Remove references to LendingPool ([39a7077](https://www.github.com/aave/aave-v3-core/commit/39a707781ad710009a6ef730cc1e81f56324a8cd)) -* remove safemath in all the core contracts ([eaf0ab8](https://www.github.com/aave/aave-v3-core/commit/eaf0ab8ebfde0c156ac9f0db581fbe04afe7dd62)) -* remove tasks, update config, tests working ([28a2f87](https://www.github.com/aave/aave-v3-core/commit/28a2f876c6047fecca95fb093b054299eaa18a48)) -* remove UiPoolDataProvider ([e6b5d55](https://www.github.com/aave/aave-v3-core/commit/e6b5d5513ac096a4a7edf7a82d3bcca34f79b192)) -* remove un-used code ([a370115](https://www.github.com/aave/aave-v3-core/commit/a37011563f1ed81f7cfe66a2c220d4155df5e963)) -* Remove unneeded `public` modifier from contract constructors ([207dd42](https://www.github.com/aave/aave-v3-core/commit/207dd42d66b144a7c85aa2268772ea3868e5a0a6)) -* Remove unneeded returning value in Pool function ([c8b8ba0](https://www.github.com/aave/aave-v3-core/commit/c8b8ba03fcc55081824588783f8fa5bcbeaf76f2)) -* remove ununsed smart contracts ([13faee9](https://www.github.com/aave/aave-v3-core/commit/13faee96ffc42b49087ebbadbfe16e946585d701)) -* remove unused imports and variables ([09e72f2](https://www.github.com/aave/aave-v3-core/commit/09e72f20fe1d219f3ce418a3b7f648916f3bb778)) -* Remove unused pause functions from Pool contract ([024b389](https://www.github.com/aave/aave-v3-core/commit/024b389c9ddc66ab743335cef22260829317e3ee)) -* remove verify flag ([6da1acf](https://www.github.com/aave/aave-v3-core/commit/6da1acfa245b24081087af10ab4f23e3e0765da7)) -* remove WalletBalanceProvider ([efa9df9](https://www.github.com/aave/aave-v3-core/commit/efa9df9b518059d38e1c6fb33c1602ec137759ef)) -* remove weth gateway ([a6583c4](https://www.github.com/aave/aave-v3-core/commit/a6583c44769628f2583b97b336ba237b1c8577dc)) -* removed console.log and commented test script ([c14b725](https://www.github.com/aave/aave-v3-core/commit/c14b7256db812d320c9e59cb81363802d91343a3)) -* Rename `getLendingPool()` of PoolAddresesProvider ([2b94692](https://www.github.com/aave/aave-v3-core/commit/2b9469250d51449e3d76d48240b00621d52c783f)) -* Rename `getLendingPoolCollateralManager()` of AddressesProvider ([e318492](https://www.github.com/aave/aave-v3-core/commit/e318492afc748d6e2274aa2e86281adc380ba638)) -* Rename `getLendingPoolConfigurator()` of PoolAddressesProvider ([6a34932](https://www.github.com/aave/aave-v3-core/commit/6a3493223fcbf2d96a7ee1bc9de1bc2c9cf519bd)) -* Rename `getLendingRateOracle()` of PoolAddressesProvider ([e50413e](https://www.github.com/aave/aave-v3-core/commit/e50413ef6da1c9db4cea63a4efa4b0fc5674c9b4)) -* Rename `setLendingPoolCollateralManager()` of AddressesProvider ([b79b168](https://www.github.com/aave/aave-v3-core/commit/b79b1684da9604ac9011381c7a34d8587275dafe)) -* Rename `setLendingPoolConfiguratorImpl()` of PoolAddressesProvider ([475fbe1](https://www.github.com/aave/aave-v3-core/commit/475fbe12323781011cd1345fa7073991bd83634e)) -* Rename `setLendingPoolImpl()` of PoolAddressesProvider ([d3070f0](https://www.github.com/aave/aave-v3-core/commit/d3070f00c1e2f5d097c473ba740b2264ad165428)) -* Rename `setLendingRateOracle()` of PoolAddresesProvider ([2988f28](https://www.github.com/aave/aave-v3-core/commit/2988f28feebe1ddba38c342ee68bd3ccaa29f1a8)) -* Rename LendingPool to Pool on contracts ([8c4297e](https://www.github.com/aave/aave-v3-core/commit/8c4297e66d37cd9eede64c9b74d1c31ad67c70c7)) -* Rename LendingPoolAddressesProvider to PoolAddressesProvider ([396ce87](https://www.github.com/aave/aave-v3-core/commit/396ce873a0f80371ad145593386161576d69532f)) -* Rename LendingPoolAddressesProviderRegistry ([d39e18c](https://www.github.com/aave/aave-v3-core/commit/d39e18c5ffbbbf7819dce9f02c5a058f4e10b1eb)) -* Rename LendingPoolCollateralManager ([aa00d30](https://www.github.com/aave/aave-v3-core/commit/aa00d300a74bcd0e27e2f202153cd0e2d7a74231)) -* Rename LendingPoolConfigurator ([eea90d8](https://www.github.com/aave/aave-v3-core/commit/eea90d86ac8630d1357c0525bf1c549647fa32e1)) -* Rename LendingPoolHarnessForVariableDebtToken ([d06d3ac](https://www.github.com/aave/aave-v3-core/commit/d06d3accd8b08df9462073772aa73c9cf59c03df)) -* Rename LendingPoolStorage ([5f9b1ea](https://www.github.com/aave/aave-v3-core/commit/5f9b1eab1e4e77d95187e048c0256b2b681b2bf5)) -* Rename LendingRateOracle to RateOracle ([a9c34b1](https://www.github.com/aave/aave-v3-core/commit/a9c34b1f179077422a8519555763f48aaad4a37d)) -* Rename LendingRateOracle to RateOracle in contracts ([49f14d3](https://www.github.com/aave/aave-v3-core/commit/49f14d3f8ed02a8a835375d0031167dd4a9d39af)) -* simplify pacakage.json ([b169a8e](https://www.github.com/aave/aave-v3-core/commit/b169a8e45ef1524e24af87b32d14467c5f4cd458)) -* Split pool logic into libraries ([a78e6cc](https://www.github.com/aave/aave-v3-core/commit/a78e6cce0fc50ce5dfe9fb1d8ed3bcac4a3163f4)) -* Split PoolConfigurator logic into library ([dee8fe5](https://www.github.com/aave/aave-v3-core/commit/dee8fe5b5f9c4081f8f2286d0bac778543ffa7f4)) -* update dependencies ([d9ec325](https://www.github.com/aave/aave-v3-core/commit/d9ec3258e90caa0ca37240f840688a6354103b36)) -* update IAToken interface with treasury getter ([2b481cb](https://www.github.com/aave/aave-v3-core/commit/2b481cb9203b2d3c3a8f1fb29b62676f0c8db99a)) -* Update README ([c42b691](https://www.github.com/aave/aave-v3-core/commit/c42b691f362745145cd7715377d424fd70f22b85)) -* updated genericlogic ([6a25b22](https://www.github.com/aave/aave-v3-core/commit/6a25b22b6455c62b6191143f268bde95c9d66d70)) - - -### Bug Fixes - -* add markets folder to prettier linting ([52abdf1](https://www.github.com/aave/aave-v3-core/commit/52abdf1fdbbe39cfd63247466f812d5b38f9e143)) -* Add minimal comments to PoolBaseLogic and PoolHelperLogic ([68e077b](https://www.github.com/aave/aave-v3-core/commit/68e077be631485c06919f4ce30c5d838c815ffd6)) -* Add minor changes to contract docs ([4f393aa](https://www.github.com/aave/aave-v3-core/commit/4f393aa2bb643524a850f55eda5a908fb529c0e4)) -* add test-amm folder to prettier ([bc34d1d](https://www.github.com/aave/aave-v3-core/commit/bc34d1dc1c28a135f0b57420e6ca957f24235eca)) -* Additional context in test name in `interest-overflow.spec.ts` ([c177a81](https://www.github.com/aave/aave-v3-core/commit/c177a810765fdc2b2ce1c7bfe32b8f63b2765d07)) -* Clean package.json scripts ([4802cab](https://www.github.com/aave/aave-v3-core/commit/4802cab74d07e68c114f9a527cef147d9d5540c8)) -* comment unused `getWalletProvider()` in `1__general.ts` ([0c3ac70](https://www.github.com/aave/aave-v3-core/commit/0c3ac7077cdb7d35caa6a8f39c102019aa156af5)) -* Fix CI actions ([11027c8](https://www.github.com/aave/aave-v3-core/commit/11027c8ff834a189cc96d1191e0b0d8551042499)) -* Fix deployment token helper test ([644d4df](https://www.github.com/aave/aave-v3-core/commit/644d4df7ecb7fdbc4437b6588253e64365c73f50)) -* Fix docs typos in `AaveOracle` ([9622097](https://www.github.com/aave/aave-v3-core/commit/9622097b2bfc9597aca93163cd8e1926a885bd54)) -* Fix docs typos of `protocol/configuration` package ([d679c22](https://www.github.com/aave/aave-v3-core/commit/d679c22dad424c76527e77abf2cbb8f76ce9972f)) -* Fix errors in atoken repay tests ([d056de8](https://www.github.com/aave/aave-v3-core/commit/d056de8c0664415b91a826c44479c01410215ce3)) -* Fix Mock contract name ([af0f9a8](https://www.github.com/aave/aave-v3-core/commit/af0f9a8206b4debea9dff94341a81529f4a38361)) -* Fix some docs typos of `FlashLoan` package ([eb0d5d8](https://www.github.com/aave/aave-v3-core/commit/eb0d5d81505783ca58fadd23d1cc62999feb4b23)) -* Fix test cases of `atoken-permit.spec.ts` ([0e0c68d](https://www.github.com/aave/aave-v3-core/commit/0e0c68de972f727ad39f36acc3e0392f42ada28e)) -* Fix the `Transfer` emission code ([f51ef2c](https://www.github.com/aave/aave-v3-core/commit/f51ef2cb5fd7593fce03fb5829abd055d764a9c9)) -* Fix typo of `FlashloanPremiumToProcolUpdated` event ([108e203](https://www.github.com/aave/aave-v3-core/commit/108e2038accb0c4fb399961c7b9c1bdd113f775e)) -* Fix typos on imports declarations ([d29cbf5](https://www.github.com/aave/aave-v3-core/commit/d29cbf5d7c76ad1fc8a85ccd8831b8ea4af7d9e3)) -* fixed flashloans tests ([d9d1890](https://www.github.com/aave/aave-v3-core/commit/d9d1890bafd31db0fd877cdf355e3b269e9f3110)) -* fixed getIncentivesController inheritance chain ([4d27d55](https://www.github.com/aave/aave-v3-core/commit/4d27d558091b736c79790b6057019ed496817f6d)) -* fixed github action targets ([500c448](https://www.github.com/aave/aave-v3-core/commit/500c44848851bffb39ece1a49f60e6aa885098d9)) -* folder name ([dd67c22](https://www.github.com/aave/aave-v3-core/commit/dd67c22c7b2ea2597a54bfa42219df0977115110)) -* formatting ([6c787df](https://www.github.com/aave/aave-v3-core/commit/6c787dfcc5c3f33ebe633a1aaeb2dd51ebf8f0fb)) -* formatting ([8a2f45b](https://www.github.com/aave/aave-v3-core/commit/8a2f45b949b49d2827825b89b17379a82f99fb3e)) -* Inconsistency in coverage runs ([cfc3caf](https://www.github.com/aave/aave-v3-core/commit/cfc3cafb891248e2ebe7e77ac2f55794711f92c7)) -* Make `GenericLogic` internal ([e7ff741](https://www.github.com/aave/aave-v3-core/commit/e7ff741792c198d186c4f48a25531c8aa2896661)) -* Make `ReserveLogic` internal ([6598274](https://www.github.com/aave/aave-v3-core/commit/6598274afd35761ca95c1240ec82a268c3659463)) -* Make `ValidationLogic` library internal ([e1d1a01](https://www.github.com/aave/aave-v3-core/commit/e1d1a01e96bc245338b914e13e4bb2fdf8f4b749)) -* Make `WadRayMath` and `PercentageMath` unchecked ([1a81ecf](https://www.github.com/aave/aave-v3-core/commit/1a81ecf3fcbf51d15e2f63099e976139bed42243)) -* meet formatting ([650f771](https://www.github.com/aave/aave-v3-core/commit/650f771ee6f1b3ff13931c11dd2fd7c50568701b)) -* Minor changes to docs ([dfc4b36](https://www.github.com/aave/aave-v3-core/commit/dfc4b3674173310ea7a427893865a74095aef756)) -* minor cleanup in `atoken-edge.spec.ts` ([b17310e](https://www.github.com/aave/aave-v3-core/commit/b17310ede6424dd19461210704826ce4ae2f5da4)) -* Move `dropReserve()` into `PoolHelperLogic` library ([38a9904](https://www.github.com/aave/aave-v3-core/commit/38a990498a0407585e75ac757a67fec368a30186)) -* Move `finalizeTransfer()` from `Pool` into `PoolBaseLogic` library ([053d9ed](https://www.github.com/aave/aave-v3-core/commit/053d9edeca2ea0070135a7a7c1e22a53d91db732)) -* Move `flashLoan()` from `Pool` to `PoolBaseLogic` library ([f9af312](https://www.github.com/aave/aave-v3-core/commit/f9af312e9111ce1f46ea9c9664299717d3a4fdf9)) -* package.json formatting ([5162360](https://www.github.com/aave/aave-v3-core/commit/5162360477490f45ad9e5d2474598af8c58885ba)) -* Reducing compiler warnings for mocks ([8adf3b4](https://www.github.com/aave/aave-v3-core/commit/8adf3b4f8893ecdb39bbb6b04c6ff5846f9128da)) -* Refactor docstrings and imports to handle inheritance ([b943f9f](https://www.github.com/aave/aave-v3-core/commit/b943f9f4e58187eb4b4615196fc1fe38b24f140b)) -* Refactor in `actions` to support effective gas price after London. ([d98fa47](https://www.github.com/aave/aave-v3-core/commit/d98fa47445099696e5a345f4403214567fbf8f4c)) -* Remove `impossible` cases. Reasoning added to notion notes ([2e733be](https://www.github.com/aave/aave-v3-core/commit/2e733be24dcab8c62ccc12568804c4524fdada9e)) -* remove blank file ([0286af5](https://www.github.com/aave/aave-v3-core/commit/0286af52c3f5b430180e56a4277a99d1fc3e2891)) -* Remove comment mentioning `refreshDebt()` from `ReserveLogic.sol` ([5ddd74e](https://www.github.com/aave/aave-v3-core/commit/5ddd74eaa774a86dd6404234871635d641aedce2)) -* Remove commented test file ([88d329e](https://www.github.com/aave/aave-v3-core/commit/88d329e63c29ece06dd263c52d771cd3dd653342)) -* remove coverage.json ([915c4a7](https://www.github.com/aave/aave-v3-core/commit/915c4a7c041aaead6f940244fb70c74999d676e3)) -* Remove explicit return values from `IReserveInterestRateStrategy` ([3107e2a](https://www.github.com/aave/aave-v3-core/commit/3107e2a76c55732e9e0314f8884b021a70f6dc41)) -* Remove imports of `ethers` subpaths ([c731f77](https://www.github.com/aave/aave-v3-core/commit/c731f77cfd59079c167d76997215697e567b46f1)) -* Remove last references to `lending` ([81aa4ce](https://www.github.com/aave/aave-v3-core/commit/81aa4ce392bd8454639f4cb02dd6314235dee07d)) -* Remove last references to `LendingPool ([940352e](https://www.github.com/aave/aave-v3-core/commit/940352e53ce2cf399b99eb52dc61c7ffdc7375d8)) -* Remove receive function from Proxy ([2b45a89](https://www.github.com/aave/aave-v3-core/commit/2b45a8952578765db55c025d5f71597e1e079d50)) -* Remove StringLib contract since its unused ([fdb5d85](https://www.github.com/aave/aave-v3-core/commit/fdb5d852bcf1eb59a24353cd63b1096226a2b9a7)) -* Remove unnecessary read ([ba61546](https://www.github.com/aave/aave-v3-core/commit/ba61546230954b98b16763b857e2bf53f42615c3)) -* Remove unneeded code in MockAggregator ([a0bb375](https://www.github.com/aave/aave-v3-core/commit/a0bb375c2775575e89c8f68fe9eea79587b6cb09)) -* Remove unneeded constant ([1c34b8c](https://www.github.com/aave/aave-v3-core/commit/1c34b8ca7d7af904dbb1c8e2a1806dbdac9e44da)) -* Remove unused `UserConfiguration` from `Pool` ([5ffc46c](https://www.github.com/aave/aave-v3-core/commit/5ffc46cc9916442b8c0992c561e9dcbbe3c78e2e)) -* Remove unused code from `deployments` contracts ([495e145](https://www.github.com/aave/aave-v3-core/commit/495e145824880397512c8cdf87b9f933b9517a94)) -* Remove unused imports from `Pool` ([a6e01a5](https://www.github.com/aave/aave-v3-core/commit/a6e01a54f90b88f1dd75e3a33f77a9b08774b7ac)) -* Remove unused imports of test files ([8d6782b](https://www.github.com/aave/aave-v3-core/commit/8d6782be9bc55823eacd5e8b72b7332c61c91302)) -* Rename `PoolBaseLogic` library functions ([df1f197](https://www.github.com/aave/aave-v3-core/commit/df1f19780b8a88a0d6a3585e82fb6339091fd3f9)) -* Rename two tests ([78b891b](https://www.github.com/aave/aave-v3-core/commit/78b891b9a2559cbfcb436f56f84eddbbfc63b5b3)) -* replaced buidler references with hardhat, removed unused buidlerevm network references ([8543ff2](https://www.github.com/aave/aave-v3-core/commit/8543ff29fc6d6e3b004a18faef455dacac4fda80)) -* Undo contracts code change ([b1f296e](https://www.github.com/aave/aave-v3-core/commit/b1f296e8b99ea58d8f3d040245b9ccb3dad8837c)) -* Update [@return](https://www.github.com/return) doc in `IScaledBalancetoken` ([c0e9987](https://www.github.com/aave/aave-v3-core/commit/c0e9987ae26a55b3ba17e96ce0962c8c14f488af)) -* Update [@return](https://www.github.com/return) doc in `LiquidationLogic` ([1998cc2](https://www.github.com/aave/aave-v3-core/commit/1998cc2500d6f15f00aea8c0a1dc5efc5a1b6d6d)) -* Update [@return](https://www.github.com/return) doc in `ReserveConfiguration` ([5afa498](https://www.github.com/aave/aave-v3-core/commit/5afa498b8523f32fafa322c71421bbc8b5bc4364)) -* Update `MockIncentivesController` to get of compiler warnings ([dd7bf6c](https://www.github.com/aave/aave-v3-core/commit/dd7bf6c917e9817e5eec97e791f3aac85de98d47)) -* Update doc in `Helpers` ([9797019](https://www.github.com/aave/aave-v3-core/commit/9797019635701656c73ab6f5293bc1171aea2d04)) -* Update docs in `ReserveLogic` ([3bfe674](https://www.github.com/aave/aave-v3-core/commit/3bfe674c699f4a1d564b3818db327ae7bd280813)) -* Update docs in `ValidationLogic` ([9298d56](https://www.github.com/aave/aave-v3-core/commit/9298d56b3ebe69dfdca165871c6386e7e7b9c699)) -* update hardfork and tsconfig ([0723f20](https://www.github.com/aave/aave-v3-core/commit/0723f201da643de71e6f286d8e8bb25e69f38678)) -* Update hardhat and set hardfork to london ([7534c84](https://www.github.com/aave/aave-v3-core/commit/7534c849bb698aabb72d0b28a83a08f1bfcdec6f)) -* Update package-lock.json ([e35f02b](https://www.github.com/aave/aave-v3-core/commit/e35f02ba9ccf9a876bc4ef8a17aff173319bcf80)) -* update to 0.7.6 ([7f55456](https://www.github.com/aave/aave-v3-core/commit/7f55456ffe13a1ea8d83fe05e9dae2d926091037)) -* Update to 0.8.6 ([932f591](https://www.github.com/aave/aave-v3-core/commit/932f591e8fe8c8d07565997421a04c3467195c9e)) -* update variable names ([0bf6132](https://www.github.com/aave/aave-v3-core/commit/0bf613268ab3307c4e05f3a4033f1f352302faf9)) -* update variable names, remove duplicate variable ([3789669](https://www.github.com/aave/aave-v3-core/commit/37896690c1f73afe23bf06858928e29a1236a793)) -* Use fresh rateOracle instead of replacing old in `deployment-token-helper.spec.ts` ([d7e28e4](https://www.github.com/aave/aave-v3-core/commit/d7e28e4cd71bcce1084c75d873a40dceca72436c)) -* Use mock incentives controller instead of none ([9ffce12](https://www.github.com/aave/aave-v3-core/commit/9ffce12a0d84daae66f9efb009d9db9ec8fdc87b)) -* Use struct for execute repay params ([9172681](https://www.github.com/aave/aave-v3-core/commit/91726816423128d284c0bc21c1d30f72e6d734dc)) -* Use struct for helper variables in execute borrow ([53a9ce8](https://www.github.com/aave/aave-v3-core/commit/53a9ce89d99c35a4d0c9986182bcbad1b3fcf491)) -* Use struct for variables in `_executeWithdraw()` ([30ffa88](https://www.github.com/aave/aave-v3-core/commit/30ffa888d13e01494011c9e573b903dd90ce0a2c)) diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/Verification_Report.md b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/Verification_Report.md deleted file mode 100644 index f4ca481..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/Verification_Report.md +++ /dev/null @@ -1,442 +0,0 @@ - - -![Certora](https://hackmd.io/_uploads/H1yqrfBZY.png) -# Formal Verification of Aave Protocol V3 - - - - -## Summary - -This document describes the specification and verification of Aave's V3 protocol using the Certora Prover. The work was undertaken from Nov. 12, 2021 to Jan. 24, 2022. The latest commit that was reviewed and ran through the Certora Prover was [`a87d546`](https://github.com/aave/aave-v3-core/commit/a87d546d57d4e49bcb450d3c46b50d6bc6e5ddee). - -The scope of this verification is Aave's governance system, particularly the following contracts: -* [`StableDebtToken.sol`](https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/tokenization/StableDebtToken.sol) ( [`Verification Results`](https://vaas-stg.certora.com/output/23658/fba2d71e4c3d6dbfb363/?anonymousKey=6b390e117ec02de424f710f58df71d37b665206e) ) -* [`VariableDebtToken.sol`](https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/tokenization/VariableDebtToken.sol) ( [`Verification Results`](https://vaas-stg.certora.com/output/23658/e86ac2232dbec433e2bb/?anonymousKey=2f3c90644d98890b8a7fa87ee0e006e8ecdd2515) ) -* [`Atoken.sol`](https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/tokenization/AToken.sol) ([`Verification Results`](https://vaas-stg.certora.com/output/23658/8e3d4e70b51dc5bea42d/?anonymousKey=05a2579876175654514e8e1174ef9c98c06dde3b)) -* [`ReserveConfiguration.sol`](https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/configuration/ReserveConfiguration.sol) ([`Verification Results`](https://vaas-stg.certora.com/output/23658/633d0d7547a80788d266/?anonymousKey=83401dd8a786839159d64343adb7c70dd22c9c6c)) -* [`UserConfiguration.sol`](https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/configuration/UserConfiguration.sol) ([`Verification Results`](https://vaas-stg.certora.com/output/23658/6b970f07251caed97b46/?anonymousKey=eec671384cee54c5a44fc278db2a489cb6fc1ddd)) - -And partial verificaiton of: -* [`Pool.sol`](https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/pool/Pool.sol) - -The Certora Prover proved the implementation of the protocol is correct with respect to formal specifications written by the the Certora team. The team also performed a manual audit of these contracts. - -The specification program was modularized to optimize coverage. First, the tokenization contracts were found to uphold to the same properties the [Aave V2](https://hackmd.io/TYI3fetcQgmkAZF_ENSErA) tokenization did, as well as additional properties. On the main Pool contract, the focus of the verification was the protocol's storage of its reserves data, their classification to EModes - a new feature of the V3 protocol - and its compatibility with the user's action. This was done by modularly checking the userConfiguration and reservesConfiguration libraries first. - -The resulting specification files are available on Aave's public [git repository](https://github.com/aave/aave-v3-core/tree/master/Certora/certora). - - -## List of Main Issues Discovered - -**Severity: Critical** - -| Issue: | Loss of assets | -| -------- | -------- | -| Description: | RepayWithATokens function lacks an HF check, can be exploited to withdraw liquidity from the system for free. | -| Mitigation/Fix: | Canceled repayment with ATokens on behalf of another user | -| Property violated: | Any Operation Should Preserve User's HF>1 | - -**Severity: High** - -| Issue: | Risk Exposure | -| -------- | -------- | -| Description: | User can come to hold both an isolated and a non-isolated assets as collaterals upon calling AToken.transfer(), liquidation call and mintUnbacked(). Can be exploited to surpass the debt ceiling | -| Mitigation/Fix: | A check for isolation mode was added to the functions | -| Property violated: | A User Can't Hold Both an Isolated and non-Isolated Assets as Collaterals | - -**Severity: High** - -| Issue: | Loss of assets | -| -------- | -------- | -| Description: | Confusion of Asset and EMode price feed for liquidations | -| Mitigation/Fix: | Price Sources are called according to EMode | -| Property violated: | Emode source price usage | - - - -**Severity: Medium** - -| Issue: | Loss of Users' Profitability | -| -------- | -------- | -| Description: | EMode liquidation may use wrong liquidation bonus | -| Mitigation/Fix: | Bonus rewarded correctly according to EMode | - - -**Severity: Medium** - -| Issue: | Loss of revenue | -| -------- | -------- | -| Description: | When repaying with aToken, the interest rate is updated as if we provided the equivalent liquidity in underlying instead of in AToken. In fact there’s no liquidity provided to the system. It can be used to manipulate the interest rates. | -| Mitigation/Fix: | Call to rates updating function was changed to use 0 as the added liquidity | -| Rule Coverage: | No Change in Underlying's Balance Implies No Change in rate | - -**Severity: Low ** - -| Issue: | Integrity of ReserveList | -| -------- | -------- | -| Description: | *_addReserveToList* function will push a new reserve into all empty spots of the reserves list, instead of just the first one | -| Mitigation/Fix: | A *return* call was inserted to the loop | -| Rule Coverage: | The same asset should not appear twice on the reserves list | - -**Severity: Recommendation** - -| Issue: | Denial of Service | -| -------- | -------- | -| Description: | Users can be forced into isolation mode through supply(),AToken.transfer() functions, thus temporarily preventing them from borrowing other assets | -| Property violated: | Informative Rule: Check which functions can revert for one user due to another user's action | -| Mitagation/Fix: | User can withdraw asset of isolation mode - -## Disclaimer - -The Certora Prover takes as input a contract and a specification and formally proves that the contract satisfies the specification in all scenarios. Importantly, the guarantees of the Certora Prover are scoped to the provided specification, and the Certora Prover does not check any cases not covered by the specification. - -We hope that this information is useful, but provide no warranty of any kind, explicit or implied. The contents of this report should not be construed as a complete guarantee that the contract is secure in all dimensions. In no event shall Certora or any of its employees be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the results reported here. - -# Overview of the verification - -## Description of the system - -Aave is a decentralized non-custodial liquidity markets protocol where users can participate as suppliers or borrowers. Suppliers provide liquidity to the market to earn a passive income, while borrowers are able to borrow in an overcollateralized (perpetually) or undercollateralized (one-block liquidity) fashion. - -## Description of the specification files - -The specification contains six files, three for the tokenization part, one for the pool and one for each of the reserve and user configuration contracts. The tokens' contracts have similar specifications, using (up to slight modifications) properties based on Certora's aggregated experience with ERC20 verificartion. -On the main Pool contract, the focus of the coverage was the protocol's storage of its reserves data, their classification to EModes - a new feature of the V3 protocol - and its compatibility with the user's action. This was done by modularly checking the userConfiguration and reservesConfiguration libraries first. - -## Assumptions and Simplifications - -We made the following assumptions during the verification process: - -- Accumulation rates in the protocol are assumed to be 1, so that no interest rate is accumulated. -- We assume that hash operations return an arbitrary deterministic value -- We unroll loops. Violations that require a loop to execute more than once will not be detected. -- When verifying contracts that make external calls, we assume that those calls can have arbitrary side effects outside of the contracts, but that they do not affect the state of the contract being verified. This means that some reentrancy bugs may not be caught. -- No usage of incentives controller - -## Verification Conditions -### Notation -✔️ indicates the rule is formally verified on the latest reviewed commit. Footnotes describe any simplifications or assumptions used while verifying the rules (beyond the general assumptions listed above). - - -In this document, verification conditions are either shown as logical formulas or Hoare triples of the form {p} C {q}. A verification condition given by a logical formula denotes an invariant that holds if every reachable state satisfies the condition. - -Hoare triples of the form {p} C {q} holds if any non-reverting execution of program C that starts in a state satsifying the precondition p ends in a state satisfying the postcondition q. The notation {p} C@withrevert {q} is similar but applies to both reverting and non-reverting executions. Preconditions and postconditions are similar to the Solidity require and assert statements. - -Formulas relate the results of method calls. In most cases, these methods are getters defined in the contracts, but in some cases they are getters we have added to our harness or definitions provided in the rules file. Undefined variables in the formulas are treated as arbitrary: the rule is checked for every possible value of the variables. - - -## Stable-Debt Token - -### Rules -#### 1. Integrity of User's Time-Stamp ✔️ - -``` -getUserLastUpdated(user) <= currentBlock.timestamp -``` -#### 2. Any Operation Changes At Most One User's balance ✔️ - -``` -{ A!= B && balanceA == balanceOf(A) && balanceB == balanceOf(B) } - op ; -{ balanceOf(A) == balanceA || balanceOf(B) == balanceB } -``` -where `op` is any operation -#### 3. Change in Total Supply iff an Equal Change in Some User's Balance ✔️ - -``` -{ balanceA == balanceOf(A) && total == totalSupply() } - op ; -{ balanceOf(A) != balanceA => balanceOf(A) - balanceA == totalSupply() - total }; -``` - -#### 4. Additivity of Burn - Burning at Once Equals Burning in Two Steps in the Same Transaction ✔️ - -``` -burn(user,x);burn(user,y); -~ -burn(user,x+y) -``` -#### 5. Integrity of Mint ✔️ - -``` -{ b == balanceOf(user) } - mint(delegatedUser,user,x,index); -{ balanceOf(user) == b+x } -``` -#### 6. Integrity of Burn ✔️ - -``` -{ b == balanceOf(user) } - burn(user,x) -{ balanceOf(user) == b-x } -``` -#### 7. Invertibility of Mint and Burn ✔️ - -``` -{ b == balanceOf(user) } - mint(delegatedUser,user,x,index); burn(user, x) -{ balanceOf(user) == b } -``` - -## Variable-Debt Token - -### Rules - -#### 1. Any Operation Changes At Most One User's balance ✔️ - -``` -{ A!= B && balanceA == balanceOf(A) && balanceB == balanceOf(B) } - op ; -{ balanceOf(A) == balanceA || balanceOf(B) == balanceB } -``` -#### 2. Change in Total Supply iff an Equal Change in Some User's Balance ✔️ - -``` -{ balanceA == balanceOf(A) && total == totalSupply() } - op ; -{ balanceOf(A) != balanceA => balanceOf(A) - balanceA == totalSupply() - total }; -``` -#### 3. Only pool can change total supply with burn and mint ✔️ -``` -{ total == totalSupply() } - op ; -{ totalSupply() != total => msg.sender == pool && (op == mint() || op == burn()) }; -``` -#### 4. Mint and burn are inverse operations ✔️ -``` -{ b == balanceOf(user) } - mint(delegatedUser,user,amount,index); burn(user, amount, index) -{ balanceOf(user) == b } -``` -#### 5. Additivity of burn ✔️ -``` -burn(u, u’, x); burn(u, u’, y) ~ burn(u, u’, x+y) at the same timestamp -``` -#### 6. Integrity of mint ✔️ -``` -{ b = balanceOf(u) } - mint(u,x) -{ balanceOf(u) == b + x } -``` -#### 7. Burn doesn't change other's balance and data ✔️ -``` -{ other != user && bb = balanceOf(other) } - burn(user, amount, index) -{ balanceOf(other) == bb } -``` -#### 8. Mint doesn't change other's balance and data ✔️ -``` -{ other != user && bbo = balanceOf(other) && bbu = balanceOf(user) } - mint(user, onBehalfOf, amount, index) -{ balanceOf(other) == bbo && (user != onBehalfOf => balanceOf(user) == bbu) } -``` -#### 9. Burn zero dosen't change balance ✔️ -``` -{ b = balanceOf(user) } - burn(user, 0, index) -{ balanceOf(user) == b } -``` - -## AToken - -### Rules -#### 1. Any Operation Changes At Most Two User's balance ✔️ - -``` -{ A != B != C && balanceA == balanceOf(A) && balanceB == balanceOf(B) && balanceC == balanceOf(C) } - op ; -{ balanceOf(A) == balanceA || balanceOf(B) == balanceB || balanceOf(C) == balanceC } -``` -#### 2. Integrity of mint ✔️ -``` -{ b == balanceOf(u) } - mint(u,x) -{ b + x - ε ≤ balanceOf(u) ≤ b + x + ε } -``` -#### 3. Additivity of mint ✔️ -``` -mint(u,x); mint(u,y) ~ mint(u,x+y) -``` -with resepct to balanceOf(u) up to some `ε` - -#### 4. Mint of zero is not possible ✔️ -``` -{ } - mint(caller, user, amount, index) -{ amount == 0 => REVERT } -``` -#### 4. Integrity of transfer ✔️ -``` -I. -{ u ≠ u’ ∧ bu = balanceOf(u) ∧ bu’ = balanceOf(u’) } - transfer(u, u’ x); -{ | balanceOf(u) - (bu - x) | ≤ ε ∧ - | balanceOf(u’) - (bu’ + x) | ≤ ε } -II. -{ b = underlyingAssetBalanceOf(u’’) } - transfer(u, u’ x); -{ b = underlyingAssetBalanceOf(u’’) } -``` -#### 5. Additivity of transfer ✔️ -``` -{ f1 != f2, t1 != t2, f2 != t1, f1 != t2, f1 == t1 <=> f2 == t2, - balanceOf(f1) == balanceOf(f2), balanceOf(t1) == balanceOf(t2) } - transfer(f1, t1, x), transfer(f1, t1, y), transfer(f2, t2, x+y) -{ |balanceOf(f1) - balanceOf(f2)| ≤ 3ε, |balanceOf(t1) - balanceOf(t2)| ≤ 3ε } -``` -#### 6. Integrity of burn ✔️ -``` -{ bu = balanceOf(u) ∧ ba = underlyingAssetBalanceOf(u’) } - burn(u, u’, x) -{ | balanceOf(u) - (bu - x) | ≤ ε ∧ - u’ ≠ AToken ⇒ | underlyingAssetBalanceOf(u’) - (ba + x) | ≤ ε } -``` -#### 7. Additivity of burn ✔️ -``` -burn(u, u’, x); burn(u, u’, y) ~ burn(u, u’, x+y) at the same timestamp -``` -#### 8. burn doesn't change other's balance and data ✔️ -``` -{ other != user, other != recieverOfUnderlying, - db = additionalData(other), bb = balanceOf(other)} - burn(user, recieverOfUnderlying, amount, index) -{ additionalData(other) == db && balanceOf(other) == bb } -``` -#### 9. mint doesn't change other's balance and data ✔️ -``` -{ other != user, db = additionalData(other), bb = balanceOf(other) } - mint(caller, user, amount, index) -{ additionalData(other) == db && balanceOf(other) == bb } -``` - -## ReserveConfiguration -### Rules -#### 1. Integrity Setters/Getters ✔️ -``` -{ r = ReserveConfiguration, x = some member of r } - setX(r, y) -{ getX(r) == y } -``` -#### 2. Each setter changes only one member ✔️ -``` -{ r = ReserveConfiguration, x = some member of r, x' = another member of r } - setX(r, y) -{ getX'(r) == x' } -``` -## UserConfiguration -### Rules - -#### 1. Consistency of isEmpty ✔️ -``` -{isEmpty => !isBorrowingAny() && !isUsingAsCollateralOrBorrowing(reserveIndex) } -``` -#### 2. Consistency of not isEmpty ✔️ -``` -{ (isBorrowingAny() || isUsingAsCollateral(reserveIndex)) => !isEmpty() } -``` -#### 3. Consistency of isBorrowingAny ✔️ -``` -{ isBorrowing(reserveIndex) => isBorrowingAny() } -``` -#### 4. Consistency of isUsingAsCollateral functions ✔️ -``` -(isUsingAsCollateral(reserveIndex) || isBorrowing(reserveIndex)) - <=> isUsingAsCollateralOrBorrowing(reserveIndex) -``` -#### 5. Integrity of User's Isolation mode configuration data ✔️ -``` -!isUsingAsCollateralOne() => !isIsolated() -``` -#### 6. Integrity of setBorrowing ✔️ -``` -{ reserveIndex < 128 } - setBorrowing(reserveIndex, borrowing) -{ isBorrowing(reserveIndex) == borrowing } -``` -#### 7. Integrity of setUsingAsCollateral ✔️ -``` -{ reserveIndex < 128 } - setUsingAsCollateral(reserveIndex, usingAsCollateral) -{ isUsingAsCollateral(reserveIndex) == usingAsCollateral } -``` -#### 8. setBorrowing for one reserve doesn't affect others ✔️ -``` -{ reserveIndexOther != reserveIndex && reserveIndexOther < 128 && - reserveIndex < 128 && - otherReserveBorrowing == isBorrowing(reserveIndexOther) && - otherReserveCollateral == isUsingAsCollateral(reserveIndexOther) } - setBorrowing(reserveIndex, borrowing) -{ otherReserveBorrowing == isBorrowing(reserveIndexOther) && - otherReserveCollateral == isUsingAsCollateral(reserveIndexOther) } -``` -#### 9. setUsingAsCollateral for one reserve doesn't affect others ✔️ -``` -{ reserveIndexOther != reserveIndex && - reserveIndexOther < 128 && reserveIndex < 128 && - otherReserveBorrowing = isBorrowing(reserveIndexOther) && - otherReserveCollateral = isUsingAsCollateral(reserveIndexOther) } - setUsingAsCollateral(reserveIndex, isUsingAsCollateral) -{ otherReserveBorrowing == isBorrowing(reserveIndexOther) && - otherReserveCollateral == isUsingAsCollateral(reserveIndexOther) } -``` - - - -## Pool - -### Rules - -#### 1. Integrity of Supply Cap - aToken supply shall never exceed the cap ✔️** -``` -{ reserves[asset].aToken.totalSupply() <= reserves[asset].supplyCap() } -``` - ** rule times-out for some functions -#### 3. Integrity of setUserEMode ✔️ -``` -{ } - setUserEMode(category) -{ getUserEMode() == category } -``` -#### 4. User can always set own eMode to 0 ✔️ -``` -{ } - setUserEMode(0); -{ NOTREVERT } -``` -#### 5. If borrow succeeds then reserve flags are correct ✔️ -``` -{ r = _reserves[asset].configuration && a = r.getActive() && - f = r.getFrozen() && p = r.getPaused() && b = r.getBorrowingEnabled() && - s = r.getStableRateBorrowingEnabled() } - borrow(asset, amount, interestRateMode, referralCode, onBehalfOf) -{ a && !f && !p && b && (interestRateMode == 1 => s) } -``` - -#### 6. `reservesCount()` is monotonic ✔️ -``` -{ rb = reservesCount() } - op -{ reservesCount() >= rb } -``` -#### 7. Each function changes at most one configuration ✔️ -``` -{ rb1 = getReserveConfiguration(asset1) - && rb2 = getReserveConfiguration(asset2)} - op -{ asset1 != asset2 => (rb1 == getReserveConfiguration(asset1) - || rb2 == getReserveConfiguration(asset2)) } -``` -#### 8. Reserve id always less than counter ✔️ -``` - {getReserveList(i) != 0 => i < reservesCount()} -``` -#### 10. Bijective property of reserve id ✔️ -``` -I. -{(i != 0 and token != 0) => (getReserveList(i) == token - <=> getReserveDataIndex(token) == i)} -II. -{(i == 0 and token != 0) => (getReserveList(i) == token - => getReserveDataIndex(token) == i)} -``` \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/Verification_Report.pdf b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/Verification_Report.pdf deleted file mode 100644 index 4e2907f9830c990c08e71a7dbe222696f4f8d150..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115198 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 diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/ATokenHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/ATokenHarness.sol deleted file mode 100644 index e5129c4..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/ATokenHarness.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import {Pool} from '../../contracts/protocol/pool/Pool.sol'; -import {AToken} from '../../contracts/protocol/tokenization/AToken.sol'; - -/** - * @title Certora harness for Aave ERC20 AToken - * - * @dev Certora's harness contract for the verification of Aave ERC20 AToken. - */ -contract ATokenHarness is AToken { - - constructor( - Pool pool - ) public AToken(pool) {} - - /** - * @dev Calls burn with index == 1 RAY - * @param amount the amount being burned - **/ - function burn( - address user, - address receiverOfUnderlying, - uint256 amount, - uint256 index - ) public override onlyPool { - - // changes for pool - // require(index == 1e27, 'index is assumed to be 1 RAY'); - // super.burn(user, receiverOfUnderlying, amount, index); - - super.burn(user, receiverOfUnderlying, amount, 1e27); - //POOL.setATokenFlag(!POOL.getATokenFlag()); - } - - /** - * @dev Calls mint with index == 1 RAY - * @param amount the amount of tokens to mint - **/ - function mint( - address user, - address onBehalfOf, - uint256 amount, - uint256 index - ) public virtual override onlyPool returns (bool) { - - // changes for pool - // require(index == 1e27, 'index is assumed to be 1 RAY'); - // return super.mint(user, amount, index); - return super.mint(user, onBehalfOf, amount, 1e27); - } - - function scaledTotalSupply() public view override returns (uint256) { - uint256 val = super.scaledTotalSupply(); - // POOL.setATokenFlag(!POOL.getATokenFlag()); - return val; - } - - function additionalData(address user) public view returns (uint128) { - return _userState[user].additionalData; - } -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/DataTypesInitializer.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/DataTypesInitializer.sol deleted file mode 100644 index e69de29..0000000 diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/EModeLogicHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/EModeLogicHarness.sol deleted file mode 100644 index e484dd6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/EModeLogicHarness.sol +++ /dev/null @@ -1,22 +0,0 @@ -import {EModeLogic} from '../../contracts/protocol/libraries/logic/EModeLogic.sol'; -import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; - -contract EModeLogicHarness { -mapping(address => DataTypes.ReserveData) reserves; - mapping(uint256 => address) reservesList; - mapping(uint8 => DataTypes.EModeCategory) eModeCategories; - mapping(address => uint8) usersEModeCategory; - DataTypes.UserConfigurationMap userConfig; - DataTypes.ExecuteSetUserEModeParams params; - - function test() public { - EModeLogic.executeSetUserEMode( - reserves, - reservesList, - eModeCategories, - usersEModeCategory, - userConfig, - params - ); - } -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/GenericLogicHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/GenericLogicHarness.sol deleted file mode 100644 index ae18b73..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/GenericLogicHarness.sol +++ /dev/null @@ -1,244 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import {IERC20} from '../../contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {IScaledBalanceToken} from '../../contracts/interfaces/IScaledBalanceToken.sol'; -import {IPriceOracleGetter} from '../../contracts/interfaces/IPriceOracleGetter.sol'; -import {ReserveConfiguration} from '../../contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {PercentageMath} from '../../contracts/protocol/libraries/math/PercentageMath.sol'; -import {WadRayMath} from '../../contracts/protocol/libraries/math/WadRayMath.sol'; -import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; -import {ReserveLogic} from '../../contracts/protocol/libraries/logic/ReserveLogic.sol'; - -/** - * @title GenericLogic library - * @author Aave - * @notice Implements protocol-level logic to calculate and validate the state of a user - */ -contract GenericLogic { - using ReserveLogic for DataTypes.ReserveData; - using WadRayMath for uint256; - using PercentageMath for uint256; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using UserConfiguration for DataTypes.UserConfigurationMap; - - mapping(address => DataTypes.ReserveData) public reservesData; - mapping(uint256 => address) public reserves; - mapping(uint8 => DataTypes.EModeCategory) public eModeCategories; - //DataTypes.CalculateUserAccountDataParams public params; - DataTypes.UserConfigurationMap public userConfig; - uint256 public reservesCount; - address public user; - address public oracle; - uint8 public userEModeCategory; - - struct CalculateUserAccountDataVars { - uint256 assetPrice; - uint256 assetUnit; - uint256 userBalance; - uint256 userBalanceInBaseCurrency; - uint256 userDebt; - uint256 userStableDebt; - uint256 userDebtInBaseCurrency; - uint256 decimals; - uint256 ltv; - uint256 liquidationThreshold; - uint256 i; - uint256 healthFactor; - uint256 totalCollateralInBaseCurrency; - uint256 totalDebtInBaseCurrency; - uint256 avgLtv; - uint256 avgLiquidationThreshold; - uint256 normalizedIncome; - uint256 normalizedDebt; - uint256 eModeAssetPrice; - uint256 eModeLtv; - uint256 eModeLiqThreshold; - uint256 eModeAssetCategory; - address eModePriceSource; - address currentReserveAddress; - bool hasZeroLtvCollateral; - } - - /** - * @notice Calculates the user data across the reserves. - * @dev It includes the total liquidity/collateral/borrow balances in the base currency used by the price feed, - * the average Loan To Value, the average Liquidation Ratio, and the Health factor. - * @return The total collateral of the user in the base currency used by the price feed - * @return The total debt of the user in the base currency used by the price feed - * @return The average ltv of the user - * @return The average liquidation threshold of the user - * @return The health factor of the user - * @return True if the ltv is zero, false otherwise - **/ - function calculateUserAccountData() - public - returns ( - uint256, - uint256, - uint256, - uint256, - uint256, - bool - ) - { - if (userConfig.isEmpty()) { - return (0, 0, 0, 0, type(uint256).max, false); - } - - CalculateUserAccountDataVars memory vars; - - if (userEModeCategory != 0) { - vars.eModePriceSource = eModeCategories[userEModeCategory].priceSource; - vars.eModeLtv = eModeCategories[userEModeCategory].ltv; - vars.eModeLiqThreshold = eModeCategories[userEModeCategory].liquidationThreshold; - - if (vars.eModePriceSource != address(0)) { - vars.eModeAssetPrice = IPriceOracleGetter(oracle).getAssetPrice( - vars.eModePriceSource - ); - } - } - - while (vars.i < reservesCount) { - if (!userConfig.isUsingAsCollateralOrBorrowing(vars.i)) { - unchecked { - ++vars.i; - } - continue; - } - - vars.currentReserveAddress = reserves[vars.i]; - - if (vars.currentReserveAddress == address(0)) { - unchecked { - ++vars.i; - } - continue; - } - - DataTypes.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress]; - - ( - vars.ltv, - vars.liquidationThreshold, - , - vars.decimals, - , - vars.eModeAssetCategory - ) = currentReserve.configuration.getParams(); - - unchecked { - vars.assetUnit = 10**vars.decimals; - } - vars.assetPrice = vars.eModeAssetPrice > 0 - ? vars.eModeAssetPrice - : IPriceOracleGetter(oracle).getAssetPrice(vars.currentReserveAddress); - - if (vars.liquidationThreshold != 0 && userConfig.isUsingAsCollateral(vars.i)) { - vars.normalizedIncome = currentReserve.getNormalizedIncome(); - vars.userBalance = IScaledBalanceToken(currentReserve.aTokenAddress).scaledBalanceOf( - user - ); - vars.userBalance = vars.userBalance.rayMul(vars.normalizedIncome); - - vars.userBalanceInBaseCurrency = (vars.assetPrice * vars.userBalance); - unchecked { - vars.userBalanceInBaseCurrency /= vars.assetUnit; - } - vars.totalCollateralInBaseCurrency = - vars.totalCollateralInBaseCurrency + - vars.userBalanceInBaseCurrency; - - vars.hasZeroLtvCollateral = vars.hasZeroLtvCollateral || vars.ltv == 0; - - vars.avgLtv = vars.ltv > 0 - ? vars.avgLtv + - vars.userBalanceInBaseCurrency * - ( - (userEModeCategory == 0 || vars.eModeAssetCategory != userEModeCategory) - ? vars.ltv - : vars.eModeLtv - ) - : vars.avgLtv; - - vars.avgLiquidationThreshold = - vars.avgLiquidationThreshold + - vars.userBalanceInBaseCurrency * - ( - (userEModeCategory == 0 || vars.eModeAssetCategory != userEModeCategory) - ? vars.liquidationThreshold - : vars.eModeLiqThreshold - ); - } - - if (userConfig.isBorrowing(vars.i)) { - vars.userStableDebt = IERC20(currentReserve.stableDebtTokenAddress).balanceOf(user); - vars.userDebt = IScaledBalanceToken(currentReserve.variableDebtTokenAddress) - .scaledBalanceOf(user); - - if (vars.userDebt > 0) { - vars.normalizedDebt = currentReserve.getNormalizedDebt(); - vars.userDebt = vars.userDebt.rayMul(vars.normalizedDebt); - } - vars.userDebt = vars.userDebt + vars.userStableDebt; - vars.userDebtInBaseCurrency = (vars.assetPrice * vars.userDebt); - unchecked { - vars.userDebtInBaseCurrency /= vars.assetUnit; - } - vars.totalDebtInBaseCurrency = vars.totalDebtInBaseCurrency + vars.userDebtInBaseCurrency; - } - - unchecked { - ++vars.i; - } - } - - unchecked { - vars.avgLtv = vars.totalCollateralInBaseCurrency > 0 - ? vars.avgLtv / vars.totalCollateralInBaseCurrency - : 0; - vars.avgLiquidationThreshold = vars.totalCollateralInBaseCurrency > 0 - ? vars.avgLiquidationThreshold / vars.totalCollateralInBaseCurrency - : 0; - } - - vars.healthFactor = (vars.totalDebtInBaseCurrency == 0) - ? type(uint256).max - : (vars.totalCollateralInBaseCurrency.percentMul(vars.avgLiquidationThreshold)).wadDiv( - vars.totalDebtInBaseCurrency - ); - return ( - vars.totalCollateralInBaseCurrency, - vars.totalDebtInBaseCurrency, - vars.avgLtv, - vars.avgLiquidationThreshold, - vars.healthFactor, - vars.hasZeroLtvCollateral - ); - } - - /** - * @notice Calculates the maximum amount that can be borrowed depending on the available collateral, the total debt and the - * average Loan To Value - * @param totalCollateralInBaseCurrency The total collateral in the base currency used by the price feed - * @param totalDebtInBaseCurrency The total borrow balance in the base currency used by the price feed - * @param ltv The average loan to value - * @return The amount available to borrow in the base currency of the used by the price feed - **/ - function calculateAvailableBorrows( - uint256 totalCollateralInBaseCurrency, - uint256 totalDebtInBaseCurrency, - uint256 ltv - ) public pure returns (uint256) { - uint256 availableBorrowsInBaseCurrency = totalCollateralInBaseCurrency.percentMul(ltv); - - if (availableBorrowsInBaseCurrency < totalDebtInBaseCurrency) { - return 0; - } - - availableBorrowsInBaseCurrency = availableBorrowsInBaseCurrency - totalDebtInBaseCurrency; - return availableBorrowsInBaseCurrency; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/LendingPoolHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/LendingPoolHarness.sol deleted file mode 100644 index 81acbd6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/LendingPoolHarness.sol +++ /dev/null @@ -1,91 +0,0 @@ -pragma solidity ^0.6.12; -pragma experimental ABIEncoderV2; - -import "../../contracts/protocol/lendingpool/LendingPool.sol"; - -contract LendingPoolHarness is LendingPool { - - function ercBalanceOf(address a) public returns (uint256) { - return a.balance; - } - - function init_state() public {} - - function getATokenAddress(address asset) public returns (address) { - DataTypes.ReserveData storage reserve = _reserves[asset]; - return address(reserve.aTokenAddress); - } - - function getVariableDebtTokenAddress(address asset) public returns (address) { - DataTypes.ReserveData storage reserve = _reserves[asset]; - return address(reserve.variableDebtTokenAddress); - } - - - function getStableDebtTokenAddress(address asset) public returns (address) { - DataTypes.ReserveData storage reserve = _reserves[asset]; - return address(reserve.stableDebtTokenAddress); - } - - - function getBalanceInToken(address token, address account) public returns (uint256) { - return IERC20(token).balanceOf(account); - } - - function getTotalSupply(address token) public returns (uint256) { - return IERC20(token).totalSupply(); - } - - - function getSystemBalanceInAsset(address asset) public view returns (uint256) { - return IERC20(asset).balanceOf(_reserves[asset].aTokenAddress); - } - - function getReserveliquidityIndex(address asset) external view returns (uint256) { - return _reserves[asset].getNormalizedIncome(); - } - - function isFreezed(address asset) external view returns (bool) { - (bool isActive, bool isFreezed, ,) = _reserves[asset].configuration.getFlags(); - return isFreezed; - } - - function isActive(address asset) external view returns (bool) { - (bool isActive, bool isFreezed, ,) = _reserves[asset].configuration.getFlags(); - return isActive; - } - - - function getHealthFactor(address account) external view returns (uint256) { - - uint256 totalCollateralETH; - uint256 totalBorrowsETH; - uint256 ltv; - uint256 currentLiquidationThreshold; - uint256 healthFactor; - ( - totalCollateralETH, - totalBorrowsETH, - ltv, - currentLiquidationThreshold, - healthFactor - ) = GenericLogic.calculateUserAccountData( - account, - _reserves, - _usersConfig[account], - _reservesList, - _reservesCount, - _addressesProvider.getPriceOracle() - ); - - return healthFactor; - } - - mapping(uint256 => uint256) private reserveNormalizedIncome; - - function getReserveNormalizedIncome(address asset) external override view returns (uint256) { - require(reserveNormalizedIncome[block.timestamp] == 1e27); - return reserveNormalizedIncome[block.timestamp]; - } - -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolConfiguratorHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolConfiguratorHarness.sol deleted file mode 100644 index 0180964..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolConfiguratorHarness.sol +++ /dev/null @@ -1,463 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import {IERC20Detailed} from '../../contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {VersionedInitializable} from '../../contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol'; -import {InitializableImmutableAdminUpgradeabilityProxy} from '../../contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; -import {ReserveConfiguration} from '../../contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {IPoolAddressesProvider} from '../../contracts/interfaces/IPoolAddressesProvider.sol'; -import {Errors} from '../../contracts/protocol/libraries/helpers/Errors.sol'; -import {PercentageMath} from '../../contracts/protocol/libraries/math/PercentageMath.sol'; -import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; -import {ConfiguratorLogic} from '../../contracts/protocol/libraries/logic/ConfiguratorLogic.sol'; -import {ConfiguratorInputTypes} from '../../contracts/protocol/libraries/types/ConfiguratorInputTypes.sol'; -import {IInitializableDebtToken} from '../../contracts/interfaces/IInitializableDebtToken.sol'; -import {IInitializableAToken} from '../../contracts/interfaces/IInitializableAToken.sol'; -import {IAaveIncentivesController} from '../../contracts/interfaces/IAaveIncentivesController.sol'; -import {IPoolConfigurator} from '../../contracts/interfaces/IPoolConfigurator.sol'; -// import {IPool} from '../../contracts/interfaces/IPool.sol'; -import {PoolHarnessForConfigurator} from './PoolHarnessForConfigurator.sol'; -import {IACLManager} from '../../contracts/interfaces/IACLManager.sol'; -import {IPoolDataProvider} from '../../contracts/interfaces/IPoolDataProvider.sol'; - -/** - * @title PoolConfigurator - * @author Aave - * @dev Implements the configuration methods for the Aave protocol - **/ -contract PoolConfiguratorHarness is VersionedInitializable, IPoolConfigurator { - using PercentageMath for uint256; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - - IPoolAddressesProvider internal _addressesProvider; - PoolHarnessForConfigurator internal _pool; - - modifier onlyPoolAdmin() { - // _onlyPoolAdmin(); - _; - } - - modifier onlyEmergencyAdmin() { - // _onlyEmergencyAdmin(); - _; - } - - modifier onlyEmergencyOrPoolAdmin() { - // _onlyPoolOrEmergencyAdmin(); - _; - } - - modifier onlyAssetListingOrPoolAdmins() { - // _onlyAssetListingOrPoolAdmins(); - _; - } - - modifier onlyRiskOrPoolAdmins() { - // _onlyRiskOrPoolAdmins(); - _; - } - - uint256 internal constant CONFIGURATOR_REVISION = 0x1; - - /// @inheritdoc VersionedInitializable - function getRevision() internal pure virtual override returns (uint256) { - return CONFIGURATOR_REVISION; - } - - function initialize(IPoolAddressesProvider provider) public initializer { - // _addressesProvider = provider; - // _pool = IPool(_addressesProvider.getPool()); - } - - /// @inheritdoc IPoolConfigurator - function initReserves(ConfiguratorInputTypes.InitReserveInput[] calldata input) - external - override - onlyAssetListingOrPoolAdmins - { - PoolHarnessForConfigurator cachedPool = _pool; - for (uint256 i = 0; i < input.length; i++) { - ConfiguratorLogic.initReserve(cachedPool, input[i]); - } - } - - /// @inheritdoc IPoolConfigurator - function dropReserve(address asset) external override onlyPoolAdmin { - _pool.dropReserve(asset); - emit ReserveDropped(asset); - } - - /// @inheritdoc IPoolConfigurator - function updateAToken(ConfiguratorInputTypes.UpdateATokenInput calldata input) - external - override - onlyPoolAdmin - { - ConfiguratorLogic.updateAToken(_pool, input); - } - - /// @inheritdoc IPoolConfigurator - function updateStableDebtToken(ConfiguratorInputTypes.UpdateDebtTokenInput calldata input) - external - override - onlyPoolAdmin - { - ConfiguratorLogic.updateStableDebtToken(_pool, input); - } - - /// @inheritdoc IPoolConfigurator - function updateVariableDebtToken(ConfiguratorInputTypes.UpdateDebtTokenInput calldata input) - external - override - onlyPoolAdmin - { - ConfiguratorLogic.updateVariableDebtToken(_pool, input); - } - - /// @inheritdoc IPoolConfigurator - function enableBorrowingOnReserve( - address asset, - uint256 borrowCap, - bool stableBorrowRateEnabled - ) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setBorrowingEnabled(true); - currentConfig.setBorrowCap(borrowCap); - currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled); - _pool.setConfiguration(asset, currentConfig.data); - - emit BorrowingEnabledOnReserve(asset, stableBorrowRateEnabled); - } - - /// @inheritdoc IPoolConfigurator - function disableBorrowingOnReserve(address asset) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setBorrowingEnabled(false); - _pool.setConfiguration(asset, currentConfig.data); - emit BorrowingDisabledOnReserve(asset); - } - - /// @inheritdoc IPoolConfigurator - function configureReserveAsCollateral( - address asset, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus - ) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - //validation of the parameters: the LTV can - //only be lower or equal than the liquidation threshold - //(otherwise a loan against the asset would cause instantaneous liquidation) - require(ltv <= liquidationThreshold, Errors.PC_INVALID_CONFIGURATION); - - if (liquidationThreshold != 0) { - //liquidation bonus must be bigger than 100.00%, otherwise the liquidator would receive less - //collateral than needed to cover the debt - require(liquidationBonus > PercentageMath.PERCENTAGE_FACTOR, Errors.PC_INVALID_CONFIGURATION); - - //if threshold * bonus is less than PERCENTAGE_FACTOR, it's guaranteed that at the moment - //a loan is taken there is enough collateral available to cover the liquidation bonus - require( - liquidationThreshold.percentMul(liquidationBonus) <= PercentageMath.PERCENTAGE_FACTOR, - Errors.PC_INVALID_CONFIGURATION - ); - } else { - require(liquidationBonus == 0, Errors.PC_INVALID_CONFIGURATION); - //if the liquidation threshold is being set to 0, - // the reserve is being disabled as collateral. To do so, - //we need to ensure no liquidity is supplied - // _checkNoSuppliers(asset); - } - - currentConfig.setLtv(ltv); - currentConfig.setLiquidationThreshold(liquidationThreshold); - currentConfig.setLiquidationBonus(liquidationBonus); - - _pool.setConfiguration(asset, currentConfig.data); - - emit CollateralConfigurationChanged(asset, ltv, liquidationThreshold, liquidationBonus); - } - - /// @inheritdoc IPoolConfigurator - function enableReserveStableRate(address asset) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setStableRateBorrowingEnabled(true); - _pool.setConfiguration(asset, currentConfig.data); - - emit StableRateEnabledOnReserve(asset); - } - - /// @inheritdoc IPoolConfigurator - function disableReserveStableRate(address asset) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setStableRateBorrowingEnabled(false); - _pool.setConfiguration(asset, currentConfig.data); - emit StableRateDisabledOnReserve(asset); - } - - /// @inheritdoc IPoolConfigurator - function activateReserve(address asset) external override onlyPoolAdmin { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setActive(true); - _pool.setConfiguration(asset, currentConfig.data); - emit ReserveActivated(asset); - } - - /// @inheritdoc IPoolConfigurator - function deactivateReserve(address asset) external override onlyPoolAdmin { - _checkNoSuppliers(asset); - - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setActive(false); - _pool.setConfiguration(asset, currentConfig.data); - emit ReserveDeactivated(asset); - } - - /// @inheritdoc IPoolConfigurator - function freezeReserve(address asset) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setFrozen(true); - _pool.setConfiguration(asset, currentConfig.data); - emit ReserveFrozen(asset); - } - - /// @inheritdoc IPoolConfigurator - function unfreezeReserve(address asset) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setFrozen(false); - _pool.setConfiguration(asset, currentConfig.data); - emit ReserveUnfrozen(asset); - } - - /// @inheritdoc IPoolConfigurator - function setBorrowableInIsolation(address asset, bool borrowable) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setBorrowableInIsolation(borrowable); - _pool.setConfiguration(asset, currentConfig.data); - emit BorrowableInIsolationChanged(asset, borrowable); - } - - /// @inheritdoc IPoolConfigurator - function setReservePause(address asset, bool paused) public override onlyEmergencyOrPoolAdmin { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setPaused(paused); - - _pool.setConfiguration(asset, currentConfig.data); - - if (paused) { - emit ReservePaused(asset); - } else { - emit ReserveUnpaused(asset); - } - } - - function setReserveFactor(address asset, uint256 reserveFactor) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setReserveFactor(reserveFactor); - _pool.setConfiguration(asset, currentConfig.data); - emit ReserveFactorChanged(asset, reserveFactor); - } - - /// @inheritdoc IPoolConfigurator - function setDebtCeiling(address asset, uint256 ceiling) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - if (currentConfig.getDebtCeiling() == 0) { - _checkNoSuppliers(asset); - } - currentConfig.setDebtCeiling(ceiling); - _pool.setConfiguration(asset, currentConfig.data); - emit DebtCeilingChanged(asset, ceiling); - } - - /// @inheritdoc IPoolConfigurator - function setBorrowCap(address asset, uint256 borrowCap) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setBorrowCap(borrowCap); - _pool.setConfiguration(asset, currentConfig.data); - emit BorrowCapChanged(asset, borrowCap); - } - - /// @inheritdoc IPoolConfigurator - function setSupplyCap(address asset, uint256 supplyCap) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setSupplyCap(supplyCap); - _pool.setConfiguration(asset, currentConfig.data); - emit SupplyCapChanged(asset, supplyCap); - } - - /// @inheritdoc IPoolConfigurator - function setLiquidationProtocolFee(address asset, uint256 fee) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - currentConfig.setLiquidationProtocolFee(fee); - - _pool.setConfiguration(asset, currentConfig.data); - - emit LiquidationProtocolFeeChanged(asset, fee); - } - - function setEModeCategory( - uint8 categoryId, - uint16 ltv, - uint16 liquidationThreshold, - uint16 liquidationBonus, - address oracle, - string calldata label - ) external override onlyRiskOrPoolAdmins { - // validation of the parameters: the LTV can - // only be lower or equal than the liquidation threshold - // (otherwise a loan against the asset would cause instantaneous liquidation) - require(ltv <= liquidationThreshold, Errors.VL_INCONSISTENT_EMODE_CATEGORY); - require( - liquidationBonus > PercentageMath.PERCENTAGE_FACTOR, - Errors.VL_INCONSISTENT_EMODE_CATEGORY - ); - - // if threshold * bonus is less than PERCENTAGE_FACTOR, it's guaranteed that at the moment - // a loan is taken there is enough collateral available to cover the liquidation bonus - require( - uint256(liquidationThreshold).percentMul(liquidationBonus) <= - PercentageMath.PERCENTAGE_FACTOR, - Errors.VL_INCONSISTENT_EMODE_CATEGORY - ); - - _pool.configureEModeCategory( - categoryId, - DataTypes.EModeCategory(ltv, liquidationThreshold, liquidationBonus, oracle, label) - ); - emit EModeCategoryAdded(categoryId, ltv, liquidationThreshold, liquidationBonus, oracle, label); - } - - /// @inheritdoc IPoolConfigurator - function setAssetEModeCategory(address asset, uint8 categoryId) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - if (categoryId > 0) { - DataTypes.EModeCategory memory categoryData = _pool.getEModeCategoryData(categoryId); - require( - categoryData.liquidationThreshold > currentConfig.getLiquidationThreshold(), - Errors.VL_INCONSISTENT_EMODE_CATEGORY - ); - } - - currentConfig.setEModeCategory(categoryId); - - _pool.setConfiguration(asset, currentConfig.data); - - emit EModeAssetCategoryChanged(asset, categoryId); - } - - /// @inheritdoc IPoolConfigurator - function setUnbackedMintCap(address asset, uint256 unbackedMintCap) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - currentConfig.setUnbackedMintCap(unbackedMintCap); - - _pool.setConfiguration(asset, currentConfig.data); - - emit UnbackedMintCapChanged(asset, unbackedMintCap); - } - - /// @inheritdoc IPoolConfigurator - function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) - external - override - onlyRiskOrPoolAdmins - { - _pool.setReserveInterestRateStrategyAddress(asset, rateStrategyAddress); - emit ReserveInterestRateStrategyChanged(asset, rateStrategyAddress); - } - - /// @inheritdoc IPoolConfigurator - function setPoolPause(bool paused) external override onlyEmergencyAdmin { - address[] memory reserves = _pool.getReservesList(); - - for (uint256 i = 0; i < reserves.length; i++) { - if (reserves[i] != address(0)) { - setReservePause(reserves[i], paused); - } - } - } - - /// @inheritdoc IPoolConfigurator - function updateBridgeProtocolFee(uint256 protocolFee) external override onlyPoolAdmin { - require(protocolFee < PercentageMath.PERCENTAGE_FACTOR, Errors.PC_BRIDGE_PROTOCOL_FEE_INVALID); - _pool.updateBridgeProtocolFee(protocolFee); - emit BridgeProtocolFeeUpdated(protocolFee); - } - - /// @inheritdoc IPoolConfigurator - function updateFlashloanPremiumTotal(uint256 flashloanPremiumTotal) - external - override - onlyPoolAdmin - { - require( - flashloanPremiumTotal < PercentageMath.PERCENTAGE_FACTOR, - Errors.PC_FLASHLOAN_PREMIUM_INVALID - ); - require( - flashloanPremiumTotal >= _pool.FLASHLOAN_PREMIUM_TO_PROTOCOL(), - Errors.PC_FLASHLOAN_PREMIUMS_MISMATCH - ); - _pool.updateFlashloanPremiums(flashloanPremiumTotal, _pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()); - emit FlashloanPremiumTotalUpdated(flashloanPremiumTotal); - } - - /// @inheritdoc IPoolConfigurator - function updateFlashloanPremiumToProtocol(uint256 flashloanPremiumToProtocol) - external - override - onlyPoolAdmin - { - require( - flashloanPremiumToProtocol < PercentageMath.PERCENTAGE_FACTOR, - Errors.PC_FLASHLOAN_PREMIUM_INVALID - ); - require( - flashloanPremiumToProtocol <= _pool.FLASHLOAN_PREMIUM_TOTAL(), - Errors.PC_FLASHLOAN_PREMIUMS_MISMATCH - ); - _pool.updateFlashloanPremiums(_pool.FLASHLOAN_PREMIUM_TOTAL(), flashloanPremiumToProtocol); - emit FlashloanPremiumToProtocolUpdated(flashloanPremiumToProtocol); - } - - function _checkNoSuppliers(address asset) internal view { - uint256 totalATokens = IPoolDataProvider(_addressesProvider.getPoolDataProvider()) - .getATokenTotalSupply(asset); - require(totalATokens == 0, Errors.PC_RESERVE_LIQUIDITY_NOT_0); - } - - function getLtv(address asset) public view returns (uint256) { - return _pool.getLtv(asset); - } - - function getLiquidationThreshold(address asset) public view returns (uint256) { - return _pool.getLiquidationThreshold(asset); - } - - function getLiquidationBonus(address asset) public view returns (uint256) { - return _pool.getLiquidationBonus(asset); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolHarnessForConfigurator.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolHarnessForConfigurator.sol deleted file mode 100644 index a27cd77..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolHarnessForConfigurator.sol +++ /dev/null @@ -1,757 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import {IERC20} from '../../contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -import {Address} from '../../contracts/dependencies/openzeppelin/contracts/Address.sol'; -import {VersionedInitializable} from '../../contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol'; -import {Errors} from '../../contracts/protocol/libraries/helpers/Errors.sol'; -import {WadRayMath} from '../../contracts/protocol/libraries/math/WadRayMath.sol'; -import {ReserveLogic} from '../../contracts/protocol/libraries/logic/ReserveLogic.sol'; -import {GenericLogic} from '../../contracts/protocol/libraries/logic/GenericLogic.sol'; -import {ValidationLogic} from '../../contracts/protocol/libraries/logic/ValidationLogic.sol'; -import {EModeLogic} from '../../contracts/protocol/libraries/logic/EModeLogic.sol'; -// import {SupplyLogic} from '../../contracts/protocol/libraries/logic/SupplyLogic.sol'; -// import {FlashLoanLogic} from '../../contracts/protocol/libraries/logic/FlashLoanLogic.sol'; -// import {BorrowLogic} from '../../contracts/protocol/libraries/logic/BorrowLogic.sol'; -// import {LiquidationLogic} from '../../contracts/protocol/libraries/logic/LiquidationLogic.sol'; -import {ReserveConfiguration} from '../../contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; -import {BridgeLogic} from '../../contracts/protocol/libraries/logic/BridgeLogic.sol'; -import {IERC20WithPermit} from '../../contracts/interfaces/IERC20WithPermit.sol'; -import {IPoolAddressesProvider} from '../../contracts/interfaces/IPoolAddressesProvider.sol'; -import {IAToken} from '../../contracts/interfaces/IAToken.sol'; -import {IPool} from '../../contracts/interfaces/IPool.sol'; -import {IACLManager} from '../../contracts/interfaces/IACLManager.sol'; -import {PoolStorage} from '../../contracts/protocol/pool/PoolStorage.sol'; -import {Helpers} from '../../contracts/protocol/libraries/helpers/Helpers.sol'; - -/** - * @title Pool contract - * @author Aave - * @notice Main point of interaction with an Aave protocol's market - * - Users can: - * # Supply - * # Withdraw - * # Borrow - * # Repay - * # Swap their loans between variable and stable rate - * # Enable/disable their supplied assets as collateral rebalance stable rate borrow positions - * # Liquidate positions - * # Execute Flash Loans - * @dev To be covered by a proxy contract, owned by the PoolAddressesProvider of the specific market - * @dev All admin functions are callable by the PoolConfigurator contract defined also in the - * PoolAddressesProvider - **/ -contract PoolHarnessForConfigurator is VersionedInitializable, IPool, PoolStorage { - using WadRayMath for uint256; - using ReserveLogic for DataTypes.ReserveData; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - - uint256 public constant POOL_REVISION = 0x2; - IPoolAddressesProvider internal immutable _addressesProvider; - - modifier onlyPoolConfigurator() { - // _onlyPoolConfigurator(); - _; - } - - modifier onlyBridge() { - _onlyBridge(); - _; - } - - function _onlyPoolConfigurator() internal view { - require( - _addressesProvider.getPoolConfigurator() == msg.sender, - Errors.P_CALLER_NOT_POOL_CONFIGURATOR - ); - } - - function _onlyBridge() internal view { - require( - IACLManager(_addressesProvider.getACLManager()).isBridge(msg.sender), - Errors.P_CALLER_NOT_BRIDGE - ); - } - - function getRevision() internal pure virtual override returns (uint256) { - return POOL_REVISION; - } - - constructor(IPoolAddressesProvider provider) { - _addressesProvider = provider; - } - - /** - * @notice Initializes the Pool. - * @dev Function is invoked by the proxy contract when the Pool contract is added to the - * PoolAddressesProvider of the market. - * @dev Caching the address of the PoolAddressesProvider in order to reduce gas consumption on subsequent operations - * @param provider The address of the PoolAddressesProvider - **/ - function initialize(IPoolAddressesProvider provider) external initializer { - require(provider == _addressesProvider, Errors.PC_INVALID_CONFIGURATION); - _maxStableRateBorrowSizePercent = 2500; - _flashLoanPremiumTotal = 9; - _flashLoanPremiumToProtocol = 0; - } - - ///@inheritdoc IPool - function mintUnbacked( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external override onlyBridge { - // BridgeLogic.mintUnbacked( - // _reserves, - // _reservesList, - // _reserves[asset], - // _usersConfig[onBehalfOf], - // asset, - // amount, - // onBehalfOf, - // referralCode - // ); - } - - ///@inheritdoc IPool - function backUnbacked( - address asset, - uint256 amount, - uint256 fee - ) external override onlyBridge { - // BridgeLogic.backUnbacked(_reserves[asset], asset, amount, fee, _bridgeProtocolFee); - } - - /// @inheritdoc IPool - function supply( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external override { - // SupplyLogic.executeSupply( - // _reserves, - // _reservesList, - // _usersConfig[onBehalfOf], - // DataTypes.ExecuteSupplyParams(asset, amount, onBehalfOf, referralCode) - // ); - } - - /// @inheritdoc IPool - function supplyWithPermit( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) external override { - // IERC20WithPermit(asset).permit( - // msg.sender, - // address(this), - // amount, - // deadline, - // permitV, - // permitR, - // permitS - // ); - // SupplyLogic.executeSupply( - // _reserves, - // _reservesList, - // _usersConfig[onBehalfOf], - // DataTypes.ExecuteSupplyParams(asset, amount, onBehalfOf, referralCode) - // ); - } - - /// @inheritdoc IPool - function withdraw( - address asset, - uint256 amount, - address to - ) external override returns (uint256) { - // return - // SupplyLogic.executeWithdraw( - // _reserves, - // _reservesList, - // _eModeCategories, - // _usersConfig[msg.sender], - // DataTypes.ExecuteWithdrawParams( - // asset, - // amount, - // to, - // _reservesCount, - // _addressesProvider.getPriceOracle(), - // _usersEModeCategory[msg.sender] - // ) - // ); - return 17; - } - - /// @inheritdoc IPool - function borrow( - address asset, - uint256 amount, - uint256 interestRateMode, - uint16 referralCode, - address onBehalfOf - ) external override { - // BorrowLogic.executeBorrow( - // _reserves, - // _reservesList, - // _eModeCategories, - // _usersConfig[onBehalfOf], - // DataTypes.ExecuteBorrowParams( - // asset, - // msg.sender, - // onBehalfOf, - // amount, - // interestRateMode, - // referralCode, - // true, - // _maxStableRateBorrowSizePercent, - // _reservesCount, - // _addressesProvider.getPriceOracle(), - // _usersEModeCategory[onBehalfOf], - // _addressesProvider.getPriceOracleSentinel() - // ) - // ); - } - - /// @inheritdoc IPool - function repay( - address asset, - uint256 amount, - uint256 rateMode, - address onBehalfOf - ) external override returns (uint256) { - // return - // BorrowLogic.executeRepay( - // _reserves, - // _reservesList, - // _reserves[asset], - // _usersConfig[onBehalfOf], - // DataTypes.ExecuteRepayParams(asset, amount, rateMode, onBehalfOf, false) - // ); - return 18; - } - - /// @inheritdoc IPool - function repayWithPermit( - address asset, - uint256 amount, - uint256 rateMode, - address onBehalfOf, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) external override returns (uint256) { - // { - // IERC20WithPermit(asset).permit( - // msg.sender, - // address(this), - // amount, - // deadline, - // permitV, - // permitR, - // permitS - // ); - // } - // { - // DataTypes.ExecuteRepayParams memory params = DataTypes.ExecuteRepayParams( - // asset, - // amount, - // rateMode, - // onBehalfOf, - // false - // ); - // return - // BorrowLogic.executeRepay( - // _reserves, - // _reservesList, - // _reserves[asset], - // _usersConfig[onBehalfOf], - // params - // ); - // } - return 19; - } - - /// @inheritdoc IPool - function repayWithATokens( - address asset, - uint256 amount, - uint256 rateMode - ) external override returns (uint256) { - // return - // BorrowLogic.executeRepay( - // _reserves, - // _reservesList, - // _reserves[asset], - // _usersConfig[msg.sender], - // DataTypes.ExecuteRepayParams(asset, amount, rateMode, msg.sender, true) - // ); - return 20; - } - - /// @inheritdoc IPool - function swapBorrowRateMode(address asset, uint256 rateMode) external override { - // BorrowLogic.swapBorrowRateMode(_reserves[asset], _usersConfig[msg.sender], asset, rateMode); - } - - /// @inheritdoc IPool - function rebalanceStableBorrowRate(address asset, address user) external override { - // BorrowLogic.rebalanceStableBorrowRate(_reserves[asset], asset, user); - } - - /// @inheritdoc IPool - function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override { - // SupplyLogic.executeUseReserveAsCollateral( - // _reserves, - // _reservesList, - // _eModeCategories, - // _usersConfig[msg.sender], - // asset, - // useAsCollateral, - // _reservesCount, - // _addressesProvider.getPriceOracle(), - // _usersEModeCategory[msg.sender] - // ); - } - - /// @inheritdoc IPool - function liquidationCall( - address collateralAsset, - address debtAsset, - address user, - uint256 debtToCover, - bool receiveAToken - ) external override { - // LiquidationLogic.executeLiquidationCall( - // _reserves, - // _usersConfig, - // _reservesList, - // _eModeCategories, - // DataTypes.ExecuteLiquidationCallParams( - // _reservesCount, - // debtToCover, - // collateralAsset, - // debtAsset, - // user, - // receiveAToken, - // _addressesProvider.getPriceOracle(), - // _usersEModeCategory[user], - // _addressesProvider.getPriceOracleSentinel() - // ) - // ); - } - - /// @inheritdoc IPool - function flashLoan( - address receiverAddress, - address[] calldata assets, - uint256[] calldata amounts, - uint256[] calldata modes, - address onBehalfOf, - bytes calldata params, - uint16 referralCode - ) external override { - // DataTypes.FlashloanParams memory flashParams = DataTypes.FlashloanParams( - // receiverAddress, - // assets, - // amounts, - // modes, - // onBehalfOf, - // params, - // referralCode, - // _flashLoanPremiumToProtocol, - // _flashLoanPremiumTotal, - // _maxStableRateBorrowSizePercent, - // _reservesCount, - // address(_addressesProvider), - // _usersEModeCategory[onBehalfOf], - // IACLManager(_addressesProvider.getACLManager()).isFlashBorrower(msg.sender) - // ); - - // FlashLoanLogic.executeFlashLoan( - // _reserves, - // _reservesList, - // _eModeCategories, - // _usersConfig[onBehalfOf], - // flashParams - // ); - } - - /// @inheritdoc IPool - function flashLoanSimple( - address receiverAddress, - address asset, - uint256 amount, - bytes calldata params, - uint16 referralCode - ) external override { - // DataTypes.FlashloanSimpleParams memory flashParams = DataTypes.FlashloanSimpleParams( - // receiverAddress, - // asset, - // amount, - // params, - // referralCode, - // _flashLoanPremiumToProtocol, - // _flashLoanPremiumTotal - // ); - // FlashLoanLogic.executeFlashLoanSimple(_reserves[asset], flashParams); - } - - /// @inheritdoc IPool - function mintToTreasury(address[] calldata assets) external override { - // for (uint256 i = 0; i < assets.length; i++) { - // address assetAddress = assets[i]; - - // DataTypes.ReserveData storage reserve = _reserves[assetAddress]; - - // // this cover both inactive reserves and invalid reserves since the flag will be 0 for both - // if (!reserve.configuration.getActive()) { - // continue; - // } - - // uint256 accruedToTreasury = reserve.accruedToTreasury; - - // if (accruedToTreasury != 0) { - // reserve.accruedToTreasury = 0; - // uint256 normalizedIncome = reserve.getNormalizedIncome(); - // uint256 amountToMint = accruedToTreasury.rayMul(normalizedIncome); - // IAToken(reserve.aTokenAddress).mintToTreasury(amountToMint, normalizedIncome); - - // emit MintedToTreasury(assetAddress, amountToMint); - // } - // } - } - - /// @inheritdoc IPool - function getReserveData(address asset) - external - view - override - returns (DataTypes.ReserveData memory) - { - return _reserves[asset]; - } - - /// @inheritdoc IPool - function getUserAccountData(address user) - external - view - override - returns ( - uint256 totalCollateralBase, - uint256 totalDebtBase, - uint256 availableBorrowsBase, - uint256 currentLiquidationThreshold, - uint256 ltv, - uint256 healthFactor - ) - { - ( - totalCollateralBase, - totalDebtBase, - ltv, - currentLiquidationThreshold, - healthFactor, - - ) = GenericLogic.calculateUserAccountData( - _reserves, - _reservesList, - _eModeCategories, - DataTypes.CalculateUserAccountDataParams( - _usersConfig[user], - _reservesCount, - user, - _addressesProvider.getPriceOracle(), - _usersEModeCategory[user] - ) - ); - - availableBorrowsBase = GenericLogic.calculateAvailableBorrows( - totalCollateralBase, - totalDebtBase, - ltv - ); - } - - /// @inheritdoc IPool - function getConfiguration(address asset) - external - view - override - returns (DataTypes.ReserveConfigurationMap memory) - { - return _reserves[asset].configuration; - } - - /// @inheritdoc IPool - function getUserConfiguration(address user) - external - view - override - returns (DataTypes.UserConfigurationMap memory) - { - return _usersConfig[user]; - } - - /// @inheritdoc IPool - function getReserveNormalizedIncome(address asset) - external - view - virtual - override - returns (uint256) - { - return _reserves[asset].getNormalizedIncome(); - } - - /// @inheritdoc IPool - function getReserveNormalizedVariableDebt(address asset) - external - view - override - returns (uint256) - { - return _reserves[asset].getNormalizedDebt(); - } - - /// @inheritdoc IPool - function getReservesList() external view override returns (address[] memory) { - uint256 reserveListCount = _reservesCount; - uint256 droppedReservesCount = 0; - address[] memory reserves = new address[](reserveListCount); - - for (uint256 i = 0; i < reserveListCount; i++) { - if (_reservesList[i] != address(0)) { - reserves[i - droppedReservesCount] = _reservesList[i]; - } else { - droppedReservesCount++; - } - } - - if (droppedReservesCount == 0) return reserves; - - address[] memory undroppedReserves = new address[](reserveListCount - droppedReservesCount); - for (uint256 i = 0; i < reserveListCount - droppedReservesCount; i++) { - undroppedReserves[i] = reserves[i]; - } - - return undroppedReserves; - } - - /// @inheritdoc IPool - function getAddressesProvider() external view override returns (IPoolAddressesProvider) { - return _addressesProvider; - } - - /// @inheritdoc IPool - function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() public view override returns (uint256) { - return _maxStableRateBorrowSizePercent; - } - - /// @inheritdoc IPool - function BRIDGE_PROTOCOL_FEE() public view override returns (uint256) { - return _bridgeProtocolFee; - } - - /// @inheritdoc IPool - function FLASHLOAN_PREMIUM_TOTAL() public view override returns (uint256) { - return _flashLoanPremiumTotal; - } - - /// @inheritdoc IPool - function FLASHLOAN_PREMIUM_TO_PROTOCOL() public view override returns (uint256) { - return _flashLoanPremiumToProtocol; - } - - /// @inheritdoc IPool - function MAX_NUMBER_RESERVES() public view virtual override returns (uint256) { - return ReserveConfiguration.MAX_RESERVES_COUNT; - } - - /// @inheritdoc IPool - function finalizeTransfer( - address asset, - address from, - address to, - uint256 amount, - uint256 balanceFromBefore, - uint256 balanceToBefore - ) external override { - // require(msg.sender == _reserves[asset].aTokenAddress, Errors.P_CALLER_MUST_BE_AN_ATOKEN); - // SupplyLogic.finalizeTransfer( - // _reserves, - // _reservesList, - // _eModeCategories, - // _usersConfig, - // DataTypes.FinalizeTransferParams( - // asset, - // from, - // to, - // amount, - // balanceFromBefore, - // balanceToBefore, - // _reservesCount, - // _addressesProvider.getPriceOracle(), - // _usersEModeCategory[from], - // _usersEModeCategory[to] - // ) - // ); - } - - /// @inheritdoc IPool - function initReserve( - address asset, - address aTokenAddress, - address stableDebtAddress, - address variableDebtAddress, - address interestRateStrategyAddress - ) external override onlyPoolConfigurator { - require(Address.isContract(asset), Errors.P_NOT_CONTRACT); - _reserves[asset].init( - aTokenAddress, - stableDebtAddress, - variableDebtAddress, - interestRateStrategyAddress - ); - _addReserveToList(asset); - } - - /// @inheritdoc IPool - function dropReserve(address asset) external override onlyPoolConfigurator { - DataTypes.ReserveData storage reserve = _reserves[asset]; - ValidationLogic.validateDropReserve(reserve); - _reservesList[_reserves[asset].id] = address(0); - delete _reserves[asset]; - } - - /// @inheritdoc IPool - function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) - external - override - onlyPoolConfigurator - { - _reserves[asset].interestRateStrategyAddress = rateStrategyAddress; - } - - /// @inheritdoc IPool - function setConfiguration(address asset, uint256 configuration) - external - override - onlyPoolConfigurator - { - _reserves[asset].configuration.data = configuration; - } - - /// @inheritdoc IPool - function updateBridgeProtocolFee(uint256 protocolFee) external override onlyPoolConfigurator { - _bridgeProtocolFee = protocolFee; - } - - /// @inheritdoc IPool - function updateFlashloanPremiums( - uint256 flashLoanPremiumTotal, - uint256 flashLoanPremiumToProtocol - ) external override onlyPoolConfigurator { - _flashLoanPremiumTotal = Helpers.castUint128(flashLoanPremiumTotal); - _flashLoanPremiumToProtocol = Helpers.castUint128(flashLoanPremiumToProtocol); - } - - /// @inheritdoc IPool - function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory category) - external - override - onlyPoolConfigurator - { - // category 0 is reserved for volatile heterogeneous assets and it's always disabled - require(id != 0, Errors.RC_INVALID_EMODE_CATEGORY); - _eModeCategories[id] = category; - } - - /// @inheritdoc IPool - function getEModeCategoryData(uint8 id) - external - view - override - returns (DataTypes.EModeCategory memory) - { - return _eModeCategories[id]; - } - - /// @inheritdoc IPool - function setUserEMode(uint8 categoryId) external virtual override { - EModeLogic.executeSetUserEMode( - _reserves, - _reservesList, - _eModeCategories, - _usersEModeCategory, - _usersConfig[msg.sender], - DataTypes.ExecuteSetUserEModeParams( - _reservesCount, - _addressesProvider.getPriceOracle(), - categoryId - ) - ); - } - - /// @inheritdoc IPool - function getUserEMode(address user) external view override returns (uint256) { - return _usersEModeCategory[user]; - } - - function _addReserveToList(address asset) internal { - bool reserveAlreadyAdded = _reserves[asset].id != 0 || _reservesList[0] == asset; - require(!reserveAlreadyAdded, Errors.RL_RESERVE_ALREADY_INITIALIZED); - - uint16 reservesCount = _reservesCount; - - for (uint16 i = 0; i < reservesCount; i++) { - if (_reservesList[i] == address(0)) { - _reserves[asset].id = i; - _reservesList[i] = asset; - return; - } - } - require(reservesCount < MAX_NUMBER_RESERVES(), Errors.P_NO_MORE_RESERVES_ALLOWED); - _reserves[asset].id = reservesCount; - _reservesList[reservesCount] = asset; - // no need to check for overflow - the require above must ensure that max number of reserves < type(uint16).max - _reservesCount = reservesCount + 1; - } - - /// @inheritdoc IPool - /// @dev Deprecated: mantained for compatibilty purposes - function deposit( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external override { - // SupplyLogic.executeSupply( - // _reserves, - // _reservesList, - // _usersConfig[onBehalfOf], - // DataTypes.ExecuteSupplyParams(asset, amount, onBehalfOf, referralCode) - // ); - } - - function getLtv(address asset) public view returns (uint256) { - return _reserves[asset].configuration.getLtv(); - } - - function getLiquidationThreshold(address asset) public view returns (uint256) { - return _reserves[asset].configuration.getLiquidationThreshold(); - } - - function getLiquidationBonus(address asset) public view returns (uint256) { - return _reserves[asset].configuration.getLiquidationBonus(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolHarnessForVariableDebtToken.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolHarnessForVariableDebtToken.sol deleted file mode 100644 index c2f11c3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/PoolHarnessForVariableDebtToken.sol +++ /dev/null @@ -1,203 +0,0 @@ -pragma solidity 0.6.12; -pragma experimental ABIEncoderV2; - -import {IPool} from '../../contracts/interfaces/IPool.sol'; -import {Pool} from '../../contracts/protocol/pool/Pool.sol'; -import { - IPoolAddressesProvider -} from '../../contracts/interfaces/IPoolAddressesProvider.sol'; -import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; - -/* -Certora: Harness that delegates calls to the original Pool. -Used for the verification of the VariableDebtToken contract. -*/ -contract PoolHarnessForVariableDebtToken is IPool { - Pool private originalPool; - - function deposit( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external override { - originalPool.deposit(asset, amount, onBehalfOf, referralCode); - } - - function withdraw( - address asset, - uint256 amount, - address to - ) external override returns (uint256) { - return originalPool.withdraw(asset, amount, to); - } - - function borrow( - address asset, - uint256 amount, - uint256 interestRateMode, - uint16 referralCode, - address onBehalfOf - ) external override { - originalPool.borrow(asset, amount, interestRateMode, referralCode, onBehalfOf); - } - - function repay( - address asset, - uint256 amount, - uint256 rateMode, - address onBehalfOf - ) external override returns (uint256) { - return originalPool.repay(asset, amount, rateMode, onBehalfOf); - } - - function swapBorrowRateMode(address asset, uint256 rateMode) external override { - originalPool.swapBorrowRateMode(asset, rateMode); - } - - function rebalanceStableBorrowRate(address asset, address user) external override { - originalPool.rebalanceStableBorrowRate(asset, user); - } - - function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override { - originalPool.setUserUseReserveAsCollateral(asset, useAsCollateral); - } - - function liquidationCall( - address collateral, - address asset, - address user, - uint256 debtToCover, - bool receiveAToken - ) external override { - originalPool.liquidationCall(collateral, asset, user, debtToCover, receiveAToken); - } - - function getReservesList() external view override returns (address[] memory) { - return originalPool.getReservesList(); - } - - function getReserveData(address asset) - external - view - override - returns (DataTypes.ReserveData memory) - { - return originalPool.getReserveData(asset); - } - - function getUserConfiguration(address user) - external - view - override - returns (DataTypes.UserConfigurationMap memory) - { - return originalPool.getUserConfiguration(user); - } - - function getUserAccountData(address user) - external - view - override - returns ( - uint256 totalCollateralBase, - uint256 totalDebtBase, - uint256 availableBorrowsBase, - uint256 currentLiquidationThreshold, - uint256 ltv, - uint256 healthFactor - ) - { - return originalPool.getUserAccountData(user); - } - - function initReserve( - address asset, - address aTokenAddress, - address stableDebtAddress, - address variableDebtAddress, - address interestRateStrategyAddress - ) external override { - originalPool.initReserve( - asset, - aTokenAddress, - stableDebtAddress, - variableDebtAddress, - interestRateStrategyAddress - ); - } - - function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) - external - override - { - originalPool.setReserveInterestRateStrategyAddress(asset, rateStrategyAddress); - } - - function setConfiguration(address asset, uint256 configuration) external override { - originalPool.setConfiguration(asset, configuration); - } - - function getConfiguration(address asset) - external - view - override - returns (DataTypes.ReserveConfigurationMap memory) - { - return originalPool.getConfiguration(asset); - } - - mapping(uint256 => uint256) private reserveNormalizedIncome; - - function getReserveNormalizedIncome(address asset) external view override returns (uint256) { - require(reserveNormalizedIncome[block.timestamp] == 1e27); - return reserveNormalizedIncome[block.timestamp]; - } - - mapping(uint256 => uint256) private reserveNormalizedVariableDebt; - - function getReserveNormalizedVariableDebt(address asset) - external - view - override - returns (uint256) - { - require(reserveNormalizedVariableDebt[block.timestamp] == 1e27); - return reserveNormalizedVariableDebt[block.timestamp]; - } - - function setPause(bool val) external override { - originalPool.setPause(val); - } - - function paused() external view override returns (bool) { - return originalPool.paused(); - } - - function flashLoan( - address receiver, - address[] calldata assets, - uint256[] calldata amounts, - uint256[] calldata modes, - address onBehalfOf, - bytes calldata params, - uint16 referralCode - ) external override { - originalPool.flashLoan(receiver, assets, amounts, modes, onBehalfOf, params, referralCode); - } - - function finalizeTransfer( - address asset, - address from, - address to, - uint256 amount, - uint256 balanceFromAfter, - uint256 balanceToBefore - ) external override { - originalPool.finalizeTransfer(asset, from, to, amount, balanceFromAfter, balanceToBefore); - } - - function getAddressesProvider() external view override returns (IPoolAddressesProvider) { - return originalPool.getAddressesProvider(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/ReserveConfigurationHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/ReserveConfigurationHarness.sol deleted file mode 100644 index 2bdd2e8..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/ReserveConfigurationHarness.sol +++ /dev/null @@ -1,325 +0,0 @@ -pragma solidity 0.8.10; -pragma experimental ABIEncoderV2; - -import {ReserveConfiguration} from '../../contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; - -contract ReserveConfigurationHarness { - DataTypes.ReserveConfigurationMap public reservesConfig; - mapping(uint256 => uint256) public intSettersUpperBounds; - mapping(uint256 => uint256) public intSetterslowerBounds; - mapping(uint256 => uint256) public boolSettersCompare; - - function setLtv(uint256 ltv) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setLtv(configNew, ltv); - reservesConfig.data = configNew.data; - } - - function getLtv() public view returns (uint256) { - return ReserveConfiguration.getLtv(reservesConfig); - } - - function setLiquidationThreshold(uint256 threshold) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setLiquidationThreshold(configNew, threshold); - reservesConfig.data = configNew.data; - } - - function getLiquidationThreshold() public view returns (uint256) { - return ReserveConfiguration.getLiquidationThreshold(reservesConfig); - } - - function setLiquidationBonus(uint256 bonus) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setLiquidationBonus(configNew, bonus); - reservesConfig.data = configNew.data; - } - - function getLiquidationBonus() public view returns (uint256) { - return ReserveConfiguration.getLiquidationBonus(reservesConfig); - } - - function setDecimals(uint256 decimals) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setDecimals(configNew, decimals); - reservesConfig.data = configNew.data; - } - - function getDecimals() public view returns (uint256) { - return ReserveConfiguration.getDecimals(reservesConfig); - } - - function setActive(bool active) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setActive(configNew, active); - reservesConfig.data = configNew.data; - } - - function getActive() public view returns (bool) { - return ReserveConfiguration.getActive(reservesConfig); - } - - function setFrozen(bool frozen) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setFrozen(configNew, frozen); - reservesConfig.data = configNew.data; - } - - function getFrozen() public view returns (bool) { - return ReserveConfiguration.getFrozen(reservesConfig); - } - - function setPaused(bool paused) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setPaused(configNew, paused); - reservesConfig.data = configNew.data; - } - - function getPaused() public view returns (bool) { - return ReserveConfiguration.getPaused(reservesConfig); - } - - function setBorrowingEnabled(bool enabled) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setBorrowingEnabled(configNew, enabled); - reservesConfig.data = configNew.data; - } - - function getBorrowingEnabled() public view returns (bool) { - return ReserveConfiguration.getBorrowingEnabled(reservesConfig); - } - - function setStableRateBorrowingEnabled(bool enabled) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setStableRateBorrowingEnabled(configNew, enabled); - reservesConfig.data = configNew.data; - } - - function getStableRateBorrowingEnabled() public view returns (bool) { - return ReserveConfiguration.getStableRateBorrowingEnabled(reservesConfig); - } - - function setBorrowableInIsolation(bool borrowable) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setBorrowableInIsolation(configNew, borrowable); - reservesConfig.data = configNew.data; - } - - function getBorrowableInIsolation() public view returns (bool) { - return ReserveConfiguration.getBorrowableInIsolation(reservesConfig); - } - - function setReserveFactor(uint256 reserveFactor) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setReserveFactor(configNew, reserveFactor); - reservesConfig.data = configNew.data; - } - - function getReserveFactor() public view returns (uint256) { - return ReserveConfiguration.getReserveFactor(reservesConfig); - } - - function setBorrowCap(uint256 borrowCap) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setBorrowCap(configNew, borrowCap); - reservesConfig.data = configNew.data; - } - - function getBorrowCap() public view returns (uint256) { - return ReserveConfiguration.getBorrowCap(reservesConfig); - } - - function setSupplyCap(uint256 supplyCap) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setSupplyCap(configNew, supplyCap); - reservesConfig.data = configNew.data; - } - - function getSupplyCap() public view returns (uint256) { - return ReserveConfiguration.getSupplyCap(reservesConfig); - } - - function setDebtCeiling(uint256 ceiling) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setDebtCeiling(configNew, ceiling); - reservesConfig.data = configNew.data; - } - - function getDebtCeiling() public view returns (uint256) { - return ReserveConfiguration.getDebtCeiling(reservesConfig); - } - - function setLiquidationProtocolFee(uint256 liquidationProtocolFee) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setLiquidationProtocolFee(configNew, liquidationProtocolFee); - reservesConfig.data = configNew.data; - } - - function getLiquidationProtocolFee() public view returns (uint256) { - return ReserveConfiguration.getLiquidationProtocolFee(reservesConfig); - } - - function setUnbackedMintCap(uint256 unbackedMintCap) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setUnbackedMintCap(configNew, unbackedMintCap); - reservesConfig.data = configNew.data; - } - - function getUnbackedMintCap() public view returns (uint256) { - return ReserveConfiguration.getUnbackedMintCap(reservesConfig); - } - - function setEModeCategory(uint256 category) public { - DataTypes.ReserveConfigurationMap memory configNew = reservesConfig; - ReserveConfiguration.setEModeCategory(configNew, category); - reservesConfig.data = configNew.data; - } - - function getEModeCategory() public view returns (uint256) { - return ReserveConfiguration.getEModeCategory(reservesConfig); - } - - function init_state() public {} - - function getData() public view returns (uint256) { - return reservesConfig.data; - } - - function xorWithReserve(uint256 rhs) public view returns (uint256) { - return reservesConfig.data ^ rhs; - } - - function initMaps() public { - intSetterslowerBounds[0] = 0; // ltv - START_BIT_POSITION = 0 - intSetterslowerBounds[1] = 65536; // liq threshold - START_BIT_POSITION = 16 - intSetterslowerBounds[2] = 4294967296; // liq bonus - START_BIT_POSITION = 32 - intSetterslowerBounds[3] = 281474976710656; // decimals - START_BIT_POSITION = 48 - intSetterslowerBounds[4] = 18446744073709551616; // reserve factor - START_BIT_POSITION = 64 - intSetterslowerBounds[5] = 1208925819614629174706176; // borrow cap - START_BIT_POSITION = 80 - intSetterslowerBounds[6] = 83076749736557242056487941267521536; // supply cap - START_BIT_POSITION = 116 - intSetterslowerBounds[7] = 5708990770823839524233143877797980545530986496; // liquidation fee - FEE_START_BIT_POSITION = 152 - intSetterslowerBounds[8] = 374144419156711147060143317175368453031918731001856; // emode category - START_BIT_POSITION = 168 - intSetterslowerBounds[9] = 95780971304118053647396689196894323976171195136475136; // unbacked mint cap - START_BIT_POSITION = 176 - intSetterslowerBounds[10] = 6582018229284824168619876730229402019930943462534319453394436096; // debt ceiling - START_BIT_POSITION = 212 - - intSettersUpperBounds[0] = 65535; // ltv - 16 bits - intSettersUpperBounds[1] = 4294901760; // liq threshold - 16 bits - intSettersUpperBounds[2] = 281470681743360; // liq bonus - 16 bits - intSettersUpperBounds[3] = 71776119061217280; // decimals - 8 bits - intSettersUpperBounds[4] = 1208907372870555465154560; // reserve factor - 16 bits - intSettersUpperBounds[5] = 83076749735348316236873312092815360; // borrow cap - 36 bits - intSettersUpperBounds[6] = 5708990770740762774496586635741492604263464960; // supply cap - 36 bits - intSettersUpperBounds[7] = 374138710165940323220619084031490655051373200015360; // liquidation fee - 16 bits - intSettersUpperBounds[8] = 95406826884961342500336545879718955523139276405473280; // emode category - 8 bits - intSettersUpperBounds[9] = 6582018229189043197315758676582005330734049138558148258257960960; // unbacked mint cap - 36 bits - intSettersUpperBounds[10] = 7237005577325680195743901738874374364099144639582604309003564681041176166400; // debt ceiling - 40 bits - - boolSettersCompare[0] = 72057594037927936; // active - START_BIT_POSITION = 56 - boolSettersCompare[1] = 144115188075855872; // frozen - START_BIT_POSITION = 57 - boolSettersCompare[2] = 288230376151711744; // borrowing enabled - START_BIT_POSITION = 58 - boolSettersCompare[3] = 576460752303423488; // stable rate borrowing enabled - START_BIT_POSITION = 59 - boolSettersCompare[4] = 1152921504606846976; // paused - START_BIT_POSITION = 60 - boolSettersCompare[5] = 2305843009213693952; // borrowable in isolation - START_BIT_POSITION = 61 - } - - function executeIntSetterById(uint256 id, uint256 val) public { - require(id >= 0 && id <= 10); - if (id == 0) { - setLtv(val); - } else if (id == 1) { - setLiquidationThreshold(val); - } else if (id == 2) { - setLiquidationBonus(val); - } else if (id == 3) { - setDecimals(val); - } else if (id == 4) { - setReserveFactor(val); - } else if (id == 5) { - setBorrowCap(val); - } else if (id == 6) { - setSupplyCap(val); - } else if (id == 7) { - setLiquidationProtocolFee(val); - } else if (id == 8) { - setEModeCategory(val); - } else if (id == 9) { - setUnbackedMintCap(val); - } else { - setDebtCeiling(val); - } - } - - function executeIntGetterById(uint256 id) public returns(uint256) { - require(id >= 0 && id <= 10); - if (id == 0) { - return getLtv(); - } else if (id == 1) { - return getLiquidationThreshold(); - } else if (id == 2) { - return getLiquidationBonus(); - } else if (id == 3) { - return getDecimals(); - } else if (id == 4) { - return getReserveFactor(); - } else if (id == 5) { - return getBorrowCap(); - } else if (id == 6) { - return getSupplyCap(); - } else if (id == 7) { - return getLiquidationProtocolFee(); - } else if (id == 8) { - return getEModeCategory(); - } else if (id == 9) { - return getUnbackedMintCap(); - } else { - return getDebtCeiling(); - } - } - - function executeBoolSetterById(uint256 id, bool val) public { - require(id >= 0 && id <= 5); - if (id == 0) { - setActive(val); - } else if (id == 1) { - setFrozen(val); - } else if (id == 2) { - setBorrowingEnabled(val); - } else if (id == 3) { - setStableRateBorrowingEnabled(val); - } else if (id == 4) { - setPaused(val); - } else { - setBorrowableInIsolation(val); - } - } - - function executeBoolGetterById(uint256 id) public view returns(bool) { - require(id >= 0 && id <= 5); - if (id == 0) { - return getActive(); - } else if (id == 1) { - return getFrozen(); - } else if (id == 2) { - return getBorrowingEnabled(); - } else if (id == 3) { - return getStableRateBorrowingEnabled(); - } else if (id == 4) { - return getPaused(); - } else { - return getBorrowableInIsolation(); - } - } - - function getIntSetterLowerBound(uint256 i) public view returns (uint256) { - return intSetterslowerBounds[i]; - } - - function getIntSetterUpperBound(uint256 i) public view returns (uint256) { - return intSettersUpperBounds[i]; - } - - function getBoolSetterCompare(uint256 i) public view returns (uint256) { - return boolSettersCompare[i]; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SimpleERC20.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SimpleERC20.sol deleted file mode 100644 index c6fb6a9..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SimpleERC20.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import {IERC20} from '../../contracts/dependencies/openzeppelin/contracts/IERC20.sol'; -/** -A simple ERC implementation used as the underlying_asset for the verification process. - */ -contract SimpleERC20 is IERC20 { - uint256 t; - mapping (address => uint256) b; - mapping (address => mapping (address => uint256)) a; - - function add(uint a, uint b) internal pure returns (uint256) { - uint c = a +b; - require (c >= a); - return c; - } - - function sub(uint a, uint b) internal pure returns (uint256) { - require (a>=b); - return a-b; - } - - function totalSupply() external override view returns (uint256) { - return t; - } - - function balanceOf(address account) external override view returns (uint256) { - return b[account]; - } - - function transfer(address recipient, uint256 amount) external override returns (bool) { - b[msg.sender] = sub(b[msg.sender], amount); - b[recipient] = add(b[recipient], amount); - return true; - } - - function allowance(address owner, address spender) external override view returns (uint256) { - return a[owner][spender]; - } - - function approve(address spender, uint256 amount) external override returns (bool) { - a[msg.sender][spender] = amount; - return true; - } - - function transferFrom( - address sender, - address recipient, - uint256 amount - ) external override returns (bool) { - b[sender] = sub(b[sender], amount); - b[recipient] = add(b[recipient], amount); - a[sender][msg.sender] = sub(a[sender][msg.sender], amount); - return true; - } -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/StableDebtTokenHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/StableDebtTokenHarness.sol deleted file mode 100644 index 471096e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/StableDebtTokenHarness.sol +++ /dev/null @@ -1,47 +0,0 @@ -pragma solidity 0.8.10; - -import {StableDebtToken} from '../../contracts/protocol/tokenization/StableDebtToken.sol'; -import {IncentivizedERC20} from '../../contracts/protocol/tokenization/base/IncentivizedERC20.sol'; -import {IPool} from '../../contracts/interfaces/IPool.sol'; -// import {IAaveIncentivesController} from '../../contracts/interfaces/IAaveIncentivesController.sol'; - -contract StableDebtTokenHarness is StableDebtToken { - constructor( - IPool pool - // address underlyingAsset, - // string memory name, - // string memory symbol, - // address incentivesController - ) public StableDebtToken(pool) {} - - /** - Simplification: The user accumulates no interest (the balance increase is always 0). - **/ - function balanceOf(address account) public view override returns (uint256) { - return IncentivizedERC20.balanceOf(account); - } - - function _calcTotalSupply(uint256 avgRate) internal view override returns (uint256) { - return IncentivizedERC20.totalSupply(); - } - - function additionalData(address user) public view returns (uint128) { - return _userState[user].additionalData; - } - - // function burn(address user, uint256 amount) external override onlyPool returns (uint256, uint256) { - // require (amount > 0); - // return super.burn(user, amount); - // } - - // function getIncentivesController() external view override returns (IAaveIncentivesController) { - // return address(_incentivesController); - // } - - // function rayWadMul(uint256 aRay, uint256 bWad) external view returns (uint256) { - // return aRay.rayMul(bWad.wadToRay()); - // } - - - -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SupplyLogicHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SupplyLogicHarness.sol deleted file mode 100644 index 8942897..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SupplyLogicHarness.sol +++ /dev/null @@ -1,47 +0,0 @@ -pragma solidity 0.8.10; - -import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; -import {SupplyLogic} from '../../contracts/protocol/libraries/logic/SupplyLogic.sol'; - -contract SupplyLogicHarness { - - address public asset; - mapping(address => DataTypes.ReserveData) public reserves; - mapping(uint256 => address) public reservesList; - DataTypes.UserConfigurationMap public userConfig; - mapping(uint8 => DataTypes.EModeCategory) public eModeCategories; - - - function executeSupply( - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external { - DataTypes.ReserveData storage reserve = reserves[asset]; - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - - reserve.updateState(reserveCache); - - ValidationLogic.validateSupply(reserveCache, amount); - - reserve.updateInterestRates(reserveCache, asset, amount, 0); - - IERC20(params.asset).safeTransferFrom(msg.sender, reserveCache.aTokenAddress, amount); - - bool isFirstSupply = IAToken(reserveCache.aTokenAddress).mint( - params.onBehalfOf, - params.amount, - reserveCache.nextLiquidityIndex - ); - - if (isFirstSupply) { - (bool isolationModeActive, , ) = userConfig.getIsolationModeState(reserves, reservesList); - if ( - ((!isolationModeActive && (reserveCache.reserveConfiguration.getDebtCeiling() == 0)) || - !userConfig.isUsingAsCollateralAny()) - ) { - userConfig.setUsingAsCollateral(reserve.id, true); - } - } - } -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SymbolicPriceOracle.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SymbolicPriceOracle.sol deleted file mode 100644 index e055bd6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/SymbolicPriceOracle.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity 0.8.10; -pragma solidity 0.8.10; - -import {IPriceOracleGetter} from "../../contracts/interfaces/IPriceOracleGetter.sol"; - -contract SymbolicPriceOracle is IPriceOracleGetter { - - address public base; - uint256 public unit; - mapping (address => uint256) public price; - - function BASE_CURRENCY() external view returns (address) { - return base; - } - - function BASE_CURRENCY_UNIT() external override view returns (uint256) { - return unit; - } - - function getAssetPrice(address asset) external view override returns (uint256) { - return price[asset]; - } -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/UserConfigurationHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/UserConfigurationHarness.sol deleted file mode 100644 index 8f83c89..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/UserConfigurationHarness.sol +++ /dev/null @@ -1,67 +0,0 @@ -pragma solidity 0.8.10; -pragma experimental ABIEncoderV2; - -import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {DataTypes} from '../../contracts/protocol/libraries/types/DataTypes.sol'; -import {PoolStorage} from '../../contracts/protocol/pool/PoolStorage.sol'; - -/* -A wrapper contract for calling functions from the library UserConfiguration. -*/ -contract UserConfigurationHarness is PoolStorage { - DataTypes.UserConfigurationMap public usersConfig; - function setBorrowing(uint256 reserveIndex, bool borrowing) public { - UserConfiguration.setBorrowing(usersConfig, reserveIndex, borrowing); - } - - function setUsingAsCollateral(uint256 reserveIndex, bool _usingAsCollateral) public { - UserConfiguration.setUsingAsCollateral(usersConfig, reserveIndex, _usingAsCollateral); - } - - function isUsingAsCollateralOrBorrowing(uint256 reserveIndex) public view returns (bool) { - return UserConfiguration.isUsingAsCollateralOrBorrowing(usersConfig, reserveIndex); - } - - function isBorrowing(uint256 reserveIndex) public view returns (bool) { - return UserConfiguration.isBorrowing(usersConfig, reserveIndex); - } - - function isUsingAsCollateral(uint256 reserveIndex) public view returns (bool) { - return UserConfiguration.isUsingAsCollateral(usersConfig, reserveIndex); - } - - function isUsingAsCollateralOne() public view returns (bool) { - return UserConfiguration.isUsingAsCollateralOne(usersConfig); - } - - function isUsingAsCollateralAny() public view returns (bool) { - return UserConfiguration.isUsingAsCollateralAny(usersConfig); - } - - function isBorrowingAny() public view returns (bool) { - return UserConfiguration.isBorrowingAny(usersConfig); - } - - function isEmpty() public view returns (bool) { - return UserConfiguration.isEmpty(usersConfig); - } - - function getIsolationModeState() - public view returns (bool, address, uint256) { - return UserConfiguration.getIsolationModeState(usersConfig, _reserves, _reservesList); - } - - function _getFirstAssetAsCollateralId() public view returns(uint256) { - return UserConfiguration._getFirstAssetAsCollateralId(usersConfig); - } - - function isIsolated() public view returns (bool) { - (bool isolated, , ) = getIsolationModeState(); - return isolated; - } - - /* - Mimics the original constructor of the contract. - */ - function init_state() public {} -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/flashLoanHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/flashLoanHarness.sol deleted file mode 100644 index 596b2a8..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/flashLoanHarness.sol +++ /dev/null @@ -1,90 +0,0 @@ -pragma solidity 0.8.10; -import {SafeERC20} from '../../../dependencies/openzeppelin/contracts/SafeERC20.sol'; -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {IFlashLoanReceiver} from '../../../flashloan/interfaces/IFlashLoanReceiver.sol'; -import {IFlashLoanSimpleReceiver} from '../../../flashloan/interfaces/IFlashLoanSimpleReceiver.sol'; -import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {Helpers} from '../helpers/Helpers.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ValidationLogic} from './ValidationLogic.sol'; -import {BorrowLogic} from './BorrowLogic.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; -import {FlashLoanLogic} from '.FlashLoanLogic.sol'; -contract FlashLoanLogicHarness { - using ReserveLogic for DataTypes.ReserveCache; - using ReserveLogic for DataTypes.ReserveData; - using SafeERC20 for IERC20; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using WadRayMath for uint256; - using PercentageMath for uint256; - - struct FlashLoanSimpleLocalVars { - IFlashLoanSimpleReceiver receiver; - uint256 totalPremium; - uint256 premiumToLP; - uint256 premiumToProtocol; - uint256 amountPlusPremium; - } - function wrapper(uint256 data,uint128 liquidityIndex,uint128 currentLiquidityRate,uint128 variableBorrowIndex, - uint128 currentVariableBorrowRate, - uint128 currentStableBorrowRate, - uint40 lastUpdateTimestamp, - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress, - address interestRateStrategyAddress, - uint8 id, - uint128 accruedToTreasury, - uint128 unbacked, - uint128 isolationModeTotalDebt, - address receiverAddress, - address asset, - uint256 amount, - bytes params, - uint16 referralCode, - uint256 flashLoanPremiumToProtocol, - uint256 flashLoanPremiumTotal, - ) public{ - DataTypes.ReserveData reserve; - DataTypes.ReserveConfigurationMap configuration; - configuration.data=data; - reserve.configuration =configuration; - reserve.liquidityIndex=liquidityIndex; - reserve.currentLiquidityRate=currentLiquidityRate; - reserve.variableBorrowIndex=variableBorrowIndex; - reserve.currentVariableBorrowRate=currentVariableBorrowRate; - reserve.lastUpdateTimestam=lastUpdateTimestam; - reserve.aTokenAddress=aTokenAddress; - reserve.stableDebtTokenAddress=stableDebtTokenAddress; - reserve.variableDebtTokenAddress=variableDebtTokenAddress; - reserve.interestRateStrategyAddress=interestRateStrategyAddress; - reserve.id=id; - reserve.accruedToTreasury=accruedToTreasury; - reserve.unbacked=unbacked; - reserve.isolationModeTotalDebt=isolationModeTotalDebt; - DataTypes.FlashloanSimpleParams params; - params.receiverAddress=receiverAddress; - params.asset=asset; - params.amount=amount; - params.params=params; - params.referralCode=referralCode; - params.flashLoanPremiumToProtocol=flashLoanPremiumToProtocol; - params.flashLoanPremiumTotal=flashLoanPremiumTotal; - FlashLoanLogic.executeFlashLoanSimple(reserve,params); - - - - - - - - } -} - - \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/validationLogicHarness.sol b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/validationLogicHarness.sol deleted file mode 100644 index c216834..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/harness/validationLogicHarness.sol +++ /dev/null @@ -1,116 +0,0 @@ -pragma solidity 0.8.10; - -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {Address} from '../../../dependencies/openzeppelin/contracts/Address.sol'; -import {SafeERC20} from '../../../dependencies/openzeppelin/contracts/SafeERC20.sol'; -import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol'; -import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol'; -import {IStableDebtToken} from '../../../interfaces/IStableDebtToken.sol'; -import {IScaledBalanceToken} from '../../../interfaces/IScaledBalanceToken.sol'; -import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {IPriceOracleSentinel} from '../../../interfaces/IPriceOracleSentinel.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {Helpers} from '../helpers/Helpers.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; -import {GenericLogic} from './GenericLogic.sol'; - -contract ValidationLogic { - using ReserveLogic for DataTypes.ReserveData; - using WadRayMath for uint256; - using PercentageMath for uint256; - using SafeERC20 for IERC20; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using UserConfiguration for DataTypes.UserConfigurationMap; - using Address for address; - - - uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000; - uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95% - uint256 public constant MINIMUM_HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 0.95 * 1e18; - uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1e18; - - - function wrapperSupply( - uint256 currScaledVariableDebt, - uint256 nextScaledVariableDebt, - uint256 currPrincipalStableDebt, - uint256 currAvgStableBorrowRate, - uint256 currTotalStableDebt, - uint256 nextAvgStableBorrowRate, - uint256 nextTotalStableDebt, - uint256 currLiquidityIndex, - uint256 nextLiquidityIndex, - uint256 currVariableBorrowIndex, - uint256 nextVariableBorrowIndex, - uint256 currLiquidityRate, - uint256 currVariableBorrowRate, - uint256 reserveFactor, - uint256 data, - address aTokenAddress; - address stableDebtTokenAddress; - address variableDebtTokenAddress; - uint40 reserveLastUpdateTimestamp; - uint40 stableDebtLastUpdateTimestamp; - }) public { - - DataTypes.reserveConfiguration reserveConfiguration; - reserveConfiguration.data=data; - - DataTypes.ReserveCache reserveCache; - struct ReserveCache { - uint256 currScaledVariableDebt; - uint256 nextScaledVariableDebt; - uint256 currPrincipalStableDebt; - uint256 currAvgStableBorrowRate; - uint256 currTotalStableDebt; - uint256 nextAvgStableBorrowRate; - uint256 nextTotalStableDebt; - uint256 currLiquidityIndex; - uint256 nextLiquidityIndex; - uint256 currVariableBorrowIndex; - uint256 nextVariableBorrowIndex; - uint256 currLiquidityRate; - uint256 currVariableBorrowRate; - uint256 reserveFactor; - DataTypes.ReserveConfigurationMap reserveConfiguration; - address aTokenAddress; - address stableDebtTokenAddress; - address variableDebtTokenAddress; - uint40 reserveLastUpdateTimestamp; - uint40 stableDebtLastUpdateTimestamp; - } - - - - } - function validateSupply(DataTypes.ReserveCache memory reserveCache, uint256 amount) - internal - view - { - (bool isActive, bool isFrozen, , , bool isPaused) = reserveCache - .reserveConfiguration - .getFlags(); - - uint256 reserveDecimals = reserveCache.reserveConfiguration.getDecimals(); - uint256 supplyCap = reserveCache.reserveConfiguration.getSupplyCap(); - - require(amount != 0, Errors.VL_INVALID_AMOUNT); - require(isActive, Errors.VL_NO_ACTIVE_RESERVE); - require(!isPaused, Errors.VL_RESERVE_PAUSED); - require(!isFrozen, Errors.VL_RESERVE_FROZEN); - require( - supplyCap == 0 || - (IAToken(reserveCache.aTokenAddress).scaledTotalSupply().rayMul( - reserveCache.nextLiquidityIndex - ) + amount) / - (10**reserveDecimals) < - supplyCap, - Errors.VL_SUPPLY_CAP_EXCEEDED - ); - } \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/PoolSanity.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/PoolSanity.sh deleted file mode 100755 index e69de29..0000000 diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyAToken.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyAToken.sh deleted file mode 100755 index 6adf318..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyAToken.sh +++ /dev/null @@ -1,9 +0,0 @@ -certoraRun certora/harness/SimpleERC20.sol certora/harness/ATokenHarness.sol \ - --solc solc8.10 \ - --verify ATokenHarness:certora/specs/AToken.spec \ - --msg "aToken spec - all " \ - --link ATokenHarness:_underlyingAsset=SimpleERC20 \ - --path contracts \ - --optimistic_loop \ - --staging \ - --settings -enableGhostGrounding=true \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyEModeAndIsolation.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyEModeAndIsolation.sh deleted file mode 100755 index 52a7340..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyEModeAndIsolation.sh +++ /dev/null @@ -1,5 +0,0 @@ -certoraRun contracts/protocol/pool/Pool.sol \ - --solc solc8.10 \ - --verify Pool:certora/specs/eModeAndIsolation.spec \ - --staging \ - --msg "eMode and isolation spec" \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyPool.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyPool.sh deleted file mode 100755 index c52d9ec..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyPool.sh +++ /dev/null @@ -1,13 +0,0 @@ -certoraRun contracts/protocol/pool/Pool.sol \ - certora/harness/ATokenHarness.sol \ - certora/harness/StableDebtTokenHarness.sol \ - certora/harness/SimpleERC20.sol \ - contracts/protocol/tokenization/VariableDebtToken.sol \ - certora/harness/SymbolicPriceOracle.sol \ - --solc solc8.10 --optimistic_loop \ - --verify Pool:certora/specs/pool.spec \ - --staging \ - --rule $1 \ - --settings -t=600 --settings -superOptimisticReturnsize=true \ - --link ATokenHarness:POOL=Pool \ - --msg "Pool $1" diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyPoolConfigurator.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyPoolConfigurator.sh deleted file mode 100755 index e35a956..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyPoolConfigurator.sh +++ /dev/null @@ -1,9 +0,0 @@ -certoraRun certora/harness/PoolConfiguratorHarness.sol certora/harness/PoolHarnessForConfigurator.sol \ - --solc solc8.10 \ - --verify PoolConfiguratorHarness:certora/specs/PoolConfigurator.spec \ - --msg "PoolConfigurator spec on harness" \ - --link PoolConfiguratorHarness:_pool=PoolHarnessForConfigurator \ - --path contracts \ - --optimistic_loop \ - --staging \ - --settings -useBitVectorTheory \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyReserveConfiguration.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyReserveConfiguration.sh deleted file mode 100755 index 7d306f6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyReserveConfiguration.sh +++ /dev/null @@ -1,9 +0,0 @@ -certoraRun certora/harness/ReserveConfigurationHarness.sol \ - --solc solc8.10 \ - --verify ReserveConfigurationHarness:certora/specs/ReserveConfiguration.spec \ - --settings -useBitVectorTheory \ - --staging \ - --msg "ReserveConfiguration" \ - --path contracts \ - --rule_sanity \ - --optimistic_loop \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanity.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanity.sh deleted file mode 100755 index 1ec9c9c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanity.sh +++ /dev/null @@ -1,11 +0,0 @@ -contractPath=${1} -project=${2} -contract=`echo ${1} | perl -0777 -pe 's/.*\///g' | awk -F'.' '{print $1}'` -echo $contractPath -echo $contract -set -x -certoraRun ${contractPath} \ - --solc solc8.10 \ - --verify ${contract}:certora/specs/sanity.spec \ - --settings -t=300 \ - --staging --msg "${project} ${contract} Sanity" --rule sanity diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanityEModeLogic.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanityEModeLogic.sh deleted file mode 100755 index dd9df4c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanityEModeLogic.sh +++ /dev/null @@ -1,4 +0,0 @@ -certoraRun specs/harness/EModeLogicHarness.sol \ - --verify EModeLogicHarness:specs/sanity.spec \ - --settings -t=300 \ - --staging --msg "Aave V3 EModeLogicHarness - Sanity" diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanityWithLinksOptimisticLoops.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanityWithLinksOptimisticLoops.sh deleted file mode 100755 index 427b693..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifySanityWithLinksOptimisticLoops.sh +++ /dev/null @@ -1,6 +0,0 @@ -certoraRun contracts/protocol/tokenization/AToken.sol contracts/protocol/pool/Pool.sol \ - --verify AToken:specs/sanity.spec \ - --link AToken:_pool=Pool \ - --settings -t=300 \ - --optimistic_loop \ - --staging --msg "Aave AToken Sanity optimistic loops and link" diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyStableTokenCLI.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyStableTokenCLI.sh deleted file mode 100755 index 3fda26f..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyStableTokenCLI.sh +++ /dev/null @@ -1,5 +0,0 @@ -certoraRun certora/harness/StableDebtTokenHarness.sol:StableDebtTokenHarness \ - --solc solc8.10 \ - --verify StableDebtTokenHarness:certora/specs/StableDebtToken.spec \ - --settings -assumeUnwindCond,-b=4 \ - --cache StableToken --staging \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyUserConfigCLI.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyUserConfigCLI.sh deleted file mode 100755 index 1b1cf8c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyUserConfigCLI.sh +++ /dev/null @@ -1,9 +0,0 @@ -certoraRun certora/harness/UserConfigurationHarness.sol \ - --solc solc8.10 \ - --verify UserConfigurationHarness:certora/specs/UserConfiguration.spec \ - --settings -useBitVectorTheory \ - --staging \ - --msg "UserConfiguration spec rule = isolated" \ - --path contracts \ - --optimistic_loop \ - --rule isolated \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyVariableTokenCLI.sh b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyVariableTokenCLI.sh deleted file mode 100755 index 2a83718..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/scripts/verifyVariableTokenCLI.sh +++ /dev/null @@ -1,7 +0,0 @@ -certoraRun contracts/protocol/tokenization/VariableDebtToken.sol \ - --solc solc8.10 \ - --verify VariableDebtToken:certora/specs/VariableDebtToken.spec \ - --path contracts \ - --optimistic_loop \ - --staging \ - --msg "variable debt token" \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/AToken.spec b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/AToken.spec deleted file mode 100644 index 3df7a98..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/AToken.spec +++ /dev/null @@ -1,306 +0,0 @@ -/** - -- values of gRNI passing: ray, 2 * ray - -*/ - -using SimpleERC20 as _underlyingAsset - -methods { - nonces(address) returns (uint256) envfree - allowance(address, address) returns (uint256) envfree - handleAction(address, uint256, uint256) => CONSTANT - getReserveNormalizedIncome(address u) returns (uint256) => gRNI() - balanceOf(address) returns (uint256) envfree - additionalData(address) returns uint128 envfree - finalizeTransfer(address, address, address, uint256, uint256, uint256) => NONDET -} - -definition ray() returns uint = 1000000000000000000000000000; -definition half_ray() returns uint = ray() / 2; -definition bounded_error_eq(uint x, uint y, uint epsilon) returns bool = x <= y + epsilon && x + epsilon >= y; - -ghost sumAllBalance() returns uint256 { - init_state axiom sumAllBalance() == 0; -} - -ghost gRNI() returns uint256 { - // axiom gRNI() == ray() + (ray() / 2); - axiom gRNI() == ray(); -} - -hook Sstore _userState[KEY address a].balance uint128 balance (uint128 old_balance) STORAGE { - havoc sumAllBalance assuming sumAllBalance@new() == sumAllBalance@old() + balance - old_balance; -} - -invariant totalSupplyEqualsSumAllBalance(env e) - totalSupply(e) == sumAllBalance() - filtered { f -> !f.isView } - -rule permitIntegrity(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) -{ - env e; - uint256 nonceBefore = nonces(owner); - permit(e, owner, spender, value, deadline, v, r, s); - assert allowance(owner, spender) == value; - assert nonces(owner) == nonceBefore + 1; -} - -rule mintArgsPositive(address user, uint256 amount, uint256 index) -{ - env e; - address caller; - mint@withrevert(e, caller, user, amount, index); - assert amount == 0 => lastReverted; -} - -/** -Check that each possible operation changes the balance of at most two users -*/ -rule balanceOfChange(address a, address b, address c, method f ) filtered { f -> !f.isView } -{ - env e; - require a!=b && a!=c && b!=c; - uint256 balanceABefore = balanceOf(a); - uint256 balanceBBefore = balanceOf(b); - uint256 balanceCBefore = balanceOf(c); - - calldataarg arg; - f(e, arg); - - uint256 balanceAAfter = balanceOf(a); - uint256 balanceBAfter = balanceOf(b); - uint256 balanceCAfter = balanceOf(c); - - assert ( balanceABefore == balanceAAfter || balanceBBefore == balanceBAfter || balanceCBefore == balanceCAfter); -} - -/** -Check that the changes to total supply are coherent with the changes to balance -*/ -// rule integrityBalanceOfTotalSupply(address a, address b, method f) -// { -// env e; -// require a!=b; -// uint256 balanceABefore = balanceOf(e,a); -// uint256 balanceBBefore = balanceOf(e,b); -// uint256 totalSupplyBefore = totalSupply(e); - -// calldataarg arg; -// sinvoke f(e, arg); - -// uint256 balanceAAfter = balanceOf(e,a); -// uint256 balanceBAfter = balanceOf(e,b); - -// uint256 totalSupplyAfter = totalSupply(e); - -// assert (balanceAAfter != balanceABefore && balanceBAfter != balanceBBefore) => -// ( (balanceAAfter - balanceABefore) + (balanceBAfter - balanceBBefore) == totalSupplyAfter - totalSupplyBefore); -// require f.selector != transferFrom(address,address,uint256).selector && -// f.selector != transfer(address,uint256).selector && -// f.selector != transferOnLiquidation(address,address,uint256).selector; -// assert (balanceAAfter != balanceABefore && balanceBAfter == balanceBBefore ) => -// ( (balanceAAfter - balanceABefore) == totalSupplyAfter - totalSupplyBefore); - -// } - -/** -Mint to user u amount of x tokens, increases his balanceOf by x. -*/ -rule integrityMint(address a, address b, uint256 x) -{ - env e; - uint256 indexRay = gRNI(); - mathint index = indexRay / ray(); - - uint256 balanceBefore = balanceOf(a); - - mint(e,b,a,x,indexRay); - - uint256 balanceAfter = balanceOf(a); - - assert bounded_error_eq(balanceAfter, balanceBefore+x, index); -} - -/** -Mint is additive, can performed either all at once or gradually -mint(u,x); mint(u,y) ~ mint(u,x+y) at the same timestamp -*/ -rule additiveMint(address a, address b, address c, uint256 x, uint256 y) -{ - env e; - uint256 indexRay = gRNI(); - mathint index = indexRay / ray(); - require(balanceOf(a) == balanceOf(b) && a != b); - - // storage initialStorage = lastStorage; - mint(e,c,a,x,indexRay); - mint(e,c,a,y,indexRay); - uint256 balanceScenario1 = balanceOf(a); - // mint(e,a, x+y ,indexRay) at initialStorage; - mint(e, c, b, x+y ,indexRay); - - uint256 balanceScenario2 = balanceOf(b); - assert bounded_error_eq(balanceScenario1, balanceScenario2, 3*index), "mint is not additive"; -} - -rule integrityTransfer(address from, address to, uint256 amount) -{ - env e; - uint256 indexRay = gRNI(); - mathint index = indexRay / ray(); - - require e.msg.sender == from; - address other; // for any address including from, to, currentContract the underlying asset balance should stay the same - - uint256 balanceBeforeFrom = balanceOf(from); - uint256 balanceBeforeTo = balanceOf(to); - uint256 underlyingBeforeOther = _underlyingAsset.balanceOf(e, other); - - transfer(e, to, amount); - - uint256 balanceAfterFrom = balanceOf(from); - uint256 balanceAfterTo = balanceOf(to); - uint256 underlyingAfterOther = _underlyingAsset.balanceOf(e, other); - - assert underlyingAfterOther == underlyingBeforeOther, "unexpected change in underlying asserts"; - - if (from != to) { - assert bounded_error_eq(balanceAfterFrom, balanceBeforeFrom - amount, index) && - bounded_error_eq(balanceAfterTo, balanceBeforeTo + amount, index), "unexpected balance of from/to, when from!=to"; - } else { - assert balanceAfterFrom == balanceAfterTo , "unexpected balance of from/to, when from==to"; - } -} - - -rule additiveTransfer(address from1, address from2, address to1, address to2, uint256 x, uint256 y) -{ - env e1; - env e2; - uint256 indexRay = gRNI(); - mathint index = indexRay / ray(); - require (from1 != from2 && to1 != to2 && from1 != to2 && from2 != to1 && - (from1 == to1 <=> from2 == to2) && - balanceOf(from1) == balanceOf(from2) && balanceOf(to1) == balanceOf(to2)); - - require e1.msg.sender == from1; - require e2.msg.sender == from2; - // storage initialStorage = lastStorage; - transfer(e1, to1, x); - transfer(e1, to1, y); - uint256 balanceFromScenario1 = balanceOf(from1); - uint256 balanceToScenario1 = balanceOf(to1); - - transfer(e2, to2, x+y); - - uint256 balanceFromScenario2 = balanceOf(from2); - uint256 balanceToScenario2 = balanceOf(to2); - - assert bounded_error_eq(balanceFromScenario1, balanceFromScenario2, 3*index) && - bounded_error_eq(balanceToScenario1, balanceToScenario2, 3*index), "transfer is not additive"; -} - - - -rule integrityBurn(address user, address to, uint256 amount) -{ - env e; - uint256 indexRay = gRNI(); - mathint index = indexRay / ray(); - - require user != currentContract; - uint256 balanceBeforeUser = balanceOf(user); - uint256 balanceBeforeTo = balanceOf(to); - uint256 underlyingBeforeTo = _underlyingAsset.balanceOf(e, to); - uint256 underlyingBeforeUser = _underlyingAsset.balanceOf(e, user); - uint256 underlyingBeforeSystem = _underlyingAsset.balanceOf(e, currentContract); - uint256 totalSupplyBefore = totalSupply(e); - - burn(e, user, to, amount, indexRay); - - uint256 balanceAfterUser = balanceOf(user); - uint256 balanceAfterTo = balanceOf(to); - uint256 underlyingAfterTo = _underlyingAsset.balanceOf(e, to); - uint256 underlyingAfterUser = _underlyingAsset.balanceOf(e, user); - uint256 underlyingAfterSystem = _underlyingAsset.balanceOf(e, currentContract); - uint256 totalSupplyAfter = totalSupply(e); - - if (user != to) { - assert balanceAfterTo == balanceBeforeTo && // balanceOf To should not change - bounded_error_eq(underlyingBeforeUser, underlyingAfterUser, index), "integrity break on user!=to"; - } - - if (to != currentContract) { - assert bounded_error_eq(underlyingAfterSystem, underlyingBeforeSystem - amount, index) && // system transfer underlying_asset - bounded_error_eq(underlyingAfterTo, underlyingBeforeTo + amount, index) , "integrity break on to!=currentContract"; - } else { - assert underlyingAfterSystem == underlyingBeforeSystem, "integrity break on to==currentContract"; - } - - assert bounded_error_eq(totalSupplyAfter, totalSupplyBefore - amount, index), "total supply integrity"; // total supply reduced - assert bounded_error_eq(balanceAfterUser, balanceBeforeUser - amount, index), "integrity break"; // user burns ATokens to recieve underlying - -} - -rule additiveBurn(address user, address to, uint256 x, uint256 y) -{ - env e; - uint256 indexRay = gRNI(); - mathint index = indexRay / ray(); - - require user != currentContract; - storage initialStorage = lastStorage; - sinvoke burn(e, user, to, x, indexRay); - sinvoke burn(e, user, to, y, indexRay); - uint256 balanceUserScenario1 = scaledBalanceOf(e, user); - uint256 underlyingToScenario1 = _underlyingAsset.balanceOf(e, to); - uint256 underlyingSystemScenario1 = _underlyingAsset.balanceOf(e, currentContract); - uint256 totalSupplyScenario1 = totalSupply(e); - - sinvoke burn(e, user, to, x+y, indexRay) at initialStorage; - - uint256 balanceUserScenario2 = scaledBalanceOf(e, user); - uint256 underlyingToScenario2 = _underlyingAsset.balanceOf(e, to); - uint256 underlyingSystemScenario2 = _underlyingAsset.balanceOf(e, currentContract); - uint256 totalSupplyScenario2 = totalSupply(e); - - assert bounded_error_eq(balanceUserScenario1, balanceUserScenario2, 3*index) && - bounded_error_eq(underlyingToScenario1, underlyingToScenario2, 3*index) && - bounded_error_eq(underlyingSystemScenario1, underlyingSystemScenario2, 3*index), - "burn is not additive"; -} - -rule burnNoChangeToOther(address user, address recieverOfUnderlying, uint256 amount, uint256 index, address other) -{ - - require other != user && other != recieverOfUnderlying; - - env e; - uint256 otherDataBefore = additionalData(other); - uint256 otherBalanceBefore = balanceOf(other); - - burn(e, user, recieverOfUnderlying, amount, index); - - uint256 otherDataAfter = additionalData(other); - uint256 otherBalanceAfter = balanceOf(other); - - assert otherDataBefore == otherDataAfter && - otherBalanceBefore == otherBalanceAfter; -} - -rule mintNoChangeToOther(address user, uint256 amount, uint256 index, address other) -{ - require other != user; - - env e; - uint128 otherDataBefore = additionalData(other); - uint256 otherBalanceBefore = balanceOf(other); - address caller; - mint(e, caller, user, amount, index); - - uint128 otherDataAfter = additionalData(other); - uint256 otherBalanceAfter = balanceOf(other); - - assert otherBalanceBefore == otherBalanceAfter && otherDataBefore == otherDataAfter; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/PoolConfigurator.spec b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/PoolConfigurator.spec deleted file mode 100644 index a35d2b2..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/PoolConfigurator.spec +++ /dev/null @@ -1,13 +0,0 @@ -methods { - configureReserveAsCollateral(address, uint256, uint256, uint256) envfree - getLtv(address) returns uint256 envfree - getLiquidationThreshold(address) returns uint256 envfree - getLiquidationBonus(address) returns uint256 envfree -} - -rule configureReserveAsCollateralIntegrity(address asset, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus) { - configureReserveAsCollateral(asset, ltv, liquidationThreshold, liquidationThreshold); - assert getLtv(asset) == ltv && - getLiquidationThreshold(asset) == liquidationThreshold && - getLiquidationBonus(asset) == liquidationBonus; -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/ReserveConfiguration.spec b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/ReserveConfiguration.spec deleted file mode 100644 index bfd958c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/ReserveConfiguration.spec +++ /dev/null @@ -1,171 +0,0 @@ -methods { - setLtv(uint256) envfree - getLtv() returns uint256 envfree - setLiquidationThreshold(uint256) envfree - getLiquidationThreshold() returns uint256 envfree - setLiquidationBonus(uint256) envfree - getLiquidationBonus() returns uint256 envfree - setDecimals(uint256) envfree - getDecimals() returns uint256 envfree - setActive(bool) envfree - getActive() returns bool envfree - setFrozen(bool) envfree - getFrozen() returns bool envfree - setPaused(bool) envfree - getPaused() returns bool envfree - setBorrowingEnabled(bool) envfree - getBorrowingEnabled() returns bool envfree - setStableRateBorrowingEnabled(bool) envfree - getStableRateBorrowingEnabled() returns bool envfree - setBorrowableInIsolation(bool) envfree - getBorrowableInIsolation() returns bool envfree - setReserveFactor(uint256) envfree - getReserveFactor() returns uint256 envfree - setBorrowCap(uint256) envfree - getBorrowCap() returns uint256 envfree - setSupplyCap(uint256) envfree - getSupplyCap() returns uint256 envfree - setDebtCeiling(uint256) envfree - getDebtCeiling() returns uint256 envfree - setLiquidationProtocolFee(uint256) envfree - getLiquidationProtocolFee() returns uint256 envfree - setUnbackedMintCap(uint256) envfree - getUnbackedMintCap() returns uint256 envfree - setEModeCategory(uint256) envfree - getEModeCategory() returns uint256 envfree - - xorWithReserve(uint256) returns uint256 envfree - initMaps() envfree - getData() returns uint256 envfree - init_state() envfree - - getIntSetterLowerBound(uint256) returns uint256 envfree - getIntSetterUpperBound(uint256) returns uint256 envfree - executeIntSetterById(uint256, uint256) envfree - executeIntGetterById(uint256) returns uint256 envfree - - getBoolSetterCompare(uint256) returns uint256 envfree - executeBoolSetterById(uint256, bool) envfree - executeBoolGetterById(uint256) returns bool envfree -} - -rule setLtvIntegrity(uint256 ltv) { - setLtv(ltv); - assert getLtv() == ltv; -} - -rule setLiquidationThresholdIntegrity(uint256 threshold) { - setLiquidationThreshold(threshold); - assert getLiquidationThreshold() == threshold; -} - -rule setLiquidationBonusIntegrity(uint256 bonus) { - setLiquidationBonus(bonus); - assert getLiquidationBonus() == bonus; -} - -rule setDecimalsIntegrity(uint256 decimals) { - setDecimals(decimals); - assert getDecimals() == decimals; -} - -rule setActiveIntegrity(bool active) { - setActive(active); - assert getActive() == active; -} - -rule setFrozenIntegrity(bool frozen) { - setFrozen(frozen); - assert getFrozen() == frozen; -} - -rule setPausedIntegrity(bool paused) { - setPaused(paused); - assert getPaused() == paused; -} - -rule setBorrowingEnabledIntegrity(bool enabled) { - setBorrowingEnabled(enabled); - assert getBorrowingEnabled() == enabled; -} - -rule setStableRateBorrowingEnabledIntegrity(bool enabled) { - setStableRateBorrowingEnabled(enabled); - assert getStableRateBorrowingEnabled() == enabled; -} - -rule setBorrowableInIsolationIntegrity(bool borrowable) { - setBorrowableInIsolation(borrowable); - assert getBorrowableInIsolation() == borrowable; -} - -rule setReserveFactorIntegrity(uint256 reserveFactor) { - setReserveFactor(reserveFactor); - assert getReserveFactor() == reserveFactor; -} - -rule setBorrowCapIntegrity(uint256 borrowCap) { - setBorrowCap(borrowCap); - assert getBorrowCap() == borrowCap; -} - -rule setSupplyCapIntegrity(uint256 supplyCap) { - setSupplyCap(supplyCap); - assert getSupplyCap() == supplyCap; -} - -rule setDebtCeilingIntegrity(uint256 ceiling) { - setDebtCeiling(ceiling); - assert getDebtCeiling() == ceiling; -} - -rule setLiquidationProtocolFeeIntegrity(uint256 liquidationProtocolFee) { - setLiquidationProtocolFee(liquidationProtocolFee); - assert getLiquidationProtocolFee() == liquidationProtocolFee; -} - -rule setUnbackedMintCapIntegrity(uint256 unbackedMintCap) { - setUnbackedMintCap(unbackedMintCap); - assert getUnbackedMintCap() == unbackedMintCap; -} - -rule setEModeCategoryIntegrity(uint256 category) { - setEModeCategory(category); - assert getEModeCategory() == category; -} - -rule changeOfIntSetters(uint256 funcId, uint256 val) { - - require 0 <= funcId && funcId <= 10; - - initMaps(); - uint256 dataBefore = getData(); - uint256 valueBefore = executeIntGetterById(funcId); - - executeIntSetterById(funcId, val); - - uint256 dataAfter = getData(); - uint256 xored = xorWithReserve(dataBefore); - uint256 lowerBoundF = getIntSetterLowerBound(funcId); - uint256 upperBoundF = getIntSetterUpperBound(funcId); - - assert (val == valueBefore => xored == 0) && - (val != valueBefore => (xored >= lowerBoundF && xored <= upperBoundF)); -} - -rule changeOfBoolSetters(uint256 funcId, bool val) { - require 0 <= funcId && funcId <= 10; - - initMaps(); - uint256 dataBefore = getData(); - bool valueBefore = executeBoolGetterById(funcId); - - executeBoolSetterById(funcId, val); - - uint256 dataAfter = getData(); - uint256 xored = xorWithReserve(dataBefore); - uint256 compareWith = getBoolSetterCompare(funcId); - - assert (val == valueBefore => xored == 0) && - (val != valueBefore => xored == compareWith); -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/StableDebtToken.spec b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/StableDebtToken.spec deleted file mode 100644 index 86f7996..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/StableDebtToken.spec +++ /dev/null @@ -1,216 +0,0 @@ -methods { - calculateCompoundedInterest(uint256 r, uint40 l) returns (uint256) => symbolicCompundInterest(r, l) - additionalData(address) returns uint128 envfree - getAverageStableRate() returns uint256 envfree - handleAction(address account, uint256 oldTotalSupply, uint128 oldAccountBalance) => NONDET -} - -ghost symbolicCompundInterest(uint256, uint40) returns uint256 { - axiom forall uint256 x. forall uint40 t. symbolicCompundInterest(x, t) >= 1; -} - -// ghost symbolic_compund_interest(uint256, uint40, uint256) returns uint256 { -// axiom forall uint256 x. forall uint40 t1. forall uint256 t2. symbolic_compund_interest(x, t1, t2) >= 10; -// } - -ghost sumAllBalance() returns uint256 { - init_state axiom sumAllBalance() == 0; -} - -hook Sstore _userState[KEY address a].balance uint128 balance (uint128 old_balance) STORAGE { - havoc sumAllBalance assuming sumAllBalance@new() == sumAllBalance@old() + balance - old_balance; -} -hook Sload uint128 balance _userState[KEY address a].balance STORAGE { - require sumAllBalance() >= balance; -} - -invariant totalSupplyEqualsSumAllBalance(env e) - totalSupply(e) <= sumAllBalance() - - - -invariant principalLessThanBalance(env e, address user) - principalBalanceOf(e, user) <= balanceOf(e, user) - -rule integrityBurn(address a, uint256 x) { - env e; - require getIncentivesController(e) == 0; - uint256 index; - uint256 balancebefore = balanceOf(e, a); - burn(e,a,x); - - uint256 balanceAfter = balanceOf(e, a); - assert balanceAfter == balancebefore - x; -} - -rule integrityMint(address a, uint256 x) { - env e; - address delegatedUser; - require getIncentivesController(e) == 0; - uint256 index; - uint256 balancebefore = balanceOf(e,a); - mint(e, delegatedUser, a, x, index); - - uint256 balanceAfter = balanceOf(e,a); - assert balanceAfter == balancebefore+x; -} - -rule integrityTimeStamp(address user, method f) filtered { f -> !f.isView } { - env e; - require getUserLastUpdated(e, user) <= e.block.timestamp; - calldataarg arg; - f(e,arg); - assert getUserLastUpdated(e, user) <= e.block.timestamp; -} - -rule integrityDelegationWithSig(address delegator, address delegatee, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) { - env e; - uint256 oldNonce = nonces(e, delegator); - delegationWithSig(e, delegator, delegatee, value, deadline, v, r, s); - assert nonces(e, delegator) == oldNonce + 1 && borrowAllowance(e, delegator, delegatee) == value; -} - -rule additiveBurn(address a, uint256 x, uint256 y) { - env e; - storage initialStorage = lastStorage; - burn(e, a, x); - burn(e, a, y); - uint256 balanceScenario1 = balanceOf(e, a); - uint256 t = x + y; - burn(e, a, t) at initialStorage; - - uint256 balanceScenario2 = balanceOf(e, a); - assert balanceScenario1 == balanceScenario2, "burn is not additive"; -} - -rule inverseMintBurn(address a, address delegatedUser, uint256 amount, uint256 rate) { - env e; - uint256 balancebefore = balanceOf(e, a); - mint(e, delegatedUser, a, amount, rate); - burn(e, a, amount); - uint256 balanceAfter = balanceOf(e, a); - assert balancebefore == balanceAfter, "burn is not the inverse of mint"; -} - -rule whoChangeTotalSupply(method f) filtered { f -> !f.isView } { - env e; - uint256 oldTotalSupply = totalSupply(e); - calldataarg args; - f(e, args); - uint256 newTotalSupply = totalSupply(e); - assert oldTotalSupply != newTotalSupply => - (e.msg.sender == POOL(e) && - (f.selector == burn(address, uint256).selector || - f.selector == mint(address, address, uint256, uint256).selector)); -} - -rule nonceChangePermits(method f) filtered { f -> !f.isView } { - env e; - address user; - uint256 oldNonce = nonces(e, user); - calldataarg args; - f(e, args); - uint256 newNonce = nonces(e, user); - assert oldNonce != newNonce => f.selector == delegationWithSig(address, address, uint256, uint256, uint8, bytes32, bytes32).selector; -} - -rule additiveMint(address a, uint256 x, uint256 y) { - env e; - address delegatedUser; - require getIncentivesController(e) == 0; - require getUserStableRate(e, a) == 0; - uint256 index; - storage initialStorage = lastStorage; - mint(e, delegatedUser, a, x, index); - mint(e, delegatedUser, a, y, index); - uint256 balanceScenario1 = balanceOf(e, a); - - uint256 t = x + y; - mint(e, delegatedUser, a, t ,index) at initialStorage; - - uint256 balanceScenario2 = balanceOf(e, a); - assert balanceScenario1 == balanceScenario2, "mint is not additive"; -} - -rule balanceOfChange(address a, address b, method f) filtered { f -> !f.isView } -{ - env e; - require a != b; - uint256 balanceABefore = balanceOf(e, a); - uint256 balanceBBefore = balanceOf(e, b); - - calldataarg arg; - f(e, arg); - - uint256 balanceAAfter = balanceOf(e, a); - uint256 balanceBAfter = balanceOf(e, b); - - assert (balanceABefore == balanceAAfter || balanceBBefore == balanceBAfter); -} - -rule burnZeroDoesntChangeBalance(address u) { - env e; - uint256 balanceBefore = balanceOf(e, u); - burn(e, u, 0); - uint256 balanceAfter = balanceOf(e, u); - assert balanceBefore == balanceAfter; -} - -rule burnNoChangeToOther(address user, uint256 amount, address other) { - - require other != user; - - env e; - uint256 otherDataBefore = additionalData(other); - uint256 otherBalanceBefore = balanceOf(e, other); - - burn(e, user, amount); - - uint256 otherDataAfter = additionalData(other); - uint256 otherBalanceAfter = balanceOf(e, other); - - assert otherDataBefore == otherDataAfter && - otherBalanceBefore == otherBalanceAfter; -} - -rule mintNoChangeToOther(address user, address onBehalfOf, uint256 amount, uint256 rate, address other) { - require other != user && other != onBehalfOf; - - env e; - uint128 userDataBefore = additionalData(user); - uint128 otherDataBefore = additionalData(other); - uint256 userBalanceBefore = balanceOf(e, user); - uint256 otherBalanceBefore = balanceOf(e, other); - - mint(e, user, onBehalfOf, amount, rate); - - uint128 userDataAfter = additionalData(user); - uint128 otherDataAfter = additionalData(other); - uint256 userBalanceAfter = balanceOf(e, user); - uint256 otherBalanceAfter = balanceOf(e, other); - - if (user != onBehalfOf) { - assert userBalanceBefore == userBalanceAfter && userDataBefore == userDataAfter; - } - - assert otherBalanceBefore == otherBalanceAfter && otherDataBefore == otherDataAfter; -} - - -/* -By finding a violation, this rule checks that one can burn when there totalSupply is zero. -It is commented out since it should fail -rule canBurnAtZero() { - env e; - address user; - require totalSupply(e) == 0; - uint256 userRate = additionalData(user); - uint256 previousPrincipalBalance; - uint256 newPrincipalBalance; - uint256 diff; - previousPrincipalBalance, newPrincipalBalance, diff = _calculateBalanceIncrease(e,user); - uint256 amount; - invoke burn(e,user,amount); - assert amount>0 => lastReverted; -} -*/ \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/UserConfiguration.spec b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/UserConfiguration.spec deleted file mode 100644 index 0474e1a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/UserConfiguration.spec +++ /dev/null @@ -1,70 +0,0 @@ -methods { - setBorrowing(uint256, bool) envfree - setUsingAsCollateral(uint256, bool) envfree - isUsingAsCollateralOrBorrowing(uint256) returns bool envfree - isBorrowing(uint256) returns bool envfree - isUsingAsCollateral(uint256) returns bool envfree - isBorrowingAny() returns bool envfree - isEmpty() returns bool envfree - isUsingAsCollateralAny() returns bool envfree - isUsingAsCollateralOne() returns bool envfree - isIsolated() returns bool envfree -} - -invariant empty(uint256 reserveIndex) - isEmpty() => !isBorrowingAny() && !isUsingAsCollateralOrBorrowing(reserveIndex) - -invariant notEmpty(uint256 reserveIndex) - (isBorrowingAny() || isUsingAsCollateral(reserveIndex)) => !isEmpty() - - -invariant borrowing(uint256 reserveIndex ) - isBorrowing(reserveIndex) => isBorrowingAny() - -invariant collateralOrBorrowing(uint256 reserveIndex ) - (isUsingAsCollateral(reserveIndex) || isBorrowing(reserveIndex)) <=> isUsingAsCollateralOrBorrowing(reserveIndex) - -invariant isolated(calldataarg args) - !isUsingAsCollateralOne() => !isIsolated() - -rule setBorrowing(uint256 reserveIndex, bool borrowing) -{ - require reserveIndex < 128; - - setBorrowing(reserveIndex, borrowing); - assert isBorrowing(reserveIndex) == borrowing, "unexpected result"; -} - -rule setBorrowingNoChangeToOther(uint256 reserveIndex, uint256 reserveIndexOther, bool borrowing) -{ - require reserveIndexOther != reserveIndex; - require reserveIndexOther < 128 && reserveIndex < 128; - bool otherReserveBorrowing = isBorrowing(reserveIndexOther); - bool otherReserveCollateral = isUsingAsCollateral(reserveIndexOther); - - setBorrowing(reserveIndex, borrowing); - assert otherReserveBorrowing == isBorrowing(reserveIndexOther) && - otherReserveCollateral == isUsingAsCollateral(reserveIndexOther), "changed to other reserve"; -} - - -rule setUsingAsCollateral(uint256 reserveIndex, bool usingAsCollateral) -{ - require reserveIndex < 128; - - setUsingAsCollateral(reserveIndex, usingAsCollateral); - assert isUsingAsCollateral(reserveIndex) == usingAsCollateral, "unexpected result"; -} - - -rule setUsingAsCollateralNoChangeToOther(uint256 reserveIndex, uint256 reserveIndexOther, bool usingAsCollateral) -{ - require reserveIndexOther != reserveIndex; - require reserveIndexOther < 128 && reserveIndex < 128; - bool otherReserveBorrowing = isBorrowing(reserveIndexOther); - bool otherReserveCollateral = isUsingAsCollateral(reserveIndexOther); - - setUsingAsCollateral(reserveIndex, usingAsCollateral); - assert otherReserveBorrowing == isBorrowing(reserveIndexOther) && - otherReserveCollateral == isUsingAsCollateral(reserveIndexOther), "changed to other reserve"; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/VariableDebtToken.spec b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/VariableDebtToken.spec deleted file mode 100644 index 7dd0ed1..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/VariableDebtToken.spec +++ /dev/null @@ -1,139 +0,0 @@ -methods { - getReserveNormalizedVariableDebt(address asset) returns (uint256) => ALWAYS(1000000000000000000000000000) - setAdditionalData(address user, uint128 data) envfree -} - -definition ray() returns uint = 1000000000000000000000000000; - -ghost sumAllBalance() returns uint256 { - init_state axiom sumAllBalance() == 0; -} - -hook Sstore _userState[KEY address a].balance uint128 balance (uint128 old_balance) STORAGE { - havoc sumAllBalance assuming sumAllBalance@new() == sumAllBalance@old() + balance - old_balance; -} - -invariant totalSupplyEqualsSumAllBalance(env e) - totalSupply(e) <= sumAllBalance() - - -rule whoChangeTotalSupply(method f) filtered { f -> !f.isView } { - env e; - uint256 oldTotalSupply = totalSupply(e); - calldataarg args; - f(e, args); - uint256 newTotalSupply = totalSupply(e); - assert oldTotalSupply != newTotalSupply => - (e.msg.sender == POOL(e) && - (f.selector == burn(address, uint256, uint256).selector || - f.selector == mint(address, address, uint256, uint256).selector)); -} - -rule balanceOfChange(address a, address b, method f) filtered { f -> !f.isView } -{ - env e; - require a != b; - uint256 balanceABefore = balanceOf(e, a); - uint256 balanceBBefore = balanceOf(e, b); - - calldataarg arg; - f(e, arg); - - uint256 balanceAAfter = balanceOf(e, a); - uint256 balanceBAfter = balanceOf(e, b); - - assert (balanceABefore == balanceAAfter || balanceBBefore == balanceBAfter); -} - -rule nonceChangePermits(method f) filtered { f -> !f.isView } { - env e; - address user; - uint256 oldNonce = nonces(e, user); - calldataarg args; - f(e, args); - uint256 newNonce = nonces(e, user); - assert oldNonce != newNonce => f.selector == delegationWithSig(address, address, uint256, uint256, uint8, bytes32, bytes32).selector; -} - -rule inverseMintBurn(address a, address delegatedUser, uint256 amount, uint256 index) { - env e; - uint256 balancebefore = balanceOf(e, a); - mint(e, delegatedUser, a, amount, index); - burn(e, a, amount, index); - uint256 balanceAfter = balanceOf(e, a); - assert balancebefore == balanceAfter, "burn is not the inverse of mint"; -} - -rule integrityDelegationWithSig(address delegator, address delegatee, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) { - env e; - uint256 oldNonce = nonces(e, delegator); - delegationWithSig(e, delegator, delegatee, value, deadline, v, r, s); - assert nonces(e, delegator) == oldNonce + 1 && borrowAllowance(e, delegator, delegatee) == value; -} - -rule additiveBurn(address a, address b, uint256 x, uint256 y) { - env e; - uint256 index = ray(); - require(a != b && balanceOf(e, a) == balanceOf(e, b)); - burn(e, a, x, index); - burn(e, a, y, index); - uint256 balanceScenario1 = balanceOf(e, a); - uint256 t = x + y; - burn(e, b, t, index); - uint256 balanceScenario2 = balanceOf(e, b); - assert balanceScenario1 == balanceScenario2, "burn is not additive"; -} - -// additiveMint - -rule integrityMint(address a, uint256 x) { - env e; - address delegatedUser; - uint256 index = ray(); - uint256 balancebefore = balanceOf(e,a); - mint(e, delegatedUser, a, x, index); - - uint256 balanceAfter = balanceOf(e,a); - assert balanceAfter == balancebefore+x; -} - -rule burnZeroDoesntChangeBalance(address u, uint256 index) { - env e; - uint256 balanceBefore = balanceOf(e, u); - invoke burn(e, u, 0, index); - uint256 balanceAfter = balanceOf(e, u); - assert balanceBefore == balanceAfter; -} - -rule burnNoChangeToOther(address user, uint256 amount, uint256 index, address other) { - - require other != user; - - env e; - uint256 otherBalanceBefore = balanceOf(e, other); - - burn(e, user, amount, index); - - uint256 otherBalanceAfter = balanceOf(e, other); - - assert otherBalanceBefore == otherBalanceAfter; -} - -rule mintNoChangeToOther(address user, address onBehalfOf, uint256 amount, uint256 index, address other) { - require other != user && other != onBehalfOf; - - env e; - uint256 userBalanceBefore = balanceOf(e, user); - uint256 otherBalanceBefore = balanceOf(e, other); - - mint(e, user, onBehalfOf, amount, index); - - uint256 userBalanceAfter = balanceOf(e, user); - uint256 otherBalanceAfter = balanceOf(e, other); - - if (user != onBehalfOf) { - assert userBalanceBefore == userBalanceAfter ; - } - - assert otherBalanceBefore == otherBalanceAfter ; -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/pool.spec b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/pool.spec deleted file mode 100644 index 6d9fab9..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/pool.spec +++ /dev/null @@ -1,371 +0,0 @@ -/* - This is a Specification File for Smart Contract Verification with the Certora Prover. - This file is run with scripts/verifyPool.sh -*/ - -/* - Declaration of contracts used in the spec -*/ -using ATokenHarness as _aToken -using StableDebtTokenHarness as _stable -using VariableDebtToken as _variable -using SimpleERC20 as _asset -using SymbolicPriceOracle as priceOracle - -/* - -Methods Summerizations and Enviroment-Free (e.g relative to e.msg variables) Declarations - -*/ - -methods { - - //Pool - getReserveList(uint256 index) returns (address) envfree - getReserveDataIndex(address token) returns (uint256) envfree - getReservesCount() returns (uint256) envfree - handleAction(address, uint256, uint256) => NONDET - getConfigurationData(address) returns uint256 envfree - getUserEMode(address) returns uint256 envfree - getAssetEMode(address) returns uint256 envfree - getAssetId(address) returns uint16 envfree - reserveAddressById(uint256) returns address envfree - isActiveReserve(address asset) returns bool envfree - isFrozenReserve(address asset) returns bool envfree - isPausedReserve(address asset) returns bool envfree - isBorrowableReserve(address) returns bool envfree - isStableRateBorrowableReserve(address) returns bool envfree - getReserveATokenAddress(address) returns address envfree - getReserveStableDebtTokenAddress(address) returns address envfree - getReserveVariableDebtTokenAddress(address) returns address envfree - getReserveLiquidityIndex(address) returns uint256 envfree - getReserveCurrentLiquidityRate(address) returns uint256 envfree - getReserveVariableBorrowIndex(address) returns uint256 envfree - getReserveCurrentVariableBorrowRate(address) returns uint256 envfree - getReserveCurrentStableBorrowRate(address) returns uint256 envfree - getATokenTotalSupply(address) returns uint256 envfree - getReserveSupplyCap(address) returns uint256 envfree - mockUserAccountData() returns (uint256, uint256, uint256, uint256, uint256, bool) => NONDET - mockHealthFactor() returns (uint256, bool) => NONDET - getAssetPrice(address) returns uint256 => NONDET - getPriceOracle() returns address => ALWAYS(2) - getPriceOracleSentinel() returns address => ALWAYS(4) - isBorrowAllowed() returns bool => NONDET - - // math - rayMul(uint256 a, uint256 b) returns uint256 => first_term(a, b) - rayDiv(uint256 a, uint256 b) returns uint256 => first_term(a, b) - calculateLinearInterest(uint256, uint40) returns uint256 => ALWAYS(1000000000000000000000000000) - calculateCompoundedInterest(uint256, uint40, uint256) returns uint256 => ALWAYS(1000000000000000000000000000) - - // ERC20 - transfer(address, uint256) returns bool => DISPATCHER(true) - transferFrom(address, address, uint256) returns bool => DISPATCHER(true) - approve(address, uint256) returns bool => DISPATCHER(true) - mint(address, uint256) returns bool => DISPATCHER(true) - burn(uint256) => DISPATCHER(true) - balanceOf(address) returns uint256 => DISPATCHER(true) - - // ATOKEN - mint(address user, uint256 amount, uint256 index) returns(bool) => DISPATCHER(true) - burn(address user, address receiverOfUnderlying, uint256 amount, uint256 index) => DISPATCHER(true) - mintToTreasury(uint256 amount, uint256 index) => DISPATCHER(true) - transferOnLiquidation(address from, address to, uint256 value) => DISPATCHER(true) - transferUnderlyingTo(address user, uint256 amount) => DISPATCHER(true) - handleRepayment(address user, uint256 amount) => DISPATCHER(true) - permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) => DISPATCHER(true) - - //Debt Tokens - scaledTotalSupply() => DISPATCHER(true) - - // StableDebt - mint(address user, address onBehalfOf, uint256 amount, uint256 rate) => DISPATCHER(true) - burn(address user, uint256 amount) => DISPATCHER(true) - getSupplyData() returns (uint256, uint256, uint256, uint40) => DISPATCHER(true) - - //variableDebt - burn(address user, uint256 amount, uint256 index) => DISPATCHER(true) - - // ReserveConfiguration - mockGetEModeCategory() returns uint256 => CONSTANT - mockGetActive() returns bool => CONSTANT - mockGetFrozen() returns bool => CONSTANT - mockGetBorrowingEnabled() returns bool => CONSTANT - mockGetStableRateBorrowingEnabled() returns bool => CONSTANT - mockGetPaused() returns bool => CONSTANT - mockGetReserveFactor() returns uint256 => CONSTANT - mockGetBorrowCap() returns uint256 => CONSTANT - mockGetBorrowableInIsolation() returns bool => CONSTANT - mockGetLtv() returns uint256 => CONSTANT - mockGetSupplyCap() returns uint256 => ALWAYS(100000000000000000000000000000000000000000000000000) - -} - -/* definitions and functions to be used within the spec file */ - -definition RAY() returns uint256 = 10^27; - -function first_term(uint256 x, uint256 y) returns uint256 { return x; } - -function setup() { - require getReserveATokenAddress(_asset) == _aToken; - require getReserveStableDebtTokenAddress(_asset) == _stable; - require getReserveVariableDebtTokenAddress(_asset) == _variable; -} - -function call_func(method f) { - env e; - if (f.selector == borrow(address,uint256,uint256,uint16,address).selector) { - uint256 amount; - uint256 interestRateMode; - uint16 referralCode; - address onBehalfOf; - - borrow(e, _asset, amount, interestRateMode, referralCode, onBehalfOf); - } else if (f.selector == supply(address, uint256, address, uint16).selector) { - uint256 amount; - address onBehalfOf; - uint16 referralCode; - - supply(e, _asset, amount, onBehalfOf, referralCode); - } else if (f.selector == repay(address, uint256, uint256, address).selector || - f.selector == repayWithPermit(address,uint256,uint256,address,uint256,uint8,bytes32,bytes32).selector) { - uint256 amount; - uint256 rateMode; - address onBehalfOf; - - repay(e, _asset, amount, rateMode, onBehalfOf); - } else if (f.selector == repayWithATokens(address, uint256, uint256).selector) { - uint256 amount; - uint256 rateMode; - - repayWithATokens(e, _asset, amount, rateMode); - } else if (f.selector == mintUnbacked(address,uint256,address,uint16).selector) { - uint256 amount; - address onBehalfOf; - uint16 referralCode; - - mintUnbacked(e, _asset, amount, onBehalfOf, referralCode); - } else if (f.selector == rebalanceStableBorrowRate(address,address).selector) { - address user; - - rebalanceStableBorrowRate(e, _asset, user); - } else if (f.selector == swapBorrowRateMode(address,uint256).selector) { - uint256 rateMode; - - swapBorrowRateMode(e, _asset, rateMode); - } else { - calldataarg args; - f(e, args); - } -} - -ghost ghost_multiplication(uint256, uint256) returns uint256 { - axiom forall uint256 x1. forall uint256 x2. forall uint256 y. - ((y != 0 && x1 != 0 && x1 < x2) => - (ghost_multiplication(x1, y) < ghost_multiplication(x2, y) && - ghost_multiplication(y, x1) < ghost_multiplication(y, x2))); -} - -ghost ghost_division(uint256, uint256) returns uint256 { - axiom forall uint256 x1. forall uint256 x2. forall uint256 y. - ((y != 0 && x1 != 0 && x1 < x2) => - (ghost_division(x1, y) < ghost_division(x2, y) && - ghost_division(y, x1) > ghost_division(y, x2))); -} - -ghost mapping(address => mathint) usageOfPriceOracle; - -hook Sload uint256 p priceOracle.price[KEY address asset] STORAGE { - usageOfPriceOracle[asset] = usageOfPriceOracle[asset] + 1; -} - -/* Rules and Invariantas */ -/* Vacuity Safety Checks */ -rule setupSanity() { - setup(); - assert false; -} - - -rule setupCallFuncSanity(method f) { - setup(); - call_func(f); - assert false; -} - -rule borrowSanity() { - setup(); - env e; uint256 amount; uint256 interestRateMode; uint16 referralCode; address onBehalfOf; - borrow(e, _asset, amount, interestRateMode, referralCode, onBehalfOf); - assert false; -} - -rule supplySanity() { - setup(); - env e; uint256 amount; address onBehalfOf; uint16 referralCode; - supply(e, _asset, amount, onBehalfOf, referralCode); - assert false; -} - -/* Rulea and Invariants */ - -rule cantExceedsupplyCap(method f) filtered { f -> !f.isView } { - setup(); - uint256 aTokenTotalSupplyBefore = getATokenTotalSupply(_asset); - require aTokenTotalSupplyBefore <= 10^50; - call_func(f); - uint256 aTokenTotalSupplyAfter = getATokenTotalSupply(_asset); - assert aTokenTotalSupplyAfter <= 10^50; -} - -rule cantExceedsupplyCapMintUnbacked() { - setup(); - uint256 aTokenTotalSupplyBefore = getATokenTotalSupply(_asset); - require aTokenTotalSupplyBefore <= 10^50; - env e; uint256 amount; address onBehalfOf; uint16 referralCode; - mintUnbacked(e, _asset, amount, onBehalfOf, referralCode); - uint256 aTokenTotalSupplyAfter = getATokenTotalSupply(_asset); - assert aTokenTotalSupplyAfter <= 10^50; -} - -rule cantExceedsupplyCapRepay() { - setup(); - uint256 aTokenTotalSupplyBefore = getATokenTotalSupply(_asset); - require aTokenTotalSupplyBefore <= 10^50; - env e; - uint256 amount; - uint256 rateMode; - address onBehalfOf; - repay(e, _asset, amount, rateMode, onBehalfOf); - - // uint256 supplyCapAfter = getReserveSupplyCap(_asset); - uint256 aTokenTotalSupplyAfter = getATokenTotalSupply(_asset); - - assert aTokenTotalSupplyAfter <= 10^50; -} - -rule cantExceedsupplyCapBorrow() { - setup(); - - // uint256 supplyCapBefore = getReserveSupplyCap(_asset); - uint256 aTokenTotalSupplyBefore = getATokenTotalSupply(_asset); - - require aTokenTotalSupplyBefore <= 10^50; - - env e; - uint256 amount; - uint256 interestRateMode; - uint16 referralCode; - address onBehalfOf; - borrow(e, _asset, amount, interestRateMode, referralCode, onBehalfOf); - uint256 aTokenTotalSupplyAfter = getATokenTotalSupply(_asset); - - assert aTokenTotalSupplyAfter <= 10^50; -} - -// proved -rule reservesCountIsMonotonic(method f) filtered { f -> !f.isView} - { - env e; - calldataarg args; - uint256 before = getReservesCount(); - f(e, args); - assert getReservesCount() >= before; -} - - -// proved -rule configurationChange(method f, address asset1, address asset2) { - // require f.selector != liquidationCall(address, address, address, uint256, bool).selector; - require asset1 != asset2; - - uint256 data1Before = getConfigurationData(asset1); - uint256 data2Before = getConfigurationData(asset2); - - env e; - calldataarg args; - f(e, args); - - uint256 data1After = getConfigurationData(asset1); - uint256 data2After = getConfigurationData(asset2); - - assert data1Before == data1After || data2Before == data2After; -} - -// proved -rule setUserEModeIntegrity(uint8 categoryId) { - env e; - sinvoke setUserEMode(e, categoryId); - assert getUserEMode(e.msg.sender) == categoryId; -} - -// proved -rule setUserEModeZeroNoRevert() { - env e; - require(e.msg.value == 0); - setUserEMode@withrevert(e, 0); - assert !lastReverted; -} - -// proved on earlier version -rule borrowSucceddedImpliesCompatibleEMode(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) { - env e; - - uint16 assetId = getAssetId(asset); - uint256 userEMode = getUserEMode(onBehalfOf); - uint256 assetEMode = getAssetEMode(asset); - - borrow(e, asset, amount, interestRateMode, referralCode, onBehalfOf); - - assert (userEMode == 0) || (userEMode == assetEMode); -} - -// proved -rule borrowFlags(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) { - bool reserveActive = isActiveReserve(asset); - bool reserveFrozen = isFrozenReserve(asset); - bool reservePaused = isPausedReserve(asset); - bool reserveBorrowable = isBorrowableReserve(asset); - bool reserveBorrowableStableRate = isStableRateBorrowableReserve(asset); - - env e; - borrow(e, asset, amount, interestRateMode, referralCode, onBehalfOf); - - assert reserveActive && !reserveFrozen && !reservePaused && reserveBorrowable && - (interestRateMode == 1 => reserveBorrowableStableRate); -} - - // proved - invariant reserveIndexLTcounter(uint i) - getReserveList(i) != 0 => i < getReservesCount() - filtered { f -> !f.isView} - - // proved - invariant reserveIndexValidity(uint i, address token) - ((i!= 0 && token!=0) => - (getReserveList(i) == token <=> getReserveDataIndex(token) == i) ) && - (( i == 0 && token !=0) => (getReserveList(i) == token => getReserveDataIndex(token) == i)) - filtered { f -> !f.isView} - { - preserved dropReserve(address t) with (env e) { - require t == token; - } - - preserved initReserve( - address asset, - address aTokenAddress, - address stableDebtAddress, - address variableDebtAddress, - address interestRateStrategyAddress) with (env e) { - require asset == token; - } - } - - rule priceOracelCounter(address asset, method f) { - env e; - calldataarg args; - mathint before = usageOfPriceOracle[asset]; - call_func(f); - assert usageOfPriceOracle[asset] == before; - } diff --git a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/sanity.spec b/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/sanity.spec deleted file mode 100644 index 204c7d4..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Certora/certora/specs/sanity.spec +++ /dev/null @@ -1,6 +0,0 @@ -rule sanity(method f) { - env e; - calldataarg arg; - sinvoke f(e, arg); - assert false; -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/Dockerfile b/lib/morpho-utils/lib/aave-v3-core/Dockerfile deleted file mode 100644 index 022840e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM ethereum/solc:0.6.12 as build-deps - -FROM node:16 - -USER node - -COPY --from=build-deps /usr/bin/solc /usr/bin/solc diff --git a/lib/morpho-utils/lib/aave-v3-core/LICENSE.md b/lib/morpho-utils/lib/aave-v3-core/LICENSE.md deleted file mode 100644 index 4a6bf01..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/LICENSE.md +++ /dev/null @@ -1,97 +0,0 @@ -Business Source License 1.1 - -License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. -"Business Source License" is a trademark of MariaDB Corporation Ab. - ---- - -Parameters - -Licensor: Aave - -Licensed Work: Aave V3 Core. The Licensed Work is (c) 2022 Aave - -Additional Use Grant: Any uses listed and defined at this [LICENSE](./LICENSE.md) - -Change Date: The earlier of 27 January 2023 or a date specified at v3-license-date.aave.eth - -Change License: MIT - ---- - -Terms - -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited -production use. - -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. - -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND -TITLE. - -MariaDB hereby grants you permission to use this License’s text to license -your works, and to refer to it using the trademark "Business Source License", -as long as you comply with the Covenants of Licensor below. - ---- - -Covenants of Licensor - -In consideration of the right to use this License’s text and the "Business -Source License" name and trademark, Licensor covenants to MariaDB, and to all -other recipients of the licensed work to be provided by Licensor: - -1. To specify as the Change License the GPL Version 2.0 or any later version, - or a license that is compatible with GPL Version 2.0 or a later version, - where "compatible" means that software provided under the Change License can - be included in a program with software provided under GPL Version 2.0 or a - later version. Licensor may specify additional Change Licenses without - limitation. - -2. To either: (a) specify an additional grant of rights to use that does not - impose any additional restriction on the right granted in this License, as - the Additional Use Grant; or (b) insert the text "None". - -3. To specify a Change Date. - -4. Not to modify this License in any other way. - ---- - -Notice - -The Business Source License (this document, or the "License") is not an Open -Source license. However, the Licensed Work will eventually be made available -under an Open Source License, as stated in this License. diff --git a/lib/morpho-utils/lib/aave-v3-core/README.md b/lib/morpho-utils/lib/aave-v3-core/README.md deleted file mode 100644 index 711d335..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/README.md +++ /dev/null @@ -1,115 +0,0 @@ -[![Build pass](https://github.com/aave/aave-v3-core/actions/workflows/node.js.yml/badge.svg)](https://github.com/aave/aave-v3-core/actions/workflows/node.js.yml) -[![codecov](https://codecov.io/gh/aave/aave-v3-core/branch/master/graph/badge.svg?token=U50KN38G67)](https://codecov.io/gh/aave/aave-v3-core) - -``` - .///. .///. //. .// `/////////////- - `++:++` .++:++` :++` `++: `++:......---.` - `/+: -+/` `++- :+/` /+/ `/+/ `++. - /+/ :+/ /+: /+/ `/+/ /+/` `++. - -::/++::` /+: -::/++::` `/+: `++: :++` `++/:::::::::. - -:+++::-` `/+: --++/---` `++- .++- -++. `++/:::::::::. - -++. .++- -++` .++. .++. .++- `++. - .++- -++. .++. -++. -++``++- `++. - `++: :++` .++- :++` :+//+: `++:----------` - -/: :/- -/: :/. ://: `/////////////- -``` - -# Aave Protocol v3 - -This repository contains the smart contracts source code and markets configuration for Aave Protocol V3. The repository uses Docker Compose and Hardhat as development environment for compilation, testing and deployment tasks. - -## What is Aave? - -Aave is a decentralized non-custodial liquidity markets protocol where users can participate as suppliers or borrowers. Suppliers provide liquidity to the market to earn a passive income, while borrowers are able to borrow in an overcollateralized (perpetually) or undercollateralized (one-block liquidity) fashion. - -## Documentation -See the link to the technical paper or visit the Aave Developer docs -- [Technical Paper](./techpaper/Aave_V3_Technical_Paper.pdf) - -- [Developer Documentation](https://docs.aave.com/developers/) - -## Audits and Formal Verification -You can find all audit reports under the audits folder - -Round 1 - October 2021 -- [ABDK](./audits/27-01-2022_ABDK_AaveV3.pdf) -- [OpenZeppelin](./audits/01-11-2021_OpenZeppelin_AaveV3.pdf) -- [Trail of Bits](./audits/07-01-2022_TrailOfBits_AaveV3.pdf) -- [Peckshield](./audits/14-01-2022_PeckShield_AaveV3.pdf) - -Round 2 - December 2021 -- [SigmaPrime](./audits/27-01-2022_SigmaPrime_AaveV3.pdf) - -Formal Verification -- [Certora](./Certora/certora/Verification_Report.pdf) - -## Connect with the community - -You can join at the [Discord](http://aave.com/discord) channel or at the [Governance Forum](https://governance.aave.com/) for asking questions about the protocol or talk about Aave with other peers. - -## Getting Started - -You can install `@aave/core-v3` as an NPM package in your Hardhat or Truffle project to import the contracts and interfaces: - -`npm install @aave/core-v3` - -Import at Solidity files: - -``` -import {IPool} from "@aave/core-v3/contracts/interfaces/IPool.sol"; - -contract Misc { - - function supply(address pool, address token, address user, uint256 amount) public { - IPool(pool).supply(token, amount, user, 0); - {...} - } -} -``` - -The JSON artifacts with the ABI and Bytecode are also included into the bundled NPM package at `artifacts/` directory. - -Import JSON file via Node JS `require`: - -``` -const PoolV3Artifact = require('@aave/core-v3/artifacts/contracts/protocol/pool/Pool.sol/Pool.json'); - -// Log the ABI into console -console.log(PoolV3Artifact.abi) -``` - -## Setup - -The repository uses Docker Compose to manage sensitive keys and load the configuration. Prior any action like test or deploy, you must run `docker-compose up` to start the `contracts-env` container, and then connect to the container console via `docker-compose exec contracts-env bash`. - -Follow the next steps to setup the repository: - -- Install `docker` and `docker-compose` -- Create an enviroment file named `.env` and fill the next enviroment variables - -``` -# Add Alchemy or Infura provider keys, alchemy takes preference at the config level -ALCHEMY_KEY="" -INFURA_KEY="" - - -# Optional, if you plan to use Tenderly scripts -TENDERLY_PROJECT="" -TENDERLY_USERNAME="" - -``` - -## Test - -You can run the full test suite with the following commands: - -``` -# In one terminal -docker-compose up - -# Open another tab or terminal -docker-compose exec contracts-env bash - -# A new Bash terminal is prompted, connected to the container -npm run test -``` diff --git a/lib/morpho-utils/lib/aave-v3-core/audits/01-11-2021_OpenZeppelin_AaveV3.pdf b/lib/morpho-utils/lib/aave-v3-core/audits/01-11-2021_OpenZeppelin_AaveV3.pdf deleted file mode 100644 index 82ec1625bb598a690eb94795ffab391d6d14cf8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1224058 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�s6SB&-}6KI@YyMd=Ttqi-|n%y~Ao|W~!TS=Ju1Xdmpu}{ckkE@t7xy-iftUIlTo*UyO zzCi(!lng51>{^uUU&{_C7O($ussu}dz|_4G#KPdYZ*^HF-G|^}WuMOv1^X2OB;^OY zBqAQy>NqhZkbvXrC*zM?ZNU;qCph!`$7Xv$)A$lqD%7)d6&EM)*S#io%FmyZYM(gb z`O}56I@2jS4*F420l_Y-tud>5UT={~dF+egw@3SLsk7Rd{_#Ev&Fqz$k@g65VzYCx zZoG3mL_k`vI_O|Hq}XyMO+2I$zZ7R=`8wV1JCCR7@|;$%KLU@*RYFM2ol5^M zGBKMV2*ozDP6DESn`r$(%~;-R*An_vi=-8o=r;~W`=f#%yjn7^{Ggv3 z$PF2-*w*sW_Z1pmH|LBE#Jx#M5&Jnh%U4|xtI9SxICT=xPXm`)zKlTt_^GczDSjsc zp`=I+ZA^`yo;xobk%cpg+#A;VY6+$AiO}{%bz;hLM&w)@#DCuW^$*-`tero&f$nXL zV#G<|fvq3(lgoCrp)rI7yUr#muPU1<4VKI0e_@r1YQ9f(G)TAZk5<~)*QmUlp^`mr z)#{=GdzU&IV%9o+^2`N>^Ag3g|CUReN}P{Ra3j%jXl18(2|6}_zhCs8oJX(2 z?d^P`+L0kqX;9tsy>G!0t%DtyDaR~us8nrhV{e(pdd-8w`(f3O7#)5rcX#=rKD|?6 zp$Rs;h;MH={dmK*rSa7xN36{+Zs#uP+}nd>cE|^8Y&*@@B^D5F%LcnR<&=I`FavnA zzi@YRj!DVqWAq>`i(SH0X*6W^I&c01S2^td|&pTa)qn|0cW*Wg2<5|>hfWiu7>AHB4) zEWSz@DN&0tFBx-p98@;BO*@6nnhoRYK^N^~5PosX zkXvxjK|jrp`TQ9$_TN=nT1Bu*JXpX~uD&CjX5SI`ko5&=)Ui0+y*d1lZJuc=zUIV` z>l3g_3hE-^1b1F_t7pbp|M}EIflt^|2Y$*1{*~7oLxq9atV%j*NaR%sLM0_}Q;&=V zWQH&r1{foYQIB}yY}Wo}shX~Cr3={p-N1#8kLa4RZoe(xox7mjhP%XitfWDaJP9ps`#i?T*ZjmVq%Em?8@WZOjIif3UAB!|-x?}66 zy45Q6P3HfyDvoU!=d6i*=zG5b-p||pk)I{yiDtnA55`Q!TCj>&eagvb^c6leQ#8dO zdGI~dWJL!#AN%|%cq|>wphQhEJPZ+>is;q|saq_)Lt&%ldMs`r72`vr;M(}MU9uf? zJ%@ZiTj#Llm0K1+8EEl0dnA07VM$9t5ZJn+R)6l)N4@!cKc8V`q>4e@cwk%I=K)?x zl{og=#Y)l>|a>839lNuIK+EIMs<-i>oR0JrfYdn#SBtfHgKf1RcsSjx@ z3)qxNrhHd1_IbqSHlLiWuOr;(p9vmwyyj>QC$6}0igzrS z^}&YHo35FI&ns*Yb$(AFyjY5#+DYj=T@$e=zu`@{v@1aA?46Y$5>sWR4;&&nX|#;3 zxwZPVv)-#wKD`^K4_Q#r_mCOO^j+MiOJ`LI2#9~E$uvk_E1U-8{i5Q(_HePwf`;Ob_{Qc{v*}+LCp%Fc_0xs*;QM*$Fo(PqrBor zW9;cwSUa7I)9tgO|F(>f)be|2IU^4=^;3-P<+NtdF>mP}wyN)}Y%K^G_ay5W&|BK8 zId`EvW~(r=stv9M^znFuTfbUUfNUsx|5E0^_h($I`hJF1f&Xh>x<{O>Gqf^TDVnFa z_8fpay}2*i-*{%HO_{P-6EnVoc(gzy%6f%%LhC(Kx)=nKlsu}(T2ZVtWm2(&_S$~Bt zT08H$zxQcIfFs+0CVsoCw`cAyyIeh#dr6qAjMgezDUrn(1S3pfS4Xd87}G}mcv#0u z99*K%KZxA{9Umf~YMz~Yp!}(L-!Im@a#cu2kfK~|TOz9R;uWeJbk2`8acAM11XRJP9~w;HjwN4;E0NO5Yo^f8P_U7h z;I{33W2Px>{1;JNUbpe$R@T2{-Q+!6y56zYtCeFnR;`d}{GRx@IUO4>e5H01Sv+X@yi6H}CgX+I`Ftb4r$35U za&WZI)AoqWS64B+zlbk0aH}<) z;N|*HC94KI!b}jI+6J(5R)F%hmQAx6YjhKX`Da!nFHy7xL(94oSU)jBN=xhthFD0r zP00?P$N1@+d{VNQ7g-~f3j=ViIh*+t`Mz<{zh9Q+@otl^hS6&UZ$?a!TP}J;ib4O7 zvoT=&zAUB@!Wp_rF3R&znhMqrs{#8tjscN12gI4|C_N1sm5j zjci{A9hQ-|M3ve!rU5CYw3}->q~wX>Cu)ZF$!s=6d$|DvT~E_9VtRYzCp4k=s)A$A z&`CR&4-K2k7K!w!7Tv$m)j2V3Sxb{gMrjO{KBxMzF#lIqzeQ!K_VXCM!s)!}z{C~1 z$<(AFRGv~Qhx_HbXUJAQ%B=AaS(bO%vJOric)R0BU|VS#ilJmh;}Ud0B>}Bl`$|3di3$X zi0EH)3$+6}=<&_o$C5=meCxA&a6_FDcZ2ZHfN08>dJA*n_;|9zWca9XpB*Z^HdDYQ23h4)KzRQ8oI( z=Oq8^<1gnC;rK0UFjbQ@%nBrm72glt%JYny{UO*k@Q(ZG*_n6{S>T-8zL zLxFMv>(H#*1BAG;x{w?%tllErY$a&$O&0vGyPrLRYvoGVFiMbBcF4SgxOr^Pw)XxGyQ#>gs!p(c?S$YgWX1qG2 zAu-YTIp)rSOr#*0DEvYc=Fn;2Ov);-r?eH|)Ygv_R9DDX1Ki{m? z3o0-vtSFUD#W5?Oif5OtqfGPEj#+8_4K%H0zvrAvmalvmO#>tOe1<9P$7*`CT1<+b z)?dx$@nPn35LO8f`c-2u4rNR^opTD z2)7hXU48GgZVAv?;k^b;Klt*kt$;i>ANW4o#?Mo8kPLWV3TcJE9~!t)A!-Bnp$dey zzzGXY?dd1>GVF#&Yx5?3BIKhU*$xIdLQT5Tp=cU`WO#t89zD1pseb2SlYw>0GC zD@?PLF6*1W+xYgT#`L$MII#QLH*@5r-hAH$wFEv0wrw^rkKQrHnnZScFfq%(`^*G| z%hOdM#{A2iwM57d4wS}LlDP#c1G~*X>ukx_^c>8D?N^vUfmL27eEq8%~9texC!*S zyF>B;s?KRIY?w&GZE-Ciux{$2$-s=i`^Gu6k|)$0R}Gx%dn#=41dKW&`BE#H{9I1= zcu^6`GSz1J(f^XPeHN*CT*6+;*Y^fqoq=(`sY12q{~jZ`d5=IL%-j!-1*{FuR-6xw z_EoMbsg6)^(=5)E!`(UCv4<1&h;#oG{6@a_{wfIN4&@vRerv)~Yum$Dv*^_k$9>$T zr}2VA2`#Tpk-B6n0Ug(B4zoNt=y{}n{-bo^p4B^m4zz#dlXA*cGf-D7LMn{z_5>%? zL`Vs>o$0r9@po^&I-&5h{6<--aK2I?*v{_?kgk3Kd!~P?cAVd>6*b%eseeKE>cnRt zI)#1Ab2v!PV63GYH=YBgrZM^)DkKsWX${YNM&BfI-nrcMplmZ!1tyi+@TmI@pZjl0 zDA9`_dqwFTx#R?aFaKi9SgAM{yMr1JgWjHCWtJT-x9!O*#jpn@v!V&yWYf#PTZ1h= zxO{fH5=t^m#HKJ>^Si=p(z3))Ee!m^Hk)c!C+5VQ#e5_m;%klo9O(v@3Y5ece7tSe z##{r1ZWlDZK|{@xhZH`v{<|H^R5(q}iK^1(TAXqwzDz2bTuWz;hpMUDt0C!E zqz$TItp?!x0sd&a`>6gJR;{HPe)spm+H?dK9%GCMo69NoJH!P>8Fu%@j`mHTLy_eQ4sQe$cBo^7U7`Yn>>3V8aeK8N021mKs()>Tp*dUBCK)7^Z@2)6~I}j!>Z3 z&H2^7uPV5?3qNA9tImB~n`NdI%u=It^Cjwl>Z@Z3L;*M=nL z$fJIr$Su4!#I%F?H{bK19ZaTsU{zL7{C)xemNVN%=w6xY0)3D$andQ$MR`x~{vY5v zxf%k>#bT@&<@c&U^l1apqfe)mfviYT_N9?vNU~fDIC9J3XK4^^H5b?q5)g{kiPo%0 z`-+oS9>b_z+sn$KR}Y{i^iqW&+Y|r7TCO3?JYNe2D!=_T{u(ScgS=om7}UH!m_Z9p zzNDXeivBv1Jyql6Ei0*$;BV7;`f)~7B}O@ts|!sS9>ok6YnA^&W?2kM)qvxG-9rlA z=AW+cB-g(VP5P*uLZv7r<#Xz2%$_MIt1k=dGvutn&l5= zDmzhlHmHpuSH5Cwaa#yXuuY;B747lzUJUi44+hE#QrGBYgS$=su*_d4O_+E*uynzl z$EcUazvm zERE64KPv}%s-(l#nqo+w>PXqHRIO9OitLW`8u3p+DEZM|K_i-7AQ!wx_cVWxzrft5F=#bRg zUa(=SGy6T%LR}%$e#}ek%1pnex-@#n)l=xx(+}g1ou3budls-G{vT;23v>qJLiAu$ zdIQgo1_$m>D3pv?P?L#hoj<5wc9eeHKghPCBufSOAlQz4Vf)rA ztfVdRI4JE&tR#q3u@r!4xS|DnRmbtN2b?cH72cdq%qfd8C8uBo6aW#8ieQfy-%5~% zCcj{0Tr_50QJd5Dg2R9nHe)??sYtUS#qs~^^?>266<6r8IBz#^Y1(ZHT(b#&UGlxm zoHw%`=+#&}GFdsUIkTWP`PJ5!Ur-VT>h4kPNgMXdk<*f0T}>9s&OZZVG$A|@KWOFyROeX_^vFp{ZW0!E!G{?VxNHZ z4@F~!zZ4%QZVDBp|5&26J?Vp_K`Y|LYJ-MMr)B6Yd;<lbjdrlqL#r%o*N91M>Ia^ScU%rrMwKdgjn-JX-~G~ z%#F*Gz}llzIsZ1GZING0PeygypxDF$!|R?S3=Oygy>;m%71y&E2Y61ii$wN?&( z0(%O|S9sBIZ2aw5@=7L@1Ms{(3o&}D3>-TCJ!JbtY zu}$@QL)lKubrrf(@STa@+w+KMe1_pre%becmm6@8#9?4Z`3ZTa`QsIT#@c8&9Dgl(@T8I+kucZw{J{@E z7Ji9Q<5+d>lsC%BPFi{!Gx*>5bt?6XS1r7HjMeh=ev=ZgqU29oqQ;!_`?{VGG-SGV1sh2F*%n>g z0G_)8TR;LFiD7I_8!am>(~Z_>7m>eus+|(%GdOzn!?=0lj!znhf90jX-H_*WwM7JZ z!MXMx^s5prLZ9D_dIB1W6PL5uN?7FygA=*u&6%J9E{@yhD5qExI1?g z|8Dc_4_|$EZUg-zvA_&NhL3mEM#=i4CfSj?P)y4s80=nSDGx#5Uz=*_B4*Jq$!@;!8P-6UMZ%tOC{ExZrlfm*?T^fx)xEqZ!+>nF3uO_U7u&!luQ&fcXTbOQM){Axu8(z#EO}kbp*_(T zr^`oepvNl)28wtjM}g)R%ukInMt&K8jRTPMufr!#$v8A%iE2G5b;vxIW&B3+1JKyO zJxRJ2THPKcSd7bki-WDz3y3TWO++YY<2ePpC|g zjr^tnX0)8eUMC$xUxx1{Mty1pwwGpF^rsQNep89&9Fj~p<5#R4XT{VNTpljn*-VkV(`>xE+xz-026XD*YN=`ju>% z@h@C*`ciZT4p>0$Fv4n03-H))I0S<>tm~=_I?6WQ8t}XtFOCBRM)j(R$KFi^=5R=( zK|8|W*76Q?wF_9j5eN(C0f=cPIf7X!?j8lBgSe-QH2&Uaw+CC}nD>ezWJW(fVKC8F zWqYKae7vOW5evge(<^@})U{#Se(mN!2e<$k$6G}U|2gh<+BOIC>T<)f3l`p5`j@uIqqS9Rj&QGBF>GRke|g6ii}lGyKY5iZhfdP?<&66xZ6& zH0WI6y%;(Svy&1G#HeqX7;sQLcm6O&!`QBaF!y`vX9*HimW*z?#r4Sn<3q6LU8k~n zXe`y%I-b1Gw_F}u&L?+HYrxrG9d?0N%$w)>Sk#S0)a68xjlKwh{v>^h5~Nxog5WK$ z!O2ooa9HzmZraFz7~yC#|TS`l!+S9i5xHHUsyy`U+Az5$+}OKm1~!@#Q0#;&8?jORCLkm zh*qhUggC^<+&)}znF((&595;E{`A6-)rC>c%~76=e1--yTOdUvBrL-^OiTMpj##6u z5%e~p(?zzqvfL0}8s6e!Dw%;On6qRS*~!|GzFl@lN)K9hTa(3P^EY`AxTaPeHq+ADtHrr?+%D@d4}5jP!D;o8 z20-9~d95Tq$6l<#HVCMTMW-{9Es_PTPn55OHV%-Y+{JBYldC;SsQPSF9(xj9yJf>} zR>^FIC?p^jWHx76Q2D?beC|}2W|c`0Zg_L)$ilAQKTdgEA+@x7RU%~RorlHz)=xbM z61tjo7+#PPHqd+63sOaV6Bf=8q`44NZKWyv7R2R0;mV`j9O;7IJec5rQ$N_*#;48r zD&}LggTf2bN;3x>Wyl9nnt@A!t>|R0X3$g-UET&ob&Kv}^ux&Ta>i8N{eJ_uVdSv+ zb6-}YOWc&^IOef>J7H2<5}~jbEHBGq#sTAgg>NBmhu14j{G`FhyH8~5cxrV@4$NWL z#q3G}3tnE?(ia z#q$-odb_!2HT++))%<4MNGs(S<6P%&zUlE&+q6nhKV9{Yhu+~NW_4b)&(&H?h6O&Y zn>qQ|sVi5CGGLp^O0vyy5TLE(;_kC$A{I!6yec$y6XoG8N&F?;s`ka!mCw1H z+p=;pgg~Ex2M$3<3GbzWTx|rZ`Z_j%2Hl;P$JMXf*%HhU= z!7pk#f^jDsbFS>&?+Tl|wTfx1Zm{CC+5L0c2DMy&Ra+VK)1D8A>-yUu%6gs~KjiVf zcbT7*DqR#DwYOC$?dUt1^Rh9QEELbiu*A)U=!c7H zk!_XA*fD9)pVY1cb>231cf9r_MpslI0ap038TnfV_I~^8@ZTj)7Ol?sddGk0c}vPv z(VX5|(20vK09gTdpy66$S#)OlMI++mlC_We#^)RpmcAw3!p~%v(*64A=Y1%<_LkVP z8XxFf`In#U56U3Hams}HrGsYKh9whkWYHX4$(!;9!P6|y$Rf6t@iVt*9~Nj4GASf{ z2eE*Maf3u0EX!i~`X3&?uff+Wcw1`AD^ZnE*&A@z9b6LE{z_}Tw^B$b@KGR-<9|uW zUCI?H<8%F{1USS~drdO%TGdGnalBC>`N!jLGcO& zwLxNcCt&9XZVr6i->HdjJEKT6bUt8cx=06MSG0I~Q zU>mBx{9P=v(2Ar7Dd}}O78pDo^Z0R%hl&&3{GHfyUF=_x9j{MCOL*N%>pw`3$(~gP zwmVMrsxOa|IXH5|HVY9gqQ9^gFGL6~XdX+sEH^xHJEKa3gW+w^3x)UCO6V;M^Y7k6Sc|8)0cT<4lT zu#92nr+~+_2U*KG>lDeJ4+K0{yBFRX)i}}9=c>U3E((Vs8=<*!4cR8Yl5<$B)+^ux z1hubdd>T%pH?BzWiK_vn9rMsDO#MU*Lct^tp(dO+(L-iW6<_Q!nJfc$5jH_O!xk?OB(olXO3A5T}C%&RUT z-9A!0vwQTG@~MVIzvhH<|1Q4R6Z)IlB}|QNL>rmJ>ojX`3$bd6zUznAHX8Kt8m1XX z$fAs8Mt5m<@k{Qf>X_m0KtYe~ku;r*%bGvEn3pkZ z-h(_(0yhznBRU49_+TexXuai#m*HLmJH7rDh4IQb367@SvCDrOVffoo(k<2dcGaVQ z{}*78Bqbs>?acVzW2D~HcK zIqX$F%!d4A-177wJU$NiG;!^#yz7(S(~AQ;(JL{EkAFzX0&N8WFL`0?BFdJGqjI7d zdug`eQnWs2Gd+ZXBptbr_^;?dh(BmL!`=%URTgO_5xkqm0;3k!XPU1RjrEa=s%l={ z+!y^Y7KseCmF&kp$Lw}{nkibkOm9k(Evgb+uvth)C~3X{>B44SmS6J>|JL0Cu4eCP z%VIJzRLaffRcle7u38|fko#>QklK{hgPJ!#76y<1!3fly)?WH!otjS$-@m84wf;Rs zkQBgbN7X00O}~^dN0nPUGd+aBPY@ZL$Hiji&*0}9rndJ$)=bvtKn5StPrl5Gbpw%p z7PTOrLw%c)(4wW38P+fJ)kNOQk1Z}xBCK-f4(-t(r2+@MD1jl>{~DhDBGlcr^O{rk z(i5*zaaAtf*xGW6`Sk9pv0svunXld{YhtP}J8=eVOz*s{#R^GNP+C=Z$diBR^CPDz zs#-4u{8V|%yXV`~F>B9~{E}pO(B&)HNb&Z-R(4g*yY+b!8iawAu4k8bZV|Yr(gpn* z??h9+b-qz%;u&}G$1&ELfSQ|GTrP;MLvr0E>O&REtmr68jU6YE{MzhovJZ*7csZ*> zGa1WNF)CA_XP|l~7pS|A8{&EwQU>;y|;I?*yI6^%KgJiK;fd z`j@5)HbD_qzjY^rZ7#!Oo>tC5C6bv83^{wMu^M|W#tuQ?awQeQi&osg_MmSp>v^f5k=$KdAV>^Bml}AyC(An2xEMP$~6IAUB<}>Oh_{vnP zsPt{&*Ffe!==B)+rX^Un_+l+}FH$hzsbw+dNAY`q?BW(yRbspFt~|x`tb`7@@;1r= z!FOJ!e;?Uk4~tf!s{tt_2p5pbbmZdvUF%)(NnfHsMXcQ4oWZst;@_Tk5j($rEV>*X zjU_c=E$p6|LT!*-Y+>6l8Km?Id!okrry&GhAz}`HUYjE590j+o81V%o4H>u586P3K z_V5!F%S&MdJGoaedy3LX!5v3;9A(&ZG)uucl9(uCsF}4_)?pGp06p+n*eimEOC5Xv zMN1Wj--J2TH&fp2F*xvXC$B5^*pIJw`&*Vpj)oxEtd%G&#{zRxGH;Cw z%Xsh1#iB-^C};L?P__ria*YM62!!oV3@E}(p{$)&mu+`VZw(ZKx4#m}>iRJX*q=2nkX9jT^%sr+m^hz4STrwn?dJY7E1<^`w zw}$WQ+DW-u1M&+xV}9JI=7jDgYV)}KP9hM^)AAa9nc>TYc{biWGGiQAFa6o7Zfl1rS`0>Aq6 zQ-cMmNqOKyfT~&wWJd zofvsy{fv!AKl^d=`{&amR;V?s|Nd)_PLake`DeWuP z!lQYGF7nvV^8}*-8X^kTD-BzWfY)F>K(Z%au-zNzYfg%&kA01H5xS`?TDu6zcuc6w z6`;Ej|Fy?P5-vsmJZs!yfEuJxpl>@^op}+#N`L-`=#j5|YEMSn;GJgGYt<>;jPble zq>ROb4{&?Jv?^{x#(V>q#1~g)uoVs)TWU0pTw6AABoaz_+Q9xAQG)O&`IhWF&Q0IM zBU*LBll(qS!!(9T5NuUU3>eTTxb=-nDN)~~-zFmbVXZ9Xd6r6*q{z?>diO_JEPuRQ z1L<|0wNDDqm+o48qtMJ(vV6rlQ}e*Dx8iwHeR}M9iqVe|!}YH`26Y-{9aXU6uY^YS zGKkKnYSLv#ekGZUIMAWNEOthh$my5bpI4C2#Ig{XazJS*&nd6lbjK^ZvqKXMQbA%! zs3c;FRioxnQEUqy^fp_ut9-ud_1E#jngufAT4=n(qDYam%E$J9QWVAKBIm^q%7sW{6E5 z=6h-dtj1%GSmx|M#-FfX#8Y{L%2sT6Z*d|5xc*ikA$Y9u`+mJLm*)%Q(B?xI@n>({ zYt@zyXkpbQ)&{L)6y&h74y0i~9I!{pwxbHN1l#bXY-iXQ(m-4Ch5UYiRz}^WgYOlP zXoIm1zVLZvwB8r&$aTL}DlMe0W^1T#coO&Ig9&oY1jM#rAw^+DJSXeVUyF2Jlz^zj z#V6|}(u8qFU=ka9G;wxyx~BU({*-=oH8IZ*RSK}IHq!Cwp-Q}1G3-8-O3kEB!wgDq zUWp&NJ#MFu5mkoXcPtRy{yJI;tsUU|PT|Cp`hUk+sz29vNibrj+T7+I3cKBO3~{!Q zL(v~?2@YEYfGa)<=w?M&Jwd8LDtxwajK!uKcUhxXX_Ix6Jk0C{apQeChYeFKsvd#E zf(InOTSULon~TPebB^}uhWkdrC$GFt@LR*OdIscD%z{?a{TWC98tnc~vPOI*UGDyU z-p>0mq45RMS-Q`93c2(=yc$YSRU+)4s?|A|d@^ko`wZVWKPx001ybY*y#|ejK7=ze zJK#;-Ys-~jFxzjZv69sp(IDRkKNgEXHoubpCGriy;8QHCjQi8TTLP9KyQoq%seSRP zFxy{LbL7K?bceBG?E;Zngw%#O##Y*4>;mBjT|d&5m0fxi38?J~T}@PYcoy4gswxOQ zA2On>k7}o@f!Ek8aCDq4F9)&nhC~E1Mb|Kt)f@J>>bzCp3!L`>ZkX3nL8Q%J2dN=(BfH<Mo6fMG>7t?FX@TS9iJ05-dbeQ`N;kXVf_M{RlYUGC_3LpPARbq=nWFJ zT39$T0noe4yQS^(e1Pf6dv|$|LfNqT7;C|1*Q1#~+}N%4G9Q~o%d!x&wgsUYA9N=) z$-Ai*Ao@UIuvWYMdHT7n=OX7527fB`Z8+OeR6!ESC&jRPSEf0bGb9sXs_8)Tl~Q(nL)>aH(jLOLznh z_ex_(TPP2DDW%&H_4v4Cqj^5y!T}scCC8_4dkr8zfyWv>Zr;;Ph^`0!P+I2T-s#6H z+=F==9^W_j1Wcbh!wP(fXNp*`87yo%ExHpdV=mEIO1ekC^AnH68sXXFKYdDy@@M-K zr-|Cwdw=JPgIIuFFQ2%=dW_9j<@e521P5i1%%H1m&V*dA|2eixu-=`iw1(*hE6mE8-R|nv+{MAx#}zOp=I?q?&~`U24xJml?)M;1 zc0Gz}KfcGk52BNyrJdB^)(7)RG*Es(7%%>tvCujv&(R<;WL2RVw+VLL|g4` z5O>+vmf^xQ{4Y6{Oofs(FRubcJt*qAn^BHZ8o3XZ2OmdV!9mk?RCN5fAy>fS$7%LF%$<_?slwb{hkZ$q&YQh zdK`B@8u?S!oHbPz9->oCvF8jduK<*THr|-JamRj=2iA<=vr0udumFglkR|p&R;f@9MJs4oRNqFZ-`rDZf1pZEyTyGlE z5P7gz#s^;eAt)T{nH6q0SM3iC2zHpX^zAg&^A@!x%O|^a|Eum`#^iT@Bze`mmXJHG z-F1-P{>#kjkE6H!qtT7FXS#AMcl8!(UoO49f8b^{;6g>;iGSy0RhGt5az57f@LAqB zB0itlyrDHkg8*U$R`taRo8TBTe_endGpX@4#OIkU%Hrt}1JXaL^YAQkapG0;@LeL5 zOwXS@2=qhJ9A=ecZ^b(j{;Ri`r*pDf(eX(F`d{cWpiHUMIR5%6q&PCdj{}WmG*W=> zzE2Bf%5`;2WL9+w0xp|B+cXW>pqR!k<)n=_jF^>x8vuc<2Mrc)E|Tuo@cO%_T4W+7 z@vUunUC9cxCvaeEIxKxNY^sn(2rtwSJz}eE6&GE;!X!bFEU+MV8?AKr7Km=e(+bAw zEZ}1Q6OIpQN`{W^aeLe7DzLeuJQ^IIp3Wu0@1qpC^Tu()Z;w^U!=kH0&SZwmd;owS zB6#;CIZQN|=@cQr=C_@pNq(mYd@Y1$eO>o;pK+YWd7Qd8j}T4}FMiqT`^5S)wMfb1?_AW( zxotDo;awhYzj4mTYcf4CW~&e4Q39K7Y4!=Rj^G$GPKrfO9P*0Lz7jQWlsnG8lHD+0 zcK8Mwm*h}=u1>f-Ru?{E$KRcTMqM|j_0`%{d#@hpL@ji(TF7VW1tG1k9Fdl%k&8P1 zf6E{jQUSzB1S5Y_M|JG)xRvyt)nmd}#1xlP{5qvd#)++-S*Vk2ExP+Ln?ZNEiIN{B9g0lkyr5@{InRPuns&;91E5u#Chv>&d~5W zdPP{~WVO_OO&mEg(%qd4&zVcwpu4~X}~xZDUAK~eOeRwG*a z>V6hs6;Sq%ZBS!`cXa#kw>^}t{p5&oB)UyafYKdO7|!-#wlDtjOGI5Rs`9v>CC-ks zA$o_UQ;zool1x}bCWbw&UkT=TL%?wO$L*SL&0@LLMMS}6Y_#s`+9l%nqNa~a?1x0> z*0FOKhE1$Q_E^NA>g9u==elDILtm&$HU_a%8J_IRn&H@`1dq}2=QA5XYB%85u+zApu=11e-=y$QcUfjh~2 zm0eTK4YM0^An3{^tt4;uHKLbsMslfKVHn@Hwc11kXdhKM0Nfz`B0#bA^)ttJhAWxD zUrzr9LTNXG!Y5akLb8r8V0K!WzdUW)70Zmnw$rWD5hNWMw@2Ph=~%p=N%wk=h$tb}DdWoOcs(>~eKI|0YV<-IA&6DdnlxkK?w%Zo zjuKUQiBqIot^4bd!efJN03oG1c2#bnQ2D=s|LISW>zVMlvRc)W^JF?3(RaMh%6R1m zRDMCvh1NP0-0jpEQDk$&C0z#NCe1$4K*fn$~%G6AJ!># zMrwcIGHaHH1KZI1RGqEf5090+>w9IisU)dcB?a$w39(T9A3QAIJ&ysdlQ+$4bJ7#A z>F!DM7%CUFs@CvuDZ+p z{KR~R(^2dI@sEFtema!GL-($es~Q!px(Xy-1eL^%>IZxU{`m2o?v&4412auS($p@KUg~sAc z;#s^lY#zJ|49=DjCNHT`s01eLp?eVjo$g~nd>Ya+XJo#u&R!<4EtwuM{qnY=zHS=y zFn5~sNH)1N%{=40C;HpVNo9S(I%!;9nTW5L47S&_!98q9%(^n$O3LmN5)s%(C(w@h zul+VeMRZ-51~p2t^eZfGjTy(iP791E2s+NNVn!bJX8$Ny`LEHD;d;sT?A4aFvXM`o z^%l#BaF5iq>xi;&EDMm&J>};YVx0^sunQ$%J@PDoywkzc>tzRwGuEmCIPhW+siP%1 zz}oJW$N`E4{8;rAAd3(pIHXlB45x)aBM!SHAgK)bRVlp3V0?jZguwSl`wJva(c^0V0{9uQ1XNBNr(Wu+`G*mfgx znS}j_vg@|;D_Vq{_0)qxnR*ma=yR`&S9FVPV2$e7UpwgFn4Yv{WUqe40=!So;IBg* z#Udq~KBtaIxkViTqsF<4LJ|sG{7-s|gtvDJh9^ptaxv9f?~_Q21fnbMYgMY#eAus6 zuJG`RvfWKYtWhB(AXCXmf$y42t0`UTSxA&aq@uaW%|eQpS;L6O}8>Lzlq6baneG>!|Low zLJ*W+`N%nQ3H_*E)U-y!AmYJf*GQp06IVxd4d;n&*oUvA8Y|fDPWwXSqfMl8ip+nd z^G`oRT9}tzgr1400>2^#KCz%TbAh){M2-CFlNsaj7`3H;@_4A|(T!SXHBa7IM{)%4 z(G5NOxl2G<{qyq%_-wS4nR65;VwQ~Wuu2)SRiDm-$Jyit#T1++Opf=Od{v&m3rQnONI;L?v zWS@+}IeaPBKfyP0LaJf?%J;~|g`9uA>2h-tEY*vFQvL3n4OtECFD*Ea^B8_68V(T2 ztfJXnO^^?(Z$yAO9#w!Kr~XmTGxC#)iu?s5-v6HoYk4c*{OYZ*QX5-a#PJ<+hb|4l zso8$5XhOpk9F=EJ6z%@ZeWbrVa~|8}(`DC*FlD;XpiccMitXnB^;i|7;lapaS^8cF zw@8Pg7Nw+qT1rHJ2Fkmw4E@LA*1Jcl5+ET7$d0ido0Ok42m#cjqDKAtd&zHnm)@n) zWl6H^R(f)+5+Q)EOh){Kh`Uatp-MKr)QO77Crm>}EAKfm{Y>7|5YJS-mnH5?cHxle zdGl#;9fhB37+`EVC3E=FYK2qLtl1a}#uw9HQ3MdAUi)c3qLq}?TYLjBFWy(ghSz&{ zPm3adNt1P$SB~SkMk~C@f79D7^+WNAsaB>%5wSEj(knX)n%olo zA;0wzU7VqUw&6wGSj)da0kcRFk>AIb&VVctT4Gu+w7t^QBcRxd3*0f5MJnmzu3m`_ zS$$aK{vQ+FeD!a=I6kf zgKTkRf$#3fmrmPy$`mO45oPr#_n)^cNjKL%pctm$jSGxaRFS+TuaTtBc;GSf&S!cXxine_W6o*5`nlLCgsMay>7_^eb>Mfy}9uL87(vN+c4tnG3!Jhx?9K{ zR=@YnyWPDy_tbq{c8IjD6txjvX(=l}weD?u8%52A2^ zMr75ZJf&!}q@KshXXYetc;Hi-jYmUOQ(@@);FVX{Zh9VSf&Hict#t=P$hz5o2^E%> z3z&~=4QYw^acTn4S!oUE(%{KF@fh)#Bye-VA9>r;MXXQVV4`252R7{!=DkZq`$j&D zu=FR(PQUq79Y!WeV|77HSIjG*%XUBjRZ3x?7BErFHA4fU2XgcSA*t#rCD}6q9p3^F zf&-7OM2u<7F>f(SNopfdSLK)j)QI%k|6>DXEe>G|0&>e?TjNDBRJ@ETK!aKwD!f5R8P)8O~s|p1Q#CCRq zcf+$nbOuhnoi!KG=y8GXU4G@!78Su2kIum)ZgIYQ0wus+eGRSW6$@D;ot>yhJnfNF z^$DDG82}3%@mYRM!`itHr0e<_|J;jLkYP}(dPW|RvW}4k^_C`_fg22$sQrMI+5OL~ z`A4-BpeCC6D8WBCI38SovF5PvEM5+J-1KBL@B8C&CAnx9?2}*cMPj)%39juep zya(tcF$Y$`8hUrt*4uUAQv^11%Fmu69Xl))Q*AeMlEEc9V*rN1(|cjLFy?S6F!e36 zJzlX|a{02G4uja8zvq1+cTM&#+=T?KM4@9!V=2I;2j2(AZm8Q=n-7*cJ$27W06q|C zeZ`9Finuy3Rdj?rt? z7IOiSV0YT_&#{joO5m_7@hpiw<-V^J+((p*R6>`mlZ!gyf2BIrKP<*dX8?ayazFf; z*H$1qk=W3b5Jr;v&VlJ@w=}~AI2HcoE^!QVj0;kV;9l#N*JQj0L< z6M)LNYuOWdi6?|TRIQ;G+PDKm>TQ=Kt8Y;p>|}iLW6Sp9WN^8ls7es^wE={WGlcyh zE4=p>`;pw;a4+#qVKCc4I>um{1%rovP-4f9{&ECuu`%nHfnlc|HE>FPCcjNVR_mt# zLjHA~wCxrwsKq^Otv1<5f5?gSbteE;;&yNbd^`Knw)GP4o_nE7TiyiliQ%!fea3`V zlo$j-$zaDr+EV}RRRr>yidzf8*RrxquO&!mRgRciSAwXu*d;<)Us0}n8dkP%C>YnG z5@(QRs}GOV4bc3u{~e23(Z4#)&0E}KBigth&_jg?a-y+3OtK777BhW+$IU*T%s$*! zR1ln6dT(nd2U=iO9+gNU;LC1R6I4+7VQLkE)Fyvm2Y6~A2d^c;ECU-X$=LGL9@#c? z0Y$}jG5w+*f~?yE3-8EypWn97^I`{UxYME-4R4C!eD)Ty-3Jb(d)sKs8O#mv3eiyY&r+dEs)U+$*+1H766KSs)UL? z^agBchxJ{g?j8~-qhi$%vP+8~raP-Sas! zS>Xi#JgUoEKB315CG{Jc=6Q1%eQ2U8F$);K6Q~K9@pkT$AaWP>2#@7?n)d$V3X(w0 zLFU{Sw+^<^9O=*IfP{+9IG~K|dQ2#+tLAAiAZ>q+pkwR%g-Gv0fno}|&P3G6FVUNt z>|Yq;J3gb5ZHWy*B_v0!^n*tlCOzgnJ4TiC808iUsoaRqmUm$rKPe!p zt4IZ+EnA$jDgJ-UB1ZRVo3Z$XaDZE`S!JaI$xk6d2%G$RI9_Ff7{ezzxXX*}4baf~6f6TdR-USsZkGtL; zn8*x8Q`x|QyWPS%p=R{6zCi$sM9?NG3nBk5X z^DCRsFSo8Ez9HL^N_@|MzUVU*%u=g0%dNaqDY+q^AL8mR^vR&KD01ZST}b6_qCTgV zXEBKd6G3zJxbm~i04}inJ*d)lC|56IVv(XgkR0VwqZ{%;H?=ASyaMsv*-X3uM#y7B z2Gtuz^bpp4?Jbq{!s!ZP6aXIlpE%F+{zR1v$mVF}sm8KQW{{aQ!StT%Icd~iS7F-sZ956N*^qUm>>MD;U{Jm@jETo`_{&R=Rv)|lwBcN{I7dD z#`x>r{(KQ2!~E`Bf78iWD?Emq5BmOoD2yT#O&7*WoE^N+SH5s3L5y1r$2+rt_Yw*H zU2Z}q{9ttY#01I@;ghdyu>vtL;!&asQ-=%LzZneImfvwa6PCpzPX{;%_CXIM!EoYh zA~gs!aO@r%5}|a*io%H(c}bMfk5e*6xbIkEWRikS@~|7XExcL%5o8!<;|x>WE*8?mj5pPllN%5O`&0uK zJk$wJs1eH4px8<{@y$4OYF{k=i|q;|ynaZH?SUbR%7wXnWiN><8>xVYCxIE&b)FxD zkycc_>)GU8jOr*AmHtB?hP$qrd)r$_QLa&K{0$Rl1oc@0x_rC{Hcp|}v*dRkh+>41 zy{7YR#AO#_uIZIxHC1kU4$q<)EJkeRlx;ta5!mFrx$M|;&$?#1ZjNnX30Vi(#+Bto z^NNW{B_u>Lnj2Iw(u>H-XAsRvj-J>tuTV~A%mcN{tn=t&?u*FnC158A&M%Z&+8u;f zvv5emN`k5@2E(<-ypCCN!#&ewMju$!me1V=n)GGZw^H59Vcmo%HJ*gT|0EL6|kHUx?w8~PYc# **yD@ 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­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 z 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

Q!6>#xuioFO>JaIloe<+|Z*~of(|Zh^3}h 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

jX}YUhX7CD9WrxecBuG!tNR^n7q6|GFthu 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

    E* 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�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�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

    R}B$Zoc9{59_0OFn51cR~wj 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�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


    &$ttC~oEQQ?3 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∋K~5sAeE#67(YBO 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 @wBLh_-{*!_F8D7qG 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 diff --git a/lib/morpho-utils/lib/aave-v3-core/audits/14-01-2022_PeckShield_AaveV3.pdf b/lib/morpho-utils/lib/aave-v3-core/audits/14-01-2022_PeckShield_AaveV3.pdf deleted file mode 100644 index ab37429450e8fbdb7a86be36d423b627297d88fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 395584 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୼P_dz?d~WdN>Vb#nw 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 Kiq+3f=uWhNL94Th$Z2x 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 nqDeX&g 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%0DuGR)hHe>3{v( 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∾N+1Es6()a>-ix7dF`G_frLywq^ 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 z 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%0A%2DsS`(x7N%GI65Q@wpg2Ygl#oIUhyzBZ;_Yb@M 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�t`CckD z3^gWqxXVL=$~DPm8i}33J1#T^Ijnuj102K(GeUijgoY6AK(Vvt>R&$+F>ZAwVbK6I z3AChsU8|O$Ov(PN<>(qEqF(dUyycV1^j1l&Zn+F(g+Ar(;@-I3CsDP0zbUaWf2uY3 z@{VItZ`(j6vZ)f5NtQ$u+0G)eI~o%1rVL|x7AT^UbjIJK2;TVCO*=RVxTor-N6q-UL#4{JeV&fRDqV#^oJE%9VB5<9!OQO`g*Cozut=@?-Kmt#I zR4a5mPzKSDx{JEZPheOD85V%_FtT-No^UWtqEBze8aZZ z11rRTf|*YY&WX3D7K`!?K?M+;wM*9ndW`JJbjX2TgPa0_?FI28z76#TDl8;#BD-Ye;kr6$vlzZv?w#EA66# z$Cc{fg62X!yNljBOKd@nK#g?b+7`dlxw@LH5m+L4EuJdf?2=g%RM~~SM7gu??TLCz zH(9j5`I-p#VfYGz7@J;YL(EL5$fz{SH?owZul5sfinG#!c zfavTV^QVWnU~Alo?eCB-u{w7q%Y01WOGrQ`D_hjS+cK84B=QetepC7w$+_5OIQmUF zboT75EOR^Rn!vNpJx7M#rEX^zWG>g^-8H2M0Te-La61kmcz~#*4~3n`Z-Sw#GsqP3 z&N2zwRc`PE=qmr~moR%*SN%+q67nk48lBth5ffUI3O6iEx_GS zRKz=0Gy3miF_egW622>bT+*2&-G!JDW-rwGzLWGU#g!#=4_r4v=5#KLQJEszIew8v1q9KGQpM4qs%B^i zz^(6u4C9)y>K`T6UFO!e?;;1Ds4NpMM2>EEAu*V3(#wMYE%MqJ3~AFRIy%A*nv6Zd zuWO~EL;F^X!Nf3kI1l3sR-u?1yaiCEJ&CvlMF_Y#YZ{6p;MEjN{fF$k+hOJcqX5O> z!axS)p^1o^^$_EuoWYJkcl5ZY7}3&^J+&49R=fu81Ee@sXtnyB(|ohnD5oIea!mDC zK$F-B_}o++N)wHSM_D)eaMSit(&X}EdsN&B{E zIEJ@KvqWdwdbW6;p39u2p3LL?-}m!y8P(p@DxyzX`6ci?J6$evgkR6s=pH)0^B`=& zBn&zRw<%)C_^hWnVzx|L0?<{@ns0QOjzWmhZfSVf#>x8GulS4_juNv2qeIycauA5R z$y73iEuuipaD=5s(O}^bZ8M1R2L(sKfd&QNTfg(qF^qdD1XM&+b;}IV#!mv|s|e`| zxH+-GBrS9{64@ol<|LHL`*fJf#Oc(2Se@Jk}iV-gpvO>-hwDOQZWcQ~S3V+Fz#~ z{x4$uS8(V5+o)&%>)yuyAjbbPhW6jY_}jS68p~Ibi5zVZ+8>zsgAyxkf%NPE{hVN2 zKv|({kVWCo0%wG~L(V<9mBh-P>s~Wp6nmx&aCZ1OM#D7H^gz<-X`e1G&pWA^Kzf73 zozZ<|1M<-?3T^bu)wXJpUC!O!qUN)BzdGG--=L?Y(El;B?{Is07@X(jIy^hx{|3xb zkt|jY8T2dyZJ?Hw&|V*HDnuC%?)Np%VLCblTnH!UVZiNNF5MINe8Bwh&PbXfRt;2- zH%f!B>Bun^BMFTo^ee0o<4D%(rNYGFp8DxxOctzz$Qm+>T z#_Y-l8Ax1&?JnII)_Q$Ji&-N@7YH&ikKPI$)c$E@EQU19#i5*Rq}QC z^<3;1GZAJhdnPye2B>|$N+&%$$yYpq#gRO+6i%j>dDQ+zXT8qE;~HvAUZmSWF3V`J zUIRTUNlT1hRU#V`i&+);oMLPk`z&>juc*`WRn#J5;%EMR>-`S$vsF))L9s#+*qBP~ zCX55e`-_P`wy$QGsscx=E@#81%QFgz3j`z*WVx@rd9Vb-xlHO(jG6Wrf$b!W&@R{| z*+}B>7=Iu8E2^yaP>!2x#b}iZLGzQZts$HzEA#fy^n=-FI)u4ws6h?*Xcsca78#v3sP84DE@#lUxSw&qbupmtdsM?hrGMC84>L z6;wk#Xhp)#hbhX)kUsKqrU$2i^vQXoP!acg++SpT!S24W5ZL~3{Pgi1DPecbWFvax zv2Ia0T(kIsHGrHF7Si*V+m8}(n^Mpo#e!6_1nGiFFkF*;alXtDW8df{(8MYb+xfO) zmb3Nd)0P-_*pVa$f>VR@3z!}xJ;iJLjb?v8uY$DjoRfvcb`{0$PWq_jWAbfogcSj}er5Fb5hY?|9w+wNs+e3#rwDNOhDATjN+MA^t-eh=9b|t zNWc_q$ds*KPgTUr*2`-%7d9Mc{SJW!F5IIiedn*+Bk&9Ngoc@02w>QJ|L_dK$K86= z0-o$X2P-lFM+gpLmQYj({P=x#G}&NKBwxWRNVl{Q_pvBQ*A$Z75zC@q8Q)JP{Y)Yq z(F$_Blps1#P-Xz>qxcA}q@(s@9{jOp%ouSsXoG3#aBrij?Y3vsfjg%*BiJ1RB@Y1r z8prSgT=C56z!qr{%q*R6C?GD1(6!QjjbgE(=lD+K<}hHLRc0h(u5-iN7u@jx&@*@B*DAKS69#LPd}SYAw@S{%B{nU2@vp* z5j?U$#8YUjs_-%VU~s{sLVCO!HnraGp0JJLr156!FlM8-5099C0YKXD+w1r0i})gc zW=D;$=hZ>Pa#4?OVfTm#z$GNnEhk;?dvyu^CQp|3e_{>H&VGB@_ikebNBiOJMB%~2 z4np;2-uGBFVrqC)JkrhcyxIft30S<8gZnqm_;2~Sf80I#KQQ6{U5x*6Ddq1w%>Ob! z$NUBN{gX3R*ZqSD|M6Hn^Fj=a+W(2d3Zr&9VBU-(s7VC8_`qNPP1Dz!r0J~c^^Ws~ z{I>&>5p~QtiCEtJb=2N^>?3D*?kHF8=>FEeksS*fll~t&TMVt@FeI&uVf5_!8pQGH zHw50-1|ucX)wIFcq`ZQELE-HYr%UMF?xR}<40`y%*GT5fxigz){4nG3#};<1_zJ09 z6{XB>b^@s;cY8ScVk&o4PG zW}o|$paZRZw7Fz4=0>4o)U^%y zCUv%Gv&hOiLiHa|`1w+xp3*NHoo5Iu55YeOx<;_e4~QhCX6IJQq<6oZK*sAtzY>@9 z(o=1qW%O3_yQ(iWHfH~RQm3J-eCr_5v`}a3AE_zHwkI{@ZSVzzuUQwT-z+{}q{E`k z9=59R1p{ia`3QyCH62BaJj3U_d=WQzUKNR9 zqEhYzofR1>(RJS{JO=NtboWZ9Br-rNoEU*p}d4y4c_=C4+|fsLDSLEn?^ z4X~+F7wtuB?!F0Zcd1>h(Q}-D;lSn)9kqU4jAF`PZiOgz4vI5qr{;I;5_!m&oKQSHK4x>_O%-Oeb0i} z(+b;JDQSc{_B#hon<1JtcvTQQ7M4lc*xhgqev3Ja5A)kNXY_bnHhxZElFVaJJt7e3(#!9z%kE-u`H$UuTCOAIPyQ?P4CQ6*Rt3v@K%Kz1J*-BTtbIDoqZ_{}qLvzC(+2#~cXt&+A2WLagJ|rv-7*owW{HaV9`kD%<8?AtX}N{J>dfhJ zbpyNA$Z5&{YCCd@4~Tt_MNDK_ji6b?A%NJ&eA;_ppjR;S_M(%d1nV4}X$&6Z@_TmZ zgI?^;BURlHmQiE#aPUun>4+;Yz5W@oy9Km#@QPv`&W2K$Xv$AAL!f)6TtzDvd%-{6)hmxy&JZnhc^>~YA4 z(=B9Rv}a3-vM%$;vRMJ)0Rx6eSx9#bvi#!Xk03s+3;Ax{F=d1KMU0Op6(_^rlA$jl z>CL?4hmj-&@vV{MIHiI}AN?tLx!<_pkYxGYTsXU*&F_Gm;+|RR=JWI~`!0Jek-O9x z*}m0p(GlT?{TRNSSH3igHE`to>IE10&j8n{_qAA8ueX0sVD?Zi5B>CYbN?9Ut^Si3 zUk&&o#uvYc@k=dOU|sa96IK6*HrSX4v^1$x-ws zj%*&ulCWY0HA{t9pQtO>P1Nx2F~;>C*Y@bg)P>&R1Mna+K?$y&J&kE! znGu~#R`I%xs9ko}0|za5cYlwRSy5x|l+Wc|&Li2w*&P@sP@8_2kmp~V*^Lp?YU`T* zN(&c6MYcc)=sQEqA|26b)G9b*{8=LBS5?CxlWA_Aaz!&rr8t+1?_!ppGE3=K+981^ ze1j=+ZIOFgo2aecPj}-ltEVinnuOk9+*<5RS>#5B?0Mzn5>HShPylkEv%JHm=PIlK~G7e(l!I!+K{?_|YItXnZo$wD4-79+G(I z)h>XFFicBRuhRzaZvQrd;sN&Lv2q15RVb-;5^`_EK>gYx-63>sT%#z%ks;gNwosUY zAHN+9r5-)m(r-7zhjPSkoq`pg*-&5boUP^jq94hpE!x z@4nm#{cOXrE4w@)LiTxwOvW_ip*MTDdMnu!s3N8?WiKF!#rI)<%@23c&CIT67Cu5w-2_b1duGS9#+3o7&=4LRN^{*4A zp0x^F^n}%f;Is>!ERPZv+&1@>Mo<6$SUblcN!Tr0mu<7lw$WwVwr$&8?y_yWs>`-r zUAArOR)2S9?%Z>}IB_Co{$xhvpEn~jGWUM>Uh7%fdp|aGP?jV1Y)C3<1dF3Ig9q5TM{#C}#ELHA{0iZYn0qXJEHVWc z12Sd3sa|-)+rLLxua%zugRJv+ z>7ClvcU-)eS2+%|7Wpa5t%k-oRZ1WNN0xHMM%q_j^97jnfzW^cs4r@6()cI(R-+pQ4ToCL%8K44y_547mmP1{m1`n>cV55aWOYXeF}?o0<4PqZs|nH1Hli}gr8cE)3S*E;;rx6~qWLKct2Qp_CM?(+ z6lu!WRnEi4ezE1E&i|Wqar4_zo8ZLOxcG{6|2y3rwk`&8@pk`w0p<9Qm;Uww`qzp7 zPB~^|p#R4UsHQD;6Vex7b?LSds1D{b85qUvj9o-l7J-amHiVhHadrg}-#l}HvTCZD zw=cCrUICememc3EF$4$Bw$CMEw|d$xD;3p_LRAGBDRm*dAp^6jR<#K`kPn4iTF-CPeN+^-K7jr&lp8!jP{F zrVX0NqU-`&>DDw|Yt2?|z{oHwF#M+={}F!UnPrAkuuy#ozj-|$^W>Of%bQP%>GXP$ zL7|2M0ssq41jH>~+fXu$cIlDT2P$UhnG!rSy{poUzbg`UT^7Vw&cHbtdLAc_Npr{3 z+D6F`o**i}++Q!y`)D?{o!7?x5q|4jESy*P`Ik%oVrONY2Q3m(^4I$vY%AZRzO2IL zJkRH-1S(S3Elu~{J{UIcdTIgesQWv8w{=Sj>i%bIiR(l=XDc)S?4?J`STiW|Pmh7d z`xCXrA29yn^eF-&}yM1Dn)NEA8jKIko_e1K;`_2v1JO+L`2S z3wXrt_4Gvg0ij84PpfiMBg`6lP~u)epgJ!t-brijF$irzQ+ zn8tx}dPh zJLFZpl;cd#)F|H7D`1x|jL&3#J}gAnHwU6O>fR~otq>^iNf4hJS%9uB!WW=krlnBs z;Y)h!SVjF0HmT%cbB0gEIZy|z@#K^Zfh)vBY_AnUu_7%!LJ|6~tu(e@OCB_Lp1|5LIwND%q3X_t3&9W+BS5RRwd;NcU9c zlF|#N#H4s0++Tv?m{K5dK(auGodA;6p$$T`Va!5FLI+_+%=Sc{v5bi7uyM1mli~xh zGb&Jp-d&#v-^3hq68yqpN_PD`k?fE;;rw+E=@=^IP5j;CxcVCU8*rZ}s~X}jJ=>y5 zjc*_6zw!1mr+D?wWffHOBv^Do7Gn7QUQ&ef)D%tWoxyJoO;b1vPCphPDP0=AN&KOP@RyX|S9f;!{ zXm6LExOs}*%>t3Fan~#u;4-|+m`P$u90V=!qd9Mg=U*C62!REMJ!=|ou;^sxJeRzN_w%{zC9lOpPdz3{mQL1kLy@E9tHKK{7klRVhT zw?q0y{tU4Q@fD7;#_zU8y6qo9YX^a96Jp8lwRQpw%mxYb@2rZATuYZrf(`k+Xsj?7d>{j>)y_O>G2R)H%w4dzCVU) zPk?%sVgtV)oc9~0jja5BKZA|QCbZwQwb;CR+x~`YEC3IGK2(|c4fZXtay|FuJ+R{4 zmX-^Qu;U5yM^>FD_%J4Lh8er3(U$DXquDZd4V9rO;U#n+K!3FMq}%4c)fPAa??W$K z5I8d4(x&g$GEmu-34)bNNWkg#D)yAh@@o9zT>)*pExw-2xO;j}9==e{fLSN+!&N5S zjuGT5dcH*=Oyp&&Y-rT?Z*@^9=Jsz{Vw*^wV5Ty&ZJq__x^$P`Ec4gi)IOb%)DTMj z#V|p%j0r&ply1PIe5@51mV`e>i<{UMd9%5JQ_oCRQ4fuE--5dA7vSb0#%5t`jO=lG za*AHF4-QZB1Dz9=1e*lJ;IUKr=aEwUtdG0gi@qz}ISk;7>H5lMf4)4vI!%Ld`f}5j zYR=T)m*j1N%~hLs9x3yhecbPr+sJ;x=Tqf4|4ldaw?ei5%;o*x98NIM|4XIXUq}9% z?a)6M;nY`c)Cko$aJizp*O&X;CEAhhqf^lj7Q+;$NFxT z(Z(_1%-AIeL88%HP3b$U>Xx4BYOa4HHgU0BCqlKv1DK9kd6 ztTX~rbWfcpXbF;c_nm%U^3h%H89YMs0xFIhm9pW-JmAVy6gVW@<(itSXPaVd*(&W- z{92M@^EC6>q$bz+$wf-?8~UPfk!fok@ToH9qn=S)bilFY(ysj2JGQRoX82iW$7VA9 zAu6u|tv~1Cg6tN3Ey3H>iL+>%Y`r*MNsa3`3G4CMu47bVN8aaQV|{ch<Ri9&5F9g$L$HKL7#nU-?#qS9DmYE<1%*sCcGzQ=ROrt(&~X~A`RfPeU|eGyx}XX zxl~uQGAW%2d70{GHUbiyP?#$#P+tbUF%hJ{SZBNgx;YNrXzf=4UCqb+RH-G<85n;E>loE4Y&w*fi8NUv~_yyi`HAH zug0Aqoio%(SXo8A;wFm_(O{SdCirSo-D?vou0NaCPk>Na)3h|*;M`=PUhp%+97gfU zo5vlDb6M0IFIGhD0A&-rBP3-jY&aF^wS+gr&d3jToKe<2j-wKp=sxR42TfWt0ehuF zsbMO=l<&NJIf_4PRWwfAY*;!HZs7H3OM;HkR(hr97gZt}1S1Wk22j&*h8%@ZcCvYB zm-E~DfG)-^=t=J__7c04BbGH0*Vw{5BLW*vqKiAYz1VrmGs8$5uTOQ;+K*f-}i$7e`E3(?2-42?;eJFGtF`G7CL^B zExgXLi;q$$h}QT_!iphL$yaI#Um7UlW@^rq^Tvj)Z>I|8CShjQ8EpBBR`UkG<< z!_uG)YOxmVFsCDL=qzqM7Pogb*R4yAxUh(5Q+iA^>j?CRWvTaw@H-_$?t@{`9XCyG6GW|%qwqJ_`Okc~ z)>zM}vMMXtQcG>s#SY)9De=OvclzL6UWM1^jS(S!Mg~48_!y}KrEz$Y8|Kub5E)X9 zK_fzjMTf-VQ^h}T!y=$= z7JT6aVr7s;WC-vyEXP59L%}}J((L^MwE+OH`eEj?wti0HpNVj-4J=7;6PKQ5KSD(K zcq3i#bxUU;p6sG1gu{q#R8C6vI0~D=$M6&oR~_GUNkw=bzS(h;iE6L?DvGy6cI`-h z>BNo$5~mZV6tfVs5a%Q+B`hT>B`(d}SGU2~+t+8>9B05PY39xsPIsuoCOdUxe1-7O zS^VN=u_FI@H&x-GrpsT^L%C*H_Y+19L^kT{KpS#igW#t&&uKlR2O>MEWZj4O#eKLW0T_NY?>4E9}N z<;0#GDkxtV->ad;04vC~CY&jA<_2<1gV@A;C0(SVpU=sOCoyvwor-0Gq0$o0 zxBKT~$qMiK8=Yn*6K+)Ks=1I#ZQ3sTlyG^j7;>Dpi%LVk)#eQ%3!dbf<~8op%J=C7 zD>imL5lT|gW9RY=1lNrhX8X`225X8A12r;98~T_@f1-M7|8jz-Y7X^O?ZL4L)qF)z zrk@5>+?Z1CImj*7Bf=N-G&PJ`46n<}t0(~GeE`2rOx0hb@5egcUCa;iVcTQAn=K`m`}I67C(7(K+_O!DNPlLk=6hwH*> zeiovOgaU#c5S2r!hSU(hJ#CtqTi{F9MUr|g7ixDU3lY*jWhU~XdzsBs96k~=1<(Lu z8qpWfNPJYj7N93MO%t4kPQaOpXF?HWiYW4Kfqr3{%*YCdpH~z~$L4Q(^I_+x-gQ^UW3tNcut+^iIc-H-bJZ&tftMc(Rs)?}8=nc-7Ut zF1YH_ud1DGWT>PWn^$Rngw-8(9_v_9sxIjYXH+EKY@+$%U0C|j;i?i=TZlf_A7ER6 zrNZ|0(weoYMb=}uXy;=W+uIEr3%?n}o_gnYYD_eH2_=ZE^Ld!-mP@BU1SBDgOddH{ z5`JKPh?uo6%DIDYgU6-d6gVsac2i{xyqmG{r8}(RmqDi*%vmx^$(tkwvJbFIcj0?eO zW|Q&5=i;D#`(!BH*ZB(4srwVK0I96)Z@QtsRSL5I&w+LSG#g@||ChwNzmEL3x*_^6 zQ^7y%YNA(Jkv=-R1e$bZM5uxfgj)OUvgOY#1vc7-7va)Ea z_3(crgP#6<@wU_SypIJcLf5(5Gq;rzS-(x`wl_oUkEH&9e#DFZfPPxRNkaUu;rjipbb==Na~HOE;#smq#5dZONTL>dAoq5)Jx9LDL>+*H&eMr-`GJ%TOx^ z-bEBWq)~?(Z;rFgMg7q!q(+szn#fB91N;`Y8GO$Cl>gx&xZ=UY;xt%Eg5x4NxSqtg zbZWa?Y27ys8xk^`Pa$G2^em*;|`KMGxXs0I&t0Au%+U$fRfL`WA837?%Vo&mbs$ z|7i{c^Drgu@I8@NIDx|NK_tC6xq{>fS@_Iw1$bxE`nckq>~Tsyo%-|~auFrgfp(Zb zfx3mWIt#;F$$peMWTbi`19E~~_!UA?z&4s+{EX{81>8D_Thh-7S_DqLOepXZe#5jX*2Oum11>)UB1&=UR{K|5aw5dK}~kiHTS%*0_rn35&}1=S+nz+(qDbii*SB(arU+l z$T|c$8U;3pRk7-#gs2L12v|mFV%D*gu_v)BgwBC-MD-DaAS6Pxb`-=4d?PVK5qlq* zJw+9YW|{n_cBw!O5KUi~@%z|N{!?a+5XshAdvT`MN2=NMkWP8=#XHy%{=V;VGBUkt{FlRECmjCcrwQAxqP$=fZ8>}!B z8Dli1meQPvvf;c~h&Jzr>`3|NK#bq`5$V3#9RDgh6Fb3{X^A_t@nc47F=mQjnc+b` zh?Oi-&ASm08ho-J9bbdiTC&Rr%=4qeuI{DJ8xe_)IQ4fAR2TQya&lKrq-D9|yBa9h zsMKO-=Ym8ZHI0=YSVF6lcqCPGQ1D2c zOOfsgaNuZ>^l9hKqwDgJIsWWFV+{j%GJxj!OgNh zhB}lFb(j)86BF(!VU^74bxxy&st`v*kLQi4y@3IW#g6@oF8KuIK2B3T!5uq+AU`c+ z-ru_cv4Vhdas5xXKZ5Nefu{nGwQ8=6f?#F*6n|(Snu3~EO!sLk_$y({=UPY4^9KnA zW%AFvRcg0J;#*#ky=u4H>dB#a9L9yR!1)#S+_$nPZo+iGhQRj|SLVgJ`^U>F$@Y2od#C7;Z9@LXXO);7xG2Fxz!s$_= zOh$;bqdJpYG__=MT>QuYSy+FOdNDE0%cX-18{Aw0!t!Rp!brdj&7WPJ%-xNcG9F)` zX=j@B%xoayAtAI%v=cj_v#M^vOo2ssM+lmEHE33U*k5B9#W`aS4|w78K6M2y$aP85 zLn{#9f-wQnY=2(g8hqza=QE1#V;mMn5EJ8^MFP{u9V3#sZOkQhnZ(b?3p>;`R90pD`T=^aTY~D+&FZX6J8}nC$=afY(1wlmh;L z!{;;5|7ZB%-*3YHZ7C)b^Z%dldakB!yT*#(v#HzDY3?6>;N4&*KjZ@Q$miI6EQo|M zD$)4kLZY$2dFx@ybvU-6yi$P(P$7p;Uvo2#X%A;_yor%$F(~$SAbxCMMsWn>*mDj`QgS>EyY1NahBZ6{^4ZjY!P2QLz|X8RG&Am zJs0LH9;|dfs)9A54fM;USW@$f0t$8(!Oom!!2l6O%bJ$)JL2%lk;3U6z>q-ZxrBEjTFqb?TXt5KqeG%5=!HI-L!{1c?)Yx8^*|;fz%l+sVnP@)s z-XP2hZ=!Ms3ahzECWLz=h4)$~&bh04ll39Bq-dsN;Ko$b7zzx!a_rPHSZZ-x2+Eg7 z@iXOXt)^|S9RkB#Pw~g22!1}t$yv8z6AtA?cWS|d9tlOu%ZPs8sE%6ymqn5PQk@;h zDPIRKgg=W-copruzNnLKJ8n-{aMgp`lo5495%5PsxSVxkbeWl|w0j%0sRf?Q?=%Me zWVQju#9m_S+L5vz&mV|^f-@HZ^0-jg zS%>jc(|#`AdDZ$v0g5Jzq+CjfWC8LdF5U*deYK`qeYCgI3JS$63S{pXDLS|sVlCu(s6Wb=i)*CTO^JmpUy#m$N% z*hRU4kmOaa^nmK#d`Cd+%_R2ogkl*eWAoid=_E~*&uC!b;D%bY#Myj-a`+8I5F~;6 za8YLHUb}2ipq4K}u z=T2w4)oHKaSq0ZA|3<@`f|2NZ6eHyYXW|p}mmbGqx|$k*d3TjQ_ru7L_M2@{89~bx zP$O`H$o;gyq_wHup^i2psEvijW6^htjM+7c$~Vbd-XV9=q7bdpA7-)XWkFkPhFo0g zW|<5?SYQQ=Qh0c6FzUQZbxjbN<4ozSJxW-t&!PnrXVhN-e4^Uc#<*>JMGWwdShtDYz49qliJzWq^R)w&hlY+#%i$qLoly?*K0C}SV? zZa_N#FLr>bIFs^7ljx|<@7%4Aa?_CvI|)0>$Lc2JwHl^_YP}7^GRe#7Z%=N6C1bk0 zDIMS6v6V8IzRYrJPd7cML+~Hll2P9>zA=yoKQJCM=gR%j=hrVAc;9V@iWytUEfos* z2Y~x}wh>ityQL5~J{W+V}}+Ln6sAKdoxn>wpwPZm;TlJ;KG{UerVUtnyRJ(_W5Bgln&7*o>}xDo@u9Kmw$TwB^ZMh~6Yrxje|2o?03HTI#)#_CZ?^);C2T2>BXC7c zXPylxdxzG)LMwR!JJOoube{TwkOT{V+ID6-Ip2UlXQ4^gQm)#XI*ycFn%GBy+M6-s z&Nn{iLRxFHgmtqPiU{LL_jqvl9wmVED6uNF<5L@ zMYy=?r{dQFg#cK}&EMaT-*Ca~gd**)({tgGn6uNm=x}>zfqpDwwK$%@d3_sW2fb{& zJ(&X&h3^Vbfx|NoP%C7VHfCq-RpKgb^}%V|Gdt8#%y}pd1P$~Wj@o+qrOF0A9L^yWLG}NTse`w%ap=8F9R!5F@*cdMj|(fHe3w zFOQg*OwSKNfgEoWph`?Uc%GWIAN(9Rk-?UJzC6%VRBmNz8o^|dgAiGtWXA?Wg0P1L z*Ie^L3c=d!kNZLm86hO_%zk7?>R{jIi)DLn#fROoW`)Jr4ATzEV*;Ju1=Kj|WY%Jx zfzUGvr^w?l3yR4H>P!eZHan)M5p&EZpFWA!`_GSq3oRtr?3vcLe1;#7z?$|oZ=~@z z_Y!O)p9fg|0Z6Z4vxc@Iy_m*tt;f}a4>`HYukJd!JB*?Y&l+)dk4ne|qZszo@Y_R3 zda-f^{Af9piOTPMBa~krDj2&-vpRd;Khz4lGL+%8{B@0So7#Jn8MfIMz)aDj6=TrC z4w$GdYTvpH9HY`g9KwC4yAd&I%Q95tn-~}W=)77TR)mlOibA& zp*`bYO@dAnxoJRSGylNO5owN=lcHSW_lTM%y{AQ_oYx|Ke@0gJc@~}(N>qb~^FZ%-#POMvZCeCr(bK4qqkxm9PX$7 z85=hB^{g5hi~1RE``UH>l=ALzT^r&YO0V@^1#I}>;?E!)`K|c)t{p26O|Srk2t8t= zG3y7kR!n&7H$n!$G-;+GcB!1np;HE{xuyZaL5^^OPNtu$FfW2zyYc+Oz;jp6hlcDm z>UUyu+AtxSXh3@03S2@=UOF@QK8nw&Sv}kjyZ3A<_eoI7Fc$YM1j5b zV$Jbh`p@*$a+giQQs3p$?k>=M!_wLy(Dq#I(Z#{}iOa}8>-4D|1d zWOx0w?J-N6C|lb?`q>?YG;Uc03~(;+l3E1`7_KFQ`$3H4eiAUCwHeOpx{hn>zO%pr zlCc*<1)U0cM9UEc1x^P+;ar~MR10M3l56KXMb0_^nUu)o&F6yT0Db@gaO2bnubDxk zTQuX@$9~RbC%C-=sgX_-24&eljl;@C#rYb#0iOy}Z1_vrS&ScCzI9{{jzt4letJE9 zlX$erVGIhf`dHeex`u<7Be)Aw!k-sE=!&m<43h{$NY^2&k@k2hJsE-+EAU86dFAc} z?S;yfPSYW^E_zqahLeIz(k9}PU0K8T!cnde(Xr#K*aa($CfD`^lh>QBcJEs2KzgsH zX?$~!sJv)g(o$cWd)h^RGO2A+8Mk#Kz>t26;a6D7z7jOC6J>iM*d$u({rO4ZwL)Oy zi6_n5eh$v%v;-hm{HA_;fIE>S2SWDEUdB|F-=6zpQl_5M6O>GrUE9rJW;+Ve(76aj zpYjEb0$GzZ8|n#NL#Fwr3lqvMJ!i6i3KWLLj$JsVc;{jj@XbbVIH%u^D}amVrM>;} zhu__$&d1JisG&X~k5SGYIdqzwHoKdB*Qfw%BzuBeP_HL?d3{$FPM}QVNnSHK*tOu( z>QAf zKbN@vb1TO{|F1B9e;xVnv~mm_^#5!*S^HXJd?o0fCR_MZ_qm3t;@DNiW0+Srw?ECo zOY@RbdC)kiu86G^j8u1F!WC*;Cpu~|3;Q$e93hT;h3GQj@HD#B$+$VVKb$Wt_mPE@ z3DBEHN>x?GN7k>c5RW;KR!CHh?iJs?c@Z>A>T>J6dEMhmX+cdiurfdGT$dL|`}W7y z52>001@r6XWg6ogn5xuD?TuJ?K0HL4$M5rRU7>+}5sn4tuuS&ouda@N6Gx}jA6{La zmw1#G>h~It%rcTNq4Wbfw~@7RCk70gua$LjBaCU;jQG$PZPjX8+E zD%I={C_qfkMX1Uqc@QZ4Z1Z^nf#Gq;8BS5G@tc<-7kAW^>=8#x=7>`s$AV1)ElvK& zv@Q3^6?!3%kQK;hy84M*;9GKHLQvn3$pZ9_q2=-VVxiSV_u|dgRQJbu61djo8bLyR zW~n<_32PYjf1M|;=;&G~9lC5s{w}}2j3+}AW>+85H3iG}3yn+T-~XiO;^NMnttMu} z0`3WC!8%M$f5N8La14p4H+G(SJyuw6D8~>K+Nv*F9VBT<9Hs;*HYB*sGb%g}yOuWw zyffdgy{PoP9Bfri6qPON`N^C6?p_NQY1iI=Nz$rS`4!C&M^U_!ilu#T0d%aARGb%7 zw>t2ZUe>{8DP?)Byw??V<&*E~HY->2?)uuJJiJ#2gwJtVaf*>)1+AX;$~HjZn$Z^ zsP)78l<)|waXF*PM{Hiat;*W5!Mz?ar;z2j0_v6=^47gtu% z8%^7gX;N8*pK9Imd+dY_5R!uB0eg<_qcz0CH4V(>(lvx;5E238H$?nDasv0KTM69U znN4Qzg-rPo$j%^Fqi5a5otlN@SEAs(>H>Y2`^2noxO?qbtQldfL{KMetsQL^LS&{#AOujuGXQt%8511aMJB~_VQ=6=ZAv}34%=yXE2?~t*{aem5+;)HCC`?2lN=M#Nx z%IjN4?Q}ppvmSm>a%3=BOeDiGLa7B~j)ih+5chScBSjw~zzbp$9z8O>t4^AAPrrcVuY9VU(UFxO{0%gT z<8Otb|LJJ?UmXYiNjCTwDZAf5yT!)29Tz%Xm`u`O|R2q#rYju;`!S0;JWDsy6#oJzaZcoC?~uu=M6Nu&U!NS#UFsYBiPt5#nYeyMAM$lf z$={tL0y9(lZ)ry>N}}0Op-QCpAR$SjW=q+xRbMIyz*-;q(j#@pyDxAORxW?>^ky#8aRj&hhVUSIIe0=K<&iCGy`(zK}-lFZNvWtqw}T>UF4 z0o2MAj5J67w|4C(YQwH)TVCf;$Iv>M{mHY&0=hyx6lwm3v<5S%nJez zO+Vb9$X{Neq2mCILQq%5mcFm=M=$xyLE_6>%?d;D_}1uwsaDf`A6# zA*dQuXMJgDJVEH}YC2oOam0Gl&c%AS^(IMjND@p%?YhwYu=qp#h~(gE)T-l@EV?S{ zO~4z9g-+ul2lV{SNA0D5T4HIh=cbnGA7*X&jQnH>!A+2vG)U(`k}2 z3669)C^g8VCgq-W#Z!*XH!8&G4gq?jXE+d}Q;soPjoP;uzP(Kq9P^QmHJ(p1)SASN~2G3PpA`W2+e)W96^*^qL$<$w>N zXt#Lq6%mA#KKuFOy10g+#?1IF{S#CtL3v{|^{QyF2Ey=&SPCYGPmbsaA%l<{QHh;S zu90cfN`NqF0)fj5P-JjF#QH`wgrnpx*i{WcLDZH1DtgHQPS^xhm=nl9Wt0Z*V+ zjlw@6bVXVSmd4hz@S$?*IpAG))2*70U3Y<@`W1{kUCdX|t-DUqbRpJSw@U#}8V*)= zWptW7$n0G5y*z_%s~Y!dr<izsi9bh&s!EUvq)$zRe^DQG%zXFR*G3j43Z zT)!vnT|E&Qdu^P#G~@ktPzZKSty()1!Md~OWuj|^8K;T~KIyzfXu*~0CTOdyHYsER zs`2**KB>0TLk@ydGBtdL-c`>ES|m2|R6*a%X>AjU5lN*slbBlSuyjho>gDha#mZC{Pe_ntY4t9_%3Q7%e)*J){do29)S#S&XL(iv z0J7?bIu(|^wvV>3#Q|u9fa?Fz6CKZgE@My-`g!bXw@)7w=$_ZQKsHUdj@)?*NqwyN z{sUQIa)-qS(5(%qm_vsGjn}y{x#~XOlG~9c`hDP+4k+ihF8g&|t<%e@{h_Sp-`HGA zG3bgy>6Y$~x)H{g0LcNw08l!R3^&Eu<_W-10ra&hqN-UnSiJnRX6PM1LXYzavq_|E zFd0gt5`a*HDK$Ef$PE+Es9tC$-=P&Ve%u1FT-1g%l{7%#u^l<$x&==%x4^-Ujd zjjX?0;>nV@g*hjtktDhEdxiTQ5#J=xYcDDJ)4$PYEE(c}?7iIVyiLhw14ui~1YeM1 zw`RX>ZqLijOR}S_p{4NB6Zt`Y7N1N1YF77S=c0wC1ta-R{GEVCKPPE>?ovx|gfBTV z=n3(y&D6I=TbAvhd#4&+6p9QB9)$d@{QXipP8Mt?I?k8-xtY7$7g&6RHT-X;B!8wE z|Jhjlml61DrS!kQ@M2*4k2TugFTDO;E+ix4znqdpgrbSdBWa?rFSXbl6~LnjP$+3=NFP&pr?xnsUYwqo`n@ zOwk2Xr@mo^t)oU~T1&^4RnTQpWO8OrBK8&c4QH_&^rLQE*{^4#IP=9cQ`mqk9DH_Ho zutFWGkgF^bDI^w&Mmhu7SjV}P)I*{&pfmHXL8t13kD=KEHZ4JRJPajH=`iMD@aTpn zjybe_ym}a$Izmrc8J#V-1q?hYrS=n8iLgMW{UI|hD>;f|Yk`mjlGstpc68N2)0v5; zFFMO}FO4|RdN%8|sm#WN61pi~AO<&6oY%Ya+vH`q&7w?Zg=6fY`_$u(2io>l9c{9r zX`soEBqJb-*?FEpkYZugDy+J0mst=INbGd}t#wZ_amRJ#bOUbdP&M*WJo8YKChdfH zT0X74<*k6cwwL_!-<4+R_w$Xhbt>d*31TzOqi)OU%e0NCMm8saNP$Xu=wY+pnpkh-5Zv8)s1H(8?Wosniu3!On9GlCH{5T*^L2?~5u;g(5yRzu97M*2JhSE`5ikd9!OBBd zlOwg7beP)A&TWoJ0P4v!=EjB!MF$-3RDH@bJb|ROke5|uzjUXy6UV!jtefbwc`Y0} zXxaEY4KJq5F~3jm(QmtN7t%YGNF2*C>_2!y>m)~*1Og`y2+}sS&>!1%$q-2WqRu2T zYPRf9T-a*yti`85V~hfQj#i7&pSf``HQbtLQ#*AyHDzlXQ0|JjwOhQNfub#TBS%;6 zuevjcO0XmdV(OKrhB4OUq7yMx`r&=^5Vo)fIa|7MXcI9{3XB>dbRPe>9V|$wtDk&4 zS}1HIrB{K{ax?p0Z1KGjc+J=#>2^a!@6{)6dRNh*`7H};H%@D3uDwx_LX09e@+|Xp zJ>fIfC$f%v%x~aT-%>(tL~TNCEN5qA z)t_XF@nF7P>)L?_;_EezUQRGnSv2tYa5DI0vhJ+djB&!-t8l=~tT8)47=dY8b*w5( zYK*g#12S&Op?Fk7SYR9@*odIj3yGBIW}22buxdI4`jKGAG0$ZBsh8?Ba?o&mm+F~>5O>oOz& z&EnLF+r%GumLknS16kaI7$$gz?z>E^#&Wht;3Jh`SYe=woQX900E(#!rmuf;)-0Ax zgd-8p!3^+YKk>o+Oln^=8>#;Jdr{=vxazX%0=i=lCU1fK;a1+&UOUkO> zL6R0ecJi7a#_!fc)XwU(?m@x%_iaunjB68Dvzo0e&F&>fRZ{@6nmUf9!Ay1nRpiQ~ zjF6j`Z@;Cbp?ToiR5dr1YLD{QepNJACEw@08CZ)K?Fnhd5pO%sybOXsuxVi6jPfy& zdZDK`BUMe{a58H2c$0`I|Mb~K3m$9{CJ8*F$dm$e98(E~l}O{ehFqjt z&9A|TpXEpXv%_#6I8<%&&t;fSS}Q1q!TeC(03|d%`vuMlj>q5lMsiH18B&-^+}2I{ zm!sIB!LSe7KiYRVw7)NOtdw^Co~-_LOTnX1Ao0_Zj4+uJ^XK?gi{GKDZ{RW3JX9WChoT`oM z=#&$wV*CB*z{c~P%*Z=Rd4O$$GvJE|UtH!vC2QOYZk$BLG=7dB0b25q#o-b)u7sIm z3#p(urOM})j0GL0H=XAmULA>~=yx2?kS8>SxF${YxC>{XvEF6!nXoucHkmy*t~!c_ zHiJH*MGl!c^?QXB7SLjwx(GMD4@3bI6n~&mz2Lh3uGh!Ul3+H1`xHA+zyfA8i&(X+`r# zCyRnF1=M6gbIrN@GEa8AIa2xn^{gq~pYPOgX#^iZ?*?~X?xz^+gYw#rb#OZb>FqwH zVxS_Llnp$vF^CHcJ-_u${?477O8UwlmZUE@Z-?4#|L?i&JDFG=h^!ol*rX2+DgA99WM(j zPNTuZJ{=#+8};#@7Wr2U?$y0hyTpQp2=4T+^70#ema_fo-m8M~WxZegQERUI|K`5+ zw|P^}|BbvU<9AN<-*lAz)4VAY7M(%R;0r@erk^0)>OLCYfV&-{{qu zoYvFkk$Da&PulZ(ONy{%Owih%?hvTJnI81igPb$}EpBgBI}xKUpsDuK-bvf6%#_IU zi>m@JQbhAG-dOhksdf=rckY$~ab#?8{_#9{{aI#V_p3g;bTZfZsso=b8HSEd{n+Nx zF5|xaXbdP1`w)LH2whZpW_2v^iUPW6jCT>YpZx}y^g>pdHhP$YSc9(3hlF^AebbVY z3TO`6oEs5kdO2RUx#Hfd8-tq-dFK>}h7{RCj!jF3QUlFs;<7|P$bF#|Cw$H7u^EQy8K=$M;qx`|3%7H=x$7;746Lp_);<7Q@} z2oxjq9hsZ>z95(fkw)Ff-1GyOJ34!i@{msKM9!K6>p_#s>+o51TcwHccNsXW1YPENQpOs%|XEB}?z^|AkzUPGG$ zf`LA`Fu4?(c*K<1W<%}d>!Ta2m6P`L#FZu|ICPLYXWq_LY{~?!b$4R%Vf>_5M-7{M zJ5fTDV;AYiJCrZf^SQrN8~1};{Je#x)^bRCK3lYv7HjluhkXERi{Jq=q(g$re^!v|$0?E=gLsIsE38~vKx9hxZ1 zP)LXPKDf8UyB)d0P({!=04Dcf(CmGNWx$b_JjfushX2t7BZvzD+ z0cMYo*dY#;m6R3+X`wK<%`w!M1+)~*l;!74YjrtPU#XCJK`g z_sewpg;lw*6I5Rez_Y`-4`)x(aJp(NU<8K zf#wP$)N_Pq9mw2>##s;G{Kf|)Gm$A`@(hoEG-PhV7lK~gIY2v&z#8Dez%%O0d=1n} z4TNjkRj--Ty#DRYf+>gx0JIiWhiXV_=qSmIAyR6L1{Fx-1tUfcP!JacC%_WwW434X z;vtq!naBJjklWblPDCjKk`FRK0ilhwhM+O0laMZMmG~5;w}1e4~PledoAxb$f%iXMhnp;#Or0I4dih= z`9nVydG4QWRXH~*^pu!OrG$qNn2{pWx#pE>)XZ9C*V?r$@l(GhXJb>NjgAR<+Yp%D0TAjCaP zah9As16x>84fqN$jY%v}9)LL0tp!doK1-o{*fjlGj+}tkSKp3k>(LvBA>l=lYaCfz zCmD`I(6n}r@22?ScxSX zRpx;$&wCh}AFMOsWru=)0GN$XFVq!PQ^q^j@~eaB_gZ)gzE~gS5knMROv4laOn`mg z*N=yv8XA!;JwG6-Ay`z_AO=_ffmbDQyGs}ONJu-^ln}pPwxGJQXl^*G?+B7RZN!i! z{E$v2{DKkRSgI%Yi&tG?KJ~p|?bN34=Cusq`gU8q{eH#_pn+cT#K!}(v>C%AF2u5T zvJVV&`ZhRn8ckAbL4e@+P@hTYX?v)Mh_Gp?@tlI4fb>l^JcvrT#s2?}a<&*Q1L?!#z z8Wll=LV-646Q?>a*TTyRLYkd)7ibIQou{Mzo!WBxmw|)3mw71qOS}+eXZENYZyfo} z)i)epWzUqgp}jycAew(Sar@fmhSJ!QZgO&8KIR-L zG@MXQXu~aMf{C%=!f@e(`%|~f)5*32$>`|uKk4y!(|HhsJZtWcUfJq%IE|64agoKy zRoeN>GTGB<%@sG9A`n=Cr>eCYJZ1zN=X-` z$O(QJeCAoCPQ==JEIu{3 z9SR&^qBjiGVI*|UdNZcu7(ZY_)*O#fGtf-%(#D%?`K7K@qF?lIX^{fDn<4m0uex3B zl-&~jPh9L@B$k`#&pFzEl31MlyR}X095mCjOPdX+m?`H#gD?+o4ui-=_3f}91Uk=v za+zlz2|n7^s+lsgU6cdP&tmB3n@sZ^(x5%%^I5{(bm=maL?$*%WMwyLfUg5^qRu3n~92iz)74X8EZAkUBJP_It=>95r7R{lt@ z{vBs&2Y&IBKkcZ%NqwLxFQdJ@V6v)Ow@)NpY}h-h zf6P_!yyG=dy4kFd%At%AdjEd78g}_0Wr=YgrlbXw>!c|>0bOz?b3$H{SCxb81+9rj zon<`dFFTkc#KB$$^_qsN{kWCw*bK8O!BgjOV4!{j@lp3Y7f3G><4dTv>CQw`08o)f zN9H%ROR@wzQiaJE{_}|G17NXPy1#QE#8^m)u>L%;El5H>w_r+m_>WMN+8*|j{V0M6J^Ncc#iBQOY zm}cy)7I)=7S?|;5r1O60Uxd>cPCaT5&#v<4du*bA>1WHz;dO1fUbFe@S{rl?gRChJ z-Qa4m_LZ|GOS?!E*D@lDErEV%Iqjox_z-3bHtmE1Nt(II4*rpA4WX^D6@TR-8&8ga zi!m>0oHTqU%It*zc>avFYa-&Kp9Hx@*? z4l%v;oB=$2HdlHzyd{*|vUT7ciWl_q45J)%un>{ERj9;}6IgC5hj#TUt0#MZ2?Nbq zN?t+g&%zRR2Ox+Sv^@~sHh8SC?*?Y10qn3qP;;>+h5HE(5)Qpc-T`adCMa&7Z|!UR z(rdejsO+d(W)jjsNfZ=2N}H+rS4(-Go$lpCDQsvrHQ&y3)J4;UmXLy2JR&%~tPht`FdMoUr)GH1;F&!FeoF z;Zh>qO0_Rm-r@({lOxPN*n+F_E?7i>0Lkk4q#u_ZQBE-2fcjh`y1IPc^2gjaL| z*e2jgpa6I)SKpEsG=i*C;!fX(MI)VO2I~R&~CU|$$ge(bp5^*9W z*_^;i7<8JUWLSHQmBU!5tExFV;ZC^kOZD?UGLew*D!$rn>M*=Lel}+0PZH8ZJF%18 zpJvEdM5E)xlNF6Qk|XEp%;R=G;fV?IFwO!8%k(I`@f5i4fLm#8c^om00AiEyM8LXH zBm_7MP(bG&;CVI%5VvgiJ0$tRdwxEcr{i><(1xf&4D1zmUR~km>jcR(ToHBBfjud|a9?5B>4ReHKQBzm5NX^Vj~zldZqGNc`K) z-hZC?A6+Ck82<%wi=peh#CFTuJ8)dugIO)H5>88z8-~Dij!p>jiog`(tVV}-eL3`` zYmo8zT-($zD~HR(bGrn$ztXv(dll~1%m#}F2n*+)mw$cPbHrj0V?lYi_rN4UA(;x5 zL_#Wax5olMGtk|QS?gl64jzJULBVZv)F-9Jh z98%iv)9lb;|nQd9Er>looPM5`nVsXoPtc zl#nCQ53Eq?sgS*gR8ryYLVa-+1@wQoQk*p?F@g0qe=7pcrHxdKt5o(QROw@0-u^O2tYLuvH#@ z7E@Gd=7c#{3z-+xDUHtxDR@4C(;%J3rNh~v4It9F4{9U_0uc-i4~5PQl4*TtT6M27)rtfvq&guZzt=pcI*BVL2sAL1(Fy z+mBoK2sK5zIh7ytQ{0sSSK~)Q;qvSI9briesd2Z{!gZP@$e4Zs*Tfnbnh4>XMw~{h zMqq-$LuLY(^~NBqNYq2$mMG#}v%Yhe5v>sOJr-jJ5+X9?R+W+cTG5QBXv7@F*8rjYYvL)q5g~;M&Yzy{zTCKUsTe zPo;xt0VhGYo7*SYhF6X5@y}N3mvYa`)msuren8N#9&e3v(1^duD1WYbMQLWO>@hz% zdEEM9Azm)*0kB#9Y^haq55e;t1B2tqvOCN$Uc+zMUg z%Y06$@-&=qJE!sIi6(g#tVg=9w7Ia^A$qp0*D;dd+7zQp9nnh}0BaU%n}})%{faQf zy?e!qy+LNwr~!AcT{~IWX)l^JOP6Ald2%=`dJF+V(my##9-WvkxxRASk+Mia76-Vu z8Kg$$NGof~v7uJVR&5SMoK)=RI6HfaDcj#VvSt_BOM=c#)_BEwTicsxc(L&P{c2;C zH&sM(T<~h9yJR+T@T{@`sXf~T2p3FEs%H7Z35xD|K!AHFfL*)=_5YiydAhf`2InKE1IMKy5NQx5>6j$Y%fp*M3 zph!?7Sfi_mQn3R(qdx#KsfsA(xERRs;y|cD(-zM@B<43B9P3XEeaU+-R(q%J8-ZAX zf^!c9vZQf$Sfei}#zl@Xqx(2@f4%S{RB*bFVn0+YqM-N*Ef777VhcnP2p!O?_*0u@ zTYWj|oqI51gM#`~rba|>F-F19ItT9pZNP8v#YWGsIYWhOQ7=5Go6MO_8^A$>y38d* zz1QbwC^u&=eIXkYeEp97?7^!>K7wjN#M0=K?b&g2s8j(|I;D8I%LU=2=TIY7sM=g( zsy>s^Vbl7tE40HC@Fng;+Robx)bFk_H*(5JZOEpf1t-y`1HC+daiJXNW1;%(hD!j_e*G3{PS_o z*b4j$@I_aT`S0re-$r%631j~o^`7J3Wp)2~=6_i4+5VMV_Kos@`OMSbe@uq2LhaUQ zXht`%OafcyVv%jQ7S@JQ&ria*U61s2*KOtJmrC(fJD`KEvl&!iffbD`l92L};AH8D zv2ba+zw|MGZZAMI7Lgt=zK^CTCQ+xFXvkq8ExH$dAluo@W~@A14R3Tm-5neXDJ795 zh0DY1;p2N>kGsUlyJ5fp^Hr=wEo9(V4l<#Mk2?O=j!T-RaR=H?!cu7DbE`=bdGgnJ zccsh=Hr_*hCs`_!Q=|u6&`6^o@-zjx6Ql%9sE8CwMVGS9fXozc&fIESsWCCb6z32< zNR?1U2vtc|&&mm+rjbS{VxRT-<(FcHr@Xq~aA5F26HG;*H3G^*Amf~Oox~JZ=$Mm0 zOPN3?bCxpKGg@?}L8AG+&JC;=V2p~r&haNZGVf^Y$YbjqT?o7VeHp8Jvwp5@FHI1U zd*(em(f>4uq_MGT%+SIfVL_Y<3qUM=5EiQA*Uy|B5i7`r2|W6)`O;r1=&6~;2uS^^ z?|87CS@skB(Xij!+u$Q*nysOkOq6#)9+W6i`D@GA=CaCHnr8JDva6ZbCANDu7eRKtyZScT-#dyVep)01poZ6G+VmkP!AZP9!He(F(z`!d@^>N|70+ zFX;4rE09z9wf_v7lhhAAJU69XDR5ae9{4@q91KiJTG(D%GES8-kDO_I0qT=0yTg)< zEfHuCQqm&2j+A+jwf#g5tg5woi#X)C=ZJg5}q47NbTDAAF(#@lbaxB*)qyGXqD z#L`!i0;tn?d&@t359jF?BW02e*aN}#{v;V>oB@ApN}INj*+EK+6kGx=vF3>+W07E! zkP;}zEaCLSc5L8~i-~QlHDM9b)Bzzh1fY)a@V7Q*y8leum(>WbwsDj#!86V2vOj(I z3bSVR15=*g-deW#Q0=ZZ>%`JNrsl4X~L&9y5h2nWYq99#3` zXUk}u(PEj94euXQzDg|}h8kq8A^WfxINzH*4_v=FHMp6d6nA8xahIyP_b4Qx5mk;; zAfp+_d}e+A6je~#u8jj>KW}}0GD53632d6Wa}4kJoN4O*5u0DCa?`68Ds>Q>YFPKk zblvW7KCs3(TVG)~6pwc|y7brAX`V*XZew661F}f|liU;5Af+X~=kfbxA2ni(Gmw1R zIE8>{l_VT|K?HIDzY4?l!sVS7A#rpm?)YxC4h_{#X5j^!TF5YXRI*#JK~O2~H{S)aANJA5hrtdO zsr6BxK&_)DokC_rZ%!cpb^2sxWD(8h2Ysm=_@7^LCn&8<QfZz~QO_doa@&1&Kl=%LDe4YS2auVeV zDlOstk#I?<2~r|zl;8pg$t@oQsrLvbiFw8nTr#|A4RXyo@Zx<$MM9c1(1WG=4sBHL zTOKh*2|SaG#trMV9kF%I14+g*X8Zj56k7~_MF&VyS1|QQ9E0$j> zk7s%yvjSgvKA1-leoH!8Ns0Z%Gm*SGL^w}g0}`b5{t0i8;s=3 z?f4NYOS|9gcjhesg%xHIVNDmo$=h&xa2G40W&ohJTu%WhoTeqxswAX!EAsuc6yzDs z8HgBnU!zw>ob4IqYrGYvFnicSvm%v{!Qa64^>FT#2d8m@2>3X2aDE@J{Oc*eInJ(=B`x;>D$Z_QGl0itBNq!MR{!?C0H@~Y*;d@MQJTmq@CUE?g*dYHU zu_0ZpI_i8lo($dd^m6Wb`FypnV?fTbw2gR~{xg02r!~;Y$|1(rtfbwKRmGc%(Sq`Ez(R=sg6Djhz$y} zCMf}x+N3fWJ44j?FuYZ_lN5H&(4{xW!shF0)6 z64=+MH30sRsgShNlOBX@zh*WBEffnjop7P+Ns(QtO_9hab}ebq1iZVJ_a@t1g}zWa zU5(Tqf3^^R^E2$DvuLx`nVWjH>zQ|V_XZu)M(28Bd22^tG83sEG)ObsKMGndx>jek zA9%VNI>v;Po%gxQsCg`<>AZGLt@E*qm?K%pw}|+cZzGMlFu>_RXWq@bY;2xJs`_Jx zRzu6q6y&T)9y8=KY4W~OyNCURY4>(or|P`wqn%yj7V}_yHtvM(YEm~SSPzNG?sfF^ z2_pfWM^TI%r;6xj6H=p*%pLHPhQOa2_C%$&$}A<>iFTu#Qsa9h*R0|T~I72 zT)Hi+(n({q(GCUzthlBn(`BVqCj#%%vem+UB!$7-B2D4w=|dm4MQnd?g{Xi0FwrEf ze80EQ>jOdnG0c{Dfwl=9`#C>aCOYNI7BP1WHctNG3oM^?j^=*b&|T*|1_)To*DpUBvjx!A_b%u#~@JL6zOL|NzW9bF*?K~kus;$ zPehF_akRNoA_NiZ*h-)i;An~T0L-{wSWJTjvVhvi6_yQzmx+C(fODc)P1s$uH4hqxHJYvhAoyxb5x-#v`*^ZSx zr660|skWRm3l|?x8Exs0e#pMhvxipccKZ^4GUjzR#KtFo@v3|MIsc*U4XT^)2j_?O zDG*#{zV!BqbLsV(DCJqNQ{f_Q*$PnpbB4{0qt3o_`0S(2!Ey2sb)IaO!s`M(`oQ@E zee{$^c3z-DxOUhc{^;t9&rqf}PWp?@U>TPwVI0*5*%7^L`>!YP*^~y0sw{(;`dB!?3CI9LgHpNr-c%QEg)-k_KO$BuELTZVBvQ8kuqR9(%Cv(pK9DgvCB%g-j6`<|!v-Qyu` zjqdVVgDv6;#dw0|x8}IVi2@fn@dRaHU=8L>9`Z|ALsrA8@gU^^sDTbhTVBmo1hg!Z zsyxVkdK=$J}uhl=`TBar}}=Tw?TikQ%ALy$+8ar+N-*>$bNkN)Zwzu z;ACqbFKwF6HD93X1>yQ1M$bVHv|NXY399ShmZHc*pvb|$Sb9m~!Rs9@wcQHqT8DP8 z(;dHxNZWqkJ*kG75)zw|n-;1|-p?VhntH3-tKI%CEF5pw^2pTN1u2rBgzLzj;)3s9 z?uo^5pWmzVvT^7e1p@~pz~rtJz~-tHh$v%kZNl1(0!G&PS)t)7o%2|mx&ChyNQ`O`^u7l?5br);lQ^fA?nc2y-pJcq2JsC8y|ffz!6zS!)|>jB9#*%ourd^iLC#H$HAtn8<;NCm;7!B9BZ_2}A~u|p%2 zg*OTf@Pe*ImpYXZ(0GOaScEX;)n{W^=;hJN_5JY4;nM&f*u|5LLW2bZjP!GVdCxd) z+<6Q>-HrQ9ogd5x7~blF`@8D@w;{^E3~~R{t(E_?x6kz79fbc&_5V*}l#DFw{}K|= zkhb6CKKcm1Ox+Uy!qt7O@Oz<_BUpd3uz(dh?44p_K9;b}?xaU4nXgIDMBNM3C zE{Hgc7oJIA-c=CRV$l+3>B#HWn3~ap!eSJwPT|qo63s#?Rw-#Fl!>&ckJ=eNJ#`kd zeSfn0G`yq6Afq9*q;kA{T;9yC>fIWYLmDy42&Jcx#wjD{_WER2Ge%cMeBO|7_=saH^+0HQl!igY zSKc!ezdB6gTnv>mgUt0VWIq$wMcL75cEGO`t(0K5D)ipsiz-ibMyE@ViH z0iK3?{E4Qf7ZcxG4TwDDYmBIH;pvCTvR59&4tP38I(N478e=|ywadYW>kzWm%lE2H0{|q>zP(XDe}xlH&5%#EYXgN7+Xp>sHVcI+hk=p3=Db5^`FJo(l~e`Y`tn){H}jz^E8L=l zfQnjE{6M3Ei{>Du7k{1f)t5hhs%k0Kb8!q7-a1q(iLBf1HjNEvIFCj)B5FAMkZ zI|V<1i$WE}S{|#?9?CS^2|9;-YM@NKP1FK`3A`bl05fg!1*jyY9}Q^FF?0b}3RKEE z8Q-Z^1B^{hpmG1=gD#9 zRn=E5j7>*pU}W$LSn;{FMTV;;$HnpDg$dO@6qM-+Hj0#on;{abD#bKAT?*7h9-2mv zMHiM}Z~}1?Fh(91aFyVtXfnrWB z&-{~ckw|ELG0reRhiC<&BZzcyq#MpnL!3k0KsYzrv5|`jrTZUG?YRnu z6RU1L)FsLXP$>PixGmY09NBrzZfN2naE1HKRu;7bP(GGwL@tUs2 zj7%UN1xF#gQeuZpn%g3<1kk+ZOyD_z&b!8Hi!~`Gc20~X@KB2N;B?P9v!)=^p*DfM z7Zj+4r+Z~tSrr3}Yw&dK54L*yf|F()mJaPd9{wKp?n1HCTG?iyt)D`6#1C9>J!0+G z(I5_l*@Z=XLkwr|XwlvMaB_s>n(u%;V7eIg{^AsYCc|oSZ%~ z0<8DWNMmdx{NDU8Nn??cy`t$T08av~CnXm+59svPnzx?-Z zJY)XD68uyzm)GpZA^!}(7t7z3roYdxG5&Al*O-|89d?TGA7}nYZD@AZf7NH`+i$WV z_|KNl{U!lM9{fUKhtbF`5nKh+MsD@Bcq`b5BA!aa(R4$+oV*z;rlC|#EE8t1p-8%Y z;l>+3#P#H%V$u3$MsRy@@p5>PSq%N9&am)8#gtO2AvRVTXo@JiKhu3b8V^y#?&Zw& z$@m1rMJ9_(fx@Pj+vVZ+z0iV_D+hiB}gTZih>AhAga7SgYufMo2#{- zqdun$Q>#O){zgXB{e_HZlM`&pCHY21;P-l_ok2#|Xg|&~E3}#ag^XbM2QtEU*ZI2# zExVW;Dwql~-L+)eGkH;z34yi?b{=S50=Rjm_S!{J1mGnt;sJkVoeX(W-f3 z(sKnxm6I)5Hge9pvuo_$RgsP?(tv3uOs2y)Q_FYC9Bvd4CgMradQJQBV%h2r(4kSAM(aLl=oAV*mic9PVJC=fJwsAvw- zc&EY~z5_lQ8pDJK4ho4X)q;?#D{bfxPxGb!XRves49DfM_`2r$ZL7fh(AEl zmMxZ8sB(YedVnU8WkM#Q7QuL;XB-8#!~l^pDw<@kW8xM)Q?p^>gWv`8%1F9Emr)qE zY>Yl?N_kJ$?Qwnjevh0WznplA8H*pEWRnAL;a|Vfx6>DrpTeMCJ?XU02Kl##SBG z@9TNNX{|r&+wO?1H8K>+Vvhz^KY6}4Z~(9@;RbvHSp=gPJcNsSJKSn-W86iy@M?)7 z~Qf&*uy`K^2OgbCBf(yrb{4jE>+f~7x+Lrm=vH3%tkmMxIAyQ+O`#p&byct7t zdJ~p=P^G)dGybf{K3SnG*KS(aO1aM?H4S)t4VoiWrLl33TRAE+!+@cDQykbeXg|HhEauS>$17Ej_6#^*f` z7B5?FicRP9IzYXsjvX4djBCXic96bfDr*sCP1+VX0ulXwDoFu)#+z94K65KDVQzm& zjqkiG&(uTN{7D|o6Jxg{Z7z4l$a=(E9`1-XkI{C6mpdrc)_?aRtOv2m{hqF-ThWKI z-s4^DE-7CnjOiala~m6R{lzON`(_j>(M&rbwlFw%$QIm-~iI39IKXiVjLUc~g*Zx*;nmLvBxs~8N(@($muc9ysXk7e&u z#~5Ru+nK`}hzxy9%r7RxDS=E2tQ`leT@(z$(0=xuI8q{ZYLgQ~KMzkI7avUeL=_1$ ziBFeV&1+;G*{{g594dBFXI5k@u%#F4cT2JG_=Xh!)_q~ywT1d*un?_dxQ$MDmMmf9 zuEWS?uGb?_^*8u27A>)Khs*c*gW#7zT4J*0M5T})dlaPL9S=Q$gUB+sw;chk#8dVI z?heAR&58u$2yXbpcflT$e}N+X%VI=QNK<3p?w602zC* zRj;*jK*fq*3@`s2l@}n>vH{95rR}=w-LBj>ORb}6Ysl1RAf7||e0^NEa%m7q?8Z+M zWCMu{nH1Fmg75kWe=7`6QlndkKImo0%j#x5`BO~MA$HW-_=P|MW8WI10^5#s;|Mh|T z_n(sgIP*WM*KADxYJkvI-u^Z~oT|5Z{)TK2oVgVXsp(Tgc)|MT+C5M92z+~nZNAHZfXzL!!`(6#XGBHx0 z80^YybcbdgiOw|Kz`+?occ(w!({8Em?#$y9>%11cTdxis(HY0j`(vHm0_G59Xh2e_ zO!+_q_N(9bBSdvsp#n@sMw}Y>$LCDEv{HRABlm`Q5g7~<{D=`{`lf#_QTjUO#yh^) z^mR{Xv+jwAZIx#{<1!dS`pqIUwiO{;wk9`iRCU}$m1kXn8%G~F7Rk{$0cuqgJuG^=W+E(F_%?6eq{QC1d0sVp}+ZFg> zeR5x2LV#nCmiP=a2L!7j1EP(*Th^NhGTT4SbKzW63No8Tv9I~1IbS<3fdO})M$O>O zQ-v|%eCV)MQQ`tZ$RjG%9noaAkB{tbjGSR!77;;Bn$o4A;D0D4u^JJOlXZu$%|DVdAi^HTHSwrXNtTF;0Rr4k&?s3|;) zn!84F%T7_Y)>DnCj<{T!0j|BfB0@|Yn%jOsXP3V}UexKG+|0jgqu3i^DnC5n zu9T=QcBX*sZXSLJ#B+|1p6I~)^+SKyh<`oucu8E67N1WZJJ5i~2_v$j<_%C9SGl(c1qG53M&?iv|GCz}@5SpmpJ#{-YRyCao^Dv~n4wEeQB zZdwhh+Sj|ZihsKVnhtAoK&@Z}pjrn2fbvVOona`VdKMGql~}X7CIR@o==qJlpbG6S zo=0N1?V-xo#G`#bedS)F4$U!pb7_lzMZ*H?FKkiS^ahSjlGTTY4(}vfgf%8G-rgAS zl4A}ChgzSN14sxL^-99WPvInS@9sLJu$Aqw!=ZYFonyt z?*Qb<#}?^-Dsw=>7KlFI)aLgv1U_3xL8g8(!TGzjSms0@Vl)%qt_ zwK3N-a=BPrim)BQ#R2m|1M$p0v$UP zQY!=;IL^V@K1?`0vrncuY1S4wi>LQ*E7#w@V+$aSOBABWt2&1ilB{zvl99_q8!D4; z7LJ|zEfRNf=>0T4AhFD3kSI~r^m2D~a=r$ab8>#lVWWRUw~nO#toAd5;Q3aW%i zx@E5mP+{Y)H^V$l!I1|kP#`@>OX7+MSjV9skf)Z3jAIra9;dUXXf!HwR_S;9Lg0bM zU?@Rg`bZ6fj5lvMi!Cm~IP3lbA~N5rtv&@`WnT%^Js8);rHNrh#NyR_Ei`QhWjE#L zhC~;`pQn$aFTQL#bz+~0p>dAi`!v069ufry+FD<<*B90j1hpeD6uI8zAav2SKJ_>w zo|y|5a8OoY)##^wkAHQ_T_Kg-`(H51*zl31IFM&!BwH`2xjV7yM4gy7bl3Zz@Gni> zcU4TzR-AdwyC@*Sos%8i+oskUez9S12Eog&&cv!5iOgG;EPF@GiNnEHTwLR1xxC?> z1XnKDC%xgq)WfQ&wrYouZHIaMQNvzS@Z12mgwR!=epVTadLfpJbP|WkvoB`C`S^f@ zEf<$Ycj)0S0KL>tbC4q0&7T{DD_``2@1D|^|5iT=t~#KF3`OX$4YpX`%o7$n_nBq9S}BIFKQC`!3S_?4yIIxqi~)>BjS+s$^S{2=LZl;y&Lxy!DT^oOgn(p zPsCy0j#FyTAo`bg2wt%hZIf29lK6~x(hx{e_LePMTlx0Hf8DM9){pAyw4^D&dthJi z7h({L!8TecbqJFZ*yKe;<7eM*j}Y&W_zImO74bQ7*f2!6_=||q$gDx$z5pl)&_pBU zvK8@6t*@*f{wp%R-Gd^Fymr~L?Vq5fr_9_czV|QfTh*iqGd}s**lXQ5a(>Iru7}ux z6(cbhRyqXlx~Czr+eLsj6=t9 zEgSJ#?twT>z1s)FNM+c%G%dJpA7hj|!0}j^AeC~H%S5M^&vm!lmgfbv-rO+d`A9HJ zEP>`tx(e?mZ*fz@?`L{nP;@E@TQYZk+s(qtoeur`^0ZT&D3cveF@5QXUT;m-Ir(xJ zdjOg_b;zx{XN9FojwAw1bKa@?+>MR+72DrJB z9pncAxqyps(|p&SI;pCET3Z}bvZB$Bh)}Z}EtMP-P;>(b0Q0lSOsMN;<97hSSbc$R#)}p8mQ1%csd}4JjL7feEqXy@+G$t9u&!{6@of| zuCsbOs|y#!LGm?jy90*w8X|aW#5v) zN4IE@tKHXlshKVQe`tHFph&>9OA~i@CvkUocXxMpDBQhp*TSuUD%{=O-QC?C3Rt@L zpWU6_nvRb6XEGy_jJ(M2f{SzVd(ZnEo^Z_QbX^K*k*h_L0S#s5l6yfck?`ARF<;{(V+Vf4!Mkg=qX z)D>cE$KicsL&(29*n8g~G+^iO;~?i2ZnMj*c(Lh11z!Z&;(Po)sHiZCI4J-aVAk;I^W=7uyzR6e!7>+X z_F+%>wA!(@M&{{=f4zNvyl{GaU^4(pl+Gd!QC0>xq^)5O-wS~*3tAw5=Hlhohq~-V zEQvDE@DGknn3lB>>Ajmnbddi%A(JR6BLOzXVwj#}MtCo^}XH4X> z=f1e3-6%?X!LWrm^UUG^vrsN&U=?ktT3jiI-PR?&Vf4>d3p=;-%&yYXvp*7#EpnFa zHH#?fQgT{y*1L4ms*%cUr#&sb}^XbY%enTjyFjTSvaL0m2-tE-=M3Y@l= zo~`J9fD1;j7&Q3y%$r$Hgayx3*fFI(NIPQ;g^ggJ3`J_8jlg8WYe*D zRs^N#0^N_F_y}PQ+b_tXXpyK{`i4|DNTmKwFJxyY)$j|3-;Jk=6BM295Kaw&&B#*l z8(K|4b@Hnj2PbC58sx4-$PBCer<>?Y1(ts!y#BQy4f$8O&d|KOs>garq|lq8gP^s`h*gF3Oyq@4o?KFZt8DcTOLIQdAYC3V3*FWqztCgK zEUmd6#ofjyM1K-_kZLBFOV85@i36q1Ix4pL(iA6}W^lnA*^$)$&>atJ`_7Y1ENJWMe@rUY3_r$_;Y&BXAA z&5D=3=;UaL@)Q=Lggv)MbPNR@u?b=c6)WWiIL+8LE(+QiS4jiY35qtY3a5ttja(Z0 zBIqa|pICk(aWgUa-?Pzl9#u_GCqy*Y4Z%g1JLG*wD!;DRL?S<` zv|4GN#OkyK8EJPkS+^Q-UV`jf95Br|`nzg>`vg{H6uu%Hgt@d$X~*0~UMjXlOR*lC z`?6D&DPDUd68ao!CD^5&ypo%UJ=S<;Ze88QeCh+B34M)FFcjq?uM4|Us&_fv6wQq3 zPBZscqM^F>!Odrgzk@xM{BDKjVM9okjbG&S`gQlUzJ2 zv`ciMYjxVGZnf%n1Mbj@n0zgLz`wxK+3U34cn}oQdNBtb-``EAWL{BqN6T+Cy=l_c zJq5v4mT-^Xc&87kf|E(ANG>WJwiTR7RB?pX^Gi2kXXg3Iw*HYmE!B#?6`u-gAkD}B zAr5Y#K7-mM?~;5xlF}ekSZ}*&kF-Ncb(o4;5RJ?ehK3c9-&I8w9f4U00FB~r8rDj4 zBAZbvFkYl=Jz7h3knEI3D1fqH-p{23X+RmddAHl;b83M_fm z6EhQt6OA4z!|x*n5*O*EeTEB{H*dG{^EMlDZ5spx9fE|*GqVVlR^HYSE|@!I+;n$D zTfB?#8AX}d>JJAe3^U2)?juJ?`p`N!ov6yUXQ4np*<-A%fkfiep}MI#1wZ!bXLJzW zvRJOb@6CvUC$xfc$CbLq-B`ol@eBJ&pbR#@YRRg3A+ony?MGZ!6P}(q&T(q#;n#v( zmCFCn6h~(}l)hNpK*U$d*KIiAP z_|qqvMIcnWKMrnE!E4^8dh{nZB0H z|GPQ4znG){!HoW23^)GcoE$szzwE?et=O-LU+Wq497cfjK5R-vfw=CINI7%H#`BX3 zbt~4(sutKL)}D1;oeL?uU@b%7+{5gipX2d-J%%DVwZ%EPb9jF!JjP^s zhbE*lD@&6QYq1)LUhTcVQ}vMhxpTgA`Xj)i_97qkvM3;K@$vkb_(mRf2Mx@A9Mzlv z)#pWqtt=|B;`NP7NSE>g?DdC<>zDh#RR*s^yc#!Qd-EyRbO+iz5PaAI+>2+?S2 z8cS?lMpDiw!4xB<6bXxJn6ThSn_#_>Sffo?@*ou^dPx0k6sx_dk@&&65Txk6m9|1r z1*zzZUr({!+xUV|?|t59VyeT=|0ln2|)qOr_B(-r=)y>h5znu15IvoWyLE!y_?1Ijoc$wNv|c zNr9?w3RYZdoy)0F^|sTc$U^xFx+~hbc8h0t>b?_jg$dmoR=EymgAR?fmA#L@z^Uoy zTmh_^KvT|Bzi-WTRwSVzHSN}Zn&sJ@0kpv$#I!g(TOBEW7?Ro|^m*{6i&UJ*2uo^6 zT`-v$Aj6TuMNo=oJ(3w|7-nltKjGC80$L>A3fnM|I8>Gujy z`}!w^v&8)*7~^%jWJ1ap?-zjgS?gUh%Mue2bU%BJ zc<@IkFiWDpOS5wJo3gIF(wHD4POi`FsKq7*#MIGN*$5a2^_TytZ%i}p%j(y<0cN?B zE>XO}7L6Fgj1u&8RYS!v#idMBd_Efrkil3I@>gQ_R4W#$nE1&#CTO#)I0krGO$pABFtk&hdt`(W2k|wi7n(IFG&-sf2a+9lX--yTs@;l; zLRNZSNmnAm}Jc5VPm9;wGlA5OK$ zg7f`(c5;47i!4DciatEg^Er^|jiB$Z@;7||Bzs6K(GpWVDLu_Qxiv+WICO$?KBkA| z(csl1E>ZqaLZx8dPp^I?LZD-B zkf!oZAHQjxsV|7#%S{u%00R4Dylq<}VnCuw>`!PQ+mMOGCqk!sphf3!5ff9F3$Ue)FeSW-f~I&DdWPe?Qbm#YS>~W* z5@J^Be8|RgpEbE~Lo_8K67Ls~M~$7g%3hdE$^g^wM?&xSu+7wfgaUp~THa3Ft_P{K z;IWvBFbM2jJSXhHX{UWsBQ6&002VxK`EyPT5a%mn&&M%aLel~>{ApUd8JVZ0TY|A%z{d-xpNzZ5=wF=N(-FE+Y@9_Fmcb+0&D+&g}pqOC|}_D2*R63}xH zd@rDrC!I+xZT@%y#~>v;O>ecL$mU<~*P_MHqzxDtQYLPV5p{98y*uAO*Nu{tzN}E2 zIVYC}Q^<}=Bt4itv1E_)Guyk7gqh-(mFSxIfWbAfYGz6e*O)_ODCq(mm~!(Z2ts%! z+{D5z=Wj1wqVd;_tMX95B7h`K3=9A`>9Z{ z>{NkbDjHOip;JhLbl_S~Re-xph9mOijoYycIxq~&4^md|#K(X&q@v(vopY*0`xD9b zc86D9BGIb;^&Ah4-!V_NdC4(=S=U<3TY#D>95e2#31M9eGy}ZyX&}v5Ws!t##iVbe z4JRqUL3ixERab)~rFtR{<#=d&wq$B)Dn4H4+GxEvM%Sa(qKC24uDf-sWQ#IFzvL-2zR#;j= z^MDulo|prItE<6B#_WF4_U5qf!<{0YX%QHQwZR7hxZBTbj3T%tzfz~gpyOm3i{Vj? zgT~8oX|@wjQkZ2wEYkYtc!GRkZX1ywjB@$OZfM>XD+rf5H0mgtsHM=9V2N72>y!}L zTCwS7=pYifv}-8psHqQ@)yLZ~`q6;&Arg{hnyl-{2kl@nGtLr+-WD0Tt$ASmy)(s8JZM#O2n$=FcWy>UGLo+ zM3=6NGPWbCHd|^LS2|+$cc~QMUUEOzjg>ij%BD#+KGW)?yq#hUou?v#X=2?#yTe!A zQ0%pvvjys`NC35TF_y_M&i$m_>(NqC4ax=jUc9hOZbV|3i(77Gw^-w;gy|`F7u~%9LR+RDa^C<| zz((TVYGj&=|1MGIIi?H5u8CF7CXP+2J`5erm5*t6^u)|Il`I+88Dp$1~Ecs1n3t!YK| zOH6rSGEBKVd{=Dw9j!EAz91#WK$8jzVf<l)x_|b;OQr3CBA&vvQP@i46%Fu31%+Km z7!Ab7H2}4S*uR1=6N$5c$bfN6g29<;dT{>nOeS9*%4Q@*++}V@APqSp0f`|4uL-h* zPy67|r#jtE3Bolj3;B@*x2sE@Dx?)}HO*l5iFFDh-N&Nf{`0;h-x{{qd#)k1s@;;b z)3U$IXGV~U7#!8(c5g5E_b*lQb?5;2z^wII+Dhp8`gCNswF{QsS_@U<6iK3CRe`jU zZY!yK0#!aZ7VY2LELJOL$hx~&Vb}-^j?IHaNFT9%WwEa)kkz^~+JY3mz(yA+VI0|| z0e;sjF!Dokm1` zmpn2so1mTy<7kd!+^h*lEE2C7moc#fr zf-s{{MdF{x;JcxF% zuDKnU(}4_;%0PC?=q>`=Y+yEBz7=$t=+)(93M6<=lCI~8?y|{P{rPpKZs)qCA;;I0 z9!g}+dUBwr^fY0fpqVf*A&NY&;R-gQDYvAyWFw*HUg^3e$b#uKfETP%0Tu^K?55U5 z*A7SE>wY9$)&<*VM5c#nBdk8aePd4qeVgE1O?qJ6hTx2Cx3}oJ=BjYvPHA1Imlm>{ z6{y_PS$d$s${i!K^q|(kp%PcP73LhSvjaj}u^2n7SLd{6TDj3&OZ`XBQ=tQJ576Sc zu@XA}#V;jRw)&5sWY9+&Ow&qxRM}s8S zM!p?)R$QWYJ@n1m&%QHyHioU-T2tE)B(35n9Q zi|-W~6EnYmoyw_noy4*`+9&;%-#%716N{9;gk=!QEd@)->G5(DyD4&)Qc9bS@V4#M zf~5vJn3OIYv!Sow!|uZ1w|6w3R_MDkp8f7o>-^S3mMP29w=j8jw2dZ4$~E`x=<$gH zPo$e}oSE=$x+!ybKgf(3>P0V90wMZ$Q4EX7H~tKm<(vr=2p@R_LhN#;O}r?vp)LCQ@VJ{BeEvzyjG->WGZaFL zaDAgQ(mdi1+(){bkiEtMVkuyOpfWg|HeDGu*3};h7T= zOo)Vc3y~FeJ%RRPuD_CJt;a1rv^qy}j1{wpps2h423 z5)|7G5aR&VMmmnXh|)+rj;xNlcr}su>MTNwvIxtr!L`aOH_+veH`BPUq1|4++}sM( zlvffVdku+t^Zk;*c*I=-R`N;3yZ{zYrh)Nem?Z9`p01UqEVVcZuLy7-&(;6?_)p{ z>)^iS8TaFUzn~e_dhApJW~px7{Af#iw_jzuV2Cp{Q~f>~KfvvEI?=lcVmVbXZ$T8) z%wnIFsaJBh*9!>vMF)rvSgIQdmJ=;S#?eVCwb(B!(GO2IAfq}bfYcDGn-kh^;q7Fl zdZgq=IqEZ5j_+}Hvu)Xc>*PKmNnYTzXkp16V&%wrwyH6IAB3=hYVq?X4eT>0X_9|I z3Kk(&I!=aeX39KXq9OxFUh1e!Z!0i|bB@c?_?*+n$<3Ac#Rzbvu{6(?diHSTecFQH znkQl16adxrO>oL(x>$-N>=ThY;! z-#J7mfr>mP12*`?fRB@s{rj!Cwl;f^~_R!l`Mf~PKIRHspeGirjh6Cb2zGn?G1U3q7 zN#X295-iuCxgk}-bmi?hk^zUT-_pnIXCA_iCk}sm zG4FxrS4pLqyMfUO?D=$$7Bv+=N&7SB$FWY?_ac%ZQg(}$>qrk=;5o5Vu9>3>Z^{y$3^EG+;2Ugke7;%4Gv{g>z|wvF>f z{jIlOsDr@Ec!e4ttyWNAejMq(G6B5Rvmo{$-w+qu(h&a*2@&`Q4^71%n9GoH#aG~B zEA=wH3iUEyt^6MLyq=q$q`F`Ui6Dq*WD+vON&27=lnT{&(hNqjpgOs0-{NF~%9 z!b(5RH$vKIP1#*d;+y;HKl|4_GF+UzJceHvGeWj#`PKYNL8P*fXB#~Sz!7Ez_FZ5ub|`P-IzVp@!JFZ(}IsF4-*-az!HdqC{kxojH$w-#efQ;p-yR=1JvdT zU3AYLBFQ83(Pe>3P--%?h}1=Kc}oD=Rm6jo@VPmJVqOEnb_(yuP-r<=@nro_%K<}Q zWIr1NC-HCtyNsh?@;D)-QmiI{Nx@PjVq0{7^RqU04^p~ z1Q_?KZ1RQ933sa+Td1$V=@YBy!or#D4NNzK%j}(R4*DjVt4PLg%|tvW6R0r5h~}8m zen`2-O1HN1^&&g{6d4|-(eU|TX$yy2b95>EFigD`d*^F@%_H(fH4R(G@WWwR;$HHt zi>N>7=uU?tRws~?hA%ouvq_PEKFge}VB37_BcqG_c;=BowroPN1@rCC>PPes&BmJj z#KyveS-4R*e3M!o!g8RkvWj?F#L>-P_$`uPDMl!&v1z4!yH#~1wIdl(kKkF z1J?<=8o%=h@bY1r2=uCju4#aWn0rkSYUVM{Q<w z(ie(B!r+>~sm7@AmD7>|ILs=$eK($)^`0$aYz^Xk4iO-YaTw5iokd|XKGM>d?=@5Y zHNY0LQXat2s)I&hd7{SV%$P8tdR{wp@6;-93}-BCzM`c zn}dF4)mW+_Xial;Bm_{tax|+f*=}wyHu==>z=V2J4^8i|V~d6kK^{&%2#yGgU(Da9 z*=-2`h)irkuNlSU%u?U%)vbeXLOSG3q4Bx)EGzcv4J4ex z#4bqC&=Q6s8|+P|jW2nwJntvD`b}|>^V-|54h+jjG_;F~Q?(OPKbkzX_Z{Yz#31yA zx@7>idDWYR@d9HRuGv>xY6Ix?rP`BG&62G1=iidr#1Q17dSCh*C`#UZoq|uWtGU}o zD@JoXvYQ;vheOs}ww6~-HPe&e?!%rt8XA3*CPD$^)mh#T=0sPT0O$IJO#}~3y=Q0& z7zk9QS+U9kFT01Xm6DhSfIVW}m1bW>W%MHiu=rNL=I(UArfE{@T6rb6yF7HNmHDV3 zJC$9^V3cTAr{2E%=#H_D~IzCgDLQEHfCe*Krc93UfvS+ZxAyy%qm?Kd1=u^xe85q ztL345C93a=;L%aVhuz%XaZpkc9?ot_}2h~hf=iz(D*N|w%v1;nW z)2>@?g)-&)rf_T%+B+YzFTr^iVeu3%bLBtEp*IGQs1pIjbZc&p5LRv(iAI|tj88_l zftf3sb!&rBKuH%JuxQ67Q5g@|-qIOk2f@qdOp;fb!)8E}Xa9_@OO8h6y~sWO%^5Lq zQ9L>=rD6u)n)W9Y;kQ(IAl-OINxQUVe{J(FLtWBs(bhR?%;O)^Z?d3yuKaavmH($K zS2CJBksMYGF}ix9>U(ngiFbXOZMEVdjibSpZ}w#_F|)&1S^aVC;m6M~9bDlAPsE>L z!ANrgos-gW`B!E4)gSPxYogirge}S~S%s?4EMJ7<+;Ze(C}pttNw~H*kwr|bJUIbV z68V^mbu2ku>cZcUp%*sTrmWBR^5zB^=aqPsNT&kOF*SgdV@~_(}tj= zmO>Fs)Xi?uZ97&O5MtMKy6tVc{87LN@L~mO05YRl3atV2R$2X}3smSYxF8nv@Yp=* zM<`!DG+Q9#3?6>&+Rd+y+&t2qV_*z|t(Yw@)wm7`@$XoNa8B4jb57fwMlFofp?Z+^ zIP&L|7$7$@e%?1Lb3@&zwzzSXa|9hO0(-xRj@G2X20~guSwPS}{kiq8FgWgzN+4^Z zg;s&*Sdejhx3ymdpvN63PhScGkv}}97+-{98^()7u&?LYk-`_P4!gfq;_X$G5{*}Ieu7{b!ssiJ~e;;02vbLSZr%EZnG57IKU;+FhNA!iQZCzk|V$QN77 zCOx5I`{OQUB$h*hVP|X2{#5wuF2+&I=tm*~x>8<@v3MC=F${HC**S>#jp?zU?W)Gi z8kQ%KsbR{j+cvn}4@A=vVBF-toE-&qnh+%MT-%l#r=A$pJpkj5vyey@ZiGNa1 z5mRu6ZQvZC=_j-+^v>+tjaKXyCpG2Gx{PX$wxSn^|)0;~ZTI1!2o> zb$B{e@kET!RfeT5)s;Osn(O^ouus zE)ie)$9@16&U)M;b6RG|YN?f(8p|!>IhiA|Zok?(B5pSh<%J-s7yNQV6awB0o7dh1VF7GHT)91SW^-ji@PA{O=ctSEYmJ> zS6h=prk(1M5PtoGk0OyZwj|p9KH2sM87bvzn|kKJG47ki-B$C?wr0gQS@DUxm4JCs zYT~t64^21VtVAbb01GjC0wO4asXmvkJ`|<}GXE$TnP5EEewTX@2 zuYpKSn>t}^j}uXi+Wm$^G6y=X)6c|%t4dS+lE?;7T3av8XLofv$5qUE>QC&3({tvY z3$LXfx*n#WhN&~P6(ob=-;EXO2d!GNDkH19@y!qxb4l(8-_qXosPd~Y}l@RH)!gY!1whK<4EU96XV~Nl;m9obClojf4#~hCh|qq+SG~UjwFaG$xzdhO z8UprD2`!FcF_7LcIKr%x74?i{u_z94GhtzMG6g!K7{PlHnwq{?rs|6b@fAdEhNP4! z=cNlH@2@OWEd*8t2x>Wsq-_Z6^pM+M_iutTH8o^{vq(~iHpG_YY);bKsmnr2L*&Ee z0Q7_>$|TlUZicV&QkaaNm2d==5q)ms^|(o+aKbe9XU>k@c5<@nSc23{aKE>2Q44=l z{`Nvz5S+>9SL9mFo$@EL=ZRnF&qlF2Hj-NBavIwNQUE?z&8T!rYQ0NZ40CJe&wygF zjZobHDs8o6$9fxCF@#*%roS2w2p6}zAbxIP5aQKqY6 z^T)}7^P_8(K*w12BkX(R+tmmbZP8!Jqs{Ogaz+~W*XGx@bTy_sqbOoDk;8FW6?UVW z&-_0?gA>kDEDSFgO4HlOm_UEBW179Q=dj}KlFh3Ls@!p`J$UGxG`tGA zsl|57gIIJwfsNUV4Wmsk9=;SXo8H+Omza%p#`t@e2L-go&6 z=*7^dQu19Eql3gl>oO!GOe2R}Ce1PmijGzM0v(09ZKL|KbMz{esCq&-_n@Gfb>p|3B8C z^B2&m^GqX;!a~vVoOXlWn`%*!9KTL7Eh*3Cwt3$6Zu&!#K@SOs!AheNX;On7cYY~kXRU2Gg8@Z zfmN{mwdh@*95Z0tIqAU4APk4u=zd z9K~APr&%@!`ucLtin_@I-()$ic~f`=yMHl#5FuraXBw-4gPkft)#v4$sK1{0a83MV z)Z*Hz99!T-iiV*lgc5D2!W=k85!B^e8|8!S=eLcV+ZAES1HVuN*F_AbI zax}HmaPLQmo_M8U>J6QwatWI({0%)i_xqXGl8c{LsM}@+OurwVS^WhQk8uG`g-Jbi zPQk)y-pI>2Xb~@q7J9gtaVU*+CO3OKdsz4A!~=PO$`Xpx3U>40QO z3`rbPp}N!=XEY~iVrt@86BM_+Wsn?0Zto%1V2=0fz1|!1?Q1Q6AS!y#4sR-_AT3d&6yUbJct<_v)gj7-vN@xyGyPRIOznF%u!APRkRL zB@ZP57`zg2^%7Fw_cU1-t5Y?MX`X*$_oAu8q5eilz|q&w7U3`LAt>fNKk&iARB+4< z=qT!nn(4c_?gQZ2mtgIe)Ng$M2zTV89kg^rzzhy^63z&zW8{51VVSY!HM7Sm*X`C- zW@a}p5#!lNo0ZlXHGKO+j{O>Qs~ZB7Zy+W{=|mnuL_Wg?fPsF~4btIMu@@rmV(%d% zZ$71H##o_N=S~m8n#{6bu~qAk$Cv~1z_slVuN|7Cu_deRnN(Qj7FRYt`ZnzuoIMh* z0V*bE@k5c`j$OBvJ(SP?3pin-L}TwESa8PuhUI}bL_`oj;y$;QN6{U1GC`QUiP0H+W%d5|ynn+yedUu_ z3*~9rgHH`rXKlZHURGo1jfXFMl%-tQM0rKL`+%E1``G|O=7QPpqApdTy*F<3jW-n8 zY=zJEAy|3|*+^D1=JaYTlb{PUl}$5%?Tu+OiHqcJJ>uih#5C#ZNqH#cNe zQDI;jFgDuBsveR+5o+c3JaGxhd^s>jl1NgZh818w4E(3}vnC~JxI7(bIr_T^15|lK zmoFcl(@aFy>C;aHsC4+S@__N7WuLd41hQ&ju7eID!ouywHb`Sr5q*)OK})pYdej`1 zGq@QX{*Bohll|`0O*M5W2qCdQgGr9cOb&Cdsb;C3iIV)b1ecB1`ehe}^DuBLf>T!x zTdh6H@nQVu4mn-~fnTkZF7gGWaA})XKqPL#LkXyqjB%CfX$T1Vf>3+ zeW}d9$rAkY%>PWTSegE(eaH(fng5cjuWM=+vS^O*N97?mUisCLu_S^-Jgi7%P7)<{ zDYE~PtG@ZYdizXlIXr)`>TdpOSRZn$`bbL`CT|xu9zWXun?87Kjs5@92P-jVGN1QN zCre`ta;LWR_yQxKlSHLMgBhj_401j%#m$d2SRneU^+_wp(GGFx!i}tw9n3jch*P9G zx<5t`EvKh^RcH!4I2?Uilx9}k9zi}f?qw(vX?n{eP~^Zkf1cUCnAM)O-?=VwUD_ z?h}a>;~c2UJu!&lHbWnTV!5FZl*xWRliH01Po@^!c;a6t`}Da>X8OEkbv}CW=50CJ zT>qfrx+Xbl=#tMXBsg$n7Jv|r+Oho{DHfg4pIZn6$tK`AZ)=nZBe&=IQCMyj`3Qyk zLm_PeA-MtG?O<(#yZ@SxHrWl=tyG3QdnjWHOTaNzWPeDS(M0D1;88dQZ2pKBQllKSeC z4gP1~G;zozPQLIk(jucm$&G}2vau!*Oo)O#-21F0o?z5=uuWSHOpjJMCHGk)+FYgE z+X;cbzTo2U3=sf3D~fjA5U1%zf|i?de1}Q!QQ`uz(5EFkJbu91-;k3B{3#Y#6>1Wa zbB?nS4P>2Mw-iYR!S9n-xlVzv`4?$QycbS8rZLsSH75QVkR%ZMqKfP%>p?1K}NMNRbvmUc^*vYk$+-brX*Uw85N< zrV5eE!COm|T=~9CoitjHiYY-Ja;%d!zg|trk%ml6L++3(cN603$~mFlDXxbQmW~8w z;Qiy}PtrVThnU=KUsT-Z{lHM!hPT5A2K}>K;|GC9#0yV*(Fi*@a~zptbYlow$V+G8 z9zhhb0m%bpFKkRL%#{>>NQ(sH1qw44#Mw@b^LBydS^+=InA&yw`0ef%F{9Z-&w<|* zTNdJ_Sh4&GpFk*9cUNG!kM|#TQl3_(JfCwb> zeMeG0LdhshfcC-f(+M6NI>Te={fd8L^f=y^U~wu6H55%cW1o+&cT$m)P9>>8phNU6 zxoXX>fd_vwQRw!VA)tu``l0goVp*5QfROGTeni3f#hh?cGT}u{>+kiM|D1pma|`gCZ2eDeZfp7{+u!F!g$@nLbrrU(vg4-9Fv zX(Vn)`iGGJC{xM|xTekEi+bA!xR;fb!LpTkTCi*vk)lYu4|;w-pIMo!x|+juHoU?7 z#~OZz2xEvq%BQc!eiHq?@4f+CXO!zR1qUN<cmTvwmp860}TWd+J;04AQs06NvIns92>b&8G$;Qrz9IbK$pUvs3*6|P^u(r$x7mw z85v1tLG9qr?rifxfHldPCRO6}bb5VVImvZ1|K`QD!wCN>Y0PR?&A*UX%u7=Du| znqn?*__MNlH?N!2b6fG8KAP_T=EHUWi`v(n<0BBgn zn$#A6GWxT-!2#TY(xwS}So*gbNGjKt@Kk=~qf~E?3)2vUlZpajE{pv2QWsQz9NE>B(t#_xu_nVnYCa+1}XI%1PXppZ`GqO2)%{cfpG?Mv)4FP5t6N4jeoqf z(`OW0PM%peg(NXEoJJYf*lIh{>>=CzUP#CO+C3a+VMVtC*vPggs0RhqnW(@HTh z{}EkW8~1opNx23QFQuB?MxqR;vuk{@en7_VE>GXvv;VOM*4x{^O zw9tQTp;2)AjU%K{)GJ@slJe_yW5>jpBZtI*PV&eo@6VQs&dTq}mdrpqN{c(oh)P)F z(Z<_+Jz*iIg2BU~HJO}6Zp!Do+^14qtCG%USB127pe!cf zNCg(1NEJt~$-qE<7wsamhP-v}?$ISrPckiq8-_=TBIvWjK9j_kWamSst-)~inB{#P z$^J$}H8p!3|HcVlm>MG{2d2~pKjT|S&S-rLt8}*a2Knt^nMw<6?7cB;C?1??e@hVV zX=!e5twV5JPd+djis?{~1qcRm18AR-=Xx69Pwqu`*@bs`Po`VTq{fyF&vlWd`NOxn z7JWe*&diRBG(y`84eHhXM$;w5`?Z2WqBY>{IVJ4mdlEc7Pr?uDc!Sgz^SydiT=)4@ zB!aBg-|L*ro+nh+b+RaSW2;_xCeGV2aE>-M=MK6tbhd~hLxM&-zrEQcB7eRo{2m=_ z#BY|9lnW(p^&B*UH*SVzaZs|7k%|hh`DH~$wH_iB^9mW2bJ~yQ|V{4DQ zx$KAEN%?9e@8cEUuKWVdSWHbE#|{#RK}MJG4wAA;@x0~EHsV!X&vxJ2 z`88tu*W0bfH(QAz6a=L2F{hdC(c?y^T)LJftSwGKXCG6i(dEN5!~FDp;Q&|IKC29? z0u-gBJl2lx~NFpB=RV!GD%cGeehq+pM%QjyqmO@ette6%%(FQZmI6)4R0&n z@Ds8i_Cjg>*?n2P(Vqf7ITaEdcW7bW4S1KtU?`Cu#*|^zF1akdPy^Yz>#)0F*%Au+ zKK$~z<-i9FPhVYNUSWnX{?box^!s}VuLLh?!HDem?~uuJuYZ-EzlVcZ{!fI1SpR)` z`k!b1N7BQ^^{?YP8RvC&l&=dqN9SGJP{z%;4Vl5(a%J{kDd;J_)xPQY$|z;5MRMPg zn;)l20wD}g8g4nAJQ1nJEZL`laAO9SHbgRXDOkDqy!<@x&wqYV>H4V#lE%vV6^$F@ zqiaH}5_Ato)?7ODnNDYyD9WDF1bX|UrHFs__CzHuSx`9q8J-zAKn^z2WJr)lg}IBt z=x5Bdb(bKF3s)V42)vU?jftDA$k~xQARy;%nf23)xb7ME*`2fFsDg< zMOc2SOUt|M5Ba}nd*|3n+r?eDwr#i5c52%;r?zd|wr$&;+BT+cr?&0Wd9(NT!+Fon zPIkWkns&8MveK;UzAsK7eEW^6iA2UWY{hrkqH}oi&o3 zD3ukESiN0P%C_S;{B%_#SB=SUXFz^Yl6PybLdrJl09$SYdsk7(YK81;83e9Tywj$6 zFrHEkW#BYd{_SktLLQv-WUa~Mrh{U&*>pPNr5dDVG~yt?m1Ygj*;Gwp^~G5n_6lDd z=8SpwgC^Z|BiyQU4Heb0wX%Y=DU( z&Z-<|I6Z%j71epu%KDLQ=}`w&TJgt{-7^PGP`mJfpenjEtOlHQlA(Ni+GO+n2TS&@ z&(1NR!JO8)lQq$j$VSUPC*@u;$Vi^h^LM!O<1@@$Q=v%L3}y_-i(OxII2vS0Hq!VQ zUwSPYfEWu^LriMWI*Hz~WK+!9n{RAtOwecF1O@_{_%84xfVsO1#e7k!lv-67h@crO zCe#x8z{GOh}~hb8SNFf|JO#?nh*(~}>>G~M{dAgfL4!b`a$-P(IT3~6Wb2!~P16q$ngfdvKiND|3TVHx2|07H9z^Ara_YSMp2q$&*^LZ-7e<3lCyQ zwu1zg<^$vb7|bDf^RlYMDa0w$LquXt4a(t|E9 zmcZZS0(XNDTnRz6Lywk$O2EY-_dIwvK*pguIAVvCN1Vjikb;CfDusz9PM7u|3eT`P zSV%4lOnk%*5jDA>!g!Do?JrW|Kk5MR{E=3lwPTIFY<&>KzY)==R;d`2e(E6RPz!qw z%-Hn_44A+Z^DNzTrPNQ~D^&QWP=?g%&62_C_2=i|^aY;>xVjqQw^q*SxVGKI&3Ebu z2Cs^KOOyMZX-P#ic%qF+@j*${ZHD*^RMBKb?n7p@sBrz{){HT|6SgCd_k&9S6BN&Z z@0uK*29J8r(pc{EAa3leU5;Jg@_@6@Xwg|%CvrD8rQE%&zk(T%0?a|DNE3J?RNuT# z6Ith{=C0%DPquHKQd^&0jtsxQO~Is`fde4c)`onuvEAb!A$7Kn3qWq@D@4!U1>7Lu zaT+;~vxu#Ty}g1mYC+c{>%1o6D^;d{3DF#Cy;6ta0-Gy{$|37l2XjC)5PYLAMYN^1 z$F&EwpNt&$l44AaH^@C@M7WrB8F>)SIgoAe+B_tlx6GNov7#S;I2?t|A!YTHvgQFl zC+tHgIumS7dED0KfqdMdZEg9)xBV=6|3MD8aOPWK@(q1Bvx}lV1K>%x;d}dV+&ViD zs=m;TX)3yKyVV$cOfMTw;cS2xjSbWrBCKtju=*mz?6aUjpj{*~E`!Rf5zzd`Z!Fu2 z3Yr1poYrFOW!AugL0loLgB(~m7~x^3#o(t9K+-Rx1eo64b*rH7I0yH!oBgMaS2Y0-M2*9F zK}*M19Kfb8Tf%Y|$8(s#c{0z$-mlqY>@e>TERHhYy1{xku0X@cT1IJYe{ah@PbB>` z7*Ne37fuZ)sJWL)85O0|seJCK_G$*V^W#9~4a77rl_VNHID1lt=?=ZeO~i->zdSyk zf9tf-L0VsN!?7Ev(+!P*gvcV}M=FLkLB$|;?2qmbEunil>%U)wAGU}UuU;FmX61gR ze~W4l4kgypKp0b9{xb{nDVx*MKA0jLzR_PF3Haf6oaQ?|c2!T4DfesKD1gAb-}7Tf zCnje;fW7vq!cNjov_DuE;&|%jS9wt zD}S#Ex{zr8VX^et)h{?V_TzVJDKZMIZv%gW%8g#mQ>1UG|4-9cCJiC{e;Jo+vy0E8Tuk1Xu^P-^W)c)68ubK=eAUNxqeqM z)gZ{brEmjj*fG|I3QRNwY#TZ*w;=!LG#kn=(o+<0T2`d2g$C9uheh}-C^GsctRg6f z;;cMHh|xL}oL;%)f?~eInTUZPIIjYo<7@*$D74=4R=EOlh@dFg)4fzAc3BEi5_a!T zqOAFWPG2Yd4uF(L0Ws!goMK%d#VLVH*~oa^Q?k{DeN}P5F1HGoL8sZo^UV1@7WEhw zQPa@qlS-fO74B1xb5b1JM8^RyS8p9T-IJ>u&gRC}we-aeukZHReFMVER3!&sS%aBv z2y&H)UQ!Uz4b7^HG(eMv5G4J{BU3Mh57B$=((-8&d6u-=?UUr`(knYwo!RMxM!)pI(h?X_v^i+dT$`bb9bzQx*ZPqhp*kVM7SXU$Hf@P*$l;OC4%c;1|-5v>xd7&zH zLkQ9~&^}wkCKtjl+G$yh8zFw1P9CpU4>~-j>4u0FGU-HS^e>Xsed5CA1~vu58_-mq za4QAFQ5``I$LRHkENed<%7Lh1q8wQc-))}bTZ$5vI25DtQTYhIMJ6ctY z=CdUn7ZbzgH&{J#Gl#WA$Q2DYL>EF8!V|(4ItGzF*&HCx;44-zPUwT&eb@+-MleE{ z$>Q(wB8rdnyx7xXQwW0%D(E4_0p*yH-zX|@kBxo<$DN#?y(ZTX5irDdG3;i?ipkJd zYyLLars^g{br4K?pOc-is3I`u$!tM|)|~NjheZHni7eM*=-_e_F|%ytvf}P_iZwI{ z`Y_VnP1A5Cx7cp}ijz%f0hF9+gf{H%i~^^u*v@YQw`8%^WrwepgsxXrMw>YIdln*X z>e(bF1UpeO)%+I47FhzI;Fx56p&OD_%$3y0SEDk#G$4ZrH>)~pCa;Klmk%Hd27NRx zAmZK@c$;0M14DZg#16ypbVgk^&9Ju+s){R=C^RAWyU2!t1@p;fw4-e_#;%U6e9qem zkMO-#_z6DqflC#=4r^UCWpX>2#wRO9`KQ`obL&y~#P|e0Fo5wIs_j~YdrS1E-iI$j zTH$x83ZrY4I!~?xHo|2AcP_vKHu_Xd`Y`r)rPNb%HW6QkbPrpI9l5%1=>*{f&7E`r zB1?V_pY{k-@r)t(p%OQ5*Nu9>RufvQsrZf0)s4p%EMl{jPQ9&B)$h|i$Z8C5y&E;P zZJ$t_;-#K2rELB(EKVv&ZNFHevr}>)(4TkfgoAppe!PJ!=i73GrhlB6Ww&y?J}jK< zDaG<5oEp4cGxAHyb@~gdR?I}PuHUixf>h0NhPK8~V&lpfQ~VMkq@Yi#J5n%syVTNe ztC@#kgj^3q6-(6_j*yaOsv{3~T*t9y?vFBl^w*sf*vsPbX!Sb0Q0Q^1r>UW8UI5>L z@|(rHNuJ5lAST54V6I%Y$OPH%-9LFd+!d_luduQ_P+RJ_>FzK08@=#=?#X@uRfI`@ zYWd8xA^R4=&~Xt`B)8o!0u&KAh|*lt?uL6Qx4Kf)sn;67!|}X7{_0o*5A$KHs-P*~ zO&}MvHRi*E^4tjRh5yXz;WD1}hHZH!`L#3mf9;Sk{=LoQpNk>?fz9M^5Q6DnBg7x2 z@83fRmj5+qt@2OZF1JJ>3u)+eR&sYadf1FJi=^B`%wCsV^+1ToNH{;jkC@fJTVTwo>C6MIyNzH(N`e{`{-_^F< ze&@A^k-q}Tj~|PalMCjEv6Fzpm~fcF9G|Mr*>lJqL`QfWMYes05U?&w(G?*7qE0tz zKupN7VR1(#%o~BW;uj*WXc`x-Y1|$}zi~@M*ZW2v7x|Q(7}Hq(lHov%lgjm8>B2d? z4BznPH2UK+Ioz!}J)&%uu<)UtM)TrEwfPA}MXZhm7y()fAYkcZMyTI75Q-_#pfM}N zVDWOEltX}HNQUK)#qle^EoF_uSKxZb?C)mv714@L>g8Ars2s?;y|4$X`H|Y_7AT%N z=hoL|YnDj*1y?Lt^0d)% zfTuajS7PfMiZ_3Z&m_q`*|yM>x0S0fIWdbkoe^DmvAYLbyO>I7_0#DBN59R)b7iW? zfD}mJxX;yf)D4A{=JZ+#%#G?4Ht;XbfK;c%9#QPeC81n8c-maU+Q4{dx@Sl^T4dNbR zCZf1devh>z7U$q{Py_v5I?sWWK^+I;3AuQ#=Ye9!62_Kb$%$fD7JyUL91xm70c2F*G8VodB7|ZvkXr{S6Y^ZQkpgz5OiT!O06X*Vig#(C?0eP1R(r3aZ)E+QzT&d)yx3dfh~&*5A%Kn55ZrGJ&L$ zl7u;)`DTcAi-=vgULX#&TAf61;8f`{mMNgniRRUz9{bUe@+V*F5`7D;4r4tC+B)EN zywS)jNh@Zxc4Xx!^oZkFF~(x;)y$?Ifmv(Yadjs)>&^br0|eao(Dqn|({0o1-%ngJIKove7K<<@_N6^8^;CUN6Efg|3X>{5w8xN`|-r?%+~@`c&R2 z;2m8A_kL{h#~A07+~)Xx0D<-ge$MCJGnZFAcp@)n;DRs{$d|uk;rLZ@kPkc!sTm&6wy0AA$a zOJbY79X&cK`UghXi~oNZ!9X$cdiLZxkv6@V70oN7-P`jABZj6T=3Nd;K7+Goj|~U% zun&mGu*Y;enB&ziMl9LeaOI1tB4Dg2oH0~&2FhoZBHDJ3Jj+HS7LQ=xHdqu7B}~UU zNq^=kEcak={L_m#+D4K>7fvd?RwrKFLHtE=BF{)r&NuioEVwNwDoj1I9cI>@?QM*E zPBhE_xZ`(%#Bq}CCA&jPLJ0pvVS5Sq4dd1?fU7MY^@BiT&t1ctaw+0m_2$fC=fbam zN_BW)-G`=pQFYmpn_Q^Ykm+Rm-l*Zjxvg^zriu#JX=>5aXDiY{wY73g-_+{pR_R6; zNG9qUp1ya~QDaJ_7wD89*_5Aqp7}9C8O6}Kh3b2(S6z9qRd4C<8^31NjVhCU0;u0O zQ@=b9zp2a%J9Ux zDvC^HzYXV5A=MIVNdnatJeTGBg$C)v^w(#0eebG~eYWa~c2Wk@_`Vi1v;m8w+#3nh z0YHL1Uzj5Lycd+KD6@s7Gf)FbC3j6-whQMgT7LTY4D|54UAfe zG#rI(6of)L3#%&x&YzF@#?d@Zy#(^FV1cc1;)0oUWMU#exsdROs%3N383pco2K19R z?pf)npuevl;U30N><&fn9oyrSaY}4Ro*m4IS_D7SjfWl^L3|M z&lE>$$T>xOT{Ram5r@rU8t5_;grNb%y-V zn{?kJSjhQJ%3_pbh;p4FU(vDb5Y9k+Vfu^=ArjE6(=Ny;&}e;sSzH4q&v{*-kk#HU zAA=x)8i+W&-+&#?sXs`qBOee0MEpXWBv~bhJ}JU?KUK(qaM8*_H@Y7mkg95txCjp6 zh7pBA^~cQGAo)92>a=$*1i~W|)OgLkg1NJIg4eEwGkm+O*L38pypbV%Tz7h0_OOsj zcl?l|<)Q`omSANmj01jz0DRG33xX_SJdbRGH~z%uwXfHLCmcbsJuFRqZ0-H(L4|zw zn+t)4%yX+;3^!dtcXE4P@Nir-);Az#tdL@Br?MQ_G^pt7;E1?CD+H8_aK1cdrooFnYXA@=(uz^O=8rhvho^aL#;#eaY{>&bhQ{<6gUD z5F2y5YU{K<*ZPli77y z+lI;hJ$SJ)oEPnFV+u+emRa8{;#VkiQ=|eNVSx)=vhf?}2bEB8d(l*#gI4xW_J^J;K zB-ZvgEx+533`C>HO_qOfFYGiJfOFmk|KGcRK-F>L!5v(J>e*$a^Qw?LA z%|JDkZF9y#K6@wKU&Ixj!rAx87qP(v^U)ci!-SY{2hoFS$oe%g$0Lmv6T&HM#JDK6 zf($jzdD*=JYS7x?1@Fu*=66zOTPq^4Mv=w?y=EJnTZqw~>FQS=&yeCm+;XhXZuuA% z`c|vhLOyK9PRH4;bR5&$OKv?5lll?(cp&RceuaW`Qu{J;X?^g$SM=RSeQx=6l_vi)5!r5q~Vj3 zjR>r8z9hCQ*NMPX_ZsH-c^wDi*dm_F-XA;n-kBF)%>rAEl%!EuLAlUA%5Qk}p4u5* zb#EC{7IxB~;MZlZf2SRO`40cmz# zoF6hWt)0&66L>}XllIHn*>0#3$6NYJ`&|m^+-pkq2fB=|GmvW0!9e|KULuuCQV~}q zvB^V;0p3W7dQXSv5Fvj85h-fK&HHLz;)+tFC)~570XaM_Sdu+pi~|FVeBDMqx&aW_ zPF0x+{FC=9+7jy>Wnp5f{ge0e60F#Y7|*A0VI-Y9HRVpnIS0U9Q~Uh!<6f$*G3`u< z4~hTX{1rCxf z4iRaXozc~gZnB*4@?O1ukYPr^mLT9oif}L7Kt)ypz(wqkwb3A)>MJ_!GhX4T#Z+0v zs+crg^eELAo;F@viG%8`**IPtn7y>9B>9WM%yVh3`}T`dn?4vbHq+>sHery&?kP_= zBUkJueR;@N7a06qsEkcIs}f6bv+p+Im%BN@k$gXBEWGll>fx1~V^u9)Ke-jOGwbN0 zEq81Ldu4J=SUPE+1S$E>`&|&8FdW5A11%5Rzob3gP&%&08;U3?TT7_jbN-j% zV$(*vKUTOj_GMyn~R$*+|O*<9DxnK12Vx#v_)fp@iqOUlSIw_F zICKw)oxunb%dsl!yFHZHW$Os@B%iMfGj!4#ZBv{1IO(teyu&&QXxXpY znGE|CBy_C`bD!)<>7jXWx3%Qc6BLmrfY`adBKY*3dT;d1(op@oh~>A^c_wbU5%5E| zwM9P&niSB=sF8jiDof*M+YaNHf|fiy^Lz(QG3x8>T0SBc1HvIMDd z%kC=I(4RzcIEAlXMyh(ROeX<8pw4YT?q;*tv{0=6gWt)wp z7XU>#OUp>c7Cv5B3;y*7hb$Z*8j{*9+zjRCEqsxCQ{M3`rJpr=-Y8I6MV-fy9{9>{FdGlKhCAi@zIt3vK2j;KCGkNA&-k2o7*>gT-KMJE}f zyk5MjViLoD>cu2!fWzPLV(v>vm};|?M`|ImmR{#3^jtfa9$Dk*P3K#7KUD6{z}oWsFu(6yoO>&=|;=hTk`l;xX=NW2y!MfSl5H8k6{9^@!O!j< z^1V}+rXh@8%CQCvw|m9;^Bt-+BoG$0nK3WX??LOWama4i3u)AI;-b4D&&HDDD{DD- z+RvBcoz{KL90f+_^;F)=NQ)2(4~fAoJ%befJqHs2c#uwi0R(C+Md- z)BofY{@a1&1; zNfI@*Ofotu=nFv{f;$>g#AQ;W`0u2jT_y)GKljr6B&_sX`1IVSHK*36thyKrN38@B z#tRxw3lf(6$s!R;P-LrZkOadPIp~LwiiPbvCA?*1Wzi$s?)nFJQcm%8b%#je6!Z=k z2SZrVKkv9j(U(MF+Vr}FIHbuVS=ABxE$i2Dym*KdFtIV5i)Qllyzt7^5eHwR6Iij6 zI?7|d7DlK07t;2^=}i7w7&W=W{cB-Vm-1VDv6!_kN)-4;RMhL32(}$uAs9LeVaf_ zuRD3BW7dSKFCKf@|YPoRgG#lHjJzWLXOc>_pV7UI8 z7FMl9bvjvG`om4-*W&ug6p}c&nif}&KQ)B!3X_g)1`Ftq=5rRE8lPdP&|+1+>%0lC z-a_Ths@2PmBhyvu6qn`n;h)hp;i5LGZnf2mWjXFYEp?}M*}&K>r{jWpVh1;*g&ex3 z#$n;+&9p(C((c%p&?jH>*EaDJ5V*m5FhQn3tys+n86fV*`eON4H+ zE@KX{cY3I$81SD!zWiGgU;ZuNtr(*mN*35MulEsLl`6} zYK9UsD0M@Eb#PgjUwlSlZNkQBGBvp(Zb!g3N07i)f$9NZt zD+zF9dmStJ(J<(;+64RJ$YoW_(bMYIFV$}yk-bl^+F`qupYDmB*hm5d&67X8^85Iu zZCC7Ie@x~FPcSkY$_oMoQOXIDOHj&R05Oxu2@-LO){7+LSdhj~8rJ6$-cB-oy~enb zutKL5av#n{Ad;0oV6O6N3`Mi2Tw4zV9qZDz%hn0foBG?e4nr&W3KO|kNF6G{#1j}n zd&NC1vc)nyDuT(vMYZcH!^!{yyE>Uiw9!d_avGp7}`bjNh z>?sy#xt1mkMcb1`mUrHUWesTo&0M%zqYBz4u*O3<~0fo-`f>p@-V{fwg(MzHa zlr45!g!GCNpe?YdmL8+)eKS7^W_!8?dgiwm_`5Hz3 zFT1Huzg7=5t@D25X3HXmOTLx!Pq%hu{u zdsJs&#A9OA8`i|+lSPm`v-_fBu;5aj%5@>|7{LHaFGmjyHaWwtT6NfnJwdQt7iRYH zvwH3F{`#5I6ycGR%kp;e>bSs1`*Jko+{J6L4_es(5aod$p3guo2!F&pFM`$afW4e7 zaP}Tx00Nl<0c4lJ48nsqRDvYmt)IEb?BB-r?${lsCcqL}amOEtE%UiUBM=4?kg!vL z!|ODQ(YNtnT&M*R01Go>fy8}bp=g~Ve$Nr5_Lk-SAO!Sc%bVBf81) zAGsniG;k|)DL3>U|*D^ABif{DxIr`+x~V}pO>P1^DtK9N|NJ9?!TQyu3l zWJo^aXW9{+29h4;uo+vsAfpotMjUjrVUq-Jue+XdM7bf@zNy?$yL#BbH%XC)CaBS> z>F@fw{27A_{ZOkBFS%HIOFsezktruG`m#DC73ta)9TST&ZZ9#}Um|QnqSlGI5VEj4 z#oX)zqV5ar7`HX`7T}@ikU^Ji#Z(CkYg2upCJKV43%ZL(n&w0Bi5s0>;kGm2q8W#F z29G*=+%3GL_qj0v0Mf2Z#Q2e^gPATs{BQ$ELeKU5o_grKt!ooR<6RBLeu^T|yOG2> z#E<|VKE)ZPQgOu}mEeoJbA-J5%9U`Py*{I-SLU9A_b5*t@6pp)2iNE^seQWy1Odw( z-axsd)320CB>F8+j?_=)f$22^T!WlxyKln)sK(<&=DonUAeSN(|5dY3>-pqVWAim^ z3KEd5jaPl?HJsoJgtK0p2HXV3?G?nmGdU-i5>-X)a zm4Q>*5CA335dza3l;oq>}K(wAzg0=+Xr`>1a<9%3PrdH>D04o6d8UF4l z^!J`IrvE=YW6b}o()@pLQ~!1i6${hl**9{$x&6HP@mHM6f_mf` zv@VjvAhapko_O@xzhepx&iJc$VsZ5B{26|R{xF=fsP1}jw4xzlOJIC+^cgS27$b(< zhCJZomzeoa;@kVpd%Qoz6SeQ*uwV!1aZKsvv#e)1Rm|+wkJ zu>N`cX5vlpAi+2BOr$@3wW+8b*I18}F3E#`T!H-fYMxNz$2{Sx{!)AHss5-vM~m~G zLk&H?PM5r(NiI?&)b~im2;ue=wU5}nm}9|V&W5DS>VDSpCq{0HEaTQ>ZVx=-F`0kV zp1V0->I!!<%U@EIh*X$S?w@b=some(q&b-z92eM^#@{`e$MtsVDbW=j1T#wF!I5pv zBYi?4qr7S~dss*{LZKEs|kRrr4w^IV9p}(ALu^xNeJCX*g3y zg-w;hg@Jy`if+jPG`pqSkMK3C_Yg{R572${mnUs@YvcSK+mJ#x<`@_M4=qPY1p2Mj zvR!Y5g7GpE)P75b~`fD)t8ooE{EJW#sY!bhm$9$3Kpxz9m-a~ zFp~(4D21CV$Ob{sfL8WU9Xb&mM=2te8#uFqUA#gCqGb7lN+U9tpB!-&Fth)yU3~@DR_IboLz)x2aA((P#mgxuYCKKM61&ZB>&As)dZ z(c(oTdnOA*&~{8yiV}kd?0f3OrvDI~+|2R~TR7?pR2c}gA)1&|K%vQq(vfM9waSrA zZkt~jK(=p2WfXKWkvgD+VUSV?0RodhAa~K`2_{ZR*-Bt6JU*=qVZ%bH5G7nY7=B9Q zH&t)l{w?Zw$96<7#_;g9Q7G~L0lB)%riGd2ro`JL5Y=lAfYYU|Xaf3E+%*`hZryGs ziGV94Li$6+4SrI>MNt9X5Qo49<4gcJPl8r^cqzeteekfj8DOx$NI*bR&Z*7rq(ZMv6kuya* z2I4_$5sq5|?$0h9LtD7rPD==|pt3yI8bjoXYF?~k+fr!J!wtFsk6r_T_uY>jVxO?M zZUsoRv;4kI%aR#gv>Ahc<3z`Sa5Htu-E=$2H zYo5%y3EyR$giL+U172mond-`bxm;tt=Tef?6Q^NT4Ys*FF?K$!w*Kg@_+-2|QU0Pa zn?8F$wd(oDZTWR}V6%FU&D{cAl%KQ{&pXt#L9Jo|A1L~h`_z6dj+}gmSxK*0rT-oi z+d!$1Mu8<_c2=vd+0p8b?guo`9tKbqLXP7qW3CrhM2pyY+&2%40bnHefbTwn4&|I) zTxvanHY$yEzR9=g`X$V(93U6nG2}jc{qd8#qu8OYhb2m>)y>UsAG1;*&CbA~#LC=- zoE2+K25ykN<>f-GWz3=t?uK*UsXYCGZC@7Pz{&RTv?Y=%m!kA{C*fuOZ+BOFBST?r ze}@9#L2|di!vzk(#$wIKX<+@r@u>)Tnscia5e24JtCMWHReN%n|?1dd>XL@BKeu^xrntvH$N4%&$U>^;X2Mco-dzodQ|pBXP;% zShGY%AxksLW$%OEfvvG>8lh3VfzhWImT4@`*!oDhdXhy&^WC3#*bCs@5`kI0w5h$@ z!|vot#6KwoYnHIQ0rM;j1IT%zpI@h{`P*C60vfMJ^ZV!AVPfDBd<-opm%j8JVL_Cm+HzR7j z_U{s;c0kF$xce_~iy zQTVyf$`j*3=~WuaZEnoWmoG*^vwQm0pr!E-qrf@x?%6)3yIoJSBxxa-L+tN{PM6>0 z5eZFm)3wgB34ERp{fANDe=$Nvp@Fi=_4s2_vLyvjKxS7aJ~ z#~OUmQvL+jc-7j3kJ@!CC>7`Br?bTJ1Peh{&SEdSedXM$`NMvk-JZxb9_ie&SMGI&zdWB67S6k-97}PCRs18DctFvJ z%B;{CQ-ZopVzHA7f~WbDW+IK2Sh{j-r((9yjWeJ?gyu>xB@u3boqhl!VoioUUsn9& zyReDC1^!B#jijiT#WER6Wth|V+RL=+2lRiop&*CmGVZE<0N$`XH9rUiYymG3m(|ws z!R;7SN%;Uy%{Yb>3d|7$A{J}4<=i_lBL1dQ@m?}NRbiI#2o_JTHYpTVAUYP&4}x`| zKWS=;h3)kI3VHeMiBXb()9%>%!b&hU4w%T>q`-Xl6>$->C!vmKMpFHSalAA?@!hKI z>RUPms>pX-;~#8TBY2}^LRep+>i#qQP3=DG_=a4-R)P2o+^Rzi_EHiVVo|cd*Kteq zjTm}M>p_tf1ZD6O!ygijGkOE(GfTuRg4IHBnYxR+eGcUdVfGDBKuAP}E~RXNKmjXC zg3GVWf$t5$Pu0u=_t%Oug@6m(d#}8%fY;Ktq=Oj26~56_L<+w4)A^DThHwyrao>66 z@*<$_?zo~x2Itl~PHRbrgCVQD61EJj2)gxM8hWd%ZDNGCgqh2|(MzuMokYb&W9 zPvOQROa~`|lwtP;@c>av9?kF^a}H*6O=d{Jw}vDPzdrL_uTZCYr1vOlRe&DMDbVVc zc<3Lnnt*7rbL7+Fj}gVA3i;-Uuh|NP#2UzV2zo&gCpyP=*g_K2aCGOXS@7a4;u4o# zqcuY`UFJe&LZfhMPk@yj_htKc>3)dCb%odgINq6|v>(lJ9 zcENAo$XR~Zs(amXs-va%GEk3fZ5r=Z`kZF<_^7<-n7-vt0SJ4q;+~oX@c75*F z;eH|E$B1N}8THwNZwCWl*wVO(89p1$IWTrFJ?&g4$={XM% zt@6IJ!5IPe9?g1n)7|pgQQj{ZJq*OD>A{ctjxsV;MuZ}>fK=aJBH)Y`ldm?RA?sNM z=G%FtYl=uK-2?smVI*m!>V0tjImJFjk$aRxGwAmgs85DUx8NOgD)kT8{s68_x_T1&Jb3Mx3|t-=9>%u z6`i+b?kLaCU>t-g_M9Sy3k>=n-y{%=^fhJ?`iigX2kMY`CCnF0p$h82%I z?bg5r5UEZH=F1v9{YQC=MHe?C;!Ug;@LETPIpRtDxz4rx&TbZ6i zSVx}#bZ264e|NU{dow2Ue{9D5=Q-kkoGt#PY5%Wh{!=*lS84@4%a_LT-|Zvks#XpQ zEC?UjI@<>cHelb~Q-r&jYz%>{7y|+DeUDQ)5AFN2q%C!TKD)kGS>_Xe_o8w|8e2Eo~ED@W7?d`}SR&NKk zH`{0IFjA=`3Y2GD+@21ePrvRhakH)HkH9?Q8q?)4Y#IrIi)J00oPG)yGL)$tZFz=( zeXd7*X%%bHS-VN$aAQ>|SC{pSSz^@?4P+8bi0f>^ON2=T65$Y1YKY2ij&KF0s;0aw z6W>=-F+_SrYAFft37`}b7Irv5^)h9UhRCBHx40z9sGMPIFS1PN_M;FO1SrarjfW^%{$CW+Kf)s|8X%i$E?zrMwZig#Ruz zHa)4IL_G}54{5UF=SRM@$b^5J10u`?jI|i!(opf%ntCAI&^mVdUT<1%|8wHILdrP3 zO)PdihN@`a20P<6`To3p(^!PsFRC&9iFW3JD{IAG+0N8`)Ih!l*Ca1>6o*Hd-E*fb zm9^#UXPmT}UfY09=`e1LcATICqT$U)rIB*$3#?4)6rR^=`O0oI>4!n|P?8CIg#7)T zd5|o~>fV)nZw~Q7xw;IBw8Kd=?{k!yZ5SDq&Xiueh!kX2Xjh8jtAk-|Wi{V{N^7_dvZgBNoY z${=HuIf2K)kv?%F#4nMf3(E@YjB*~QGBQQ~tKh4LX#p7-Znh?(?YjMp4Eto7S|j(- zv9Ta&m~7`X>BktpI_6mNV!}W%S@1GF>F!rg7oD&v0veoJy@Aa7`-?*k5wozdoN?AK1TWnu_C_Hr-8 z!R~Wl;kS`1Dfl)rl49->Z{`WCtjS0W8-7(TI*k%w%0x6JI5vruFXxO&D|#iH<${U! zXd;Vart532GfsmXq~YwP^_{1rVj(F4GscIx2F+0jMB8%DRLVI7D@57)%MqMe!JuCc z>blxOCmg~+PaLho%?lvkE zl6QDb-WHJCCxq~$iBoFv>(NZxUwJf?1B6u~ z4ygYPFY&QeYPISLw?C$W=L@#o1bi;3yrn{T2KRDOw+&tz4~xYpn*E?L${1ANErM1Z z*LfQ~7X&L*f@jLO@9o=XbQkNQw>w6(1^{omRqgZ!n#T_jg(~0|OGtG&UJN!x__=9G zX{f?c!@~A`CeofNsc&O-8mAw)!b(n^SZP@`cTc~#?KP$c7jZoU)K*>Y7Auj>Utop} zz~I>Wj(00!0Lf+gH!;MnON(3OQU;Y1U;=kH2iVf-|LJ z_yJhkOGui-E9A^K!}%hc3?d|HRoJThB{p_fjR zd_r`zsVC{hHtzDQXTed994lQVsWv;PXV}q>UePZ@ZfdY?Rj#e=s73)wm1%}I zy>e$^+Oqq})GG=sYFbaaYUfNbJN+YX)ds=A6E#Gn%88306bUOLaVCs*iR;$XWLoE{ zxd43REc!z91!0@yeGSPUbfT^!?AG|gwo~2UVlI+xJh78)v#Da;^uvsJ5K<7yafP*! zgP}7hA%bm!QD5;wW`5qfd4G(5&>RWfa)i!TqSC(WberpvL5>5B8F=?b^2t7RKl5ls zaX^PoW~mM3k_jB8#oERNTbXrR!n=^0-N(xyc3)rOc08SWwK0Q5cAur7{8*rdXuGPp znr!G1UW(0x((5Pf%noufBo?ZR4iyHPA!<$Jw_JaGB+6s! z;K^+1bOipRuF@nVOrLv=(^kz?YhWD|My>KeCe16#PA&NG@G7xzMq1r@Lc`YG_RN;VvwV%D! zhQoA`{!u+&#VvmUX#Q7m3r#VkLE;cCO-wvRgckTyrwa(#Wne6(KB(niTK}0#ru>2v z_W2Q1eiF!9$1gWKjfHV%O4T`Kcj4}@zRC<^ zOOv>GCTY%2m8E$Q7Md}AmS)ySHKJ7Luilom;lSU*ztB{YBKWwmfCj^g%2{1++gl3T ztW!=cneqPYI>o>UHI?1!TYi#|?{MbIzwenQF-Oc(exFV`Jyo{*u{Vem9nZ9AZpkPH zD-P2dXZx6rskxtPdgBh6t+c;9Wt$uPi1v}VK{H~*dKoCAqjW?Gb zs^JZ|iJ>n%B)6I1br%Tq5>Z(bRG_nU0oh!YiP&Hz{#pTVfePmew!Ghnn5g0Y-gjda z)N1C5v27%L3vOqDz6pTKy0XfP*^P;@ogaeBDRRn|>D=y$c5p9q#P;1pZ^*bw;sCVJ zUTea3f^(Tl&NiFb@J#b)hKp^;ypv{3&3P+rIg#A_WxZ<57?UWs_tuuL?RNgo`(%5T z&F)keO9jEt*-!DNl452Rl634EvvD}Uw>RjF)*PD6p0uy>SqaAtia?Fex1iJz)O1PoL`H7|#=#CLI0Y*g; zT2d9+MJV_wM9tw4_D^-F)I|<|BM`^LXP3K%DuO8jD*}}$Ay+0hB2OaEDrgiki<)EZ zgW`lvoB~teiS4`7NQ6r40SEr^$qu0r;!^Wnwt+(;(0|Wp?Nws4vu3a5^`v4`Wx9b+ zjE_R?)c=|y^Vj_m?y=nQWUv5DE6^}n=;qLptA$4&>094Cah^NIbswDY51~Y zZ-0a?2WS~ZThV@mq^Ff`B5J3U#)W`F(yq8)pRFT5bOOufy0r`~{ts<$8B}MuW$WS| z+})kv?(Xiv-2()7cY+6Z2<{f#-QC^YUC&Co_w7FW=Iq*a``kaQKh%1u`luS;nC~;k zXcAVI)&KcaFuImsP)fu|O3+;5)Bt=4>w(YBgkUXzF5><9+UGWuoZrl|_j>sU=7cliSs;yFf6-JqX7v+lW zfObxYu^g-M7gL&dHt;On2lq;ChojVZZ$DvN@MQ=7K2#^;)Mg5Z1gkfl{<^3S0dpiF zGeBIaF%*sXT)%pPj2i(adLj_P8fK51#1;0584v;V%J&~oQ4eUMJ=%|q;+7a54|e;> zI`E4?HDa1z1lfoKA~0+-;kXJ9ha zTq|u17O@g5Af-2mX(6RC+Q>shx`cO92lyj({X4-0Y|@4KEQu{#&We39W0t>FseKtN ztMJRBwRlEjhE_5Un0`wEyZG6uXMkxPrU*}1wt@xKia^;yk&PEMg#lDQT)nXJz>?ZE zDV+^z<#anmQ}GfV%<@I_pwlF?^3k`o$)q>`GT;l61Q8ECvvE4Q`&C{26I?(O2uY*Uf{MiKALTDo9$nbXVRw5oUMC^e+Ta zz9XRx@%ORugG2Za5R(OE^}ng#Z$bKpXZtVMjrD&FyZuf5IRCZ!{kyOmBkMoy@&WAQ z|6Bc9iL62zEMmOOBLw43#FOdB;?gTVyv6a!w2J)+ar_O1rxKzi@P}Gy$rcqS%wEGdGD+$}H?@yJtx7T~no{DCz|_{5U%`SB2Td z=EfO=6EPsQER}K!kXi<&6Y@K?j5v8Xyof57EHbxia&0kNy`~V;y-Q3V5VE@qUMy)j zB`1iva1+QVwUbvmV?1uS0OU-N?mz7D**I7OSlUi9d6VOr#0=GBO~|9h-<(X4o&K)9 zktVe!4Hn%8dOB|`7NRxJ<4A9$B+~(fJzk1K-o22oy&ZG@qUP(0Tsf^$T!97s!@g-| zXEz`iq+tG!d;I*{J)&aZn&?!QWI(1$V*GZG0o^P7t>kyI>R)T_>PRTJWO$~K?iz+7 zhUk0;C1mMcyqm|DPZpfibWq(CyU$}Abmhmg?5vCS)W&= z5yQPp1kuh%==RF0+AhGJis(TO$)2H`3zhr&anVPV+~CH7)yGn?P;cm%p-DL4ZNQNW z{M5rMXct_oWnJvvW@U>ywFooAmP+7WQpo(??&s$$f&^a;(ahirDzCvI@<*pg!r!1F zr!~50XK1M;N>uWL2vMVg*e{%xoC6g7u-j8%cfHe34^NcCU8$#}o^D7rIpm|hmmz%y zOU?%bHh%&HHp3I0`!-eT>WF|IzX&VkU1d95kbqT(3TI3sXWP_&Y= zN%>;%kv95XV(f%2`loN&hba&>cG8Ky(^?K6(OQZ z6!eK!$haN&mr^c<&eO&0As@}kv?1k?qPf9c66+4Dni=ZnQLowh z=+nNT+;IR^y_b_fvXRPGtGeK{iEUL`y9n25OdYbXVxT_`;N7Dei<^L)Wx20ViC zrts*H?QS%R3RiyAmg5VDs-rW)hki8m3JwBtjxJq&E_nV2R44YiSue&$(=S=jDf3r) zPu+T>pMU~Me0;7EU zb{7JSsL{PpAktMmI-HOf*ho8$s25ZL=hf#PbK48?Pl4%-)`Y-?6yTNaMdDRr93mR0 zz}V%J=0R@ukURYhPRyy#@Hx1$I&g8gAmHrZg-zcqm@a@ZfX?jUuZqI*y$X~+cnItF zvdilbHNCE|ooU~KW5I~(`j&fQ!48xjy%G+s!*l^!r+X{;lJ2~XFOF5w7BewmD#aJAbK#VBVsAu|`Q1vi;%oc)Du}R&t z=|Wy++bvz16TD0*z*KRbsdF_{Z|j?VFlYfkfnT}dq5Z?ox@^Q(U}uzjn++tVc2K(8 z&OjM_{Blgc`obP61CqUTZ$dnT5T$%sVXU^@{p7=0t%p_8U(@cxa9v+4o8oojW1Kxc z0=#$M;LE0PBbY@al?1GdAUDsaXcx+(y*NQcf+0Qp4tLkAc5Kl2j+GQtT5LG~&#$GP zPss=I>vsVM8)v-U50C6G(qHQSrgVR2nE+DqfBzDe?O$Wvf6n}e=>E$=DHG>ErJHE1 zeBEI~^m!MB2zP_D2WP^tjx9+yAz6*N7F{&Wh5*y@i;zKI zFR%cxx~^tt*FL$MkFV3Y;l=J$0Dze^+-)yf+%xJ&XYCyDbjv+WM_N+ zamE>}X!jdtIuaGcO6Arr%-3#Y*-5Y7eY}=UyzX`BY(`l39q}OAP2_?m56snu!Sy2J z5Z19ZmseNHLwiK8TTjXwcACqNqd-t>`NcUbR4bJCvUAlo4BkJS)gWusLGAv+$6Va+p=DttIU^jXF=O9I&f z3-Tbz0u;M7$Q`0)He3`yzR5(SWSb7g-saa%q9L17m!op|Zf}+N6E`;{UG^Oo3`wt~ zV2vqRUIL~h=z}6($Kk*UPMnz%+T*@l?e6XpcTVH=J(b$=*T;rliQ7EH=3|^_HjA&N zpYA=E9Z)^O-MOQyTi3tW4-w-tt~*O}WzK1`nylB_S{o9`$m2J%$C* z&+m{W-)@VRo{lQ3ny@%Ct5{>>o;MY=s7|Lkv%SKN&) zf!@|%Gm?FgWlKQ3u_0!7E(`9Tc;bRiR5ej(W#XIl!vnfm4Skq~CioD0X^ZTTEA^&6 zedHz|=*#r7Z9@oIH$;x028lINcxKtTO5k`rO@ZHjVB8QV(`z)86N2w|hw@Dc6I^(W zHpuxAuw8nY-kH%avFX0w9Xb51=7kxm zg#vs`bklZ!u`rWAy%8|-`;5N6)?0d)r+(b1-pKNhM@yMGIyZbL{SY}yr#SH`{TiGn z_|r4CS+koolQ1MSxq|^o`iXtm^wAQGPfeqry37MjtqjNtOz(jj?^rj;>Ei33M=%q> z0eedCX&YY&u~gZYQx2jp_mc5^85>I#x-LYS&b$k#jB@;i7CAcPvG}WsJ=di>XlHgm z*j%1);}K3$FbLv3s9Q6@3x{5ZwstfYO0%P>#jk56sUbj-#_oeBlXuPA zaUyq9fHNySiVGjaUS8lR5=<8JvrYvOW)6-TE-AjCYgOu+r-vsLmvKYbnBg?rMUU+- zOPug{I6iD1+GORJ-jBBjLq>C2VrQ3`Z;zziVjzW72bEsUTDkA=Cgr;GRNG!lQ$sF3 z?ecn&ena%m(&046=wQUJbUio4gJw2|ErWWeYXS9-kh({%e=AL8{X1sE`u_)J!^Zfp zz0ALj*|7gJt@_2rc9sM2eO)hhM_Elga$_3wT`uJ8K` zjz`?7DUJ$tmuiTb4KJ35^+cpu|HN0Ryqi$55RVrM4}?rufSa*Sy*}Kfold~~NnHNP zKuUzd?Uv2^+PJ^yyL{HzdRD9N?@`_`D&z(aH?RBsFM=fx=b8b1%=w6X)xd7gau@oP#S4oZZQA!gDaJ!PKCO#dKrBF(aH|y1}x@A{DXudA%}6HBPxZ z&mkuS_da1T$(H%jHQp-Q-E;rOY`(J@gDVz;t@+PZznqrjra+_XIZfyF#A3JRxgRBo zHl^C*smDvX%0m>cw{~FO+tw767doQ{V;Z?PsbkcFu{r-7DZKyPJ#z!FGgKZp7(8Rx zF74O&MdUg$-wZ95r9133GrefhH<>37ESHf0`O9CALRGcK)^?Euj4{_nGM;T}?Vv>O z?YH1p2lkCkU0a{c&~ZhM=L{`d0=1+$b``q4a*x*2pDddkO)^>gO466{O)YqneXfg( z%)(H4GAoxw&k00dktQHsP7K|uDc2Q=bfS1Q-|P}8Ew&pdaWaK4Y0{I%4$f+Hd_QjT zYV3cM;-p_SYFTE|X}4$5#VJ6<$)V9gz@QBeH<75?4bF`?UquzvQ93+0B|=qfgAIi= zIR8LkeVFHOqtML6Sl_g^k731Z>;0RGIu*xAMmn9+Npe3H_?g($D8g{75rvX}+2Wbk42j%7eDUkqmm`!c` z-B@RyVc0ZG)nZlX%ukszCIL{F*8W+rKYy^x4cml>7A0}om5-P%ZZA}e@Q9p60yhqK z2r2HHR6e%-9bv97&wVwy5Je1U99-Cj+BE}0Bks_qG|XF3&weN8ZhLMhLT_<6$dC{zo@M7wF^_EEPldNJ z4qo!rP7fSgN6?EVXm$n1fJ|r5IvicZHVlqv{!VP%9p9yFe8iCaZa~=@cvZNuIcYGcT~)ZR;m!I*S!*KkoLBxHiBhCt>5f`n=Ou6J8k;<;WN8*$ydubfzWK*5qYan!ji8?8 zwtkgM^ih@3S|ahK5d|8i5g**`e0F!O)SuhIE4C!+B05)C2_dC#8l6?`G_$EVgn$vDu$Z}by(H( z1*&L(PBZRJ3RU)&vHOS0i5h{Dn2UWNz>-kE9`Q~7B5ZtoLR=LPOhUF|MR?#e$}tD= z!(_12N#6ull-0pslXYZk_MrB;DBg-YtstPCv{JH}by-$_S;o+sku_QE#p~jt4Gg=O zK>nm2Lw|^Rp+op0@%lw&AS-4hhPLVku1Q_O7bW$n5AM@LC``X_3yclUGE?1VFzVn% z*8wKx50^$C*PTkBpG4KV2#8|DRne!8*ihT1R_q7^)0XBVEe3pN)bNu6v=hUVzJwzH$^h^K@S zV8JmcjH;7J#K9#HlxMldmf*(jny!{$-L_1)-Ov@7c5nM+N|QZ?Tx}MWF8meN-&_2V zsi<1*{qU02^0ED#+b>}^P^hmBB7c`HCa#5^+C|{_+*f5yxOk$%nu{Uf7e<63yspUW zR?Sl(d^}5*d+W8{7V$6IR9S_(MxmejWatkt?rXNu;mMLd=+uC#O%${tJnH3~+&@3` z2+-~vOP)b;*zWos&OEU97;ZsI((0+7k-?IBJdCjEa*Zhaa#pXWf_mskmWwEZq%xf; zrPE?R<5ad2&4W|$1i3>K$SE)Cxm0$r&drM9N%o&U>u|I~UT_n7aV8qeBiQc$T6dMc z%)VRrMV1IIt}RCBhzTy4{JBiB3o8eQ7M>)tdov*7rj|dG4>;wp^?cE7zBXyg#fDXY z584zs(YQ-rOh5l+#WRzhg8hWj8DT`|9yB{ZO9fEXgDd^f?(HcgNuLDg|Cj~)0_o%Z zl3p?9*QZx0d;Hsr5xvq0d&K{T7t^zS6&I5K0GF?`w)vYG`#ZJrkFc-*?@^Qg2srs~ z)CwEZ@ArcLW9Z4BGyg3!#`4c&M@=oj*bx=5SVDMD3X0P6V$$PVFNvM6#puXd6ViZC zF`C~`%UQjv`~C(`A4evhk(S%V#S+>>a*Z2z(CzRjNPGx`6cpl?MzQ_)G1iDl#D5BWheaOm05@;L>G=E(7*=8u1<=jkqn_>_5_ol@jy5 z3nwu|kP5pv#Ou1rS092$bW(qw?SvIFFv`ooRsLMa`7_XX07L$oYU~wg(d!mW<-94z z(wft{3rxnq{+>omGT{#A&X`k8$rpga26-H?jhGHw+%rld_>-`>iq}t1B+j`HJ2qgc zc6%^!++Du6u5_fZuee*A{SG7k@v`Hd+S6b0Euy;3&y2Bf9UPU$db*x;NRS<$#PFQ^S{)c9R8_=Fj%qSZzZ7AP1Aq z+Mdk(l$nEiMlCjM+Sl4{sm?%aj3OGT-{p*!*P*Y@TcQ8s>f2CtEHc$Nqu(nO`CEIL z3j{zut>|K2EE1;f0Wpl6A;7sphR~_Vu;HUDzl4m(lPD5@WKLRRK?kluC5~lNaLmFG z!bMphs>aU7YKv`iNs_DFhf8c{xuy%(^!Zv7+sDr084TwaC#29KVP`#B zS62+N5b%HQryrt&B~}a8AsY$@UJ_G+cQ2Kg4kSm$7$T0lktkt|9m`h#MNEPgq!pfW zZaGPB6p~IYiA+GO3nx=T4c@+Jidg4gX+0z6GB+4}UY#SCq&&+k$B& zTx+(;bUq*hMOWu-F#{eu6@ah)>Vu7Hie)N-2Lr>{mMpPV|6_UpEb~`RxzNg^#G!s= zSaGkDLTqU^JD^i{9Wo2gnBTpHMb44HK!9AUj4~VZGf}f6B-1S4paP^I#K$qA@CLB) zq%E*q<}$nn=T#frD1E@TB~c?`N_VGN0JYOX^b8ybK|$A zTi~8!BNZ66T+Pz#g}3uiK>@;q*#|#Nu>2G}NVwy6AW)A^*bM~T7zEd?mrhuB0{TP9 z*2_z!?G;ZdBwa4J4dGR9`752a1bt*Bp~V+pOc_RN7MwoJ=XJ*5R+q>ttcCbkJ)B^3 z%KMOtgQ=5#kX7an?=|z$&A)BX)VkEtbiwPcQ0fk^Hg34WCnjzZwfrn zvORCaF~U$Th}aN9!fAc4#U0dP@rfO~!Ek)&mq%SJ$>VZjNt9H|l<`Br!|Jm5 z>OPR%H?x3u+>C-mjBTBZ0!*ud#6@d3(YJ0!9GV!VibvQhrRS*IPHqldRv0rkPkqY= zmAH0*>aTVPo{+6znv9oe0fVmwMUD9bI>wxP^5=snlpF@+AX$za5KwGYhn!vz%T#Z! z$hCpXLl~tuz9l5oJZ&Pe`~>{N10NVPW!3zKV@x6o$2NrDBo<5@10eFa3(EkL79LmL z&&|=x>FMN(Bt}r(=@|W{!2`vcyVQyDg0u58He3NF$5F?Jc0yhn8FomE3DE@53ndU# zx8bn$1C|x$pPtgLN5PA$A=|8|nR3A8*Gu|8yky`-=gJ^WRnIA2#&wdl`Su{I^tyo$;U04@@h73SGAN1l`L* zPzPTO1jCP%3O0WgR;KTnL=T`IDQ47?vTo9;;_o1dj-yi-O*K4X$PVp6aT?gUa+ROj zrOp{zIy7hEawRtJ#y7BU3x+#gtA)A2LpDl|eul0Hi!zJHEPKqoSM2AXA|c z)BhO=-X#CdvIP3{ihRV9Q?+g`2v;jvjk^~4yRXOpOj*EuF)O4P(AR@*Z`ZCeB+2Uz z@57FFA_Jg4m?aAU)CY=t;Geo4{XLNy>UgZO+^g)Bdc_KBafVrc=}i@(<4p8?^7$=J zaD#5ZQZJ=!G<}w_QQ|X(-FW~7;dK;D3XxnVx^_2mRH>f5SnRxQoiI(P8nQ903jMIl zp5=NZxU?;a)5W)Z;IqTT=R!Bt=q5?^03ladh@b0i9f$X}*QT}j%bFU7tpySqY|&hf?wTjIaz zl8l#+*kLWa55Bm z?+vZLcAdHRNBN8R!tAPa>96&RPF9U>s#wpH_ZGMo1v_x+05 zcMt!=OM**~W?M+4Gf#;aQj|;o<4v+SQF;TR@5~fG)e($%blf|qIsHx3HHT)PNArOO zAUnI>yUT>C#2ADXoD;N%XsJ{jvbN^aqwU;FZqHH!JRm)i3L5gf>F!Hy!k9%WAaQb>lJiN3`R-c_fvD+$g)LX0|I_6;?P=f z|Hf>=Ve>p?umfJJug;^%d3R1?ZRZmCy`WkuxswJ>41N@&Qt5AdZNBFlWAl5L-4+qVij^VR6fi~g}-0Aaf}Q4!)U6yc$k&9n=jhScacnA#sQ8y>hlPK-aecEdEk z%%H0i!2?RWgZ-aY1W~>`m0lrW@OetNV~~=y9+9n!9|~+5w|L7nRNtnp&t2f4Y2*Xy zlHU266#P|!nprNlFXW{K;*e-=A)myj+g?eI7QAoy&&1`A2_>riB-Tzvj_H$K1kCi> zk-kG`YwxQv(;LDUo7t#^xuWi&Q@Eiq54QlC!569-)B8l`$Z}1*z1I4U-ADs=>nLwx z8rxN9xYyb=5f9&&zFQp{r@M!q_U8zoSyvhL#a!B&utO1jDb{t~Q2^r(-Id<3d(?m; zY0NV*$md&ML2NSs%SrxW13AM6@-{idht0+6J78pL{LCwpow=c}xk3Mg1BR?Oy%x8D zEyK@t%Rg%9VNjh@wWzBxwf)WWs1{>4gWuBw>Dd-1%DBf*n9NuhcHW>3M!Q${m&S${ zf(s5EE)y0ID&78`RjLf|9co1{XGSYR;K+F?g)I6IY*m&%N$UaJD&ygS<8}lMT71Zv zR^NDtmR^wEp)=u%Ky9wR4+{S}HcY()vfzBy*N)w7^;N*SSa2Smo2&DK=Y>Z(*o7S* zhu=w6c4!({=y;p}^hi)GOahW_PZ(&wumHZc-k3KBA6V+HC0?QEx}0sdt%v2HF>(|* zRa_7#Gf47d$BQ;CBzpv+o{M!(X$a3xqBv=BOl|3x`X(P?P3a`3z{j<>!`*@CjTuNQ z-=~|i*zK@pP+%AzRm_WN&-s$}nb(_)izB*MNIfr`zimje{T)ML`=4Vde^KH;hy9=Z z;J=NbumG&%{{~@d{y!K>G!p}(r_WM5t?j32o5dRJwU7o(RKVrja-z}FnZLn@*B=h0 zndPj;KzLFmI?81iFM2l*RybZ$D86=T%GmKzW-^d*J7Ifhmzps_qa4ME*5C_iyu~#& zFApyB@pMw*4txB;B%@KBM6trt&C$rsj9#m$BNrAUpr0npF;(I4_ZGuazDDF%F%fE` zfUa{oN|wh1!QTufHT*aRHD|Fn#^pr;&VSpE4A%X#!~hojjaV~j2<mX%O4|3RO=*2hqjd@^)zJ% zGGBFS&#pKr!dHM;!&}{dbLOO%A08Pqws!l{ffq6wQ;>UH!N}IlE!4S99x@L1$7|b6Et7 zg*5by!jzbI4W>Tz*GqLAkyZD#1mcB?QKTqT;Vnf~Kk4-EKQJ}88d|@&MtUX4@7PZe zIc7z!U@rSaHk}>V>x!?xHTf|4Vca?6GrKmOSWSzrYLwZSZ%>NerNU_Pq|5$Dup93Rt6+yW3NG<52=9F#Ij`E>jN-C7Ca6y{s?8fAAZU~BG-w7%S?};muuk8 zkQPyP5ej!)qloZG*ryAp--*2>RZpUWpoqj5hwDCJm4nLldQ~`(u6ay zlP<73v8Ou7Z;^vJxR630mk;DJaH85|ow-%M+XHWX!L8`DLnz?+2zdiJFPp3Oc9__kA>hU8D=4mGE1D4vDHpXm4;^f0T2oA6;7cJB- z(`@&hQ>6X68rJv)3!F*i#?PM&y$qQ~JFK3n6T3^jQ7H&U-7u)-gh7}?#M~WG+z&0- z*7|vlaI2o9P6=q1sza%AebN}FeTybyzf__ z&e7{opjV#|@mFL9E@^)Kph3{<2I~xf;9Wt|;ElwQO5S z{c!Clv@*#^lf54=7k!44nj+Tc!6uhzfk9x{0Rdf&ClzNeGzs<2nr5Lsog7?G=Q}62 zf&`eahU`B%^1cdXcW0Tnt|vW}$$BL{MYQqD)ICycWcQr^%@h6|6Jh(GVJGOvjN#^IXHZ76PxVmb|eKIU&D0#Ne8aD%~^@{lkL2W!8NB#c~mLHYs_=t&pq?}CGjo|Tb9Nv|1N zwZ3m0NRcp~0r&QI&b)MxzkuX|YdxS_v=a;WOqj8_W9PE^8R;CA=|duSyFIA0zkNd* z9?6ZH`Nph6Pw3x_T?2(ZP+f76fD?MQ&d9rf{Un=mWLy7%ZRP1f< zj{3ZxZIVnt=JW-Hgv>+%k+D?|Bdq|IBDNb8&}Z|uDa4KcjWjNFic2kSyEqO6!7ZCmq~NMJn#VYX$eT!xQNpbUAZqjyE}sgU4&gS=vTl_sk=bV^d+Z#_F_2+9|baHn}G=AXZw-)pl7m(dK zEm$S?MV+0&b?!6aSv6PsXy znxcIWZ;%pJXi=N9ochmzxSV96%N$BPF$;nS$caLb-LlM{JC;dWbm5_pzzi?9-Kp9F}i1{}y|1&4WB zckm_+Iku=RA&U?TpafeI7wz;{{E6ivtns-+G+1# z^yjJur4=(cW_b12W0PG3Cy;3n0=StfP1m1gpsFDu>^V-#+u5Q@$G*sVn?W#lO+G6# zIuv(07o@nlOt~%_m9eW*`OP7(W=ggvu^+AjJ{A~j3QeCfzb@_Yzq5Qm@A7Bdk5ebU zvAXta;WiflCogOzdVj>mV$lXYUjwQG6z%4`p7o6-*Sj$+n!1GJ=hJEkZdezyka7(w^qzDFz6I_tRL?(a$c~-cNHIstJa- zCcyAP_fgfRKi&?GEGIRD($8nV!G9;q$A34yMoo=Bk5~2yxmNpp0d}>sGBTrwzflNz z;d{N%5~C!dBTyB{ulo9?vVX&Nr?anj;iY1A1z7a?=JYqc`aAT(_CJSS{-Rf$|LMp6 z4>Qbv7kXi0{^zt>EFFgxw(GSH|1s%ePLwWoKj*LeryN(i6&bq5^3RjbTnQp0=}P%@ zigI2Z?Xa{^u{DMRO}phNkR#yeu=+05EgDnCDU-Xehqu>HN9C?pJNt zIOh0Kb@5-~A|#!1x!mw1L)ka%1IzY6>b zm#M1xW1mKIx3XKB4D^=tjVQs>I*S8mNvI@bBl{d+x{djUF!NZv?%rkD42n;D9XdQg zweUk@_IhD7{H43W29`R$0j8OBEZJxxG|(P5Dj0h@O%=^y`bS>b_*CNigm`Pp9~!J@ zfd@y=o8;-FZ3a_S96k-O4=2iEe5gH?uC zXgA1#oCFXnq-&IH2mfO3h`%o=RTK5nKm<%PGpRzITQZX%Re=%>uKhYqo!r#Mn@7U7 zEM5kBBZ91#pC^g2ekIy9a$>nG(1??p?U}Y$Y=YT1n2VM}?=Kv&kpD;DLPnb z4mDn=GThw0-&z$!zYmcU-1!`lmezb7A1TqoCeQ);*tk5;>OB_TY`&k<^6iD43B1(Q zB4lIltf86axaO$8brs}6wRUx9b>3jiE>O61Cj-!@pnQ5}c)0c)z!F8YV8AtMJ&dr3 zl4xf{2k*2{btRxii*AyPz32l-%2zn@SvZ4>+{YhCZ4h>^R6Q(WOS6$|<^Czc`2c?Q zbcnNhI*tP&|FcWKb3sJUyi2hvP?`8?91H$Qbf6K8JcPuLP>gERIy8|8`BlM&D}l?J zwXp-T)%Uz50F>9;oJ5j5JHYaS+4wS5W?9nIA%5L&=La<%Vi^*LLk=;S{)yU8LVof{ z6n+%9X9`0+f7nwv4ZlUWYV2y{>Z8#72p(2n9}wR=@1Nn_anpP?H0RD_l-h&~7SnVf z@`gy8YQQXuOGM6$-7sLxr)7{gWgEv)`8{%GUMe0bjS+CuwNW6;9vkn6D*zM)FC^pn zhQldGvOJ?=b>J3PM(DcjktD~=Q8;SK%ugA|UAYEUc_Y%=U}Lybq(01GI6^wRkz-i$ zHXG2FUJc(x<%}LW2NjOA$0LV<*eu92if!kgk{^Zm#YNV}{is80Lk=>JkR1X&^oxra zu-@oVRtUWr$_G>hVs~b&(G!C$olF?Tcg%rEN%eLcua-NTot5!lwvfEa8{1_b1KXS> z(FJ98>@a&!*}@9j8XOGCs*ls7m4A-fg5!IeMBan{@*8 zDbwB{bu=3d?Q72sS2hn}^9Y(HEYH$f{AMkrHk9l1)<2_89`f2wc`E(VrLZnrQzeGo zYgw}n-4*wRJa}R1p#2hje?VcMo+5G!+J$6D_kKonT+}3F6IL)X(`Unrb+jk?)X8m; z_70yhyV3#b0+k2__zjXcEPrglFnuoKqwQp^E_zZU7ED+v{!oalE&aJ9CPtI9$*%j7 za4zf;YA_{Ur5{477Ailmi>0Dfek!QOE;))!i?V*B;ir*sBl+ogfzD@;2frHGFQuZC ztWIQJ?SNCrZRe*SVdN(b#Ol005VWb<>|>VWbvwRqG% zH<`X-c2oT>3ygL6=8~efS{yNqm9*y6 z00vOj_H)06q6L#`D3!gEB|7)&b8{Kz)0!MgNcrK(G`;n7sx*tw1>y`>FHDzH8<4D-l=C>tthQ zRCk|4C;joCuN9{1wnAUvav$w?IBfS8KWFOg`yGN-^mu>gLLj{sc?e2s(=CjrA|i%f26ge+3|g9v^%>ho2)=P_vBE!p5O&auAe zufi?GN`4ZpbI2lcbr%*GUM6tW zpAUn9nJl7@QRX5=E}Klb!W+N`L&Qx)$(#6vvZMt90;ePpstma2E`7(8F|hDEx@Lyw zWnk%}7Ln}nE(lM-L%1jEN23WT`=9wkoHmJ=2iEH^M1#H+ktd+d899CcHZ6&{qq`GqoR{+VTkdKsPQeBta;Bpk0XXtnFS>*P8Utlus@J zdO04C7~?hwe@oqE`#T)SiE-4gwj-5spX~HAV{0hV`sAPNQXxXpkBD)2ga= zk$G&>-AQ}zCibP7`%~~&4`w+XbBkoC&os2k)1qCAIo}P%O5qA%s832xA;hlgrYx+d zOF0xH%Mh6se@r`@g4?7Z)XDb+!j}p`jo(mIW?|684nQnEJUJ*l^#*oVXX`^3rzpgU zeGr3FEHzGsl^M>PPk#ETt7=>Nb)hn0aD(C~#i0)LWKrGiu7FHL$Je`cy#&`(qNEl%}^Afa#hh&0@0NQe>+cOhwN=7e^mIyt zh{=KR%7d=0xU$!ETxBhIr`a}%YGC4Ad=;)vTIDcgqTYu?Pn#f{ChNa=F@2k(TwLxv zEWNen2UrYU2$$J}%_KkRc&x4~NjrrGpU#BdlaKMzF00lB2eRHfq}0fjif@IYh$^K| zcE>$0nCP&b9A82i*AJyNMDvSfY%V~|1rb#7XY*JtSUZm;ekrZU^FmP8CYV7r@iNCK zM0}#dRl~jeT)#o?hdi#;Bs*GhR0ndJ#W&+H&57XP%1y{}(jA$5&5P4VhtsosDA`gg! z0=R6=zTf2naD0pWXu?W&xQO_BH9fsazhQ)tZ0AXkZW>}};~p4m<3jW(I;r)VfDO!0 zGztXyf}*wl3~Lj};1$pCvksdT(RcNA#9av9j09z26RQZ&^j+zFn-mhLAc?gn(S^`f zo2mibve({?5@DEC-gTTJyBZjQy=+Y+*d_TySBr8L$^a*Dj;gbi(9oXN^xC8EFX3n~ z3SsX6kpX~JW8);)cb-#>Wx=$8pfgnbSLrvG5%-t-T^TXy{a!2ZAOaeU6(dH>VLnyC z`QnQ#!DnfCu5Z^yXUSJ!0pzb3R{N;Wm`R#} zKxnTi*(~$@qNo~MgpWQ`#8*1;Y5K}I0MmFXC0x6dG1HeO%tL-PN<#Si3ZtWI)lI|& zCKtMp8375M7#NT36_!okP@ymW305L*n6%d&w4&m7LQ1H}JVKXhB*H`c}pcLL(LiC;XFqA0+86QnglBRujjTDgq5M1gW4zru_#&NOKjq^*sfo3rQ<3Xcz9&^sBd)1JFz<@6XSi%D{vZ;Sa|;gd^>5Y z;WlKHknGt{q~wrvH#E(+n|GnvHjN-u!{pQ*oK0Lg`GL~o^gOu#D}p%7~OhRK$J@mD{p=KV1SnuuEG3&dGp(SvbWl% zCQh1NMEu3qWc(zUPkPP}sl~B348kXWa7`c$DXBre3I)bcEV|ND+joGJ^@&e;o(NW= z2=U|HEkzis>s9F(k)QznYG^j6-SyZGK>}}E>-bT+wW#iy)Cm`v@Zt8D?rRn{p?m5r zvXw(?smsZ2KavXd!co0C>`{(U#PH7`)60*VFTY;A=B$TbW?}I=?O6un8#qtdRFhDb zFP@=)gka=n+tzmHf~!VI@$*zdWebK>#;Rv0>rW5$wGy{qJ`oRXM6|w#2Y=Z4 z#gjR=M8kpa3bqReW{f!MmWG8ggJ;uqlJc1%i==B`iYd%R416dKGKo);>)dq^nQH&^ z)+?@E7XDK@r{nrg6;~QT53;{f*6yIxC4DAYSlY7e5?yIQQv~nT?aTZNo678xFc&NK#D!wx2oF zNd~XMTn`G2gJ^k#Ub637M;+%6GvY@2*BCR2(^37O1To%NA72ypBD!w#_Vm&{$?y+9 zfGf|QGyXCN`$K;J<5lIqk}TN&=P=)Ye#3u*`Pc#3$o~Q<|8wR){*-^Y-^=>XgD}mt z-$@oe4|-j9k^q`7i@3?4^LmbOEjXw6KW}bWO{K#~3r~DHNaVAk!f6qJA!tK;vLx`` z21qVk>P81s8NM-cYmP>(O8_oz^&BKXoL`03ZX zJCpxZQf{VMi@jScEnK8FPOjaUUmw%(jO z>a$B~I$EvErOSdW9!(CFOK>mrk8W4Njhufh_zp*|c2dsM))A~Mq9MQu({q57#!+Lr z36jln{a)~ma2w?`nmP($ze*Qx2cGx3g^*7n4S;zrk)AYcSg_-m!6yRGjp!h8I0r;japn8gl<6MIToLjzxhb(1oDj94Rqr z@$qsmq_BMHEMTtf>VKD|f zWb?sZU6+0m;q@g}sL-}Nn_1r2Hr^2-DImm4ibh0;o4!;WEjl$ZAwxoZskFPyazJZmbPzK`T*($gfgRwS)=aTSyx}eEpihopU*MLPmHEF&d#C73ylqcA zw(V4Gr()Z-ZQHhOR#LHT+qNsH*w&Z&ckk}+oKbzo9%J8SzThth1hU` zzk^3mBYr{waF;h(Wnug=BDI4tTh&WWv&>IO1TkrM>fDa=)tfm)lnh|*wFjblW``7O z(w=(BV8Gp6JoyCeIy*>IEVG_L)t02SM z5a0V4`ndbBcHhN_g@d`N$mXi&VfikDUo)S+*4{QK{z2{ihXD_XPF zx$BIt*02awpeUKIsI&NBU!-qO*690j%)jBOzCNxz!L?iKEkG1H#G=P8!*8ijvB6L2 z0{AVu*$v$fMxoy(sr9%lFpp zz>W0>e0iS_eV;luq$w>CGTY7l`*sM^daT9S$MiMVT+e^uMrgLSAP?x`%1rsZfADZ) zd?iwxrY=;JXd*c6lEEJs=EVNPpR+!F&mZ&!@Jr9-_*=>PJN3r;pHpvtDOunDfDQjo z>g}I1|E-e6#`s^=&*$o27kwdwKNtNwXdZvoSDzmA8;c|bvrIhUFv9((tc5<);sXkX z_=iCcwEm*rqQ173QRTe~R(Lhb_FFbR!9I21wM`SK`m)3sr9oJ?W~d60gv8_dRAq>@ z)3pSsu+ZDAv5%6^rC>UDkktNH`ck-aiwu97LVXm2#C!odd_AUQC%{tYCqhxjF9DM< zWO|U)Ajp_XT?dibCHMxzKiJzLT18GOtFdaONx)Crf_rkdIX~CCp_leDbJLB&&3)ny zvOvX4JYASy)i;Z6xmbT7^vxCS)*NGcyVaz~(pvs62z~1x2>n+;ftRvQ;}-B{;XhUY z{l3#k`osqhWtv-$f3}q`j>B9wQ4fqD^i0+2f7L{`anaJL+@>Fxzphia1m9V6e-|6d zCc=@C8G65FTp6`rMb`$UGRrJQY$RA~oeaBGJ)llpDq?l-j9Gj@Iu1Oo!5zyi(|(j~ zFQX_s?ckX>?V$K^j4nni=dy&No&I2s(BP7TPG+WA4?+c!rsVC7Gf_ZB>QKje2vXbJwya#pBm8N8Q zTM$Z+^7A{fQ!$=U*%(njtO!_0U?A~IOWQk!8pRS{;BTo!DTT+t5jG~+`nFu6vZC~p zRg7|>ailW-j@&CktJ$#B>rzKGD#$(vrxj~-H;Gae>Qh9e)*Hl>lu_9FZ!KYnWDy7WdvzXHODy9G!rf{i`!iRhNSg z)Vk=6CI$gNBL|M|p1a>bedhHDngkE_dFDDNQd51r;7w@Mcpka+k$ z%&6LOw3NZE4}t^<10PpZ@r)2AOa(vOD@YZe!jCJMRMom-W2QLjC$b2oaU4%fd!dPm3T7L8{D_?}4Q0n$Dft24K-zc^=f2=t|=T-}#jT z#v2%Ofs{$IU`@&Rm3u}$ zVtW`ImAbmySjKzZBb&~FB`xlHS{#S-I(MgTu_c{zUx2DUSkWb)3e7Q$jFLy~&4$Ew zEObVsaDL%TKusV&i(~#0Da5r_vH)tN!%!KyaRXdLFEdz)GKh1YB@&*^MOX3TTFI7U z$eh{k{CH7oDM4Ld0fQ+xHW1<WgVxF?0DVx;2{hP^JU%^Vg*B zle&l2(t&bM2rxdR*YfkDiYnd&wIuJZp)z8@0o=tMB1#zv7)!gA2k}{mX|8RJZ>})Z z(EFF%d$iccpVY6MK8|^)8h+{>JO}#&8hlx3F70@7J1q2QhusKchiijiu0YNgXY4Y7 z82+9#$vsXh*aK5yo50Z(Wb6uo+*BZ_$>KQ>5)UbDK|On_YP;Rs+{R+=g`EB*bl9g3It5{%W2;q9{TG}2mANis*AY2aDM<_u&*@v<&9U9{rk?dDJO5J)$d%&i3z~J zmHodXhF_7s|LNMd7Z!}xm zGCMlesj=2CcI+r)675uOs%v5zuTg@Zk5hJEYCZWKN5E!b`IW=CtX(^{{WrFxL_K8U z-pt6$6m&Y>apIjU^-AFyEpYQbM#BK+Neos-HMCyYT?54Hfe`%aAGxW%0saiCQWVk? zkE;09)gK{Qk>v-V;4HtPlfF~?Uzf&HAE?)?>3X&5Nff6evn_tTqP_Kfk2cYOiAr7e z#MNR!zuY+*FX2!TV6vJ2#v&Dg0vey+V5Bh$prnr3U|bU-AFlh`yrP+khbgK<4_GZ( z$z%`ISk1&dJHb9%nBhnqsq5v5BgQQZx8@?Xx_6%m{U%8rQW0XX1%>$~aR+jAPsp?` z0kg7)h3r1RgJ!)fmKgrB^Ulao32KWW@D5&iQ-~0DU7ctqajGsC7koIW8TDXJ)FM2U;JFS4f9#I&#uNXIax} zapJB^EM@mBq{}?)qC9m0gcC!JD^2ctFeKgCGuhHl7%POIrA;YUP%D~)8&6#f=WWsI|mK}1On!4n2 z2TrEzgi5X8^cWk(eUkS0I$Y5PnZ~}NCH)4mkO*0xsZO|} zi8m2&k&swDAe7~!48Z0nh^CTM{n1H@dl>8=8qQMf zS*DbEwM@>!@ish=4D20t4woo}APHL>o7=O=1LFEh-ZK6f==tEa^U-t0vi&am z&GR8Mp4*TEQ(D~y{7w`9G#UGs#%2@y1ytWSF3y^X;CMgg{+p1B;LY z@sc_F^@l_usX|=XQ6sYPqYx!hDOp*n5ItoQTmNB}UQ1eBikNsIws=YcV20aT@1we< zAc(Vt%oK(@$rjYyFPkF8Wm~By==hwl%Rg@m4urHKZ~B(@$h9|k{2J0gn)U!}Jkp3d za#?)T*`X|)`iGaKq5Henf%R11SURaMECrTG)>;8H9v3_$D-WZh2%#-d7uJwVOOTU( z)-ZH`6j_q1xKS^vKE{dTZ3vP+$MP^j1V+|@o_)}DN9J7TUwfp^<6d2M1);f(QeU?{ zFK;2F8aG>%_cvEzu5>6}&42%81B;0^iC6Dj5?Mn9&)$jVksIG)(-vnWrh@BX0UP+j zuXqH0keR^duI(mYy|a=GTDxRjU(AECUv$KjKASjcWoMAg&kjG>BbM@+>ZL1jh9V{zIKZv z;ihM6ac|*!ig+X#$7wdb>``4^7rL6E_Y}b9^?4}I1hwzZv2?-)9`7^0XB{2emMz*h zotHO9rY01Q#gMe5rZIavSdU8Q&4S4DG)JXClS)@f=4K$1P>en*70Q`dc7xeC-`flp zPJY_lYAbWGoYwGy;^48dQZ@?0f%V&Dmi<0NJL1;Iv%%=niDWF^r~pj1EQ^WVQtU{7 zc4Ojszf;#!?nj(gt)#M-$YKFQI+28W$fTC_iE<2xKVsy z;o0c!Op8JT<|!FIYq+QN`*nB6tPBC1m%$^NLAk?VYr1{oM8Ip9LU~PLyHUG;XAUYZ zYrCDGfr}`f4Rp(KjyFzfZ%z|8Ektk6uyH^>6F|JIhN&ZRHS&oViC?286!%NV@SINV z4L1^g#WlFGSw|@JQgrvAWQUuSm+`INYKdv4brLv1E!y*Oep*}(02(Ml-72*B;v(AxK~bPocx#F|*4SozuV@uJ85*6H6!i<7YZ8EbR{zAH-8mDitlc*K!I(gl zG&=aqdwg9QKGGGZuGX>8L-a>a4d)X)M~3}~4VpBjou}^G7Ykm_^x_5XvIDytJtBfy z`4oHoVcX+*+z9YiH3l3V}^{3Brw=< zabUnb$r2E!N|!a_c2WPYm)A~!$K>^u-IS-DZHgCuyLTwy&!Bs7JBDs5#uuI{@Yk+i zKjR9~81|T6_dgp7Zagixaz860q1I*Xd;NS7h5y-5*jm*}EEwFu`Pj6PLYFWb>m&)z zS6IozKubzdq7v^(N;OhXpjsJJ__5weQDs0zUlBkSm#kEz2x?q%n^qj;an-T&W#zrv zD;#l0!{giXBty87fo%P$69Ao0o(kmZiHEO~u%7yZ8e zgsqdB=0SE2mP=Cwv}Wb3%_4q&O1_nB;lys)I23tLy?Du}OmmUZ-{`Q)C@#&&UB$yt zI>g+>QNYoF_QrGW1qQX^VsS!PAh0^vB+tEJAOlh$Va4gZyi;UZtoJjwh}c;p(EK+< zX$>K->SS42ahlx8q-Yc0L)|Qgj@jURunIL@NAfC!8h@?ToIi;`_>5JL zV~X-O_Vh)FasWb$fQAiq7f zx#qYYhwwgF(wkT$gfzc1;%{sFO^|Ly20#jfzlm+Y%>(2JsS!;e9wAT#qF;;1&xx3E z#Z0<`a93KkN~#N1Cqcbk%lx8oqWLcs^RM;EnpUfuWb% zjz5e6bW(j{SyfX<8LHgXb-K|s$zJrGJsQ-xq8)3SE6tYtn2ivT#(l0)X7ImFs#|sa zgwhmjo#Co07HCrzOM*I9A=soW)C_i7x0#8zL7l4<$k`OAtAirIhIzJ~uk;dYzOiok zkPSUeR5yxm|AcQXl7A_&8X7+tSDb(fHI4QdsQ7g%uS^7)gUkIxO0BY(rd6kMjKm`5 zYV`Y!^;~CPrlX*zpv(m)_xoIRV88ID5;6?X)29PyzU>IY1>2BHs;hXu2n?=WEdH|e zvx5z~%wUc;s7=>bEt9I7|u`O3zJ3nCx(6BU)K1ob7fIe2x&@6d6UnMnmV4=GU zuAi_8SgAm%$T19HRS4h{BEaGN_*7CmAH-1Ml#QLs&p7VX-~0vOZ(9IicrYGf32=DC z=&}@IzKp3-bb`vghtO>_F&_x<0AFt-0(^7fbSd$#}myT5K&Zhqj<{thp&D()^D{m_g zfkHYLJ&r}bVE-Fe+?VFchry8zF+ZZVX290-^Opwj*! z{Aa7#3r0@KIQIS!{%xRD=oi_ir}kuO9>}e#k$?QL(;L$#P3!iF51Icf*pjDP?GQiG z9;?X&jeYdi>+tp3BDHs*%6V~VW5zW6pGmPb?;t3Ai(tVt0{18;kt4n`4Yqs*brtfe}BKTy2Ex&di=sd4sD<~gQc z+|^?r@Qso_mjxVy-?b%R`IBezhVVHIlv=-oRA`0o6RbpQBJ)s>uwX#^R$KhHLs9Z$R z0TgM_dxQnTo*!Z_ff9r);u=kgk1#BBBv{MQV+KSt0EvMAPH{3<6mXe<+ZBOi;mq$q z6bv$QNk}W#pPfi7D=-JrAWIP6QC$m1-yx~z&XStypzwj}N2EA2>FDZN2ZS3V-j89DZXxt25-WDdKO7K1$>jtB1#}t^J*q z0n@hp5yM;L?Z6MyWx>I@EE_#qwvM}AA`*IJ-dlMJNXdiezEU;&r;a8pxI3$X?5PAR z-z&mWLwB!=D>v#SLa@^cTJY#yqyc;tMt9Glt1wgRH`E{;wbzjjufUQ6?ENQyJ)V^I z&i=DjoAD~#Z@Dhk?t#+w8)2DKs@jp%VBPqE;--y@g39j}V2TfDhrss!M|o?VDb zmSw$Nb+TCPn|3g9Fur4jjK<4;JRr0ZgE@rx?yL){!Flpo`FNK2eysQNxg=`(I+oV3 z$;srO2_D-*NvBfLZdtQ$S%Y0R*-1mS)OOv}8NHnE4k7I(+}Sl+oFRhw&Zpb0YT()E ztr&s!`Oy=;1;`OKl=Fo2AUYs`iHj~^(2CQ=j>Q%98gCLvt*j7!C+z4MLMjEy?-dDE zIxx<7<^efwF3P{_1WAG(!6k+=;wl+bqlW=N8U4wNCP+JHdqBZ(+^Y7Iy;HXKu1*Rj zb+jUdV%T`EMG9)rpv}(jgM2;D@nSbs{79bTmpc}qH9FxVVKkIvaiF-IOMaHXYRH_Y z`u0UFX7e6`pTl9og4|Hl+ZWhY_=7AY7j`n$u?+5LL5|FtJk3of2IGQ9(?J8&_MT$~=7 zksb}k1jJ+S)4p@VRt60*6TPC9OGANCH43lR=ZBV)!{gr$OI-{me1$4^NSt~ zgs%@hg+>Dgi1w4EpnK*~{px+>Q7(Qb>+}haSL?kE08Y4Ui$-Zz$o7tc`CG5Li{13V zP?*PI#!U7{u#Wi3Dx;4Qh$f*DSQ^zrSk=FjT%2&Uy->l+(jw(#<#6$Ex?gEs3qhbo z#gDGK@3Gx3kxsdjR!B@m?7!a479{Twc)wcR|5{b8p-0Xzw>G<3tZ$~v@eXAoo1T&Z zk?QvehfA?nyR0yfc{1wcbocFRu;*dK(Xj6e@WO0gq9+Os2d8r(b#LQ!hxFZw)il+> zA`Osa98Yo@2}52ZH))X2E6+=4lbX^;y+q}%IG;|Ih7(bNfHeErkgd+Ic?f)5+Jonk z4B6}cvVVSSMWTQM(236#N+c^qjsp!PBsLk8(C`9I!FK&453>4;%4XBt_t5qsKb3A* zAbekOoX#r1RU3xe*tRNrmuPFy;R4ZM#JYERwn*AOv|gqbSIKd|1n;ulu4F{eQZcS2 z#y$j61d{%i*0@Vc>Xy)aFo;JZN0-qfhSq}FvaNJ#ot}uuNMikhjC;oTS@WD^&6X&z zIm_}|rIQ+|NnSfue%MiQIjh!A_L5r{Lz8_dET1YZ*pFbTEIBDHc&iNz zmtDDeL1%VSTvf%gIOzSGB2h==mriBju(gFjEA{CIGeTb)McqeD5*;SR$5FcoOksJ_ap=$M;oG z1?je6;=sfBDWUQ_*P7@p{-KAuLO?q$>B0oKX_J% zyv@|{X9E4MM-F$!j-h8yL-G~TX0yq%Fr`MXxU(B~kJ*f#cwVup(|1qec7Tm|L zxQw2TLkyd`{j^hZSqD29!XX3PS9347GmBz@!uoiMb=RSvy0o$|UcRtUMo{35A)%7j zVm`6Pv4AD>@ak|WS23YB0w9$~EM$l@Ieiu6nekFpMDwsLWC~H4QtKCBRvZn5LfnfZ zLZ&$K@nLFABdF#TPr>z@hP3#Mujwmhcth8=HXrpP2pGsv%P>uLxV&kB#MS1oEqb@| zTfi4E>66?*=#B9UG-_ZsJsT7@O%N(j0*t53Sc$8C_t-;(gRouQRiPDHR6K*>m!F&*hVUoDlc90iI$-HIUMJ`Wr zOqb_}&#End4c$=j&iN!FiOMw-z=*2HMfYX7Nj;>W0koQ6QTyM+MfZ0eYd&r0-P_@}=WTdwp108m>0JYzz>-6)`Iso89?+%f z;l(J!jyBEQBV=~@bLWny$ncG z3jpGUq=qnyaEYwPAx%g|tqS<z3Mqa^JKN`SqUcxS!0hds4Zrz#eaUYL zP#cB@fE!s-qenmgnc1}5F09Y}bJt!|jQNUGv&WvJ#~A9DEw&@PF|aNRBT}5_+udpA zyOTAn)yGYqLiKD3g4FCbrH^gB7fYH?!`t|1H7oEt?)e8u+21;czjIz}|2gONzw=}M ze`qor{r{MD{m+^IR_E~j%K`Xb7P{0V9lyjBUDMTe_BRU#!k6G$EJ1Nl?F(pe2Jk(- zQQ5tXhM7_40G~dZ7OPCi6DIYNHYmL`rJ5(9`z^h#6bauQUdHnO5-HzAo;fgR}0H3B~7oBya5*DSvkJ*%OU2AZ$AFRmDic5(xc& zW{EW!J3!W(Njb5y4ke$1hA7)X8j%$8lmsjca7-xjai1~%xw!97)?1A#@B+Bwa|gyf zN{qnR18MzZ*n7n_MX~NI;MU}CNI=l6@zB;uT`$vxO7V$a0?#CZRT7O|qAM%Xc1W}_ z4ZKQ*5$@dVPJ4TF=XG+-2_{)uo4tsY9sf!;lUAR22FoT2ct)cC(bz5tDRa}M)!YTN zzKTRHgQKk2(;tc;{#sgn;>Dy3@glv*vY2eh+$kCyukzDUi$tNtd zWOY0>{R$V|{W;p=TMskktKm{^4cgm0nZ;xshM;Ip%cHW%7|2Q%Y&dto5jGdf4Un_@E-h+r5Jb)7lt#Kh{Lp36rY(8l(5eldJ8dzGMywNkVDK6?+ZP8- z7w-inX?Y(&%Lfdm7)0ECL|nV*BmGR)P2(^mk&c26a=pPR)>7RQf-;fMnE~Qg_E zysjO0ml?3M&3t_!O3;>}RXAu|08q&<#l>Zhoo^>3#&XRF7czuFvIH}z7HT}CPxY7B z74}->>D7d$#*?`mT|5t@6T7__)*nWJ?oG#4Szsl!2MDC}9NxD}J2-^?((qv_I?-gMCn{e#U|S2nSLF{@wJM;Q%m5 zdUXh~1=+!iHuW_T0+v)Ze1BMtKd&uFGZuw7@-5WQx=oRAKazN1-eC_iMIQ3R?+|I~ zTk%W7Dl7%^BzgEC(lmy#$vwkvV!Q*>#Pp!j49~SPzKpHR*#|X{NL?8dinqpDZ|20BFOE>kNC6H^uT{cH8XH5a8(*ocap(6%-I7kU!I2 z-o>Dw6UJ&9qZVWb9Z(=gu7`(?7D>|+H_+a(?9eaC?I7|Mh+AD?)4az>*Z&n?NTEETCu8NmTAA=DNi;my@&fNR? zbd+I*_>|T~^?9We%D24&(43?Y6k$rBFUpVfW81d+MBP+=@2Y`Xj$)?-tR_B&ekJ8v za(5TbxImi)b8qu$bbh<5TXuWmOY3l<5P>NT=@0dpan(_Iv#Rz|dPDcv6&!P8n|$yr z_P09scd&`=KL?xsQs=&6u>S|1`JXfYtvbiX`rmkFOiSC%rVCG>;74;7xpEJ+I_FSW z$xP-EJlAIH8E>`F-r8ixsF!%WSK^WG?j-W{;q-Rqo&f8fxB+Hi39m3h^I)({KQL2K zI@*|=ZX{;CC^HIoJA2f^BqIq>^9;lyAv<}n?x5je!~za4SFCrBYh0-)b%6vS!t2T7 z_S^YfnuFhWdtrc>OVCJ_5W&x-NW{kKa?GOmv0{Yt6ATl!F?oDEt|bXVH}O|*9r3;5 zu6I~IJTj8Qkf}k(%wedAT#ZpFabo;Ngg|N%k$R>9RB6JU`L|lts$O{*9{k{X$zltA z(BXvXBAlT56p;o)S5n9V#<`)!!sY z^D=*VSlUcfVG;KBaZY!xWD$d2mc+jfmz@*lgtRM@RFGvW;-}D&J`3`ky?!4hBvMa_ z_TtqRWq@F*q*yirmPYQafX0xQ;2i>`yY02&IQ8EwgC-`+7>j=`bc{fG9csw)Tx>k; z`V-_Srt9>ot*_z=7(gURhB|RzhiJ@o#v?REM)#HP)K$JLG@xbKxBGiwBd6L)>j$07 z;(f)30^XTX87a87l{5-;Ro@n~JExLxteLB^J{BAi?qcihJ{3MC9A;B8zRk_)Y1!t^ zg1y}~TH`1#uXd$MeYXHFuPN|QXqi@h;PMJGL4HOGU=omggm;-s{4$>_ zJVisWr%jEX$6V#Uuxg4u#*lod6jSDjP2?Eep^e0lWY4AxNR3)* z$ZbXO-t6$2GwOVOcYrilph!%RcMuf6YN8aK&{nnxIbm5o)e5!;Ge=(LwrGQY+ zZ-6BT4QMrXd{IPk5GY~Db5LO5_8BkD)TlNtq#IUjslWzcy_~*@(kOAsIm@FM(r;(rLPN$)8pm(bMZWdck>}J< z8&LW$0R7yz)xoMSri!lqdc3gxlm}&aJqs9F?F=B#3t@I&TyupRyvBl7{4@Y6M~CpBy?7usFc`e+>VN|6ERl8X_jiS$Y{w`49b}@h5|(5p33^d(-9Pwvml@orNF3XbLxw|E}luITZ%uGnd0@gcVUvCxOB?A z%UNg&(a_mP_an@er=1g*m7n7l?0qF5@WL{Q7kO;X8ZxUWU%&q<3c212>4ms6Wp4_> zr9Q@)5LQQe zXHUasvGTkF8!|G3dF_lgVY#F8v2k}PqGFP%XK)D@Q!+c}4q0YX`j*Ko`tCuQ0W><; zkM?M~LRdY5(lUqLLx8|JtXGMzD+%yBRO0(df;1(|S1mSRIMGN%UJ)lSzK!zuG{pWA zBi(KFey#R?Gr_k#Un%u|%{7hR%?y7w(AbH#_8TyD;i*!oX6D)R`9<{63I8N{3A}aT ztrE1AKYHq`ba|Ve3J3+4g?EtMpZd}@Aea*k3)7KQ#F9yYT7MxY<`H^C|k;99gH_+bsMxzW(~mQz~_AJ!QY+0i-kTT&O%MA^z6 z1ALv68XM6BQPi^Pw5%kg)x}SK$?2?bZWfMn^XRI!g2!8aHNB{vy@cFM%);^kZ{ZHq zvuw9?oxOOj`<=01tm_geT4rz*?KOB{99L zRSOaP-3&oMIhsmd-{)j7lDIrkLXGmBB?gxHO-9(09U8Y~_c%Jj2uqPUDNqF@Qt$AY z@dQshZagLmwp}C(C@<*1dFPYr5ycDzTsH)|+2<~t%dufVsBPrm#?aGvLzkNoWC)yV zhXm5hjxkRd0Q2fQZ2E08=^&;p`ZX)^)F6Aer<04#bg}+qD|dJ_H;C`QeN4;qbx8Ek zPy`OY2I=Gi20qOYO+yB-m{GDH7`_K8MzcdO=|KsA* zKWF|sjlx&L$$ulDv9uNUS#Gj*cgH2q%GAnj)m`a^>wp^}!Q1K2c!(*+CNNx1Ooq-T z07P$&sx@gmhjz5P9GpvuL0j5?s+2D(G;1JnwTijbHQ#%*+*_!AjnWUJ<43Q!?6Xk6 zM(LX%-m@Q4?9KiR z(osgun(o~r&3{Go)C>s(2Y(oUtJD`^L9O1JlDa9{@_^^f)tqfj34y#!*kB~VWi$w8 ziNLHxLO4*aD@kxP8~nw$Y+a!99AaPun%h&7)PzfAHV!5GOG%0?`#``h=fZ1ck}2K* zFzR)YwxmN}U^h*5CU`-LT)fgZApn`qrJ=Vx?K_qewAS#Vb7NWsBgx$Q$Ywguc@Ia^ z?#Hr`j_KUbNF9=ygx(VP$Lh5Y)q@j@)#Z9hHF*@+?Oo#(!QsUYtjBv;=Nt-uQiKVO zPZZ>{r1Fy=BGA+x(t5b1t)=ck0JTTGBXiIPsV%VBCUXvj0&Igj_?^S`Yuvv-Rv)Qwvc zSh%}0Vrym-Mh+|(vyn6c#Uq@U+u9}owhZzmr{%iWl|jc{gkXM=o4KpUP%f3*on^gk ziuhKG+*_$k4j-f{4ao=OnF#O?j<#s{eg@=xtEWgm7#AV z5!B1~veN7~k8pw(KVWk&jWdjtKnC@rUbkb|SJZax z5IJJY3{DA&zatRpB8}aB_#K%In_j}2SYiyK84&3Ra2a7up#VTe`&~OV9Unp&ls!D$}(*y*jOR~05yc3qihOr z88HI(!opiybtr^f+Rt5Zv@8`3Pv|T~p_m7~V>5SCsu{UC^|kGIR)L^Z7%Qtz!?((M zlZz^mRY+@oPCO+R=5ao4#4u;aGR+^->yW{i?ER}hYWwe&grrMj4tvaVJ|uXc)||l* z(U9&fz3DeHBAoN00<_s&%!FTP#FUQdnS?!(FjH-aT>MrT4BDSCzqtpkm}`25tsvCO zp{2>jd4;My;WSMGZ3EP@s>Ahvpe4`R^FgVs@^UO`duE3WfYd?EB$?AK_sZoTRn zP^UzGtk@g59sCo{-Vtz0@S68q7NPsh65M*7;egDKB=VCQRMaOhHL#qbNc4;3vCf`t zD5&^|fJ8!cAbK*ttshW9A4C?i%4$RXhJL9`{$mQMepuSJS_#yg(`bY4MaBvx; zS?{v=AA?=-Gt04JpSS%8JpbvwLwxfZRVB+A{-%DLjiDVWDylk^{b5a5k=J3|J!v8E z;|8(TT0%!a0C*pucAjMva&_#V53g|2_=1Ev+OL>|`CVV7`?r`vkh)@wK}o?a*w61y zXMB`78Y#F_=Vx2;AuK`wtl2J^qL`1t1ry7(NK(`ChmXGTS1^y?eFYxRv!s5!LfwY) zq;GgP#l>LmBEemU@-mtIKx50VN$C)daH$a39Fc0*0y_^C#4lC5ksdzVz2|AjQDDOrPvvnUp->M%Y zP979j0*Y+CoPMA|fFkVxMgOkT*3JS>PZX5ok0Ow(1Qe%>*jv~$%}D?@Zprs2CfOmm zd+rLfOKS&Y4Ab**Hrb+42I}(~FXQ3KpXl`7EDRx#$gFVH9Bo!y7lu&e>CA4}`Fhp6 zTZ7;}!?=&)AnvJJ-4FAUzKT8Ri46mY7u-_Y?(@rOMS4Lu6Onph(~$J%B>u=5RPfNZ zq>zL3dvbvYl)BnFS)Y!k*lr1t#>Aq=f2fpRHy)zJR6=UNL{`nEp-xvj67<;9okX|9MsXpELiRj){TwzweA;XxnbE zoN;&ejVHpFD0{E3$?2JA8lAJiNC#Zx(||1(6N_A)4ID`>zrV;Ao^cjmL;&G}!3fj- zAeTq!mYO>pRqjii4;)4ZhnGc>4bq#!NY~OLWj76O6wg8bYL~RA6IG9AX9et1ySQ{Z zTHWBlnex+@LRh9_ba^;GxX*BKba5b7zl?xPQ7Pep7`Voy$~qKW)(Qr#Nd|rR%W^o+%{yQ5~?9ZzdXM#y7}rp ztWR!Cmgx!0!#H(sQZu%!u==pOvYxRQ3DNuOEw#}x^d{Cls#@3Zv04HVrT;R?<55rU z1-d+<>G^7vplN1o+Q+8X@C1I0fVY`SA7plQm4Duh|EecTsF!ZfFw7M{N(%}lN!$$| zJAP8^E^T`$s$Ms_puNhT5>2PAI-Mj`)GG4PezafH^~}J*+uYDYX>dI_p`YWo+w%8< z2ZB0mty2BiVnEkfAkjGn+5_ac6AWiv11gxY=JAg)W%~hQ8p`SkKkKJ z9PTP+Hr=fARzfRbHOZa#phAKQLh3OnByr8cY5n!`5H#ZSMa+efxZo2iPfqTZ`SalS8;rcDpbQoPv+MV%_7&IFfdSv zNCBgu2mSLAw?tXh_FH>ik+&v!h%#`Ln(-g>@fKv84V5DmMsT!&^|a5&DWW41462dU5D>P9i%hNLyBTwXbI`EGqV!JEO{cZ#4sX!V&3bj9SO=E zDZ%=2>Vzp52RqGs!6^4(soRM?{@a@~J|r;v$Hm8Vrn2_p`$_)~gyU3J2q*y&_FG$K zh#d#7$_z_{8(Y}EX0Tn&z#cMtEjAT9Ir+YyTrMDe91unY_9WtNI&z zD?2NpZ#}%nBB0vwNG2zuqX)|m1vF;UGl4eXGjn?>HEGaSm6{)coT#hHvKyr%RUX^f z3cIigZ~zdrz)PY*%AS01Nt!^g{yAU4_$o4K$qma=X_KCd0?i$#2|VY@&!`<7J*`Mk zeu|*p_aS7GD;{tpW9*q7qJ8&I+zDjm`#2{QOH%B|M1{!IbUVSD^!f%9Y~1n2mx&gn zQ31=~z{2oZMmrx|J}Q&$Q`$)UEW)naYR9i9H9hLIrBz^VFYa$!sYT+ocV86 zUM42C|MGa>srr9%#Y8dFFnl8RbCwRFH<#e71HTF{l(34HeoB&>L!H&<+eJ)*Rr5)N z&B{#DFz41$?0z_!)g(x}7FVZ6mX=v>;eM~iV3kc8@`fp<18v`;UZO@i*2IsN5JlzG_hT4(1K5s!V z%pR2i(|9Eox=hYuN_Jyp>eZ!Mp}-4XU3bMSVD&u^fiJ%HUR?7?B=xc z78X6YQe95g|JEq{J%M&@(~MQ-PFMZc0%_MFTUv8fR0Mh?qTJ6DJM}@!pl!404c?Bb8# z$tMU?{>Ee%f-}qdiKANwR0O?*8=H{&SOI&t%)*ycQufRmODoBy(eMp7M|n$SdSh$x9Fi7SaWMuzl8 zCCP3FwgDys9!I^Fp-~>W6)5lv4-bk0C8QoD369ypJdv7MU8FWj2e*UADSOn=q#>L) z3`7RrFg`Wl8sR|$2;vj%A#uu8nt({dCe3~ux;2ROX`^49#TdRsLq1-6fbE>MSS-7-6W4j&+H>m^w0 zsQ5$N$Ajt+@S1?;HDsbn{eC^u8-EV^y-j_f*v-D0l*a<#Z>8*hQk#jV;$I%&bBgr2 zD0|b@<>vgpp80%DfJgL?q_C*6paV*8))sGAwrtkDC zc0`U0x&DUMYf9^TQ$xX+Dm@4~5x_M?PdS+KIL=k1`<8R`WuB`-tzR*vNO7@vB zu~#PA4xc?PlW|tY^Ue2V*PceEk)ckJCG)7xc?sqh#!AJiL8>08G*Tu@Q>B6mzcv=? zCJPSjfTky?N*yJlyX2w4xmBrXu;)P}niiidwUBRRWtqm*bk9RpWSq)3Y;03uXaIPh}->SU~RaK45#j$x~@A8hx@z&_O zzGQ1UcWstyqFO4VeA^hg+JmH|t9ELTXFuprfxH4rJnZm}gDz_-(^=XA&hDXOU~}~h`!VB;=C`&m; z3SrqoqG0LXiItq4QP9?ercPZa5tmiH+ID9%Rkh;XNm)M}NS$g!aVGuJ>6)At!N(}$F-+C1fiH(KxzQaHiXq< z7!`z7u>~*(b_28GWQsa4pLhb4@>zmVJl_c!G5s=($q0KG>XSkc76d{=LH!PlcWNgg z`wGIoITorr6>}grC`}JxR+I_fu&P;Xc}o_J;%8itLtX>W3IOST%kMdWbO6=@kQxAd zVxUt*i5CG%w#1iQWhkO&tf@_OrR_0E06#<_N7=B7iq%buLLor)fHVGi$@Nr1+y$8x zvY^2h@Kn)wRz;e!z`aKP`s`6SkZc9GH~adDMk@ZX2Bl%NP}6L&Qi}rcB_MT#NP_TsCXm6o6?6K0LQRm-ej94xyZSL|>t7u0sk znAl;!%B1dx-C;AL1K9Y|dQDdYqV7x@n{BDJzR#i(mLG5}b0aFO3^9+O<0oPSD~U4F zyBmGL{3Muzxg{|hU_c!8We$%qgA2_RzRc!iF!HvV{+ZZkbNIB2xts~?r;Pb3J7CXJ zISqgwz*-P8s!1{@;z?eh7H}b;bXgtqh>XW4R08Ds^$tau6tMes$%#^*J1&zmxpw$q z%PoF44DX{rS=69n@oq)q03QZ`fvP3$+axTf-pv>B)h~p=W`zB?d`62FMx(YNatX6@ zJSGVjGyD3HJIx^H6=eW+hN}Xs>F+)h71FDVxKQWs7%Amonf=mY{7kIfECaOyZjTn( z67yu;sSAXVKULy2&GFm4d`Wb?)Eu7OsEoT&cGYx2`?+Sk4Tg{p>JP56 z_whS@Ug}Zf=%F^l5St?(-X+>uZO-Fu(|ayHPYGmBqexd>2f$)L zmY65C!dV1Vb~R}QWkt1P-`*N3WNJhBBs?w*2~W-HkYS4>!?@w2RDE0plmJz!x1fyH z`=ehI+atEg#H-^3a?F8VB_7-s$Y;j3Y z&`Q%f0A>bk1!@IW3aC5C8Q2Phb&(`T!QD9Ao)b+7ilh|)$_#a2Yr#c1Lmlb+u(}UH z&b_~E!-j1j62$n{XQgnk5>YhDajft=`w!OXC%A+yh$uW?E}kX=d4S#n=l29*`CJA0 z;Ph#C>}eFLEV%1HT0j;8V0QqCt^}Wjd!e?Ht;pNo-um5z}aFl3!k0fv4%QE6EaGW-m}cWgK=~LH zt|zy;~WOHh)(;rmV3JyJnKxT({I>I>p#LX_%C z9UWbwgE_*>YIR7GM{H|#b3Wgn_<5;>QGEdz3e71@5zU)w4&LosiL39?^K|gGLi3Y8 z7rL1G-|@k}7d>+R`=ZCc)&u^FxSx~xe--!t@E&-MtEm1R@r{ zG{Dr^1+hXklRzx9LWvXy7I~g*UA(x^5;1*w@jw0Up;>bvaIJ8QZ*Skuy6*hfvy$(s zkp&kQ^b2H>#1{BuRWhPzGB)!z@ueX5mQHEk}h5}3IRDmLLX}iRs(XAk_1}a%&enaEb z`9`5;!mQ@|@tCCd)GVbYxn=2gx+-tli3KkQq_rg5>F$jxyI(T<`sBDHgXB*}vW!F7hKg^XOTlCjrWQr*+1C$Q=1SYF2e!RfY$7O9 zg>ft*J-X9Tg6K2jqjPGP#V!7^lr?2vlu*g5LH7t22ifj)amE1IQig&uh-@xQGiquo zYSKnGiOiLig^80zmWx}Lc4E?_$b_kgRhiWTBpSzAn+^8atZ$2tYYbaL&9#Z98Z_g% zX7#Xo5xHWOsSfQ2&;Cr@;7S-$s(p_+)U&QhXN6>QOZx_BS)nR55N4>>B~jD1A$lqF zsVN6-B}26FX%>-yWya33)4Yqbd&5%=ebVczfv7aREJ+51kq9Kc0qq758WXmB%u?}S z86an83xODEfJ_b~tCumQ?Q%$H3wYc!1O*_f0U*a?2Ime|JrGI&=T7kQ&K&aUZ;C~^ zUxmg}iLt$+jHIlUNO;necEuzDj>YLtTVkr?ko&b~)_Yl9|8rxF|^Rr>+Pr6F`s^I_tp zR)t_ZKvG{E4lSTbFPE9{O?rXV0F(m2Il>3vfUE1bhz@-ydwRH>h>{QY=Wx9?j&nBJ zOiBe9(YMY0$2D4B6odv0*$aduSrG%*m_jN=&H_M`fEM*5tfwB80PH_Bw6#ZXVGH6w zfxh;vbh+U6#f7Vg-pPJ_ z`TIZvb>M}*VRQj+Nnd1W*ZjaX5BlYivZb=CJC^~mIfFb`CwR+!hO@%gxlJIdz*G!% z0H_IQ@%mspxl3^oR5VE=00*azxObA_U<~;lG)}g$@&hGl8ky#9>Y1 z_D7gT+|6~6@$0jrR_vhMic9i zvXctdokHY9s*jGtR+97bN;N_x73$}g3XqPH=RnHNMAtJ zKgp~rxi4Rr{ux=d_CN~)MtWga==4cSG{A_LO*SxGyc7T)|BRRb+$wx=PL=x0+?pKT z5*^b5y@eIWo}V_Tgrd>R zeF#e8tiUV)T+!pEEI}vO0fuU@dq0+!F5Y*VDFK_mg>!IVP%b^PpTjvRRF9~|EY1jgix zR$A7kyYf1Snjohu*E!Vv=8|I?ukYBg)41al2kOuqsKWylic*pAMdkqW0F(u`A|(>> z>?xd&O~cJTt8*=a_Sp1DQQ1mxo#93YYy?vOLFR}vtQBf&Z%E90Izh;vQ@+R?C*U%Pf5N5jCHgg^6%L%)xA!+OL_Yl76lu1@CQ8x^2Hwo-$}z5YqDP zxW3~t;+gz*o{M_}>An5;>qVf4VX)H1B~Q=_&;qa;KzRgD@bTV#YIEA>xo;5myq9YI zx{Mpar`wVSPF<5_CyS+9xgufQkqceP4%%pOl3jn;oGLreCCNuVI%_4%do)(8z+41f zY%~n4G$Jc_Dlk@^AZ!)TJ(vn?)h*Y$OYbPt@*g%wKP@r|K+Q0gk=4)jhs~W$2W^Ho z6w!#fra1Lo4T@4XpksyCS}6~uA2;jw9yK01O_>fHP^M?=LGrP(L6+O}Dm&%0y3L;1 zP97kqC+I(Dsq#J-;p$>Izv*(b9w4L0$X!|hfEomLVl7}@gB)@z_!w8l%M08DwoRru z4WfI0Z&@?*nHztKNO24+IO1=o$zVP@delklQS-6bqs?J0IqJeQU%ek|W5Be}u9c7c z{@Yia?o%hRT^EP@#?{_F&+$3Dk6rmWZ=!Lz3UlphlkQ_VEX@)lI;AEy-tdV;k}Jf} zg4viyDbgd9UW)}HIlNZlYf}Nm?aPE z7$;KcZ`0a+aPpF78Z=|@-3F6!JY7~#}NxvIexxQH?0p0-~?^DN;{?} z5(5`DLxOgczLy4F6-rXGpMczC$FiG$dacS&uPGemyHRn*a)nkv`J<+X)9_o$Zfkxh zU$tS-et@USt7-ooUHp6LE9bv2ef=A{`2R6Z`j@TySpVmajK-IX#Fv%RW1Yfwvw+B5 z*$SHluKwsOPTU?JiD02si*=#(*pd}4$nzbp6NRNIwX1Hw1r!QjnDaH()KBsxv55$= z5pH=ocei+uSPWt{O1xY;B4NoYR}&ej47Ax39xwc>i%E=@o7LU(y%Xl+3iKh=yh{d!A&eIYW`eL%MZX5;7U2@6N_Gq_y+T93OU-W)zjBQpPeP;M zPIK9>ofqMAC2Ap>$fQ^hH#mgL6QmGGML~o$5m`l>1N2yIT#m7qQf+8qdJKqH{^|HH zY2}z7RG%`5G)xiuI31US8J!F8(Blmvz4c#goVM^eiY?B_)*AoVI9cDR*+-uhQLbki z+#DJ3a^YC^b9XjQT;f7`3Qp!XWuw3a&o<`bYFk)>7o*N5(XNiU7G^o@(n#1y+S8}o?wWn*o9jEYRW@8XoUH|k6%-O4J(0#EG^}R;oGkX4KPD27r7<0Yy&?> z_JAywQKu19DmAc>fFqn`r5|@)wrAt#CeA;nl+2Gux>>3R5P>~r zumLshn}f~Hp#&4jg@ih>I-z^iK29jC6KE1E)O6cR=xS`XAQmEj7HMV6O(C+>IbOsd zT+hr83S&kv=wac#w{tA=5r>?l?FvUEk_bku%~yzIKqND6<1q!OKJ47RNeDxQ?ieg5 zw%A8=wh!2kJfT<88Ri0S0et}1#^8eO@CWJw`anF;SL1@KfINWBY)sVsG&5Cqo01XJFR8dOr(CKh<~1IF1W6 zj$}QbS!)7;S+(FalvxVj+zXT!0mZXww9wiDED(c!FavTIJfR?r<_q;1>9Q>2R+xBp zZSHYt+d?sQWY;$;hPKnY1>G$jbVDSY-g(BOX@*u$(9t_`!t~PlREKB?>cR=N&A$Q{ zs9ax2{SXEqKtaY3kq091rvQM-Z_~l5@Ci_Xu6f2LK~2Jm6ekX}AmL5`NM>olb1eB( zGemNPZb#mS+Fv5B6}A>kg>*%~1QH}3ZDqy_t=S%>T3^dtHR#Dy-grLWX zXhOm3+Qs4Jz}o8p7(|j>%;p$Oq##*yotdY=X$R{#OB_Rl0^T?pZ6RKP+;MgHhIq}&|q3#>&^M*nBBc5ITpl_qA(;0f#eqUI{T@ZEG zt+O*aymw0g&~X|2iswgXd^$m>DoQ(02h`W&`R_ge` z%t;GV%EG9BWztmS=0YVDs8FR7*zzx##Zj5w0inS;C%5;Q?K7UWK2xFH-6?--;d zCRQw+F+zAQnhs?B;D`8~&+BE&Iy^;$J=|AAtdsU}kuT@a=jJ8@NirkmLBARQGh?i8L z;C9dwkZK~W1^)5)2mB63WjC5F;6rVFbHF+Ge>$+B#kL~GPNB=IM;9{-5)VhHMu}HX zP?UbRz%8vLl!>-ziQF2N&!fR?xyhbCcwKbP_y_t?__)3tuAbP-HFD_EVni7BNN9b9 zQOmawP%_VU>TJ+Ns8rrS?TtdStQ_SnL{V%($K|C`aaE$z?;e?Ha3y|u7|v77id-*H zas{dcQBV?Tj7L?B6-#G`4hfEQ80wD=49`Hb1t~*TlIta8VMHIHgkW~aU=*|P`8lW2 zXr5y@ToyC0{9`w?1^`(HiHu{)Zv<0R*Zf#O9pM|v`J{Evl>J@Vaazz1cR_C?oXjA1 zm%4Xp#YO47;mLEd9P%DzetUhGhpw9SHs`cZ!r=_PtK~COps+it?Vqb)nWRCS=wDt4 zzA?~oO?2B!Q^1oo|L`z09D0TKBfoc5Pg%9wLQHWW!#j!a+OD}sQ@bL+}J?98IQ$i%8^^T@4EHH}0y*Q~(OXE)t(?+~axdK6rH73DKR`*x7m+>kzVywH z!?!3>;bF)_2l!FRq1h8ea*_MSu3S3y6)M^qCcP}sMkzt5u(M1lhv=f~p5Yw^p$u94}3i){+5qw&utcY&1P|I@{fTKFOpz?O_f6MH5LZ zq1kNPrj>n76G7PDQU~dxLz@q4CyeG&srI%Ndc9=}N_!sm2KlK!Lv#hVmzVu0eRNY6 z`nJ6K`5-EA3ULL1-|9^&WBhf<#*d#s(C%9n+n?h1QvJ6)r&{ojK2EqSDGLR|B%+>D zsmvG4@Lc_{Ni{*_!tpuxF2S)94v@?Bs_i+{~w}q7dw5sndNra)d0;4|_f!+-+)v0eb zaV{)_4_iAJR_{#FzEU#nh6>0os9|SP5_ID(zXdAHVA$-dmf_#I#5=m=2WT1B{cO9k zYzCZlZr5KrJuX(K39l1kSre@*#CU?9CKpZC7E>xFE`?AgEL)O$aJn{}a81u~_^c}m zaOeDrxNT3JOIf23U?Lr%*L_N@Hdjb;qJe^&=9k}o%_A*b&{V&oZTQLkiwvmrZq$0v z#V{7g+=DG=MH(mQ`q<0+dHx1@CbHF*U|Cas>uLLDVTM$K1FaeVPyTyCNZ-&+XAUbG z!s<{X%nKC+NjGjODa_!Ue{8lG#mRk=AYz|1AMf+?E{87@IGR5v9%YUN2SUVk+wJu9 z7fR~#dwd)WJPzZ10vL$27W|(m$@G;8`Zo#_CWe1sarieV$?=!!9 zLt%2DY3sbviuh5hKj61F8N#q7**q_2Be}%UP~Pg}%1@FB<2u6K;Ow3vnTK<*?A`#~ zJElTID!Z2XH9XZY0HnzSP1C@SZ$*r!lhdP-&+Ad)K?>qDHfi1vp)}8IQOq)v(LkkL zo^`*uJAxk2ecSc98M?*B$bgt^W?S&|{McQ5=J%Z*d%hJBVE>73X^t6wQ>jXWs@c4j z@55ubR)R?d!}^c>_gO46ljWQ9#Vrx@#WC)uyM}zO**S*YIf@3Eu?6ZEI9n8EEm4M4 zWkp>PY>Xd6V&M$~wI(JQ4Ld}C^4|x8T4|iW^4~?w&?6CYM#}N^$eEH_he6)Nh*OQaC{6VKvC%oXt8YhrM96Me+D_uVv>M76 zhiZ}~&N73Gk|llml#@Y4K;2S4HGSD_k8`@i`S^^qYkMnq*2*F z007}<3V&G%LtVJeqHI=VXW!P_N&q=CbMWRWVOF(0UuuA);;0TDXLnon@0I8yUXD|% zj5(eiGqq<}For@(yV=Kur*0GctS*U_>>((`j3^H4TtRVl)Ify|R!xaaUpB?iz*BSG zb(i@?wSD138>_B5AM^rq;$t;t+EDfI`m25lpJ>BW=HC1r#fEMf)S);emVa@SK<9&& z6~MmmsB_J5@jH8ac2#L`LzPRhae3y zW^(T{p8d*>+vv?ra+aBG1WV3H3vMU(!OR;* zm?U9%kp~}*&VFjtYE~c za1B~jqQ5|N(nOOSck1&aPO1^XMP(1 zesm&K#(lO*$e8UhXQ1=|-Mgvi8+nG)vTM-S+q@NVnSE$fJk9y%vCsj7S7b`CO16=p zlH?|)AU7{SB%x$(CtaUe_UR`|_8BHpE&x$fG>}pLK3IS_+H}PJgh(n%Ma4QVEF30S zB-xBpnQ=IAc|+$pP-244?;fMX$C>Xiafrd-7Q2s|b&lJOca@2X8?c7DZ>>u}pP^xuqn{)WU=^es6tyEzPe=jT3L*|)g`JMvj68WlV^5a#kqxWAWQ4`+y3n_4GRyb@e*yd4B(P3m%%UtfZ%wUvmzD(4~X~ zmr_z(Dy#M;1&cZfj>J}iN^;E$pOVW?xc(Rzq#OC2nmIAel1?Z@!rwMT!K5Xry_4tx zPzy-XfF}YYFI$b0Ct?_11iElva%2U(WZNUYRJawE4~6FmaCny}80E$8NJS4hC3*PT z(mTL~uT;B3A2&g{1lxiF5)On`@Q`z{4=1Qg`!fQeM#m@4tY@Hc&?(k5@PIN6rF~8D z)vZL|*z>5(Fz8Ncqz5_Y?o{E$8&*>ybTA9#l#`TDyb$-%rlF>yQmhc?@zpltcOu;E zFaFn17;=pm`Fbamh#xz6(8aU4FM{q~@!)d?it<>)vf%^EhUcyrLa%AgG}{K6hF6`- z-;d83g1BH>-eK1D^ut##c>;d{e(m(6XP^(L%VI_(7)db9|L6f>ey=0TIN1H<9pHhs ze+xF{?$ES!( z;=`CR=lyn{@<@q4dO(y%7L-Rm$tR0THhZ*5NG1pEQ4T*6lLL^Cg6Zd{47uHoPjK`& zArE?7SV=;8sjYAnR}ysK#N3K|ad`_Wi7LPgyu{*{U80tJ@no7 z-u-L>k9{G24jU;x%EtD20y>9q3JTlF+F=!BRpdnICar*k3gQ)%bjV?$BTsHg<{W^q z#P@OACZ~B9hHOF}q(L+ra~fv{7!FYkW2}gQEKUhg_JXb_$3R|U|GFUd`4W3Q(d3#2 z&bM#WGThk^Hh_Dtc+H*v+5%R0TVTUsN-ST&ar^U;E8cC^JHioTWS_)f0;YGDjp=LM z@D0p9Gm^GgAA$f@AxU!2*&FnV;BxMoT5w$XvIt;I1;>x6ARoFDY)VOTU~2D2`hhn; zj77xGls_}BGf?CcM&O)iNEU-m$4>yv6&UVey!e^tbF;4Jm*1SnBI{%k)!oSazqSpR zuLtMqX*YevK!WqG?RE4o%+aAGCf}QdB=+?vE;0bxT==bJcvD=wBY;@ZTro3#6K*$c-h7J&zvv zY|+BwnGqpZ5^;3zyDRQ}1upScp!F`+sG?BYI5Q5CaORrU67f0066ca7+KSoZXE)8*hQQN(`j8?xUk{74Z{lfwwlSQOLbC1Z=%gOmW^MaG3 zfx$Kz^hsjLP=?F35>iYR8+f0b1WKfs>*~F4aj}+;@)n~g_}scVH>-}@IiCRd^~)-e z$50K)Vv%G)kLx-YE`qdt)!k~hUqaNo=Zva-UTg?Ft^JKYNUPp z)2fcA+a{$(;|4r`o#bZloDQWS73)X(Q?18+eE+J}+h+1=3A7~ZC#`*(+gfQ~Qw?sG z3wWX9WCpms7Wk;o%zn(b>#_`b&T-%0-2Z6y%YPJZYi=BsNHZ4?)L<+jPMqA}=ChPzn(;cSEu^-^X(=gTl9|)HrLM|Q zXAOI`hy>>2@)B=_$FWT`k#`u_H`-fKI8E$FG$glRFuxy!rm$dF(?omfBcA#CHB6&@ z2u8QSGCm6n`4tJ-g_F67=FgMV@Su=cVIBpu{Y98ntUrfcyC*+SmYPOUTQBY!-DI%b zLz~K{dU#FeLjf)FMRB36Pm4f!wI9C|!;p^WT3BpP=K*@U0U*NF9a4^wtnUT~4h{V& z%DDqp@*RMpVShHp#08m1iE35ga(%R%d&PjC69^0jcL-c{{fJA{XZkK2p*EgRJT}Og zWRr?Pws%1_W|8xX76i)Jbu(RRZ@nF)N|Ss;UPTe23{^fw61(gTB8TOKCdrNnyAMyD zHvSYJhj_EoS)v^Xs7`#6Xkr(*Knwa%T7S&nFLM$mu>OpO#xVGeO;XOs`*3~uv6fsG z6aSg*(YB9$$ZRg%kZshWR^#pc=MUl@_)EMLmlOd6(*2Q;%R|1-Z1Gv$H~h_}bm2#1 zkVc~wAb@>t4px+Vj3`>JjaVC9tMmE_p{9Q&ju>$JEI~&~PN||qAF!{aD3q!t;&i7ZfoCOD z2H4fe62`%FkT{o!B^g*E{tH1J65LaebbdIPTdyw0Tn~Aa5XyPKGjsf)rcSh0giidD z*=f;cgD?p!^uop?cmvnzsA(+d%PW4FN=Hb>WH)XU<__8d_cN$O94Ul02}?4r#7SFz zPaAyk812v=bU3AnaNZ-^vU@URfV0w_E@4L97~g|DSbGTjkSNM>xznLD+}YiA6mv-e ztbXFKe2*0m!r*Z>>^$Mky~(8`KO*6WRk-w&+`#*Az=FgE9sm=k6BHx~JUZ1=(wV)k zpFUPQ7lq@8@wEpofV`)8E?CbZ$LK)5C0X9-JL7 zsL42%)fJeY8S}79t+iD&grAL|Nj#4|UA5P`)Sou=;RUrG3~|UZE>5?>CG}K$tGb}0 z*0aaMm>@}UP2zj7s;)a@&8BMe;e3_WE?Hp$-C3mzzDuRBc9Q-xWP_rk%i4{P$*oM3_y<<+NhLUh!>bq+1Kgyl`KIUTs~aPg0E8Iu;MP@IzHf0rp{brIA< zGd7vMAb1|DB1OP zlTx-S5=i3gdTo!zZxsg&2`awA@%`lRzd~*eiD9^eE+P!`6!(b~IPu+QHEd_d{OUI_ zp07M|K;_!ov8nrWc|mi{mO18xj`5#=wdGlCAv&+y9xjaYBAB~pbz{f9sdsS|5n1t^p)54|9e}WiGlgAHpc%2@c*3oF9AL)+kaniyug@n zT4%eytlLSv716kmwCy-@>l-14Q>E-J5qB9f1Xq5VEY?13flZAA?B`u#MlQWCidinBsJKys{n8_ef zq9Pp~Eu$ax!KM5WE`piNq)Svof_fH%GSbMWttYP|6Qz#v4(*O1fA!??{=htv9DOSl zr?s5k!1RTlD_IB8&n%L85eH@lIFL#ZMJ1Ag@u(8lF{}~`h~EU*Z{u+|Lo_QOMMz5G znh9C^XnQCI$&*aO6telc{L^MMxM&2I^G7?kicpz^Y5|aRkjOZt{(CV*R|dxse_HZS zhaGgAxz-bYWEwAg4&q<##3thL8~mxR%zI?EC5ZgwrXzT^CAKVK)zdTh!mFR`woELI>*!ib>Q z8^Sgh(y7&MJ(wgcSOH$qE`Fr!@;Wp7$^g39Xsvj4S|wbo0k@d*D`~6UZW+q+Jg=>A zqpMHDZM-}+J&3}bo==nU!ln@~oZf6)9R#b1f`7JlCi>CqmB;F;UaP~MQF2n&?R@g>Qnl650;fUV70Q$8rw+hd%&=dy}sM1dks~*N~WZ03PUlT71D+^kODCVi(v6?1SJU9_%Os3 zd_)YQsR0NiDBFsm(Df^F&?i4(?`gi)MX<2n zu1R+hQegaNkMWz+J}y6I|m)ndQj zoQ`*jBjzL*G`U=nmE-w-?^a%rndFA>Y*}MJ_(ir4CI}ho&<&c;rv)M)`Xe2Kb`T@U znU_=R2_27it>0qy)V`Brgl-B>muEsYPsowkG#u9)iX7a4)JXd~6bLHaN07!(P0^Kn zai<2k=m)1OOatfdQ4-|m^(?0hzuQsb@l`eHL^}as^r{A6(k;XL3ERaGENFw6kTeJ? zh&sw4vWPiZqr!i$;>jn9mv94tpi;EVsBmX^2Fw-F+ae(;0b(*>^)`bo$ZuMrd= ze10n-;Js{kLuQ1@COqQ}dY}K8<S#`5RK?&0tux0oikqJCE@`I zbSdInIn2GV$fN$bxM)eNIxXY3IRn)_K8f=Vq({Jh9;1^)(wQm5w?G5T*-nUVku|Ia zR}p6k>|e@n&Mb88kk45K8pt;LG>(qZ8i5+2D+h??E0$rQV+oZ2|YtCzG2)uwkC#A8-P^z;_w+tjnP8x<-oG4kOdkw`hES3$j=)G{pD5+ zo($Og#Nl^ETpY5O7Fsk$)9{o07aL$1dgKv^qoFhC*!2WLLpcmWL^*r*z58??fPCW# zP$!Mp@1;+?qOgg)koq08F`xbz0Ma*He)_iLVW95^JzB%<(|?B1!xtaOmfgauqv;oz zH^w*fP56A>^6(}C&(*>bghjpr0)yLYpPw3sO^o-iKl`{|Ab1A*03M5|lK&3%{#J>_ z#PIJcvHn`(|4-rm7wY}>um2a+`pNo-+lA>xr#;GTtqt^yRI8db`9=O!g0N+2tP*$pVN_Rtn%Lb=!rcr^deN+?NOAG% zz}Wc!@?Ya<@}tDE?TI`DGiC04TB19g+nOB{ULD6S-ma*qL*U#9ZXnbzyycCGuz zJlZv-M8x3&1Xq|!Fa-s%qLIkz_83QO*5KIAMnj!R1H)@T%pf)4WE7f-bhs!N=n&;D zgi&fwyj(tsGa480-0vDBjmLp-{{PL?<98NQT#{u;KqXN{S~@I^yUXsTT6ge_YjYeZu9>8_ItnzK1C2tKRwaMWFMFWYJgl}&PMweY<5ip%SJ5`fl%K^98T15K zLh-@DKiz8DHOlVkoXr1it$U390!W6_4%>XDx?`7db>U!PA%P;vf`MxHvUEOoYO;~C zcCDzkYzc4|wFv%d%oNVAo@Gj(?rst+zs*(=tn&r5lIZV25y^z6d1ex~N9X&sTRA#|0O?zn7C7{^| zjrC>wBCs}4&asyU4WgR@WI{dU?GpEj)K{|ytzi{a9_dAOZKF`XQy}uhHZ4|F&L zBc#81X|r(7bx$56g}1T}QsWC$FyIzfq-pSH`Cv-GdQDWGhu!<#RNXDDvlokW%t1XC ze}Qa(ZYi9q3Z@(hdzX-HVN^qea=|6ly@H{B3%$UEOE%JX3eYOr*{H(wUMe=*s|twfo)5fQafgnhJ%@LwIX}xZ)Q2W`FkMsk{C-Gjn;bk zu|f6tdZVx&=O%>6nx{w@0ZwV0H3BxV8etldD{ab22N18Yf??kqOkxX!e*JQl4801D z`DAT0GMKbr2joT@G)aK~g){292-(<{8H@o`D zN1Jw&psze(<~-NCz*6ngLeXHE9k9}=?LFXIkmJWgNs&!jWx!g*i_ANai0SOsITFIA3D-<~X9^5hf69 zz=(d1lqa8yP9daFAf9PDXe{8w7USl&smR3=GxvG?TqyUFcUbgM6@)y5zDFaFK8h}TbLa-4hDt`y66Rg32 znaQx#AadJ-L#PJdd)W>2h+Z)&sS*8Ys$IqRmS>#f4dpEFK0?K=JPt&GP{WnzKAH#b zMquLBClB65YD&J9r2rdvw2kFfw~6Gvd+MtQ0v=Tpdm)Sja!c2v+Ccpy$u0Kxvb)5o#wrs`n?y9; zH6zxPLtOkmj9?I3M8Vza$-((PDtUyGO{vN8EtX|atdfLvaOJOKr`RpB>HKNRhOt|l zkB?jKj0~l~&;-SH4((pP*HvjV^K@n?qx$d=)r@|hZyZYt1&elW%tJy}$S7fT1PVL( zplXsdn&cdwJ;}$WoZi6v>^&zc43U+K6sj4_7pOe~5^<$F5Hep*zu~opXqL#hhpmpK z;(?+lG(k1(3dATOgTuo-oc|APZy6g0mu+dAnVFfHA!cS~wqrYHW{R1)%*>22Gutu6 z%*@OTvHdykz5UJHo_AU;wMHeC>QB`vsY+*^efG20dP=-aR2Bwcj%gfcQhW!x;r9S1 zCKQrnZ^F}M@~1X)c;FG2n!AsQapqQ67PJ;R?Zeki;&hTvP^fw^cL;)TRxNom)=zXQ zPOxNwiZubcclhXd+%);sm3=b~&oSieDd3Y?vbBV6%eRkfg5h*RoU2LwiUy@`61|#8 z;BScnGEz%kH_QKP;Wm*q32m8ykz-a6X`ITJ1ZlrZyOsLGq5^BuFXDu8-KA-h16HH` zWJ@12xCj3;jEUp9HxRjNF)Js}w-z(lyRLLJ=ijPCRQpVVs$9Yl-O_cTG1W?u}KxjV2Ogkfd6AY@(R;qQsG)*g?w+ zL}o^bMsFP*t(Rvh)3M)yGxS2@k2baGG|g`+Hr=C+a=fLaoJYQ?g%t*oc8xWC5{*d`!qXq|U77j5EbEfIRSHoBD5YRD?98I7&IEM+&U2p7R_+E<^tGOcbj zLCD^e5$e|Xc))Ec^1oTgt_q5~^YV!PWY<5h7)AdzlhKMAMF7dVOfXDn4mT?A!rBWk zcyvMSz9F%@vCjCwpe@a{K?RytJ&N5uGV3DMZ8`tK((G|7Gf)z3o+z>DnB6!gmJo^r zQ=#Z;+tzh=*EEpSTRX@vqO+s@wR+h^M>(g0e!8ht5juF?G6By}2L>7nLRoBwhi@A? z1jopw?k4a@paZU&q=YUW9m%4oEq1H*R8X%s7T5)iyAoi=Cf+0+N6^poS7RMSw`wNN9yZtkGY$Y|j@amN+CoYheh>`K+|Xps5V5G4N59rTe%es-if2rg`0+G4kf+5i#X-L73RWuv%u z&j=4@GYvkssc5`h3d{nE$rxNXpz4Yn6sANc5lc>OjT@4t`koGwqVd(`)i6Jt0;7=( zzrO!e%A5Nb0&0P7!AN0}@bI!D9_oley{B=gZ(RV$AyDub4_q#FqADIp94jO$a6knq z+j~vd_jQN+C|7R1uA|K~v1-^c>zzii0Q6`%KEY9_Ar< zZjUr~OrP32o+y}}2&DY)3^{Si@Vo)bEG%Q_SrTkHfZOrKg`ZMN*D|3u7GGdE_Mc{K zVE-E@f2O{HqrWlAkGAPQvZ4#YWSXjr*8nV+~ieg)${Ax&Gr%h}@jY z6FVffabj`oChrIY-93KpV<2ViK0GRmNTwfo3)w$Hb-w4p>wkvG)i(FI=w@Q7X(58i zFp|0*+7|+!9)-Mma2vq2NL6gexywKl=y!LSFV@_8HlFEdX@0G;d5W2Uz^2n3kCfV6 zVLAvi+yIL*KezoF@Y6#tlc58=Tp#sMirjgKMoynRhS_HdSjk(+XQApKB0{G=-*TiQ z5E`v%w5Y%J~r53XJL;f1xJcm|wJ!QpwxeAF_GhH<=-i;Y3YoC>!D={7cv-<3)l|5lL*fHeVdWXgpF=EL-l5yc3 z-e9{Yd)p?CP4TM)Q{S9_i=#8@7IUiJ;{@r(Nqa(cRl8kQ2PA`5CS7PQV~Qvj~MAEN`o(mn(F?j^VJRW!l}W8vyPtaF4)t z-WC0s-iA;fSRjLepGD0#ocZIJn-^2re;cGM&OJ~m9_31ha)#L%Cas!RD4Cr)Zaltd zXn`59G#c+M%px|yb%_iZT+BC}_3$@YLRN29ZkRe2QLvWwDUtHMNG)Xt6$DunRmOnN z{k6^lbV%KTxJwrnq8`1648R+y>vvq+9(OoHZ7Pxt(%nPo{=UY50}L6x4>P;Qp=<>Rj1!qKXbkymr9+WNim`p|KdPzRjFt%l%vlmE&a zte}l8(A-%!(3~3=y_zqNqRc~<1vOoFQnDk2#LZ7F`*4sMrBo;%j!riMmQhQo{2w3^ z=);4jIDMIn#8_9aot2GX^p@!UEcBHGWn25ErUoBn zhv3ExH_)_JpdHRySdILv>JcI*i!0&G^MAJ|b03-td0>wo=II8b?AebRa|{)|Lhw5< zDlv&-nD(tu`345b;|hXl*Tm0BN|VjXpTYt!-PuDh$Yl2@fC3PHecnz-tx1Z z?JfW=I3Dwtk?3+{x}pS2(ksP#8I>^T*uWF8rm@2v;sP5)ZqVOigXDnSRgB7QM3i92 z@Xk0XE?!pqpc-KlEb@(M^H0D1ZWCxAQt7k-%|mlWR}@wq&unxl2$=&UP3YNFMtLLX-wceJLe98~*iHw88tM&yPeH>^@p@zwTzNj9_->a3e zW}T5@5$jc&5S+cM1ddn|Sa>qGZ{t2kOXI`H|24yO#2c&sQ$pgiU;6vTxcW{3irlOw>(^A)I5bi;>wyYbfm?@qw3^*IC0rN8Gt?u>Qxz-0~?Hs_WdSN;q!T^xm3s!Xo$ zVF;R}Hl(cT>e1Kas9_Ffvdue6JM>kNW#kRWxlR2MsUFeeELlN8 z37mgDG)dCeBdLXu>@;%qkruzZeKvh!U1C)NqLnz1$ztiBz96QvPtbmB*JYt>`Xouj zp93V}bF76lg)D{AL9E_Kap|$8AZ7H*2xT~CAF$T`S$clgz5Fc!-y>mj)qf%qJ(Puq zLq;0z^egb6l_f(W2IuJu$arYt3x-S)>BhLv3yMC?J6xq|(7S7fZ5xeTe`c@vTR_QrF3XR_uJH$8V--OS_*$psV?V#E=~ebWqMv%QH;m5j6KZ=h(uy$Mxf zTaQwKx>2o@e>gqw$o*oCbk>w38J4RpX%{3rTYDTeBoK?isySC0Lq4OSj!(YD1YL1T zi`}j@vSdb^wxq%0?fYxe`0q$**E*N|wkj2^rR%0jn{>G*U43JE zP|TJE+*J~*b!D5;5ZUy3dFC&06KfsXRk~?rIV|Hi`R3ifcgw9K*5>t$2K8FJz>{D+ zRj33W6@`e4gu=5cbI)Yd6^C7`(A1}ze9&QFVvDy^cPQ|*mjLcm$Xnx_<$Skb1m+-< z(#uNheXc|#yO^LO-*sc`gGlHvvGRm9N$kQ^Luv`iswFzqZ@@hE!yau5oy@>ezI+!! zzjs3krp8$miQYm=Cy1)sj>FVM2X^G0#8>tuYRQJY4jg5pnJuL|FZEPp4hU0)tJt8Y zp+EyMT~4V^)xJl+we9lPOuvHvfZUvN-wicZ1G9%>zkoYKPGqab#t^6SMw_r<|E^}U z>w?w!4XaZ--d{) zZU&9*UR@rTbY-~;+HaIyDyce;O36&~3eMk;aliC$Q3clDue=iK+v0f7R$|cCpgMNp zi*BGd1x`Iz>8(3EYK>K`liYoKHwxBlADUm4zwcO~b27;-S;baQYA$fqMAO!hIFy(j z8t!lx3C`T?+~180ew@2;u;5?5x%L_3Ty6G#{q(@SIoIj>utGZ30e7%e`wdeJQye^V zT9dLZMR0LypA-Cw$TZ;{ymi#St==1tRdBJ&5+71!WRB7wTMH-9r+vLHO0`e?RX849 z7viwwDE*=RdkJk&atT*}@Dx(O=MSI$`a$9RR033;VNc&bA3OI_U&E!853ZCbLYv=P zwaycLPuSVcc(o~7xluaAxj4P8+7BgIb@R4!+RQfUe~*U4V&!s23|0N|QD@N*l`Zm! z^+lB5aEM|C|l_KNXLeUEg>|Dzxc2*qeJ=?(O0@Q`9DvWt2ac6pu zmnBiNiqx3SNLw^P>yF~HOFCW}sh}`)Nik_;)JGPtyuDYEFl$EH{hT&EVlrTe^AK4$ z8`S6dNeGRL&+Z@fhkXW^D=szk1wp*>I{y(o)W;lpHD}$J@BY4oFI9g);0e)iiU8c2 zBg#S)Q7PnJb$L-WjI4f|6$0n_rhD3DM>r*W$L-4YtM{WNLdy&M=g2q(Qu}WzOfd%Ix7ilx$P{$MU839l) zdrLf~lXbCvs{6@dZ+IJY$&JW1T&MoJD*p%&ECD2^L?V>}+Lce+EQIjtmHZeq&eBi6 zGmD?SStfrRFyJq(?UtOT@LaJe^n@yv<1qphTTHi88E@K-^=#7)R`hcpceg|r2_4Cp z64YsQ6-HK0sgJoF#NE--3a_mtRH<0dTo@}=uU8WC;RERkOELMs$P1R+@GOp0SmSC6 zON1-Np<9bI-_Wd&PR>+uO;vUBwfQ7YFcEH77e_eII~_C9!_>RZQ%SI zbt1zu9QtyqIea+m-D$ln0ZLqjNpEXLuWdA42iLItaN>Gs@tzFBy`Ga=2tfh3;0Tk# zdBQh&B4Qp{B`IFWWb2WU9lC1KJXwbB0z&UFu9%wWZ-z3kkI=&IE`k}38WUnM<^-fc zTpNx@Mfu`Tj-EVWaj^Fm#=aNxL2r&R)xn(8dA~W)katicNg{XOoRP;Pq0bm^R@A!r zcfxu7T#`{@rz3!fqYaLG=^1rsbRLM3>Ycjd5rs&*rE z1T>oiBx?XUu7rI62fG?@H3t6~EweTlHwt^UuM;?)kug(RHceB~%dW|PBDi-_$z z{PbZnq(c(D{L7spSiu9?{+kZ%OpXnX@6eWQ3Xy#+G8 z)MC>_mP!IKj3mVOU5fpkVQoczHJBhj>$Kf z{ME%+?v;1uFah%Ns)w5sM98InMg&H9@3AXz`hItB$O+PIJz2O$gRX+6Cmj;&A+1L? zob8=%i08%x5nwQ(teb1E+Zb`yR8IsT?vjF7A&2FU50Yq%X{)erVOX23CTk!9$CA{2 zs*hWW^}Dc3@3`>@0LQ!HFlS8H zn_)9e3#SqUhj*Fh%chq*jd>52RN_wWGYeDVfHvgNK#&D;=3#Hf)s=m(IZ7A5RtJwS z3@9l@cp^*^qr84j*6$rQFUmtNxH%>RB2+o5C{Asp{v9HnOP@7T<+LT-vyBen{+G3S zZRA17!T$P27=lGFf&R-~*Aq!cG0m?5lBm7Wtj;ih>NPMXHIjfK2pKG~SH$(`^GEb( zju3rGkS7}A`vF+x1g_pov>=tvuusAh_?q~Fui;pk@f)_jQ$+%|x-0lqDI!aH#IgMD`q5oJe)zmOHow`{x zTO6umFo*BD*S=mmBKP(+)jhAR4{vz@*m%cfp1pLtsQhVIr9}Hq&9jJa(LHd#CYZ8JIwL2h`5s{ z_bciiE9frl%}50SWS+P^w~_gJq7(;4>UN`Roe@`jA;4)(ng+>(Iy8m9rdezVh5BHy zLkCgF?aJ~~$`sO_*8z_fY3gZw_W_a`cIj979B)u(dvy=&IU z(AE6{yf}*ay7#@eBYXIYUp2;k@+?Y|u-3Y(_Q6oHz%x-s+y;5G?RA!DQ%wm*z+}rn z=(&uFAuG(pR?+8SnwL{9&7Az#3$zA%CT+;V{@5{bGiv4Bjw^-%xgh%~GNTLQp_KdJ z3C2$$(NHfKo#gyF@;T2za%3=-)Xj{Bn{bBC$}^ByASIfZ~o^ zLuvJ7>6w^EJ%ncVgawDJZ>s~kxUF)NIM z>J0SxCh~xdjJV7>P+r1`OpuQ(0_sjw1+E1A~e%%Z>c@@^h+qzO0gZiX*-P5 zEi#QS!0)i7llGF7ICwWJ_4x?Z32dBWo)+E&*OVy`OdJnrY^AL|098Nrg{d$;_>m4P zYPS8u^QW35ueyw=A#yfpSv(%`vCCL^_40{ozPKUOl@z|1XRD(10#yo&f#QPO6o7!vP%eUdr>)S>nt3Qb> zwGJ?A&vlr>3VS8uW||#+ZH^QAV?)` zbi_SKG%Sa-U+{m^FUEm+x5;F;Sw^mTLVa~eJ!q9MHJ40hg*j0N(f#K z&8Ck;gzac_Zwie3Me6nx_~~+-Rpq6jrdtKnkMq1&p z8z$h*r!Xi^$Bn0Yy^+2v()MTGY8vpHt#kWROnX-73fM|N-(pSFsRx|4L1dx$&PwtC zErdNj;HwGXNgrbEHk?Uff`nTXkZ1d43>~KGl3wX7Lpu&?HBp7a?u;`xrw-5V$}q z#Ai*s>kO+We=3LiwmE@-?^HN3h$Fm_ZgX6+ju~vFs-|keG#7TjlC>eU;7A3Vgck~; zY9On+D==*b!%%|WSoV2jJ=9a(VaN4{k1zvp=wQ!}AwTb3Ju{6sbHNwhVRxy)vi?pI{~j`7`OhJf|E>xDH|~|0?O#gbUu*tb6&>5> zFv|bnUbWUgxmP&f?rvePdVlTt=Aw(^^kT6{gw+)?FZ0)}HSRLtP3}gYX7JwkN2TI3 z9?A=e5Ywdyk+|Qo@hH?0h3290GJV65%d-i~yN3YeiLzPkxCB@Li)A#ig(Wp7Ad_yS z-JCy`+i7~);rI3)x~yzVzO;o&7dO9`$M1~8@fd|~cuTbeN)w6@w<@F-qx4#p-*UdG z9?!Xgw3oyf34R8|7L;M|?Ou;1QB0OE*IeCNXns)=R=H3HV9|)3fb)r1NHqe$k{tna z+^v3Ebf1Hroc}f0X%FT~o`mfogl&m`p`zTYn`u9x>FoT#8}6|OX}B4i6FB0m5 zRKS;FuVaIg@_LhaMot%Xd7c2J-hDoNC7Tm5eh)AtY!3WA4h@a{`_q#;&8cFV5)Anu zCsn~FvOeWOx#4tgr7HDj&$LFd#%$$1x_Rr8BjZNu6bF*v@QLYXg&k2T{PiaxqA>~y zR|o&6Y>Os~o0n4UZZl=QnS5@Wi2MBx?($KTH8_M@78eBJ)l3YT+?J2QXHGqN)^Z<& z-c8H`v*CL^=@4gT6xWkA22%VWTFL+=a#!ls?yb1&l-f~eKERx%9GpqMf8!Uk4u*6L zj(~3=WF7Sw!+dEbcXx@zWbsTrvY4$Ap~L8F1L2J%FQ|UEPRtb~{v$M?&VoZrOW!yPSYWT0e3b;YtBm6` zL_Qr|)$r#PrxhVuZL#J7J57ZXFO28qO<`1#czP(60?j8ngNKGgzj8HAUI-D8P~E+{p94044^ zh66cA2=&|(_|!WH$MDVmM?;BaVN+n(46o-LK9ji7xx%7A$91zmjvCTn9^l3Sz}wg1 z7qwAC?5vULizPOB-V&6{k^Wfscnd!;6J$4l>D`|noipKp-a!Ox$%}1G9ke|iyACS~ zLN4#fw_z8y_;%FzI&Gzj*@*+cP+DGM&kD3Uy+z%p=@`yLSmhX`NSsJIjI`4J;ywur zm_&+*UmfmD7j(&*RcJMbb4JB&zg=xq*+NWYZ_&fDO(DTlOa z0W9^EY##1{&Zq}D?@;Akx3vz@rXyjR>aO8a z<#H57kMl1!0-AX0q=$v(EXa+*hAb$zb)p__;YcQlE1VWFEHWX{Hp7>!f>VcbGay6x z&!B~MNb%$zPjI(7r;y(p(A6Qne9X##<|#pExd1E|>ptOItFQ$$ONh3J%@=$4whs`q z406K1(G-@yCsbJeb3)~BG==?Ng&?r}wdTL2DIBc-WEr4oV~5K9=a%rtqs`+0PWP%; zSb}uAuu@*WTx$Z58u4;S(hbNm*g$tT_TbFqhHoQ<$U-zR7ef)s{sH%bU*hn{n5D}o_lZ^wwV`=i!4czLrk_UxCv zz`GS3j&x=EMYjQKEadn!UjsQJu&Yq8$`wb-Wvg>B?Ks*_S1V~Zb+EMZBn>sBSCi2j zOuKS@Xeffm9Y52FUu$A-WDB2wAKtE@k~_?Vw>9$&Van1J0iNAS0SOH94J8$+>^KV; z4HILN`{mkZ(uD@N=gCeDpr=b!50REX#tUUMvLXdP0hRZ+-!v251XY|ai{qoLmv8Eq zcgD&61N-@z&cEPoz*Ruxh*BE|^<<|AtHzE|=xa~d{NpRPzE$|Nz`Wr0Qk`Cx zzqIIhc+uGB*H3fwBbp}DTFlbkym~iKcz6UK&D@99*{Wh>JbO9LMDVM!A6sJ>bG6kw zqJwY({yJbc~f!oIUi?#pt~OhH`!#pvXp&byNNc#Tr7h2^5m# zy%GEjk~qlYwK-BhxnMG}!9-A(8z?N~nDS#IpQbVR`Nj*SAh9*~p{yV^b#vVV8i_Gd zlz4}B&?7LFctx*?Xb213BN|iW3=$r8f%3NT28FEoB0%pll+uAG>U4P$_z@WLoa%*r z4foHeTlAWr1YvWbhFIYiVf1ESY`x*#H*~2BpwjEJzt8_uy((=Jbv4!4| zCRx?=UR`p*Y}}$9VR13sfx5>MO|4U@ff>)K>P>L&d3)90`own)CxXn6Nl@doPfDc9|~B z?adfmqIw7J*0DBDLB=tX<@ka(5v-sQ-2fw=p5!+9LtExx3u;p&WzX z!;o!fbEKljlODHgW+^~-|^$L!HH!ytRua~(TQJ!X+?E@?IrI-V`H+1E2wOp~D zB@Rs@M9MZG@zU7CD1O9Y4MZc(VkyZe^5%tw2JHyUNVJR0J>WLD6UA;+g3y#WUw4z& zGOdt07B}nayCx=HD0w~p(Tte~XAQqklBnX1 zaC}Gq^R;R2j(>(X>+CbPiYiVz;7b6wdnR}LJili+6*5SMB0izZ>njn&f)^W2!? z0#})MU6TBEw0cjQOk4E=y@l9}89*9DB_Z_VCk*w9`)mu+YNA9v1tS$hY#=7&HYxU9>qeGYtp3@v>Zt$pAcOMDtFJ{mm$2BynnrY5?+Ua}Y}wpn?l>oGy5xJa;wS22@~(d~-^=0m*YV`5V>_eXv$-<+N(Xr?-fCC!v}d})8Se~6u> zn^1>Eu)LB`wWSKYPm5>UO|EQ?{0Xl1rG8_J=>`V$6_yc4t`Q4Og0Lw)vnjHB>yfKX zK4~iP5L*g9iNq;HKChurTMDGwQK}8F)=Ptd;Hio0UWED;D>$>KtdKgasu>RfuWk!26%&7AYh$ZCWS{0RB?OOU9pXulbvo2d>G<+E$S5V|HU`91Izb ztj(N9jx?>Xz$HU_HPF3M(ZEoNy7JYNkdK~FHec?4PuvJRk z6elY1yRVSu^cTXfc90I&z>oYiI%hp1__piac0>G~Soqx$PzNi{3GB z+{DkCEh;gww-a$>_3Uu`p$Cx^ASuit>$sDi>>`6V_bHklb+HtIQn898zoTm-DR_c* zhnI1RFo;`hNpeb@aKVpJJ*o5Y0~+w9pnA8(Ee!farACvYFLPHlq$f3CCNT>Uw!tWM z5^;iff?!yi=2&wqQc->I59k*Iz zj~-%jVZfGgTTMNOV<)XbJbrm=9o#Ht$`ohPYi!_a425DCMl0rDpcEM@Z<#QaNyrpE zBU<0l##*Kd(4fAT!ioH1dMC;v_7*iq=0KI%t_OyNNqmuXBdmhu&$+(oAsrm0Lm<)B zBWMg2f%T&lDPCutRUC9T2iASJgpJE2=j@Sz^#$?6$rD}@Z6nANZLueU9Fquo8ygF( z7BfeZKad1_LOX7gTp@vWBdID_!EB8wIE|39=#a&!Np^)Lhh5C}>eAiz(HN-$4Ud*2 z*NC?bZ6k7lQkdR@7WS_dU++H>>oaz4O4Q#;qosR+!v$H08t?>Z85$ud0x8l-vy)u8K)`m~3I)3@+tVcHdcQo@X|4ryD zMuOiGv1adQqg_ja;`0;%9_`_cWFp)BgRpNk;53xtu`>F8oB64O?MV{6B}z78xKNy0 zQ(s|WzpD)n09htn7A|{|_Px;HNCI@C(;k?KiqC!X<#$p%d?}I6)w1cZn_UaOzz|m1 z2z!UmGbbH#CkiZV4qAx$Q}V2Fb7X7J#s_eoJa5k5?b&~iMX>zmSj6A#*FK@QtTxZ3 zeu;cMIvzCV97dC(J7%EyZ|?&7)3)RA03z3CUv`(r>g^aNvO5$%+pplpCa%}~PM=i| z>z}H}6!Y{f^!M>>@D_2mch}SPj!t?DTDpY|)6>E8e#PNO7^&GL;{+J|tY;cRvP1f1 zqfp;=b;7%er7lWi=LTxmb?Wf(sqB!nkEXKn#ryb-<+4C6m1-efU)Fc>SGdP zyeVaRk~yGhEu}BN2=1R;TR33{9Bn3Qbw3E#9Wg(dR>|f zq6E;+7nF>Wd+{*A#zNB=%B*>0-?|e50y%BjcGSjk-nw@E?(Co$9Q#3Bc<$XU2gLuO#_T_tPGMSpZ`K*zY=U!Kc-46WLQ|9tx|g{N}Ytxn?D>u3D9a|f5e?Nt(PWi?%! z6~2XiwOM&Szt@u%${fms`eoFn84`{q4vxeM&vtsZsi`&WzycjC&)vm#k;a%AnXy~7 zA6odFY%Xs2&?I)Y(otxuFD+JAdfh*_?w}mNBqUL-6px_VU4z%#44gROhN`|s=`=aY z$%EprbolWj#B1$kEWi+Q4wlQ7bMKB1w1{*wQf{IVhB7ULV9AW;5=}$?5aiS~0kG1C zQgP_l#F{TQ40}UqjN^*XdVOm=!Mg|I8v<=`IIV9CyPT{C#pkD#Y*H27;?Q$l58*Mo z4{$!Z)rm-55ls@Sg$zR&RGY}he9eR-E*u_%8ioOa53}=2>OmllDj5uO=P~kts03;P zah1u4Nxk?{>i~X7A+tP=Y8^pCA|)jyC#3b z`wOXmp$cT<=ifT!$cQ~(x$%*aFEN zxr!0%Dga0K_=vrzQuh z5j;Y|PX|0wmXQMhoYI6?ULgg3w1MRTb^cVYp)e?}2!Jt`?1*Am%_ZK!b)L zeG|Z=y}bQFWfumZsz5muR_cKltN0;m<`(qUZkd}wjF6#3%bwbjLdx5sq8(uBKxaag z6a%z=zf6+sfGm+7`|pw^w-AhL{LXN{Z=X_zK>b$f9|;{M3U6)C}x%OKh=JPg!U-v79j}v7aePr!s%<1gl#qFTE%FCt_1t;{;cJ~hF>;`=>}q4g zz*nczYZtxsCfXVP0ZPZxw`tvD;kbiE(vs%vwK6daU&=C>O-h?ka9j^G7ni{@5R z5qcX>%T39z+BWpl`Yzbtc;2V4JqQ8sT!(~(A536@-Gib*qI60SNT2_J1ZHWtiD6Ai zCE?uP!Lp`h40$ACThXT~3y##x&!UeO=$PGAa)j%9TrrviY@9N%3)4Z1ntFW=qU^_A^ z1^hT+R(>G4z*Gg2yxlP%FAUh5Ahhk)o|6bTDzR@!*LO|Fvr@>g@`MU20YtfGEK_m@ zl0zW$)csp)IHP`)&Z3~Exgodq$wrkBL|zaySYI1=6z!S-kp1+c4pP%2}yRviGaY&8(X@5o=QA!|<%D}}9t=s?}V&98@p?8NPX zs4gwUqy@(gzLze3QR{ONUEPVEN(L*|0a~4u92c%bi+4YxEbxV46KEEw!^=;(!xY7G60r zITNU%8RB|xE10YwB7R8|8y^t3BGfK_clh~xsOBH^=6_%i`+pvOSpHE4|26*I1%+D(JGBzeObcMk>zka{`B^_ zWYEB#>C;yNCU_k2aPe~D12%K{`RkBB{7YS*#pqVYGyuo8e&6%KMI6@D8g0o}ECk|} zgrPBC`YvkM%_=FYvEFz4@HF=eV^IED8r`BQ3@R9Cfg+$>_*?Gii1lv$q==aaEHR~{wRb0M?@rIky2=q69m*1x!%P_nPifmYbBlXo? z^k@GtFb`Bqs*z^PR_SC$;7P7AOGdtn{8-5z2K4Ai|K+mW;;=97*B&_t0C}$De607q zY3-todTd77%7*cA@{Jd=zw7$bGOou-^#%yIM7upj&|cg2O%E4oNme))%taO+6S%`R zRrS-PaJS-{OH1}pun^Hctb>JHMo~@_6j=m&=i2MZX|;CJYProuv)eqt)rPN#4|75Z z7(Fpk@f(Cf&a-W6*+u^`wF;7AL8QgxVJlj?D*g--zRU`Oazll!6`?Eq^A2bB&=*tH z;5NTayU&^P?pGEW^4v(jlqHR{K(xIy!v>^R79Lfu#5H{LvkVq*@B4o0)Q!&cU0UO_p`h(t*aNsu^M6c|yOx*$1Y zN!&1U_G%Pr2d7Bd*ot4kj8fW;0Tma1n!JWrE#w+4mT{_qmhcq<2dykIR~`sn)-;X5 zL6)c@A$VdV1!bx`5z+^qy(LI~x)D(JqJ9M;pyB!~&i(}=c*v3+LN{>a36e8f#9Fb5 zMWD<%_#UW-2tkvIHexseFIp*>@&I&e>8R+rJ&X~I5omy|=x@nA7^%QQ9Cw`IS)uT^ zgI4D4Nx1M@j85SWf6*EysM;?=Gx$ggG8FOkfxC1=!e8mg{_6>(5v<-${C;tk@X&17 zfW{iQv4lw7TR?a{mUNDfTX_Ezs!_l$NdLliS56y?_q6U^?OU- zwPKHhZN$<7Ipd&t`AI!2mJpbir-psz`4 zRDE8gQJ6dr-9JRX&Z3zq@3`=EBwA_rbt~nQ$ixk@9rfsm49_ddY?6a44y0U(H`QWv zb4e3tu=aC!@>^&x-_j!9u9~9bt78)QO~8DaQCL(Z6uK$6GH^f2D1zY9LX)AUd~Dae z)HjbMIUp2xKH53~_UfI;P$eFd>>XyKIc6i}-=&i-_shb|1W3_mVfQd`PZ8N&R+ZJ>itiJCbnMe zTGRF0_uvyso9+FG&B922-QU4rwmU0kkHjN^wkcicxk(EzEfpU=p?K1?dWjo)4%Ns+ znu7h?a3kCH{KLz1tT%befutNx$d=@q)O*Uw2>zo%ycnmi)G>C3QgH=(- zjG!r?_TeNx`poz4VddPpm6ZLg{ZBjFUFD{$xa7J;FP68V;8&DD9|a=H^_jCcB8A=M zAc{6R`3V;sH5)DJ?ij3K&mVk+3_&S;u-v~kUo?N8JM!<8S1Y235jF3KNp%rVr6 zuz#fCfdl)z0UWUJ?CYNu&x@bx^jZ3-d~@|rx|Z7pQGrF6J-576ye}g4Hqc$}i@Ru= z3aiG7mKVph`+5Qw#@o||rWtkHZ6XQ?I~x)~boQJzPtN&k+Fok4VasQ5=71iK+z>F* z`!3+m_~RlLMABYRSq1YfRxwhFL{2u?FR0mCrC@i4Evs0Q4O z3K3G{{AQDfCEb5@X__~CQBB7$_=W1L=}NPh3;L>2!j$rH0%&PL%Xbv$oEOVTVF)%m z(p3hmG4cx^%(8c`oV^Ac!uX0;0T!vDJ%~P9~D85g&CIIv1HlH zvTHDnIoj?INTx~32*p}LVQ-YyOhFh6KmXG0d9;pa+L8$%vqHd6gHh5P;2mhyuBv+Y zA^c(u5fe-Q&D|3oUpQnIXo?6Za2E+J43gwNnIiF#1CasQdDtUHlLyqcFMp;P3I_~4 zfF8jua(ks`I~(N80JBpTY49f)2ui?tPu+s&a|eF#rPxuK$m?^V58t-Icp-$cKgNe1 zh%Yg=-r?i?a3D@AoX*0A1W;;&C|v*^56=Kz00hr1bO|&JWMvi*D_mH=fT3BiCi6@x zG=*SZl7+R$t1zW`hr{zw`=Vk0j=C*o2vts7@x=pLBgnc+RotxJJ|pXGXO%$lR-6R7 z-Bi`~1^FAhrRQ=~6U}&*bh4IW-M-LBGI$oSI!Q9=0ME(O(YoVdL2)*xLip+xo&$AbcJ43^*1AC&IcX-ymCpnw6(_FOs0_e=+drW zPE@MCM4#(w%(I715%?})?d6xZHtWyLoAW#CUJ0Lz^b4*WKbSM}9rR67SQ6^;U>pnH zSNH&LjxD?&{nm8^KVW{?PJfgVN7c8_k6xbpdXIeE6};qNEF(SrMg?c+y9I6Y-D^)O z+NYDL_+XYX9)-!2p?SPC@kC7en07LON?;}X?e⁣I8h}|p+fAS#&|Y(> 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 diff --git a/lib/morpho-utils/lib/aave-v3-core/audits/27-01-2022_SigmaPrime_AaveV3.pdf b/lib/morpho-utils/lib/aave-v3-core/audits/27-01-2022_SigmaPrime_AaveV3.pdf deleted file mode 100644 index 2dd64ac4c312673180503a6c3d8008ca15e145e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 418139 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

    S{A`W zWVh7l+bbj~MdKkNPpXx2ir$p&ml_I{P8Ot)J531^wQ?+5(5VbMnl5P*@*GH!aAuSO zcqW@dr6ACGWkIJl_KdgeR#!w(c+nWt2S7Rw$fT6zwe|_oZKL_zb~dd z$CUDUf4g&b_L%=G8#ynJFSaJgYP~uQHvwnS(_!o)uu*fVR|{H5wE&G_dcC9bp^H`_ zDy|;oxg^_FRk2@Wvr36^jbD4A``TuhO?7Q|Oe)DjCm!#zoZMg*SWaW{O2JL{Lv~3w zF502poU50bn)KoMlU0Z`EGC6E0yK%T&)Is&DnStW0p+KmKEXN7a=8)qDzwRvdk8lI zhc9Sc3h-DI3C^&p-!1nD%A93|YN}h#8gG8`Jb90+*mG5K zpis^ww08A!!K4>53OeBk3LB^Sodx}%ayV4pIn)(z!#5+^@#AQ|s11l6-sahou9?e; zbiv0^^)DYPRjU*XI5jBznZLqL?ELdNH!h)HYqz;~gC^)($)#!(NKxiuxxIVxyHnGP z;!|fi{Y1Md#dHIIec=VDo%Tg^!+mwG>}jy(nw8j$FpZ z4w`9QCF5>xM#U)`$QNIF*M2L}96x|u>YxPYwKi;w;?Fn~>WwsmQyh&hfo`l2KoUmrrvS?CTj*iNz*)h3zH3vJhC=iF?Yt+6UDk zy^zf_s`VOibG}>l44QLdbt|r^cx72?5tG@|#JQv*9zNfWOCy@3;D>J96?gO(TIfip z>qxli{q4w3v`)X&gWBJiu#S$)3#fUcqsNz^Y&W7xS8j9nkh~ki$LfBR4Ix`XZ>Kid z25s|oZk{h02uG2rn2fNDjEtxZX{+ChC|egrnc24dCiR^sFEEbl*Az5d<;qrfcKcBo z^(hC`4@<-kKNx~~d55a~bcUd}r0)4=67aj2R#?02uzu83R?2z%Li)4+lyTAD9mL8qB(r%)=W%ZQq+jAc;FQVm!i{II< z95S7>9akn~%T_`U+Y4DPMXu97ZFg`y`NcB*@OX>My~_7>o~>uZa5s_<_5+#u9z4}E zokx5jS2#Jn5f+}ucnbQd0=__#i1n)febr_CaSivRjx4SQ$8(|Idp1 zV+#G(9RgNH#-AYQKga*muvxcp2X-L)Znm{?W|~WlWUjN_Xzp2Uw%u?e%lhXu{hsT* z?R&kYUDIA(@vLWUT&1tB&Ptiki4+@9SCt=GS`~{73rx#PE`V}kkY{3WAVF+lZ3>fD zVqR=oU>q;%Hv?VV5;dFs!B#8%u4@bsOG z#l7*V-WDAhOgy^`CUD!+p$vp00~2FwTe} zbGeBdV0I)2Am#-omf>%Au?S%5j2sYC1wK1I4nSaaZgUTRuU`dg69YI-rbbrW%qBn# z9Dq~>K+D>zFuM$!cVTA^gwVi-^35(j+S}KMb^?J=?^@g7%HZ$@&ZJTV)(Vt82^d8d zM+QgtE%Tj<(%bX+^_DuT|Lv@=Xii<>KY;Qb1o+JabVE=4MJ_+}cV|QS>K+h>xmO!3qb3k@!s<2KKStTfskVtl5g6;+`0{%}@kT#7@+17nr5^V_>Cp&>XpGIpV7=Z}Bmhq?{a#|Q>8GCMMH>k_FpaWz47yN?#meG{d_xL5f#i{uRwYWnTJ{4 z@l`nAsl!6Dn`EP*d0m*chh}sVYNZ}{RV5l#P8Rqg@fHi{@1oHQ7=kA1LDy9IM=q4P zFVT?9N}9cGTIA5$&kjLgBxz$LT}K-wMsc}Dd6r9PP_EU6BGL#Me)+%F>}hRLZ(fLkbEI+KRs;2LxGBz__z)rHuL zuJL6$6nPT6x17xXS@OZRXi z0UtXZKf&up0#Xz+dpQR{w5(X_jb~#CTCpmT#AkF3m9S%_FvwQXL=}m#a;H#&eoHu` z&h?*kL_im73Gae)1_ix`fnz%grL2D)SQ@r+ zcZ@{}K3vBri^7EyJ{~(N%-XTlp0#(h1SV*BoCFxV*s z3or-M!YpUJ>m5ilQsZ&cq_na=Q#Mk{DT(N-4}fTt(+Yv2y{GAWIl$}@%k(;XRXcDd zreeHvk3#s3z;KVD@kqCVFys*wRt*SQC|cHhPq}|I*i(W?c?AD3vU#gV??E#y)G3$o zvVNVZrXm3r(xJW!bu}t0FiP**cXXP`_<9_O&Te{jFn}D~YhN@F`m<-iU3(R@rZ*&&VVb_)o!tNpC2bJk~`YW{`I5~5{ZvyQ%dA64+ zU=d2Py}Xjt*RcnN>xE6bu(^xzn9cwh{?#gW7}%Z|wdz|2=;7nRo*5aOa$l~a*JAY>a@&aa30}#?w9+tMLKPBE*w2EDE->#_FMyhG{4sV0E1+mcIecr$cmP-h?YL1USbhPCPAkalt)xmq1I1gHEXEoKkh*&y02~2%vS}Eh z$IHkNwU@}gLLrFlpl)x~YPtnaU`{eJENB%GbppvJmfF(gIz|tb=Z6V-^es>O zBS6cVlTvzWtkevF8rjdhrdQ3mb|P*LchA$QXTT3tcUID*`rwuK#{=TaHkXI;+^z&J zMhT$S%MUKoqbgZL?OMwvf!tU^xjxoZb;@SvPYPU)a$G_)fsg=W_oDfMCC|M{z$u9n z$JdFND+kXM2D+&u*j{;?1x92 zFS4ir_!}{r?MiZ`dJe_k2sR4uQwele`cc&oETWM4Deb!B&_R& zPKV;qB<7^(eHso_xilz9qt&S%wqeA}kY+EzCLntQe=Gq)Q1q0BqU?_vZs7X~e9UrD?p>6hiWe)VjKKztj(h7v;vK}8`tQR3zMG^*ag5;TC;``H zcD7knt8z4Dn`TW`K1w$JmF&qo8aq57{k1nP2)6_c!?9kmTXu0+1NA%BPNk+Hb4a9ruvajbFr{dS6(G{;v9*&yC9s7*6x&!}nYXu;%BpvdI zCBEg!hO%f=#gB-4bfA8f$&Uij<_voet+lgE4W;uE*<&JH&FQUkxm|s5eVg5BIJ#D? zMtLxcn^i*{{)a2qw67jN9Rq04C2Q`YVU1_30-bcS0qV{K8}A3ylqG=zvU=WUIm8WkzpO71g*wJuZg&oF^)Evn3aUR{drx zUG-WRZ7f!a2*Q9&KM0~9yTBrpq&$}WsUG3qKkZC{5TtWPIK}Uyu2{7OYwwB^w;Vs5 z(hDkxFn@f90|Ce%bI$Vp;__-9!5JUWj=w;}zI!u{YuJFZfxf2%w{Bz07UgI&L}YlJ z#UcpE^d3ev#c1!O1UlVZxkAW1gJ377GoIksc`C(pQnIvUXUC{W6pdk}EB=aFoVVFa z81m2<1oC<s5emR`zc@?ywjZ29g&C1&kN}zU2%fF zvL7lR!n<0`gbfki*sz`F&oPlsn7S1{V-M;e8G`X_-g2b~LAYzk9Cie`QRnT~c~*SA z?s^L6wQPazZ#>(lCs#(w`wcA_1K=55*l4vQTc8e|Tsb%%-rJ-X%G_}+5&~q_4XR41 zGL$emY2Ii@0;Fb7o4F5$Ybg&J9qIA#rO#E6`?LPLSE2Cm-)FZIUCz0WQA-(nhi#f6 z;dEeJJrG6Ij3}na5zHyr43kI5<-JWrIv%QqMFq2r^t+PI$NazPT1DT8{6@D8Xo`<; zD~wjTZL6Wbo1N(q?o6ePwX2;8A7jg! z;)p_x$QLFU0g5yYP4$^stiA4Hq(FjZQq9azbloSA8uzRNcyZoqFy#TyGUGo5ZOX6h zKUfi|&`Y3O6}^LFyBU#u|MYN});kHUb@hvI(q_Y8G|sFqHyu5wt-sSEnQL3mWRR9h z_DO^JaM-H9LM9JH`M5cQ_fM%O1_WEtSoL5oE<#ACR+xh65&m3hmDjb%GAEX#d6m&B zZ$|cJlu^OsVDVQC1(%8D4M`jH7ZO9@gXLEtkA@~waXT!fdb8VA*G)z`ISdoZY!K)= z!8YN}g3%V#X?OYO-vLJ|ZxeJSrslzr6;b&rP{OI^0?by5kbV!B%y|_GtKa;ay=KYP zNrP)-&ajB$>_y4+If^$!veLbNaWC@1`0$y5K4N^%lRpf}h*=yK$Iam;0V0OL6IQ4D zq|#$8a}XzTkJ@~1NDNXF$sdx>VMC4LG*5`MFMPudPF@u~D}EDPfCsnyoTX%R?wF zZbB*{@T`I&oS9baq z8`6HfRu_<6wP*X5X(puL_|*ESyLFmsjPjF)_Ut}_=c;D|l!!jP8~i17$v5=J1LL|{ z!F^4zR7y^D;!NXYfh*`?;`wQ)^+y8LPtdqR{uL2M;j!|ws<9k#({n6mY&ksn*du&8C{dbyyt-&w41bPzcnSTo+jlDAVDJg?va@Yc zysVLL=3+9ZTI6LhfdirMs>w zq9@)fq{@!(PX2OoqTO~=)K&XLUG1AJda?+_!j2!Odm&U*JADu2M2x%n5?Q`z@@@D& zV&8l&x7FHTsU2a{Az{JnPBce9Ub$`C&5cxOPQ?Ra2=27TU9-Ct)WGb4}4k$I7d$*u(J zezEkv8+_z;SWkRdq=1R-Vz=7!ZoSdWr@1_31yD<<{?bucF3-SRKR*i%yrCJac+Sf>fDnaQD%AjQG)Pj{sNz$}Mnj_BA?aOCTlo z1T;;t9sa1?4WThU2a~` zr0&gGI$@yNy8S8}f4gPma@AS^EZoRU{6T-O2lu#=B-@G~D!&Atne$FoUn?t)Ah|~N z)&za0vSmcnhxf~LXKXFk9=|R+>XfI*yiKH%odMezn#YNAk9UW3} z`{Oefv8pKOT$bGZ_f}(RXyxf9V2IBB@)6CWw#}fY8}Byy)?&=BnNlAUB}MN{vnEL0 zG>wH~mK?e5M{9o@y2EceE9!A@!AM;9jj}FGs?Ekyx3I7(>b>ROMImK|oKV0u`YhqY zvRw*Tcq3itq<;w-SZBB9(8t1R@--;Mk{l7LjYohTISqav1 z--=!(_3PrlVIv~2f>92Xq>=p~_6N{@;@o`JZ1QWLKqC3OUw3?#7k5h45&26JrBhYM zq$lul<&N`5i-Y&IGZnFq{Ywh%hQX;5F>MMyU`x^pOxY0uNfz;T;-v~uJ zHd)nIu3s(&UfAL$lUD-pU=T8oW6nV_9u!>Sr()tAzhq~-`cz7Kz#R2@h13R!AYUC( zpY4SA6=yB)Y!f89HsN7^UdbuyIxX%bj;{byK~Z+VmV{*g2^)7fZnlH!{*-fryC|38 z8jP>g8N>`rr@(5F6bW1HkAgasys8?OuiO*NMIEPPqm~c74W_A1YCM_%G(6u5(w3j8 z13wnEXP;poJL49EN((N(GpJHgD*-!K?(HTkwM)8EyUh*fDO2%QC){rE^nN+wl!e5LsGz<6w9~5hUOey`n`aL zGS~T8yW?k$-X-R_b`m5By&Nqb@(&wrqgc~_-ZD!KO;rKp~8Ah#eQF}B#G=|+H=VPOc-m0;MWdGa{a%PV$6 zrH`g&H+Df6j*Tw5>1C(7G)qoJr4bWe>(AjUGw3zCLr9sXLh`uFuwPfeN#k@3!v!>k zYM2-Uf33X5aD^ax<4k!xlb~Z~qh0un`w(pX8!(xHv2Hsz3or0=>lBMU#E>G~ezxsM zDMat5MkBKVY83||eBNAJSeyHLSAsXZT~i_=%&GUvCZ<(k#MTYk-?p6T*T2<1Pe2rX z&DMXO!|`GvquP~_R|BeI1G650%^hx;lHY_Pi{ zyDaPbxR6zc*psY&D<|JE9LU2!V_hcH=9k8j`J|OI)C6vU*m+NQcuTT%jMIgEF0r) z>8gjWj=4F(W`XF5q9Zwn&c=)bg7Bfx2_1)>H}5+Yr6ZYB>sK1wW>Gw}-+l`gP)tO# zBITab6qO!lLKr{aY^;v`^{?=4?Z=3)E+)ljy{TH}nG5F3P2&!AZ59_6#`@ZhD#(Va z)R7LI^iHm26yHno_K`$iP@Rhq4=tL=xqO-Ue#FP?wv*JCo1Zg&AIEG$Na@H}ea|x? zFwUTsq)Lfp8<;%RI~1ZvOPIH^MCKy74!+QQu7Vf|>flcBRFFRPk9KUMHnp<5v~J+M z4!%u!`LbiX9-I$P#8UA@;l16O{Xh(xpVGLBrLUz#AUmD7L`__ zAF{fn-EqHYf6pw`p0DH{J$pq$Pcy|y{rng_W?{~OMfJjO`e;iA-?rFGh-_O#5mUH7 zFK`gP+HCG9+e99K3-rMr^YCa61^1nzXkGsLkT#a*S4LRTp-ZQ(--mn?Fo($|nnG>y zrwuR1QDe!t-hTkZ%#kK0zkWP-TPRGTd@(S2yxg<+RFPm9=tw4RD8RjJp0a?-iXT+u zHw2=eAv7uceis>2`xRxbi^YWQ>9+7x=7ExNAe_w;G4rlAU=JU@plx0Dk=ci5C2{W_ z2@E^D4KnG2iwAo^cG?K|ospz*#tO$6Cf&;%F2a_Wuqj+ghR)m}i3^{^4_)%!b%nnhfxJ!UV@cHnC+)DKAG~l@5?^eW9zO-u+ zj296V3+6pUtqOsQ{#VmdG8l&7ZWyKuGx!)9Qs;7l^Wi{G3JGaTOG>>w%l+i3Ok%m3 z#>+q!Jfp|gLqWqYdcuWVAZR`uPMzOqVz-nhNyQBE`hKLF@G|8VS1X#@9Z}vKS+4lI zGw$;Q8WNPx?ALDu?4L<(4l;||LBzGmyg7-KBM%0tq1da_iq=lFQUOnuo&tQu3!Ebu zV-kf>n(l_#97xY07WXYxDOJCA38nFvaQR{D3N(Z_x2Y{g3$2Sr%H9c*+FY2P=ibt*_t0o^$tpJa}hvuhO&=)SV`>( zc22&KX61tp(s>|9C^doYVzQ&aPh9>@2N3wlLs}3Vn}m19M9%W;wOPRPSAQR~VCGS% zu9&DQ&8JU@{UrlmSC*Kjp1X6MEw$WqBlMSv7+9p?Lk$>>7MsLC83G+ZjByxr60I7r z_N{z;+*VuldA=HAbw%FxMOP={!j)-gxV65*GHTNN!xz!4g>z43cqgC+JD5Vb)T2^z zrNIK{0kb2;@11VM{+wKJvzK&FGCDgGcxPs9t^+f>^!7P=+klc>5WRaaIytP^TXssK zESTOK0cY@79+1#u(AN%k{ixN5IaFtG9b1+2iN~373$KatyDXpJcvXY|r?O8{TsHWM zGIe}z?j`t{A_I2Rz1T8_Dxp)x4ywT5{Dj)RZW)s+@RzbLVL;RrCeV6aV}` zPpP<|b(cXT(}JaSH>1%(SOHT?H`GF$bE8MY&FG((`t590O=GkMI{l>-PYt%m;O=Nb zI8#5Z9XRyZcQ4>i=Xn~MQDt{)hMmZ*QMfH;{t+7Sr9$3~*BMcu{Mog>nsxBjg+!rv z9!+_2r}#l1-$Qf>%^JSnUonA_#AKHi=HC4iXgzc5+?k@Z#LtuJobO#0Z@~t)+C$Y@ zC|}xv!lHK9xqf;*!m}kfBK%^9u&R<6*!w+;(wGxU0{sogk;1u>BRIp|sIE~RxlDIY zGMlwbOdw%Dizb8Z&$iD>s^)>-nrLDd(I71o>vdoH$DDc}Hy-MmEK3Io_j?2)rs-bn zwZTMi@FO17Oi(Kpy>=;W^Kr(6rWLzu5w%R# zZ%g*%+H1pMdH|TU$j_moQ)dj}c!@1KZPxZr_&ln;4aP90kO>E$uuf=;5$<=|`g!W~ z>{$6s1Rf83%62NA#BIyFSK`Yj3X83pk3twz=Ba{l$aE?_cW*#Ol6N_&*X?x)I|Lw1 zB3kl3Aoy2BRTah)mY(Hz&UN2M^vf(V2+^!1mnAWxDio#4s&qJU2{k6{Qmz1`(vwx1 zYeq*`T)vPJp(J0HoINl}@d$zYYh*HN6zHo+pK!Vo5i5ub7>FB>{f5R3%@xf08k6DZj&RfDReHWHe2iyI?CjkeF zR)) z(=-@oa%d)y#&|yj=Clz-3V~OZxcBap29d5d$_58VnWmUl&9d6K>iu3TW5a_e5`L4s zB&-u1PyTw?VEEy#al{0Q<6#u@hl;wdzspy*N}p1gh%O&Jf1xfpNSWUeGKnGTtW%Ku zHK6b29DM(J*sq+b?OCUTu_PQ!(J$8Gl3ZJd;C!I2^hV8ia7`-P4atDyj10I7%^wOK z({TH{^J4bWvcN@KjxlVSPxtpS<~B7U#APK@o;QrGaatLeS_kk4Htmd?eVFD?wn0sM zHNmbxA{nLgjk{xi70y*EpRJLGQ`Y@s3Ml;_qi<%&@sWq0?EX$NXD~N<=)BSOs!$GX zVi@5N#1OiCObJPmov(`5P)Ed39Qi6F`tVD!nTqPN%#1&T$tg)8Xq204ZrpA+;KJ<0 zh|7yI)T}azkd6sAJxWHpg`3RCIQFGE^x8>7qbX$LO*jm-+{sFxPZ!XTIK30t=a$eD zx-yXjHGZr^egO7IhH?NKV#u&UCE8L}rHuDmk?E}4QXc}qBY0G#z3AHKCv*K7@L21L z0bYI~i}cssc|=lH;s^uf36RQequnj^p)$65YU$QhV1qflu}`FMZuz2V%ZEM>XUjzF z^nBlpI}tGU^?O1I!QDh9UAENj?9`ggg{E|_FQNajKTads;2J2+%8jhID0h45Wipz; zZJdG_>W|FXgX`kOjScQ(q7##1!PS4d>iAc==FulYyV6gmnmY>C2UdwY;Nn|eWZ)}S zpea9ulr(7DCjZ(@)8Wm=RDWZ0a&g6bH#G;XOcAk>i=!dMOSd(s?)^0RavG6mX=*-& zTj1B}R}=Y&Wban=lj!#F`S!2BSwyg36%u_CMY>mH86w}CTM?#;1{ZF z7cx}FSD}{OzjV8}{c=vBP(pBHs>GZot0F4nKP8Z?$Qw{6dIKI@1ASm9H#hG8nr*I1 zZ$~?t&S-ka{GPl?-wcB1{W)QVaZL0RZwV5ipV$rkWHwz`lu{cT$pixcL-hC8 zQ3E*^`nG$(sY7UDL>5hDezS5=S+`%TRf=odXGDa?U(MDKmj2z=bn&iS#uI1=e3mIO zatjImxX;g+C*dG6)d=3vjhv_3-Rc0BgW_VMR1Mfjon@lh=y@1Gtj%|{TC9+8M$6mU z_qr`hDr-sXA2(YLLDS(^tlN)F4oc8+lQMKd3qjhMVD@z$M|COErO!>_Kx;>WgayVInu|*>x4DM!s zKl|(QQqAgwhG}Xv3H2g8`e{4xHNZ$XuZ}#KNJ5^X4f0W(&d^XL&_ZtmWkREizfUYsI z%00bHlGv=VwBZXKq;z8F3S%|L{1y!rC0&v>1|3qMGGD_rr^?xmKUzRIg!+_p)~Kt1 z*uSz(59LxF_m2a4m)%TwA~Us{Z3d20Kz(S!Zd?cMIH=~4inQU)ng?<9=f`V z@o*`=|LRygBJ)wDFhZ_lG+T?(j<4!#G1Q@RAvLn6z#Dlna7}xQE$gj_87s*6o$cfq zMkSSMQYybQ_=pzjZ@=u1;J@xtr*FuIYOYCOy+K7uKTt2(3^vvls z$S&Le_CvZzW{L`_`^4%l+-=^?|3Pgxz9V-{iF(L=qQt#n*SYONx60e)MJZ~;rQE38 zncN|Qhlu`r-2AOY-)a`0A+WPt9di$J_vgdZ4RG|cdsc*#HI9!DmtT(zr7C+Z*{7}y z`AC~vc4>8;GBcyFvqSHUvvu83=B`ZoB3u1u-+}A>bQP9z!yS3_fcpmLC$Qe-_{E1) zar83KF)-<8g)RD23Pc30+Vs#g^xnI;l$E{OQ>dI(mK!gt~KR1rtS)B({=;9;rY8eeMm122R_n+ z@`Q7Oj`F<_w^8`{gbt@OO1uMZ$uLW%F^wM0QQ+`dTv`6K>5GjWtnX4zF%#^{=H%`ghZDk)t~lNS%8yMIF^rI#r!d z9E&~&cfj^nWQ$$IBNrN>*`DEw@HNB3B+|G$FZ*#VI!c%4jAzgWnGGQ1v`&ZsKMy zJvJGC?+vdB@um(t_ZE#o8ymh3qe3e%@Tod&ds#d>VawBRtUt^!=0_H8N(9(P9;$dx zDwrCf_L3jFlb?HHB_992Z>Cy&+^uT`zPx?w0LNm3?LSW=|5Z1?+ZRYm8;x*&qW>`a(hNgZ;J-PPy!JF~wdiS`Hz|MU(Ah!D1E z5=c9VwDbgqzmnL)lwDs$^a4RXD`@HPG4P0F9KPoX{>E)bCgk|p#LL?p6Q!f@q=8{G z3<`YPf9utUiASn2!v!!Z=tSkzDaEEV#H`58!ay@6?BkQjx3rDlP4LF7daD~nLk-+@ zCG4yE@s{2M0UV{|^AW#si3v1f^fd{uca;+zZhusW6R|aK8pQK3%n)cK@itu!f&(-^ z?sPE4pm&!_RzqW{!-Uh&4e%DbVAi4hN9^0pL6PS%gMlzSoa1cq$R?J2rn{gJ_iq%7 zh?&+NO}{I>z43`^vSeC8ZuY5iO>&#X+r}_=Ho1YHe{ygc0uj0bP_wAQ_~L<8ZJu?n zc@;#k~5%-{8rFwexMG znV>uxmzNpxbr~EQ0AVTDgd)=b$(|o8yFcH*Bm$n?u^mZ^rW3|3y{ENUWvi!>JwY(( z_gm@vR^dWL-Q+YM0_}*xwZK#Fp;=m5rbQ^9rWzCcjojJ4gL#U?_c6(z=)`i;1R@Yk zA{;FP)Af(8gtU8MLRk?1HXavnh%Ku{A`hiF@J1=#L;A(vSWL5BkFQ-q-&;SI@h0coPr)h{S7~ zUeTqCbHE;){T8RL4L zFO!UrDi%D}znPhMa^DL4sZ6NjD`0M>b}Y@$VY)>eE0o@?amMMq+#oK@$N<4O0%!V; zdJ=-asT<{K|draPpL0pPxF&$%hw@f@7Uc4Q1MgIuFf$D%_NnyC_kPXRngGRCW+}HZk}tdYF-?bPq$pmNQ7G7 zHuTROewrtEpPHovo05zqgHVf^YtMJ zgsnHDm);ojqmC}D9T0JAIF|jbksBH{Hcmc~PSWC8kkS>LrJ->FG+@$^L}?UxVdD$U z2quatylGXRbl5d7>iwVNqmYZ1BCvD?Ywx6XZi~g)>et}JC{oqhpoj5(WcU)N@voNJ z6cexG?iN;KdIOiQo~)!I4Ed*or4**UyVv#5B�o_)Ee&^dgZ`yJ3YDW{P#cH^w&z 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

    naA`Gu7NZjB$y; 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ⅈQq#CZQsj0tHu=AV1Z-d_A|`QhG`G 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�AZHude4 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 - // solhint-disable-next-line no-inline-assembly - assembly { - /// @dev Revert with an ABI encoded Solidity error with a message - /// that fits into 32-bytes. - /// - /// An ABI encoded Solidity error has the following memory layout: - /// - /// ------------+---------------------------------- - /// byte range | value - /// ------------+---------------------------------- - /// 0x00..0x04 | selector("Error(string)") - /// 0x04..0x24 | string offset (always 0x20) - /// 0x24..0x44 | string length - /// 0x44..0x64 | string value, padded to 32-bytes - function revertWithMessage(length, message) { - mstore(0x00, '\x08\xc3\x79\xa0') - mstore(0x04, 0x20) - mstore(0x24, length) - mstore(0x44, message) - revert(0x00, 0x64) - } - - switch returndatasize() - // Non-standard ERC20 transfer without return. - case 0 { - // NOTE: When the return data size is 0, verify that there - // is code at the address. This is done in order to maintain - // compatibility with Solidity calling conventions. - // - if iszero(extcodesize(token)) { - revertWithMessage(20, 'GPv2: not a contract') - } - - success := 1 - } - // Standard ERC20 transfer returning boolean success value. - case 32 { - returndatacopy(0, 0, returndatasize()) - - // NOTE: For ABI encoding v1, any non-zero value is accepted - // as `true` for a boolean. In order to stay compatible with - // OpenZeppelin's `SafeERC20` library which is known to work - // with the existing ERC20 implementation we care about, - // make sure we return success for any non-zero return value - // from the `transfer*` call. - success := iszero(iszero(mload(0))) - } - default { - revertWithMessage(31, 'GPv2: malformed transfer result') - } - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/AccessControl.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/AccessControl.sol deleted file mode 100644 index d7834c7..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/AccessControl.sol +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.10; - -import './IAccessControl.sol'; -import './Context.sol'; -import './Strings.sol'; -import './ERC165.sol'; - -/** - * @dev Contract module that allows children to implement role-based access - * control mechanisms. This is a lightweight version that doesn't allow enumerating role - * members except through off-chain means by accessing the contract event logs. Some - * applications may benefit from on-chain enumerability, for those cases see - * {AccessControlEnumerable}. - * - * Roles are referred to by their `bytes32` identifier. These should be exposed - * in the external API and be unique. The best way to achieve this is by - * using `public constant` hash digests: - * - * ``` - * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); - * ``` - * - * Roles can be used to represent a set of permissions. To restrict access to a - * function call, use {hasRole}: - * - * ``` - * function foo() public { - * require(hasRole(MY_ROLE, msg.sender)); - * ... - * } - * ``` - * - * Roles can be granted and revoked dynamically via the {grantRole} and - * {revokeRole} functions. Each role has an associated admin role, and only - * accounts that have a role's admin role can call {grantRole} and {revokeRole}. - * - * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means - * that only accounts with this role will be able to grant or revoke other - * roles. More complex role relationships can be created by using - * {_setRoleAdmin}. - * - * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to - * grant and revoke this role. Extra precautions should be taken to secure - * accounts that have been granted it. - */ -abstract contract AccessControl is Context, IAccessControl, ERC165 { - struct RoleData { - mapping(address => bool) members; - bytes32 adminRole; - } - - mapping(bytes32 => RoleData) private _roles; - - bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; - - /** - * @dev Modifier that checks that an account has a specific role. Reverts - * with a standardized message including the required role. - * - * The format of the revert reason is given by the following regular expression: - * - * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ - * - * _Available since v4.1._ - */ - modifier onlyRole(bytes32 role) { - _checkRole(role, _msgSender()); - _; - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Returns `true` if `account` has been granted `role`. - */ - function hasRole(bytes32 role, address account) public view override returns (bool) { - return _roles[role].members[account]; - } - - /** - * @dev Revert with a standard message if `account` is missing `role`. - * - * The format of the revert reason is given by the following regular expression: - * - * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ - */ - function _checkRole(bytes32 role, address account) internal view { - if (!hasRole(role, account)) { - revert( - string( - abi.encodePacked( - 'AccessControl: account ', - Strings.toHexString(uint160(account), 20), - ' is missing role ', - Strings.toHexString(uint256(role), 32) - ) - ) - ); - } - } - - /** - * @dev Returns the admin role that controls `role`. See {grantRole} and - * {revokeRole}. - * - * To change a role's admin, use {_setRoleAdmin}. - */ - function getRoleAdmin(bytes32 role) public view override returns (bytes32) { - return _roles[role].adminRole; - } - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function grantRole(bytes32 role, address account) - public - virtual - override - onlyRole(getRoleAdmin(role)) - { - _grantRole(role, account); - } - - /** - * @dev Revokes `role` from `account`. - * - * If `account` had been granted `role`, emits a {RoleRevoked} event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function revokeRole(bytes32 role, address account) - public - virtual - override - onlyRole(getRoleAdmin(role)) - { - _revokeRole(role, account); - } - - /** - * @dev Revokes `role` from the calling account. - * - * Roles are often managed via {grantRole} and {revokeRole}: this function's - * purpose is to provide a mechanism for accounts to lose their privileges - * if they are compromised (such as when a trusted device is misplaced). - * - * If the calling account had been granted `role`, emits a {RoleRevoked} - * event. - * - * Requirements: - * - * - the caller must be `account`. - */ - function renounceRole(bytes32 role, address account) public virtual override { - require(account == _msgSender(), 'AccessControl: can only renounce roles for self'); - - _revokeRole(role, account); - } - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. Note that unlike {grantRole}, this function doesn't perform any - * checks on the calling account. - * - * [WARNING] - * ==== - * This function should only be called from the constructor when setting - * up the initial roles for the system. - * - * Using this function in any other way is effectively circumventing the admin - * system imposed by {AccessControl}. - * ==== - */ - function _setupRole(bytes32 role, address account) internal virtual { - _grantRole(role, account); - } - - /** - * @dev Sets `adminRole` as ``role``'s admin role. - * - * Emits a {RoleAdminChanged} event. - */ - function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { - bytes32 previousAdminRole = getRoleAdmin(role); - _roles[role].adminRole = adminRole; - emit RoleAdminChanged(role, previousAdminRole, adminRole); - } - - function _grantRole(bytes32 role, address account) private { - if (!hasRole(role, account)) { - _roles[role].members[account] = true; - emit RoleGranted(role, account, _msgSender()); - } - } - - function _revokeRole(bytes32 role, address account) private { - if (hasRole(role, account)) { - _roles[role].members[account] = false; - emit RoleRevoked(role, account, _msgSender()); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Address.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Address.sol deleted file mode 100644 index c6dcfda..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Address.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -/** - * @dev Collection of functions related to the address type - */ -library Address { - /** - * @dev Returns true if `account` is a contract. - * - * [IMPORTANT] - * ==== - * It is unsafe to assume that an address for which this function returns - * false is an externally-owned account (EOA) and not a contract. - * - * Among others, `isContract` will return false for the following - * types of addresses: - * - * - an externally-owned account - * - a contract in construction - * - an address where a contract will be created - * - an address where a contract lived, but was destroyed - * ==== - */ - function isContract(address account) internal view returns (bool) { - // According to EIP-1052, 0x0 is the value returned for not-yet created accounts - // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned - // for accounts without code, i.e. `keccak256('')` - bytes32 codehash; - bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; - // solhint-disable-next-line no-inline-assembly - assembly { - codehash := extcodehash(account) - } - return (codehash != accountHash && codehash != 0x0); - } - - /** - * @dev Replacement for Solidity's `transfer`: sends `amount` wei to - * `recipient`, forwarding all available gas and reverting on errors. - * - * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost - * of certain opcodes, possibly making contracts go over the 2300 gas limit - * imposed by `transfer`, making them unable to receive funds via - * `transfer`. {sendValue} removes this limitation. - * - * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. - * - * IMPORTANT: because control is transferred to `recipient`, care must be - * taken to not create reentrancy vulnerabilities. Consider using - * {ReentrancyGuard} or the - * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. - */ - function sendValue(address payable recipient, uint256 amount) internal { - require(address(this).balance >= amount, 'Address: insufficient balance'); - - // solhint-disable-next-line avoid-low-level-calls, avoid-call-value - (bool success, ) = recipient.call{value: amount}(''); - require(success, 'Address: unable to send value, recipient may have reverted'); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Context.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Context.sol deleted file mode 100644 index 445ee64..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Context.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.10; - -/* - * @dev Provides information about the current execution context, including the - * sender of the transaction and its data. While these are generally available - * via msg.sender and msg.data, they should not be accessed in such a direct - * manner, since when dealing with GSN meta-transactions the account sending and - * paying for execution may not be the actual sender (as far as an application - * is concerned). - * - * This contract is only required for intermediate, library-like contracts. - */ -abstract contract Context { - function _msgSender() internal view virtual returns (address payable) { - return payable(msg.sender); - } - - function _msgData() internal view virtual returns (bytes memory) { - this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 - return msg.data; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC165.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC165.sol deleted file mode 100644 index 15336e7..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC165.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.10; - -import './IERC165.sol'; - -/** - * @dev Implementation of the {IERC165} interface. - * - * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check - * for the additional interface id that will be supported. For example: - * - * ```solidity - * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); - * } - * ``` - * - * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. - */ -abstract contract ERC165 is IERC165 { - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IERC165).interfaceId; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC20.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC20.sol deleted file mode 100644 index e794581..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/ERC20.sol +++ /dev/null @@ -1,344 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.10; - -import './Context.sol'; -import './IERC20.sol'; -import './SafeMath.sol'; -import './Address.sol'; - -/** - * @dev Implementation of the {IERC20} interface. - * - * This implementation is agnostic to the way tokens are created. This means - * that a supply mechanism has to be added in a derived contract using {_mint}. - * For a generic mechanism see {ERC20PresetMinterPauser}. - * - * TIP: For a detailed writeup see our guide - * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How - * to implement supply mechanisms]. - * - * We have followed general OpenZeppelin guidelines: functions revert instead - * of returning `false` on failure. This behavior is nonetheless conventional - * and does not conflict with the expectations of ERC20 applications. - * - * Additionally, an {Approval} event is emitted on calls to {transferFrom}. - * This allows applications to reconstruct the allowance for all accounts just - * by listening to said events. Other implementations of the EIP may not emit - * these events, as it isn't required by the specification. - * - * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} - * functions have been added to mitigate the well-known issues around setting - * allowances. See {IERC20-approve}. - */ -contract ERC20 is Context, IERC20 { - using SafeMath for uint256; - using Address for address; - - mapping(address => uint256) private _balances; - - mapping(address => mapping(address => uint256)) private _allowances; - - uint256 private _totalSupply; - - string private _name; - string private _symbol; - uint8 private _decimals; - - /** - * @dev Sets the values for {name} and {symbol}, initializes {decimals} with - * a default value of 18. - * - * To select a different value for {decimals}, use {_setupDecimals}. - * - * All three of these values are immutable: they can only be set once during - * construction. - */ - constructor(string memory name, string memory symbol) { - _name = name; - _symbol = symbol; - _decimals = 18; - } - - /** - * @dev Returns the name of the token. - */ - function name() public view returns (string memory) { - return _name; - } - - /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() public view returns (string memory) { - return _symbol; - } - - /** - * @dev Returns the number of decimals used to get its user representation. - * For example, if `decimals` equals `2`, a balance of `505` tokens should - * be displayed to a user as `5,05` (`505 / 10 ** 2`). - * - * Tokens usually opt for a value of 18, imitating the relationship between - * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is - * called. - * - * NOTE: This information is only used for _display_ purposes: it in - * no way affects any of the arithmetic of the contract, including - * {IERC20-balanceOf} and {IERC20-transfer}. - */ - function decimals() public view returns (uint8) { - return _decimals; - } - - /** - * @dev See {IERC20-totalSupply}. - */ - function totalSupply() public view override returns (uint256) { - return _totalSupply; - } - - /** - * @dev See {IERC20-balanceOf}. - */ - function balanceOf(address account) public view override returns (uint256) { - return _balances[account]; - } - - /** - * @dev See {IERC20-transfer}. - * - * Requirements: - * - * - `recipient` cannot be the zero address. - * - the caller must have a balance of at least `amount`. - */ - function transfer(address recipient, uint256 amount) public virtual override returns (bool) { - _transfer(_msgSender(), recipient, amount); - return true; - } - - /** - * @dev See {IERC20-allowance}. - */ - function allowance(address owner, address spender) - public - view - virtual - override - returns (uint256) - { - return _allowances[owner][spender]; - } - - /** - * @dev See {IERC20-approve}. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function approve(address spender, uint256 amount) public virtual override returns (bool) { - _approve(_msgSender(), spender, amount); - return true; - } - - /** - * @dev See {IERC20-transferFrom}. - * - * Emits an {Approval} event indicating the updated allowance. This is not - * required by the EIP. See the note at the beginning of {ERC20}; - * - * Requirements: - * - `sender` and `recipient` cannot be the zero address. - * - `sender` must have a balance of at least `amount`. - * - the caller must have allowance for ``sender``'s tokens of at least - * `amount`. - */ - function transferFrom( - address sender, - address recipient, - uint256 amount - ) public virtual override returns (bool) { - _transfer(sender, recipient, amount); - _approve( - sender, - _msgSender(), - _allowances[sender][_msgSender()].sub(amount, 'ERC20: transfer amount exceeds allowance') - ); - return true; - } - - /** - * @dev Atomically increases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { - _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); - return true; - } - - /** - * @dev Atomically decreases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `spender` must have allowance for the caller of at least - * `subtractedValue`. - */ - function decreaseAllowance(address spender, uint256 subtractedValue) - public - virtual - returns (bool) - { - _approve( - _msgSender(), - spender, - _allowances[_msgSender()][spender].sub( - subtractedValue, - 'ERC20: decreased allowance below zero' - ) - ); - return true; - } - - /** - * @dev Moves tokens `amount` from `sender` to `recipient`. - * - * This is internal function is equivalent to {transfer}, and can be used to - * e.g. implement automatic token fees, slashing mechanisms, etc. - * - * Emits a {Transfer} event. - * - * Requirements: - * - * - `sender` cannot be the zero address. - * - `recipient` cannot be the zero address. - * - `sender` must have a balance of at least `amount`. - */ - function _transfer( - address sender, - address recipient, - uint256 amount - ) internal virtual { - require(sender != address(0), 'ERC20: transfer from the zero address'); - require(recipient != address(0), 'ERC20: transfer to the zero address'); - - _beforeTokenTransfer(sender, recipient, amount); - - _balances[sender] = _balances[sender].sub(amount, 'ERC20: transfer amount exceeds balance'); - _balances[recipient] = _balances[recipient].add(amount); - emit Transfer(sender, recipient, amount); - } - - /** @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. - * - * Emits a {Transfer} event with `from` set to the zero address. - * - * Requirements - * - * - `to` cannot be the zero address. - */ - function _mint(address account, uint256 amount) internal virtual { - require(account != address(0), 'ERC20: mint to the zero address'); - - _beforeTokenTransfer(address(0), account, amount); - - _totalSupply = _totalSupply.add(amount); - _balances[account] = _balances[account].add(amount); - emit Transfer(address(0), account, amount); - } - - /** - * @dev Destroys `amount` tokens from `account`, reducing the - * total supply. - * - * Emits a {Transfer} event with `to` set to the zero address. - * - * Requirements - * - * - `account` cannot be the zero address. - * - `account` must have at least `amount` tokens. - */ - function _burn(address account, uint256 amount) internal virtual { - require(account != address(0), 'ERC20: burn from the zero address'); - - _beforeTokenTransfer(account, address(0), amount); - - _balances[account] = _balances[account].sub(amount, 'ERC20: burn amount exceeds balance'); - _totalSupply = _totalSupply.sub(amount); - emit Transfer(account, address(0), amount); - } - - /** - * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. - * - * This is internal function is equivalent to `approve`, and can be used to - * e.g. set automatic allowances for certain subsystems, etc. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `owner` cannot be the zero address. - * - `spender` cannot be the zero address. - */ - function _approve( - address owner, - address spender, - uint256 amount - ) internal virtual { - require(owner != address(0), 'ERC20: approve from the zero address'); - require(spender != address(0), 'ERC20: approve to the zero address'); - - _allowances[owner][spender] = amount; - emit Approval(owner, spender, amount); - } - - /** - * @dev Sets {decimals} to a value other than the default one of 18. - * - * WARNING: This function should only be called from the constructor. Most - * applications that interact with token contracts will not expect - * {decimals} to ever change, and may work incorrectly if it does. - */ - function _setupDecimals(uint8 decimals_) internal { - _decimals = decimals_; - } - - /** - * @dev Hook that is called before any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be to transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol deleted file mode 100644 index c6f3526..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IAccessControl.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.10; - -/** - * @dev External interface of AccessControl declared to support ERC165 detection. - */ -interface IAccessControl { - /** - * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` - * - * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite - * {RoleAdminChanged} not being emitted signaling this. - * - * _Available since v3.1._ - */ - event RoleAdminChanged( - bytes32 indexed role, - bytes32 indexed previousAdminRole, - bytes32 indexed newAdminRole - ); - - /** - * @dev Emitted when `account` is granted `role`. - * - * `sender` is the account that originated the contract call, an admin role - * bearer except when using {AccessControl-_setupRole}. - */ - event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Emitted when `account` is revoked `role`. - * - * `sender` is the account that originated the contract call: - * - if using `revokeRole`, it is the admin role bearer - * - if using `renounceRole`, it is the role bearer (i.e. `account`) - */ - event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Returns `true` if `account` has been granted `role`. - */ - function hasRole(bytes32 role, address account) external view returns (bool); - - /** - * @dev Returns the admin role that controls `role`. See {grantRole} and - * {revokeRole}. - * - * To change a role's admin, use {AccessControl-_setRoleAdmin}. - */ - function getRoleAdmin(bytes32 role) external view returns (bytes32); - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function grantRole(bytes32 role, address account) external; - - /** - * @dev Revokes `role` from `account`. - * - * If `account` had been granted `role`, emits a {RoleRevoked} event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function revokeRole(bytes32 role, address account) external; - - /** - * @dev Revokes `role` from the calling account. - * - * Roles are often managed via {grantRole} and {revokeRole}: this function's - * purpose is to provide a mechanism for accounts to lose their privileges - * if they are compromised (such as when a trusted device is misplaced). - * - * If the calling account had been granted `role`, emits a {RoleRevoked} - * event. - * - * Requirements: - * - * - the caller must be `account`. - */ - function renounceRole(bytes32 role, address account) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC165.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC165.sol deleted file mode 100644 index ce3c290..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC165.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.10; - -/** - * @dev Interface of the ERC165 standard, as defined in the - * https://eips.ethereum.org/EIPS/eip-165[EIP]. - * - * Implementers can declare support of contract interfaces, which can then be - * queried by others ({ERC165Checker}). - * - * For an implementation, see {ERC165}. - */ -interface IERC165 { - /** - * @dev Returns true if this contract implements the interface defined by - * `interfaceId`. See the corresponding - * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] - * to learn more about how these ids are created. - * - * This function call must use less than 30 000 gas. - */ - function supportsInterface(bytes4 interfaceId) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol deleted file mode 100644 index 7dc5593..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -/** - * @dev Interface of the ERC20 standard as defined in the EIP. - */ -interface IERC20 { - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by `account`. - */ - function balanceOf(address account) external view returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `recipient`. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transfer(address recipient, uint256 amount) external returns (bool); - - /** - * @dev Returns the remaining number of tokens that `spender` will be - * allowed to spend on behalf of `owner` through {transferFrom}. This is - * zero by default. - * - * This value changes when {approve} or {transferFrom} are called. - */ - function allowance(address owner, address spender) external view returns (uint256); - - /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * IMPORTANT: Beware that changing an allowance with this method brings the risk - * that someone may use both the old and the new allowance by unfortunate - * transaction ordering. One possible solution to mitigate this race - * condition is to first reduce the spender's allowance to 0 and set the - * desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * - * Emits an {Approval} event. - */ - function approve(address spender, uint256 amount) external returns (bool); - - /** - * @dev Moves `amount` tokens from `sender` to `recipient` using the - * allowance mechanism. `amount` is then deducted from the caller's - * allowance. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transferFrom( - address sender, - address recipient, - uint256 amount - ) external returns (bool); - - /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). - * - * Note that `value` may be zero. - */ - event Transfer(address indexed from, address indexed to, uint256 value); - - /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` is the new allowance. - */ - event Approval(address indexed owner, address indexed spender, uint256 value); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol deleted file mode 100644 index 0269305..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import {IERC20} from './IERC20.sol'; - -interface IERC20Detailed is IERC20 { - function name() external view returns (string memory); - - function symbol() external view returns (string memory); - - function decimals() external view returns (uint8); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol deleted file mode 100644 index 020feec..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Ownable.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.10; - -import './Context.sol'; - -/** - * @dev Contract module which provides a basic access control mechanism, where - * there is an account (an owner) that can be granted exclusive access to - * specific functions. - * - * By default, the owner account will be the one that deploys the contract. This - * can later be changed with {transferOwnership}. - * - * This module is used through inheritance. It will make available the modifier - * `onlyOwner`, which can be applied to your functions to restrict their use to - * the owner. - */ -contract Ownable is Context { - address private _owner; - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - /** - * @dev Initializes the contract setting the deployer as the initial owner. - */ - constructor() { - address msgSender = _msgSender(); - _owner = msgSender; - emit OwnershipTransferred(address(0), msgSender); - } - - /** - * @dev Returns the address of the current owner. - */ - function owner() public view returns (address) { - return _owner; - } - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(_owner == _msgSender(), 'Ownable: caller is not the owner'); - _; - } - - /** - * @dev Leaves the contract without owner. It will not be possible to call - * `onlyOwner` functions anymore. Can only be called by the current owner. - * - * NOTE: Renouncing ownership will leave the contract without an owner, - * thereby removing any functionality that is only available to the owner. - */ - function renounceOwnership() public virtual onlyOwner { - emit OwnershipTransferred(_owner, address(0)); - _owner = address(0); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Can only be called by the current owner. - */ - function transferOwnership(address newOwner) public virtual onlyOwner { - require(newOwner != address(0), 'Ownable: new owner is the zero address'); - emit OwnershipTransferred(_owner, newOwner); - _owner = newOwner; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol deleted file mode 100644 index 6d70809..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeCast.sol +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol) -pragma solidity 0.8.10; - -/** - * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow - * checks. - * - * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can - * easily result in undesired exploitation or bugs, since developers usually - * assume that overflows raise errors. `SafeCast` restores this intuition by - * reverting the transaction when such an operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - * - * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing - * all math on `uint256` and `int256` and then downcasting. - */ -library SafeCast { - /** - * @dev Returns the downcasted uint224 from uint256, reverting on - * overflow (when the input is greater than largest uint224). - * - * Counterpart to Solidity's `uint224` operator. - * - * Requirements: - * - * - input must fit into 224 bits - */ - function toUint224(uint256 value) internal pure returns (uint224) { - require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); - return uint224(value); - } - - /** - * @dev Returns the downcasted uint128 from uint256, reverting on - * overflow (when the input is greater than largest uint128). - * - * Counterpart to Solidity's `uint128` operator. - * - * Requirements: - * - * - input must fit into 128 bits - */ - function toUint128(uint256 value) internal pure returns (uint128) { - require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); - return uint128(value); - } - - /** - * @dev Returns the downcasted uint96 from uint256, reverting on - * overflow (when the input is greater than largest uint96). - * - * Counterpart to Solidity's `uint96` operator. - * - * Requirements: - * - * - input must fit into 96 bits - */ - function toUint96(uint256 value) internal pure returns (uint96) { - require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); - return uint96(value); - } - - /** - * @dev Returns the downcasted uint64 from uint256, reverting on - * overflow (when the input is greater than largest uint64). - * - * Counterpart to Solidity's `uint64` operator. - * - * Requirements: - * - * - input must fit into 64 bits - */ - function toUint64(uint256 value) internal pure returns (uint64) { - require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); - return uint64(value); - } - - /** - * @dev Returns the downcasted uint32 from uint256, reverting on - * overflow (when the input is greater than largest uint32). - * - * Counterpart to Solidity's `uint32` operator. - * - * Requirements: - * - * - input must fit into 32 bits - */ - function toUint32(uint256 value) internal pure returns (uint32) { - require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); - return uint32(value); - } - - /** - * @dev Returns the downcasted uint16 from uint256, reverting on - * overflow (when the input is greater than largest uint16). - * - * Counterpart to Solidity's `uint16` operator. - * - * Requirements: - * - * - input must fit into 16 bits - */ - function toUint16(uint256 value) internal pure returns (uint16) { - require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); - return uint16(value); - } - - /** - * @dev Returns the downcasted uint8 from uint256, reverting on - * overflow (when the input is greater than largest uint8). - * - * Counterpart to Solidity's `uint8` operator. - * - * Requirements: - * - * - input must fit into 8 bits. - */ - function toUint8(uint256 value) internal pure returns (uint8) { - require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); - return uint8(value); - } - - /** - * @dev Converts a signed int256 into an unsigned uint256. - * - * Requirements: - * - * - input must be greater than or equal to 0. - */ - function toUint256(int256 value) internal pure returns (uint256) { - require(value >= 0, 'SafeCast: value must be positive'); - return uint256(value); - } - - /** - * @dev Returns the downcasted int128 from int256, reverting on - * overflow (when the input is less than smallest int128 or - * greater than largest int128). - * - * Counterpart to Solidity's `int128` operator. - * - * Requirements: - * - * - input must fit into 128 bits - * - * _Available since v3.1._ - */ - function toInt128(int256 value) internal pure returns (int128) { - require( - value >= type(int128).min && value <= type(int128).max, - "SafeCast: value doesn't fit in 128 bits" - ); - return int128(value); - } - - /** - * @dev Returns the downcasted int64 from int256, reverting on - * overflow (when the input is less than smallest int64 or - * greater than largest int64). - * - * Counterpart to Solidity's `int64` operator. - * - * Requirements: - * - * - input must fit into 64 bits - * - * _Available since v3.1._ - */ - function toInt64(int256 value) internal pure returns (int64) { - require( - value >= type(int64).min && value <= type(int64).max, - "SafeCast: value doesn't fit in 64 bits" - ); - return int64(value); - } - - /** - * @dev Returns the downcasted int32 from int256, reverting on - * overflow (when the input is less than smallest int32 or - * greater than largest int32). - * - * Counterpart to Solidity's `int32` operator. - * - * Requirements: - * - * - input must fit into 32 bits - * - * _Available since v3.1._ - */ - function toInt32(int256 value) internal pure returns (int32) { - require( - value >= type(int32).min && value <= type(int32).max, - "SafeCast: value doesn't fit in 32 bits" - ); - return int32(value); - } - - /** - * @dev Returns the downcasted int16 from int256, reverting on - * overflow (when the input is less than smallest int16 or - * greater than largest int16). - * - * Counterpart to Solidity's `int16` operator. - * - * Requirements: - * - * - input must fit into 16 bits - * - * _Available since v3.1._ - */ - function toInt16(int256 value) internal pure returns (int16) { - require( - value >= type(int16).min && value <= type(int16).max, - "SafeCast: value doesn't fit in 16 bits" - ); - return int16(value); - } - - /** - * @dev Returns the downcasted int8 from int256, reverting on - * overflow (when the input is less than smallest int8 or - * greater than largest int8). - * - * Counterpart to Solidity's `int8` operator. - * - * Requirements: - * - * - input must fit into 8 bits. - * - * _Available since v3.1._ - */ - function toInt8(int256 value) internal pure returns (int8) { - require( - value >= type(int8).min && value <= type(int8).max, - "SafeCast: value doesn't fit in 8 bits" - ); - return int8(value); - } - - /** - * @dev Converts an unsigned uint256 into a signed int256. - * - * Requirements: - * - * - input must be less than or equal to maxInt256. - */ - function toInt256(uint256 value) internal pure returns (int256) { - // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive - require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); - return int256(value); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol deleted file mode 100644 index bf5b1ee..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -/// @title Optimized overflow and underflow safe math operations -/// @notice Contains methods for doing math operations that revert on overflow or underflow for minimal gas cost -library SafeMath { - /// @notice Returns x + y, reverts if sum overflows uint256 - /// @param x The augend - /// @param y The addend - /// @return z The sum of x and y - function add(uint256 x, uint256 y) internal pure returns (uint256 z) { - unchecked { - require((z = x + y) >= x); - } - } - - /// @notice Returns x - y, reverts if underflows - /// @param x The minuend - /// @param y The subtrahend - /// @return z The difference of x and y - function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { - unchecked { - require((z = x - y) <= x); - } - } - - /// @notice Returns x - y, reverts if underflows - /// @param x The minuend - /// @param y The subtrahend - /// @param message The error msg - /// @return z The difference of x and y - function sub( - uint256 x, - uint256 y, - string memory message - ) internal pure returns (uint256 z) { - unchecked { - require((z = x - y) <= x, message); - } - } - - /// @notice Returns x * y, reverts if overflows - /// @param x The multiplicand - /// @param y The multiplier - /// @return z The product of x and y - function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { - unchecked { - require(x == 0 || (z = x * y) / x == y); - } - } - - /// @notice Returns x / y, reverts if overflows - no specific check, solidity reverts on division by 0 - /// @param x The numerator - /// @param y The denominator - /// @return z The product of x and y - function div(uint256 x, uint256 y) internal pure returns (uint256 z) { - return x / y; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Strings.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Strings.sol deleted file mode 100644 index bcb1ee6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/contracts/Strings.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.10; - -/** - * @dev String operations. - */ -library Strings { - bytes16 private constant _HEX_SYMBOLS = '0123456789abcdef'; - - /** - * @dev Converts a `uint256` to its ASCII `string` decimal representation. - */ - function toString(uint256 value) internal pure returns (string memory) { - // Inspired by OraclizeAPI's implementation - MIT licence - // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol - - if (value == 0) { - return '0'; - } - uint256 temp = value; - uint256 digits; - while (temp != 0) { - digits++; - temp /= 10; - } - bytes memory buffer = new bytes(digits); - while (value != 0) { - digits -= 1; - buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); - value /= 10; - } - return string(buffer); - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. - */ - function toHexString(uint256 value) internal pure returns (string memory) { - if (value == 0) { - return '0x00'; - } - uint256 temp = value; - uint256 length = 0; - while (temp != 0) { - length++; - temp >>= 8; - } - return toHexString(value, length); - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. - */ - function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { - bytes memory buffer = new bytes(2 * length + 2); - buffer[0] = '0'; - buffer[1] = 'x'; - for (uint256 i = 2 * length + 1; i > 1; --i) { - buffer[i] = _HEX_SYMBOLS[value & 0xf]; - value >>= 4; - } - require(value == 0, 'Strings: hex length insufficient'); - return string(buffer); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol deleted file mode 100644 index cc8f3b3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import './BaseAdminUpgradeabilityProxy.sol'; - -/** - * @title AdminUpgradeabilityProxy - * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for - * initializing the implementation, admin, and init data. - */ -contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy { - /** - * Contract constructor. - * @param _logic address of the initial implementation. - * @param _admin Address of the proxy administrator. - * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. - * It should include the signature and the parameters of the function to be called, as described in - * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. - * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. - */ - constructor( - address _logic, - address _admin, - bytes memory _data - ) payable UpgradeabilityProxy(_logic, _data) { - assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); - _setAdmin(_admin); - } - - /** - * @dev Only fall back when the sender is not the admin. - */ - function _willFallback() internal override(BaseAdminUpgradeabilityProxy, Proxy) { - BaseAdminUpgradeabilityProxy._willFallback(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol deleted file mode 100644 index 4bab099..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/BaseAdminUpgradeabilityProxy.sol +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import './UpgradeabilityProxy.sol'; - -/** - * @title BaseAdminUpgradeabilityProxy - * @dev This contract combines an upgradeability proxy with an authorization - * mechanism for administrative tasks. - * All external functions in this contract must be guarded by the - * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity - * feature proposal that would enable this to be done automatically. - */ -contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy { - /** - * @dev Emitted when the administration has been transferred. - * @param previousAdmin Address of the previous admin. - * @param newAdmin Address of the new admin. - */ - event AdminChanged(address previousAdmin, address newAdmin); - - /** - * @dev Storage slot with the admin of the contract. - * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 internal constant ADMIN_SLOT = - 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - - /** - * @dev Modifier to check whether the `msg.sender` is the admin. - * If it is, it will run the function. Otherwise, it will delegate the call - * to the implementation. - */ - modifier ifAdmin() { - if (msg.sender == _admin()) { - _; - } else { - _fallback(); - } - } - - /** - * @return The address of the proxy admin. - */ - function admin() external ifAdmin returns (address) { - return _admin(); - } - - /** - * @return The address of the implementation. - */ - function implementation() external ifAdmin returns (address) { - return _implementation(); - } - - /** - * @dev Changes the admin of the proxy. - * Only the current admin can call this function. - * @param newAdmin Address to transfer proxy administration to. - */ - function changeAdmin(address newAdmin) external ifAdmin { - require(newAdmin != address(0), 'Cannot change the admin of a proxy to the zero address'); - emit AdminChanged(_admin(), newAdmin); - _setAdmin(newAdmin); - } - - /** - * @dev Upgrade the backing implementation of the proxy. - * Only the admin can call this function. - * @param newImplementation Address of the new implementation. - */ - function upgradeTo(address newImplementation) external ifAdmin { - _upgradeTo(newImplementation); - } - - /** - * @dev Upgrade the backing implementation of the proxy and call a function - * on the new implementation. - * This is useful to initialize the proxied contract. - * @param newImplementation Address of the new implementation. - * @param data Data to send as msg.data in the low level call. - * It should include the signature and the parameters of the function to be called, as described in - * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. - */ - function upgradeToAndCall(address newImplementation, bytes calldata data) - external - payable - ifAdmin - { - _upgradeTo(newImplementation); - (bool success, ) = newImplementation.delegatecall(data); - require(success); - } - - /** - * @return adm The admin slot. - */ - function _admin() internal view returns (address adm) { - bytes32 slot = ADMIN_SLOT; - //solium-disable-next-line - assembly { - adm := sload(slot) - } - } - - /** - * @dev Sets the address of the proxy admin. - * @param newAdmin Address of the new proxy admin. - */ - function _setAdmin(address newAdmin) internal { - bytes32 slot = ADMIN_SLOT; - //solium-disable-next-line - assembly { - sstore(slot, newAdmin) - } - } - - /** - * @dev Only fall back when the sender is not the admin. - */ - function _willFallback() internal virtual override { - require(msg.sender != _admin(), 'Cannot call fallback function from the proxy admin'); - super._willFallback(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol deleted file mode 100644 index bf52cd5..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import './Proxy.sol'; -import '../contracts/Address.sol'; - -/** - * @title BaseUpgradeabilityProxy - * @dev This contract implements a proxy that allows to change the - * implementation address to which it will delegate. - * Such a change is called an implementation upgrade. - */ -contract BaseUpgradeabilityProxy is Proxy { - /** - * @dev Emitted when the implementation is upgraded. - * @param implementation Address of the new implementation. - */ - event Upgraded(address indexed implementation); - - /** - * @dev Storage slot with the address of the current implementation. - * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 internal constant IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /** - * @dev Returns the current implementation. - * @return impl Address of the current implementation - */ - function _implementation() internal view override returns (address impl) { - bytes32 slot = IMPLEMENTATION_SLOT; - //solium-disable-next-line - assembly { - impl := sload(slot) - } - } - - /** - * @dev Upgrades the proxy to a new implementation. - * @param newImplementation Address of the new implementation. - */ - function _upgradeTo(address newImplementation) internal { - _setImplementation(newImplementation); - emit Upgraded(newImplementation); - } - - /** - * @dev Sets the implementation address of the proxy. - * @param newImplementation Address of the new implementation. - */ - function _setImplementation(address newImplementation) internal { - require( - Address.isContract(newImplementation), - 'Cannot set a proxy implementation to a non-contract address' - ); - - bytes32 slot = IMPLEMENTATION_SLOT; - - //solium-disable-next-line - assembly { - sstore(slot, newImplementation) - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol deleted file mode 100644 index 79b720c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/Initializable.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -/** - * @title Initializable - * - * @dev Helper contract to support initializer functions. To use it, replace - * the constructor with a function that has the `initializer` modifier. - * WARNING: Unlike constructors, initializer functions must be manually - * invoked. This applies both to deploying an Initializable contract, as well - * as extending an Initializable contract via inheritance. - * WARNING: When used with inheritance, manual care must be taken to not invoke - * a parent initializer twice, or ensure that all initializers are idempotent, - * because this is not dealt with automatically as with constructors. - */ -contract Initializable { - /** - * @dev Indicates that the contract has been initialized. - */ - bool private initialized; - - /** - * @dev Indicates that the contract is in the process of being initialized. - */ - bool private initializing; - - /** - * @dev Modifier to use in the initializer function of a contract. - */ - modifier initializer() { - require( - initializing || isConstructor() || !initialized, - 'Contract instance has already been initialized' - ); - - bool isTopLevelCall = !initializing; - if (isTopLevelCall) { - initializing = true; - initialized = true; - } - - _; - - if (isTopLevelCall) { - initializing = false; - } - } - - /// @dev Returns true if and only if the function is running in the constructor - function isConstructor() private view returns (bool) { - // extcodesize checks the size of the code stored in an address, and - // address returns the current address. Since the code is still not - // deployed when running a constructor, any checks on its code size will - // yield zero, making it an effective way to detect if a contract is - // under construction or not. - uint256 cs; - //solium-disable-next-line - assembly { - cs := extcodesize(address()) - } - return cs == 0; - } - - // Reserved storage space to allow for layout changes in the future. - uint256[50] private ______gap; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol deleted file mode 100644 index 49ca134..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/InitializableAdminUpgradeabilityProxy.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import './BaseAdminUpgradeabilityProxy.sol'; -import './InitializableUpgradeabilityProxy.sol'; - -/** - * @title InitializableAdminUpgradeabilityProxy - * @dev Extends from BaseAdminUpgradeabilityProxy with an initializer for - * initializing the implementation, admin, and init data. - */ -contract InitializableAdminUpgradeabilityProxy is - BaseAdminUpgradeabilityProxy, - InitializableUpgradeabilityProxy -{ - /** - * Contract initializer. - * @param logic address of the initial implementation. - * @param admin Address of the proxy administrator. - * @param data Data to send as msg.data to the implementation to initialize the proxied contract. - * It should include the signature and the parameters of the function to be called, as described in - * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. - * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. - */ - function initialize( - address logic, - address admin, - bytes memory data - ) public payable { - require(_implementation() == address(0)); - InitializableUpgradeabilityProxy.initialize(logic, data); - assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); - _setAdmin(admin); - } - - /** - * @dev Only fall back when the sender is not the admin. - */ - function _willFallback() internal override(BaseAdminUpgradeabilityProxy, Proxy) { - BaseAdminUpgradeabilityProxy._willFallback(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol deleted file mode 100644 index 5ecec08..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import './BaseUpgradeabilityProxy.sol'; - -/** - * @title InitializableUpgradeabilityProxy - * @dev Extends BaseUpgradeabilityProxy with an initializer for initializing - * implementation and init data. - */ -contract InitializableUpgradeabilityProxy is BaseUpgradeabilityProxy { - /** - * @dev Contract initializer. - * @param _logic Address of the initial implementation. - * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. - * It should include the signature and the parameters of the function to be called, as described in - * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. - * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. - */ - function initialize(address _logic, bytes memory _data) public payable { - require(_implementation() == address(0)); - assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); - _setImplementation(_logic); - if (_data.length > 0) { - (bool success, ) = _logic.delegatecall(_data); - require(success); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol deleted file mode 100644 index 44b790d..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/Proxy.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -/** - * @title Proxy - * @dev Implements delegation of calls to other contracts, with proper - * forwarding of return values and bubbling of failures. - * It defines a fallback function that delegates all calls to the address - * returned by the abstract _implementation() internal function. - */ -abstract contract Proxy { - /** - * @dev Fallback function. - * Will run if no other function in the contract matches the call data. - * Implemented entirely in `_fallback`. - */ - fallback() external payable { - _fallback(); - } - - /** - * @return The Address of the implementation. - */ - function _implementation() internal view virtual returns (address); - - /** - * @dev Delegates execution to an implementation contract. - * This is a low level function that doesn't return to its internal call site. - * It will return to the external caller whatever the implementation returns. - * @param implementation Address to delegate. - */ - function _delegate(address implementation) internal { - //solium-disable-next-line - assembly { - // Copy msg.data. We take full control of memory in this inline assembly - // block because it will not return to Solidity code. We overwrite the - // Solidity scratch pad at memory position 0. - calldatacopy(0, 0, calldatasize()) - - // Call the implementation. - // out and outsize are 0 because we don't know the size yet. - let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) - - // Copy the returned data. - returndatacopy(0, 0, returndatasize()) - - switch result - // delegatecall returns 0 on error. - case 0 { - revert(0, returndatasize()) - } - default { - return(0, returndatasize()) - } - } - } - - /** - * @dev Function that is run as the first thing in the fallback function. - * Can be redefined in derived contracts to add functionality. - * Redefinitions must call super._willFallback(). - */ - function _willFallback() internal virtual {} - - /** - * @dev fallback implementation. - * Extracted to enable manual triggering. - */ - function _fallback() internal { - _willFallback(); - _delegate(_implementation()); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol deleted file mode 100644 index 896707a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/openzeppelin/upgradeability/UpgradeabilityProxy.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import './BaseUpgradeabilityProxy.sol'; - -/** - * @title UpgradeabilityProxy - * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing - * implementation and init data. - */ -contract UpgradeabilityProxy is BaseUpgradeabilityProxy { - /** - * @dev Contract constructor. - * @param _logic Address of the initial implementation. - * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. - * It should include the signature and the parameters of the function to be called, as described in - * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. - * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. - */ - constructor(address _logic, bytes memory _data) payable { - assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); - _setImplementation(_logic); - if (_data.length > 0) { - (bool success, ) = _logic.delegatecall(_data); - require(success); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/weth/WETH9.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/weth/WETH9.sol deleted file mode 100644 index d6dddb3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/dependencies/weth/WETH9.sol +++ /dev/null @@ -1,758 +0,0 @@ -// Copyright (C) 2015, 2016, 2017 Dapphub - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pragma solidity 0.8.10; - -contract WETH9 { - string public name = 'Wrapped Ether'; - string public symbol = 'WETH'; - uint8 public decimals = 18; - - event Approval(address indexed src, address indexed guy, uint256 wad); - event Transfer(address indexed src, address indexed dst, uint256 wad); - event Deposit(address indexed dst, uint256 wad); - event Withdrawal(address indexed src, uint256 wad); - - mapping(address => uint256) public balanceOf; - mapping(address => mapping(address => uint256)) public allowance; - - receive() external payable { - deposit(); - } - - function deposit() public payable { - balanceOf[msg.sender] += msg.value; - emit Deposit(msg.sender, msg.value); - } - - function withdraw(uint256 wad) public { - require(balanceOf[msg.sender] >= wad); - balanceOf[msg.sender] -= wad; - payable(msg.sender).transfer(wad); - emit Withdrawal(msg.sender, wad); - } - - function totalSupply() public view returns (uint256) { - return address(this).balance; - } - - function approve(address guy, uint256 wad) public returns (bool) { - allowance[msg.sender][guy] = wad; - emit Approval(msg.sender, guy, wad); - return true; - } - - function transfer(address dst, uint256 wad) public returns (bool) { - return transferFrom(msg.sender, dst, wad); - } - - function transferFrom( - address src, - address dst, - uint256 wad - ) public returns (bool) { - require(balanceOf[src] >= wad); - - if (src != msg.sender && allowance[src][msg.sender] != type(uint256).max) { - require(allowance[src][msg.sender] >= wad); - allowance[src][msg.sender] -= wad; - } - - balanceOf[src] -= wad; - balanceOf[dst] += wad; - - emit Transfer(src, dst, wad); - - return true; - } -} - -/* - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - -*/ diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/FlashLoanReceiverBase.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/FlashLoanReceiverBase.sol deleted file mode 100644 index 2390898..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/FlashLoanReceiverBase.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IFlashLoanReceiver} from '../interfaces/IFlashLoanReceiver.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; - -/** - * @title FlashLoanReceiverBase - * @author Aave - * @notice Base contract to develop a flashloan-receiver contract. - */ -abstract contract FlashLoanReceiverBase is IFlashLoanReceiver { - IPoolAddressesProvider public immutable override ADDRESSES_PROVIDER; - IPool public immutable override POOL; - - constructor(IPoolAddressesProvider provider) { - ADDRESSES_PROVIDER = provider; - POOL = IPool(provider.getPool()); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol deleted file mode 100644 index 5d30a22..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IFlashLoanSimpleReceiver} from '../interfaces/IFlashLoanSimpleReceiver.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; - -/** - * @title FlashLoanSimpleReceiverBase - * @author Aave - * @notice Base contract to develop a flashloan-receiver contract. - */ -abstract contract FlashLoanSimpleReceiverBase is IFlashLoanSimpleReceiver { - IPoolAddressesProvider public immutable override ADDRESSES_PROVIDER; - IPool public immutable override POOL; - - constructor(IPoolAddressesProvider provider) { - ADDRESSES_PROVIDER = provider; - POOL = IPool(provider.getPool()); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/LICENSE.md b/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/LICENSE.md deleted file mode 100644 index 506d18e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/base/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanReceiver.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanReceiver.sol deleted file mode 100644 index 132c547..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanReceiver.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; - -/** - * @title IFlashLoanReceiver - * @author Aave - * @notice Defines the basic interface of a flashloan-receiver contract. - * @dev Implement this interface to develop a flashloan-compatible flashLoanReceiver contract - **/ -interface IFlashLoanReceiver { - /** - * @notice Executes an operation after receiving the flash-borrowed assets - * @dev Ensure that the contract can return the debt + premium, e.g., has - * enough funds to repay and has approved the Pool to pull the total amount - * @param assets The addresses of the flash-borrowed assets - * @param amounts The amounts of the flash-borrowed assets - * @param premiums The fee of each flash-borrowed asset - * @param initiator The address of the flashloan initiator - * @param params The byte-encoded params passed when initiating the flashloan - * @return True if the execution of the operation succeeds, false otherwise - */ - function executeOperation( - address[] calldata assets, - uint256[] calldata amounts, - uint256[] calldata premiums, - address initiator, - bytes calldata params - ) external returns (bool); - - function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); - - function POOL() external view returns (IPool); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol deleted file mode 100644 index 46236f5..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; - -/** - * @title IFlashLoanSimpleReceiver - * @author Aave - * @notice Defines the basic interface of a flashloan-receiver contract. - * @dev Implement this interface to develop a flashloan-compatible flashLoanReceiver contract - **/ -interface IFlashLoanSimpleReceiver { - /** - * @notice Executes an operation after receiving the flash-borrowed asset - * @dev Ensure that the contract can return the debt + premium, e.g., has - * enough funds to repay and has approved the Pool to pull the total amount - * @param asset The address of the flash-borrowed asset - * @param amount The amount of the flash-borrowed asset - * @param premium The fee of the flash-borrowed asset - * @param initiator The address of the flashloan initiator - * @param params The byte-encoded params passed when initiating the flashloan - * @return True if the execution of the operation succeeds, false otherwise - */ - function executeOperation( - address asset, - uint256 amount, - uint256 premium, - address initiator, - bytes calldata params - ) external returns (bool); - - function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); - - function POOL() external view returns (IPool); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/LICENSE.md b/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/LICENSE.md deleted file mode 100644 index 506d18e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/flashloan/interfaces/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IACLManager.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IACLManager.sol deleted file mode 100644 index 4bb6e64..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IACLManager.sol +++ /dev/null @@ -1,175 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; - -/** - * @title IACLManager - * @author Aave - * @notice Defines the basic interface for the ACL Manager - **/ -interface IACLManager { - /** - * @notice Returns the contract address of the PoolAddressesProvider - * @return The address of the PoolAddressesProvider - */ - function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); - - /** - * @notice Returns the identifier of the PoolAdmin role - * @return The id of the PoolAdmin role - */ - function POOL_ADMIN_ROLE() external view returns (bytes32); - - /** - * @notice Returns the identifier of the EmergencyAdmin role - * @return The id of the EmergencyAdmin role - */ - function EMERGENCY_ADMIN_ROLE() external view returns (bytes32); - - /** - * @notice Returns the identifier of the RiskAdmin role - * @return The id of the RiskAdmin role - */ - function RISK_ADMIN_ROLE() external view returns (bytes32); - - /** - * @notice Returns the identifier of the FlashBorrower role - * @return The id of the FlashBorrower role - */ - function FLASH_BORROWER_ROLE() external view returns (bytes32); - - /** - * @notice Returns the identifier of the Bridge role - * @return The id of the Bridge role - */ - function BRIDGE_ROLE() external view returns (bytes32); - - /** - * @notice Returns the identifier of the AssetListingAdmin role - * @return The id of the AssetListingAdmin role - */ - function ASSET_LISTING_ADMIN_ROLE() external view returns (bytes32); - - /** - * @notice Set the role as admin of a specific role. - * @dev By default the admin role for all roles is `DEFAULT_ADMIN_ROLE`. - * @param role The role to be managed by the admin role - * @param adminRole The admin role - */ - function setRoleAdmin(bytes32 role, bytes32 adminRole) external; - - /** - * @notice Adds a new admin as PoolAdmin - * @param admin The address of the new admin - */ - function addPoolAdmin(address admin) external; - - /** - * @notice Removes an admin as PoolAdmin - * @param admin The address of the admin to remove - */ - function removePoolAdmin(address admin) external; - - /** - * @notice Returns true if the address is PoolAdmin, false otherwise - * @param admin The address to check - * @return True if the given address is PoolAdmin, false otherwise - */ - function isPoolAdmin(address admin) external view returns (bool); - - /** - * @notice Adds a new admin as EmergencyAdmin - * @param admin The address of the new admin - */ - function addEmergencyAdmin(address admin) external; - - /** - * @notice Removes an admin as EmergencyAdmin - * @param admin The address of the admin to remove - */ - function removeEmergencyAdmin(address admin) external; - - /** - * @notice Returns true if the address is EmergencyAdmin, false otherwise - * @param admin The address to check - * @return True if the given address is EmergencyAdmin, false otherwise - */ - function isEmergencyAdmin(address admin) external view returns (bool); - - /** - * @notice Adds a new admin as RiskAdmin - * @param admin The address of the new admin - */ - function addRiskAdmin(address admin) external; - - /** - * @notice Removes an admin as RiskAdmin - * @param admin The address of the admin to remove - */ - function removeRiskAdmin(address admin) external; - - /** - * @notice Returns true if the address is RiskAdmin, false otherwise - * @param admin The address to check - * @return True if the given address is RiskAdmin, false otherwise - */ - function isRiskAdmin(address admin) external view returns (bool); - - /** - * @notice Adds a new address as FlashBorrower - * @param borrower The address of the new FlashBorrower - */ - function addFlashBorrower(address borrower) external; - - /** - * @notice Removes an admin as FlashBorrower - * @param borrower The address of the FlashBorrower to remove - */ - function removeFlashBorrower(address borrower) external; - - /** - * @notice Returns true if the address is FlashBorrower, false otherwise - * @param borrower The address to check - * @return True if the given address is FlashBorrower, false otherwise - */ - function isFlashBorrower(address borrower) external view returns (bool); - - /** - * @notice Adds a new address as Bridge - * @param bridge The address of the new Bridge - */ - function addBridge(address bridge) external; - - /** - * @notice Removes an address as Bridge - * @param bridge The address of the bridge to remove - */ - function removeBridge(address bridge) external; - - /** - * @notice Returns true if the address is Bridge, false otherwise - * @param bridge The address to check - * @return True if the given address is Bridge, false otherwise - */ - function isBridge(address bridge) external view returns (bool); - - /** - * @notice Adds a new admin as AssetListingAdmin - * @param admin The address of the new admin - */ - function addAssetListingAdmin(address admin) external; - - /** - * @notice Removes an admin as AssetListingAdmin - * @param admin The address of the admin to remove - */ - function removeAssetListingAdmin(address admin) external; - - /** - * @notice Returns true if the address is AssetListingAdmin, false otherwise - * @param admin The address to check - * @return True if the given address is AssetListingAdmin, false otherwise - */ - function isAssetListingAdmin(address admin) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAToken.sol deleted file mode 100644 index 21726c8..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAToken.sol +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; -import {IInitializableAToken} from './IInitializableAToken.sol'; - -/** - * @title IAToken - * @author Aave - * @notice Defines the basic interface for an AToken. - **/ -interface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken { - /** - * @dev Emitted during the transfer action - * @param from The user whose tokens are being transferred - * @param to The recipient - * @param value The amount being transferred - * @param index The next liquidity index of the reserve - **/ - event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index); - - /** - * @notice Mints `amount` aTokens to `user` - * @param caller The address performing the mint - * @param onBehalfOf The address of the user that will receive the minted aTokens - * @param amount The amount of tokens getting minted - * @param index The next liquidity index of the reserve - * @return `true` if the the previous balance of the user was 0 - */ - function mint( - address caller, - address onBehalfOf, - uint256 amount, - uint256 index - ) external returns (bool); - - /** - * @notice Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying` - * @dev In some instances, the mint event could be emitted from a burn transaction - * if the amount to burn is less than the interest that the user accrued - * @param from The address from which the aTokens will be burned - * @param receiverOfUnderlying The address that will receive the underlying - * @param amount The amount being burned - * @param index The next liquidity index of the reserve - **/ - function burn( - address from, - address receiverOfUnderlying, - uint256 amount, - uint256 index - ) external; - - /** - * @notice Mints aTokens to the reserve treasury - * @param amount The amount of tokens getting minted - * @param index The next liquidity index of the reserve - */ - function mintToTreasury(uint256 amount, uint256 index) external; - - /** - * @notice Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken - * @param from The address getting liquidated, current owner of the aTokens - * @param to The recipient - * @param value The amount of tokens getting transferred - **/ - function transferOnLiquidation( - address from, - address to, - uint256 value - ) external; - - /** - * @notice Transfers the underlying asset to `target`. - * @dev Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan() - * @param user The recipient of the underlying - * @param amount The amount getting transferred - **/ - function transferUnderlyingTo(address user, uint256 amount) external; - - /** - * @notice Handles the underlying received by the aToken after the transfer has been completed. - * @dev The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the - * transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying - * to receive LM rewards. In that case, `handleRepayment()` would perform the staking of the underlying asset. - * @param user The user executing the repayment - * @param amount The amount getting repaid - **/ - function handleRepayment(address user, uint256 amount) external; - - /** - * @notice Allow passing a signed message to approve spending - * @dev implements the permit function as for - * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md - * @param owner The owner of the funds - * @param spender The spender - * @param value The amount - * @param deadline The deadline timestamp, type(uint256).max for max deadline - * @param v Signature param - * @param s Signature param - * @param r Signature param - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external; - - /** - * @notice Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) - * @return The address of the underlying asset - **/ - function UNDERLYING_ASSET_ADDRESS() external view returns (address); - - /** - * @notice Returns the address of the Aave treasury, receiving the fees on this aToken. - * @return Address of the Aave treasury - **/ - function RESERVE_TREASURY_ADDRESS() external view returns (address); - - /** - * @notice Get the domain separator for the token - * @dev Return cached value if chainId matches cache, otherwise recomputes separator - * @return The domain separator of the token at current chain - */ - function DOMAIN_SEPARATOR() external view returns (bytes32); - - /** - * @notice Returns the nonce for owner. - * @param owner The address of the owner - * @return The nonce of the owner - **/ - function nonces(address owner) external view returns (uint256); - - /** - * @notice Rescue and transfer tokens locked in this contract - * @param token The address of the token - * @param to The address of the recipient - * @param amount The amount of token to transfer - */ - function rescueTokens( - address token, - address to, - uint256 amount - ) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAaveIncentivesController.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAaveIncentivesController.sol deleted file mode 100644 index d0663cd..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAaveIncentivesController.sol +++ /dev/null @@ -1,176 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title IAaveIncentivesController - * @author Aave - * @notice Defines the basic interface for an Aave Incentives Controller. - **/ -interface IAaveIncentivesController { - /** - * @dev Emitted during `handleAction`, `claimRewards` and `claimRewardsOnBehalf` - * @param user The user that accrued rewards - * @param amount The amount of accrued rewards - */ - event RewardsAccrued(address indexed user, uint256 amount); - - event RewardsClaimed(address indexed user, address indexed to, uint256 amount); - - /** - * @dev Emitted during `claimRewards` and `claimRewardsOnBehalf` - * @param user The address that accrued rewards - * @param to The address that will be receiving the rewards - * @param claimer The address that performed the claim - * @param amount The amount of rewards - */ - event RewardsClaimed( - address indexed user, - address indexed to, - address indexed claimer, - uint256 amount - ); - - /** - * @dev Emitted during `setClaimer` - * @param user The address of the user - * @param claimer The address of the claimer - */ - event ClaimerSet(address indexed user, address indexed claimer); - - /** - * @notice Returns the configuration of the distribution for a certain asset - * @param asset The address of the reference asset of the distribution - * @return The asset index - * @return The emission per second - * @return The last updated timestamp - **/ - function getAssetData(address asset) - external - view - returns ( - uint256, - uint256, - uint256 - ); - - /** - * LEGACY ************************** - * @dev Returns the configuration of the distribution for a certain asset - * @param asset The address of the reference asset of the distribution - * @return The asset index, the emission per second and the last updated timestamp - **/ - function assets(address asset) - external - view - returns ( - uint128, - uint128, - uint256 - ); - - /** - * @notice Whitelists an address to claim the rewards on behalf of another address - * @param user The address of the user - * @param claimer The address of the claimer - */ - function setClaimer(address user, address claimer) external; - - /** - * @notice Returns the whitelisted claimer for a certain address (0x0 if not set) - * @param user The address of the user - * @return The claimer address - */ - function getClaimer(address user) external view returns (address); - - /** - * @notice Configure assets for a certain rewards emission - * @param assets The assets to incentivize - * @param emissionsPerSecond The emission for each asset - */ - function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond) - external; - - /** - * @notice Called by the corresponding asset on any update that affects the rewards distribution - * @param asset The address of the user - * @param userBalance The balance of the user of the asset in the pool - * @param totalSupply The total supply of the asset in the pool - **/ - function handleAction( - address asset, - uint256 userBalance, - uint256 totalSupply - ) external; - - /** - * @notice Returns the total of rewards of a user, already accrued + not yet accrued - * @param assets The assets to accumulate rewards for - * @param user The address of the user - * @return The rewards - **/ - function getRewardsBalance(address[] calldata assets, address user) - external - view - returns (uint256); - - /** - * @notice Claims reward for a user, on the assets of the pool, accumulating the pending rewards - * @param assets The assets to accumulate rewards for - * @param amount Amount of rewards to claim - * @param to Address that will be receiving the rewards - * @return Rewards claimed - **/ - function claimRewards( - address[] calldata assets, - uint256 amount, - address to - ) external returns (uint256); - - /** - * @notice Claims reward for a user on its behalf, on the assets of the pool, accumulating the pending rewards. - * @dev The caller must be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager - * @param assets The assets to accumulate rewards for - * @param amount The amount of rewards to claim - * @param user The address to check and claim rewards - * @param to The address that will be receiving the rewards - * @return The amount of rewards claimed - **/ - function claimRewardsOnBehalf( - address[] calldata assets, - uint256 amount, - address user, - address to - ) external returns (uint256); - - /** - * @notice Returns the unclaimed rewards of the user - * @param user The address of the user - * @return The unclaimed user rewards - */ - function getUserUnclaimedRewards(address user) external view returns (uint256); - - /** - * @notice Returns the user index for a specific asset - * @param user The address of the user - * @param asset The asset to incentivize - * @return The user index for the asset - */ - function getUserAssetData(address user, address asset) external view returns (uint256); - - /** - * @notice for backward compatibility with previous implementation of the Incentives controller - * @return The address of the reward token - */ - function REWARD_TOKEN() external view returns (address); - - /** - * @notice for backward compatibility with previous implementation of the Incentives controller - * @return The precision used in the incentives controller - */ - function PRECISION() external view returns (uint8); - - /** - * @dev Gets the distribution end timestamp of the emissions - */ - function DISTRIBUTION_END() external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAaveOracle.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAaveOracle.sol deleted file mode 100644 index 0ad9b47..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IAaveOracle.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IPriceOracleGetter} from './IPriceOracleGetter.sol'; -import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; - -/** - * @title IAaveOracle - * @author Aave - * @notice Defines the basic interface for the Aave Oracle - */ -interface IAaveOracle is IPriceOracleGetter { - /** - * @dev Emitted after the base currency is set - * @param baseCurrency The base currency of used for price quotes - * @param baseCurrencyUnit The unit of the base currency - */ - event BaseCurrencySet(address indexed baseCurrency, uint256 baseCurrencyUnit); - - /** - * @dev Emitted after the price source of an asset is updated - * @param asset The address of the asset - * @param source The price source of the asset - */ - event AssetSourceUpdated(address indexed asset, address indexed source); - - /** - * @dev Emitted after the address of fallback oracle is updated - * @param fallbackOracle The address of the fallback oracle - */ - event FallbackOracleUpdated(address indexed fallbackOracle); - - /** - * @notice Returns the PoolAddressesProvider - * @return The address of the PoolAddressesProvider contract - */ - function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); - - /** - * @notice Sets or replaces price sources of assets - * @param assets The addresses of the assets - * @param sources The addresses of the price sources - */ - function setAssetSources(address[] calldata assets, address[] calldata sources) external; - - /** - * @notice Sets the fallback oracle - * @param fallbackOracle The address of the fallback oracle - */ - function setFallbackOracle(address fallbackOracle) external; - - /** - * @notice Returns a list of prices from a list of assets addresses - * @param assets The list of assets addresses - * @return The prices of the given assets - */ - function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory); - - /** - * @notice Returns the address of the source for an asset address - * @param asset The address of the asset - * @return The address of the source - */ - function getSourceOfAsset(address asset) external view returns (address); - - /** - * @notice Returns the address of the fallback oracle - * @return The address of the fallback oracle - */ - function getFallbackOracle() external view returns (address); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/ICreditDelegationToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/ICreditDelegationToken.sol deleted file mode 100644 index a06de1f..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/ICreditDelegationToken.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title ICreditDelegationToken - * @author Aave - * @notice Defines the basic interface for a token supporting credit delegation. - **/ -interface ICreditDelegationToken { - /** - * @dev Emitted on `approveDelegation` and `borrowAllowance - * @param fromUser The address of the delegator - * @param toUser The address of the delegatee - * @param asset The address of the delegated asset - * @param amount The amount being delegated - */ - event BorrowAllowanceDelegated( - address indexed fromUser, - address indexed toUser, - address indexed asset, - uint256 amount - ); - - /** - * @notice Delegates borrowing power to a user on the specific debt token. - * Delegation will still respect the liquidation constraints (even if delegated, a - * delegatee cannot force a delegator HF to go below 1) - * @param delegatee The address receiving the delegated borrowing power - * @param amount The maximum amount being delegated. - **/ - function approveDelegation(address delegatee, uint256 amount) external; - - /** - * @notice Returns the borrow allowance of the user - * @param fromUser The user to giving allowance - * @param toUser The user to give allowance to - * @return The current allowance of `toUser` - **/ - function borrowAllowance(address fromUser, address toUser) external view returns (uint256); - - /** - * @notice Delegates borrowing power to a user on the specific debt token via ERC712 signature - * @param delegator The delegator of the credit - * @param delegatee The delegatee that can use the credit - * @param value The amount to be delegated - * @param deadline The deadline timestamp, type(uint256).max for max deadline - * @param v The V signature param - * @param s The S signature param - * @param r The R signature param - */ - function delegationWithSig( - address delegator, - address delegatee, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IDelegationToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IDelegationToken.sol deleted file mode 100644 index 288f1e5..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IDelegationToken.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title IDelegationToken - * @author Aave - * @notice Implements an interface for tokens with delegation COMP/UNI compatible - **/ -interface IDelegationToken { - /** - * @notice Delegate voting power to a delegatee - * @param delegatee The address of the delegatee - */ - function delegate(address delegatee) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IERC20WithPermit.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IERC20WithPermit.sol deleted file mode 100644 index 3c67e56..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IERC20WithPermit.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; - -/** - * @title IERC20WithPermit - * @author Aave - * @notice Interface for the permit function (EIP-2612) - **/ -interface IERC20WithPermit is IERC20 { - /** - * @notice Allow passing a signed message to approve spending - * @dev implements the permit function as for - * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md - * @param owner The owner of the funds - * @param spender The spender - * @param value The amount - * @param deadline The deadline timestamp, type(uint256).max for max deadline - * @param v Signature param - * @param s Signature param - * @param r Signature param - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IInitializableAToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IInitializableAToken.sol deleted file mode 100644 index ba0ca82..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IInitializableAToken.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; -import {IPool} from './IPool.sol'; - -/** - * @title IInitializableAToken - * @author Aave - * @notice Interface for the initialize function on AToken - **/ -interface IInitializableAToken { - /** - * @dev Emitted when an aToken is initialized - * @param underlyingAsset The address of the underlying asset - * @param pool The address of the associated pool - * @param treasury The address of the treasury - * @param incentivesController The address of the incentives controller for this aToken - * @param aTokenDecimals The decimals of the underlying - * @param aTokenName The name of the aToken - * @param aTokenSymbol The symbol of the aToken - * @param params A set of encoded parameters for additional initialization - **/ - event Initialized( - address indexed underlyingAsset, - address indexed pool, - address treasury, - address incentivesController, - uint8 aTokenDecimals, - string aTokenName, - string aTokenSymbol, - bytes params - ); - - /** - * @notice Initializes the aToken - * @param pool The pool contract that is initializing this contract - * @param treasury The address of the Aave treasury, receiving the fees on this aToken - * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) - * @param incentivesController The smart contract managing potential incentives distribution - * @param aTokenDecimals The decimals of the aToken, same as the underlying asset's - * @param aTokenName The name of the aToken - * @param aTokenSymbol The symbol of the aToken - * @param params A set of encoded parameters for additional initialization - */ - function initialize( - IPool pool, - address treasury, - address underlyingAsset, - IAaveIncentivesController incentivesController, - uint8 aTokenDecimals, - string calldata aTokenName, - string calldata aTokenSymbol, - bytes calldata params - ) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IInitializableDebtToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IInitializableDebtToken.sol deleted file mode 100644 index 740cb8c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IInitializableDebtToken.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IAaveIncentivesController} from './IAaveIncentivesController.sol'; -import {IPool} from './IPool.sol'; - -/** - * @title IInitializableDebtToken - * @author Aave - * @notice Interface for the initialize function common between debt tokens - **/ -interface IInitializableDebtToken { - /** - * @dev Emitted when a debt token is initialized - * @param underlyingAsset The address of the underlying asset - * @param pool The address of the associated pool - * @param incentivesController The address of the incentives controller for this aToken - * @param debtTokenDecimals The decimals of the debt token - * @param debtTokenName The name of the debt token - * @param debtTokenSymbol The symbol of the debt token - * @param params A set of encoded parameters for additional initialization - **/ - event Initialized( - address indexed underlyingAsset, - address indexed pool, - address incentivesController, - uint8 debtTokenDecimals, - string debtTokenName, - string debtTokenSymbol, - bytes params - ); - - /** - * @notice Initializes the debt token. - * @param pool The pool contract that is initializing this contract - * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH) - * @param incentivesController The smart contract managing potential incentives distribution - * @param debtTokenDecimals The decimals of the debtToken, same as the underlying asset's - * @param debtTokenName The name of the token - * @param debtTokenSymbol The symbol of the token - * @param params A set of encoded parameters for additional initialization - */ - function initialize( - IPool pool, - address underlyingAsset, - IAaveIncentivesController incentivesController, - uint8 debtTokenDecimals, - string memory debtTokenName, - string memory debtTokenSymbol, - bytes calldata params - ) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IL2Pool.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IL2Pool.sol deleted file mode 100644 index 27ac223..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IL2Pool.sol +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title IL2Pool - * @author Aave - * @notice Defines the basic extension interface for an L2 Aave Pool. - **/ -interface IL2Pool { - /** - * @notice Calldata efficient wrapper of the supply function on behalf of the caller - * @param args Arguments for the supply function packed in one bytes32 - * 96 bits 16 bits 128 bits 16 bits - * | 0-padding | referralCode | shortenedAmount | assetId | - * @dev the shortenedAmount is cast to 256 bits at decode time, if type(uint128).max the value will be expanded to - * type(uint256).max - * @dev assetId is the index of the asset in the reservesList. - */ - function supply(bytes32 args) external; - - /** - * @notice Calldata efficient wrapper of the supplyWithPermit function on behalf of the caller - * @param args Arguments for the supply function packed in one bytes32 - * 56 bits 8 bits 32 bits 16 bits 128 bits 16 bits - * | 0-padding | permitV | shortenedDeadline | referralCode | shortenedAmount | assetId | - * @dev the shortenedAmount is cast to 256 bits at decode time, if type(uint128).max the value will be expanded to - * type(uint256).max - * @dev assetId is the index of the asset in the reservesList. - * @param r The R parameter of ERC712 permit sig - * @param s The S parameter of ERC712 permit sig - */ - function supplyWithPermit( - bytes32 args, - bytes32 r, - bytes32 s - ) external; - - /** - * @notice Calldata efficient wrapper of the withdraw function, withdrawing to the caller - * @param args Arguments for the withdraw function packed in one bytes32 - * 112 bits 128 bits 16 bits - * | 0-padding | shortenedAmount | assetId | - * @dev the shortenedAmount is cast to 256 bits at decode time, if type(uint128).max the value will be expanded to - * type(uint256).max - * @dev assetId is the index of the asset in the reservesList. - */ - function withdraw(bytes32 args) external; - - /** - * @notice Calldata efficient wrapper of the borrow function, borrowing on behalf of the caller - * @param args Arguments for the borrow function packed in one bytes32 - * 88 bits 16 bits 8 bits 128 bits 16 bits - * | 0-padding | referralCode | shortenedInterestRateMode | shortenedAmount | assetId | - * @dev the shortenedAmount is cast to 256 bits at decode time, if type(uint128).max the value will be expanded to - * type(uint256).max - * @dev assetId is the index of the asset in the reservesList. - */ - function borrow(bytes32 args) external; - - /** - * @notice Calldata efficient wrapper of the repay function, repaying on behalf of the caller - * @param args Arguments for the repay function packed in one bytes32 - * 104 bits 8 bits 128 bits 16 bits - * | 0-padding | shortenedInterestRateMode | shortenedAmount | assetId | - * @dev the shortenedAmount is cast to 256 bits at decode time, if type(uint128).max the value will be expanded to - * type(uint256).max - * @dev assetId is the index of the asset in the reservesList. - * @return The final amount repaid - */ - function repay(bytes32 args) external returns (uint256); - - /** - * @notice Calldata efficient wrapper of the repayWithPermit function, repaying on behalf of the caller - * @param args Arguments for the repayWithPermit function packed in one bytes32 - * 64 bits 8 bits 32 bits 8 bits 128 bits 16 bits - * | 0-padding | permitV | shortenedDeadline | shortenedInterestRateMode | shortenedAmount | assetId | - * @dev the shortenedAmount is cast to 256 bits at decode time, if type(uint128).max the value will be expanded to - * type(uint256).max - * @dev assetId is the index of the asset in the reservesList. - * @param r The R parameter of ERC712 permit sig - * @param s The S parameter of ERC712 permit sig - * @return The final amount repaid - */ - function repayWithPermit( - bytes32 args, - bytes32 r, - bytes32 s - ) external returns (uint256); - - /** - * @notice Calldata efficient wrapper of the repayWithATokens function - * @param args Arguments for the repayWithATokens function packed in one bytes32 - * 104 bits 8 bits 128 bits 16 bits - * | 0-padding | shortenedInterestRateMode | shortenedAmount | assetId | - * @dev the shortenedAmount is cast to 256 bits at decode time, if type(uint128).max the value will be expanded to - * type(uint256).max - * @dev assetId is the index of the asset in the reservesList. - * @return The final amount repaid - */ - function repayWithATokens(bytes32 args) external returns (uint256); - - /** - * @notice Calldata efficient wrapper of the swapBorrowRateMode function - * @param args Arguments for the swapBorrowRateMode function packed in one bytes32 - * 232 bits 8 bits 16 bits - * | 0-padding | shortenedInterestRateMode | assetId | - * @dev assetId is the index of the asset in the reservesList. - */ - function swapBorrowRateMode(bytes32 args) external; - - /** - * @notice Calldata efficient wrapper of the rebalanceStableBorrowRate function - * @param args Arguments for the rebalanceStableBorrowRate function packed in one bytes32 - * 80 bits 160 bits 16 bits - * | 0-padding | user address | assetId | - * @dev assetId is the index of the asset in the reservesList. - */ - function rebalanceStableBorrowRate(bytes32 args) external; - - /** - * @notice Calldata efficient wrapper of the setUserUseReserveAsCollateral function - * @param args Arguments for the setUserUseReserveAsCollateral function packed in one bytes32 - * 239 bits 1 bit 16 bits - * | 0-padding | useAsCollateral | assetId | - * @dev assetId is the index of the asset in the reservesList. - */ - function setUserUseReserveAsCollateral(bytes32 args) external; - - /** - * @notice Calldata efficient wrapper of the liquidationCall function - * @param args1 part of the arguments for the liquidationCall function packed in one bytes32 - * 64 bits 160 bits 16 bits 16 bits - * | 0-padding | user address | debtAssetId | collateralAssetId | - * @param args2 part of the arguments for the liquidationCall function packed in one bytes32 - * 127 bits 1 bit 128 bits - * | 0-padding | receiveAToken | shortenedDebtToCover | - * @dev the shortenedDebtToCover is cast to 256 bits at decode time, - * if type(uint128).max the value will be expanded to type(uint256).max - */ - function liquidationCall(bytes32 args1, bytes32 args2) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPool.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPool.sol deleted file mode 100644 index 7f64b4a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPool.sol +++ /dev/null @@ -1,747 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; -import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; - -/** - * @title IPool - * @author Aave - * @notice Defines the basic interface for an Aave Pool. - **/ -interface IPool { - /** - * @dev Emitted on mintUnbacked() - * @param reserve The address of the underlying asset of the reserve - * @param user The address initiating the supply - * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens - * @param amount The amount of supplied assets - * @param referralCode The referral code used - **/ - event MintUnbacked( - address indexed reserve, - address user, - address indexed onBehalfOf, - uint256 amount, - uint16 indexed referralCode - ); - - /** - * @dev Emitted on backUnbacked() - * @param reserve The address of the underlying asset of the reserve - * @param backer The address paying for the backing - * @param amount The amount added as backing - * @param fee The amount paid in fees - **/ - event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); - - /** - * @dev Emitted on supply() - * @param reserve The address of the underlying asset of the reserve - * @param user The address initiating the supply - * @param onBehalfOf The beneficiary of the supply, receiving the aTokens - * @param amount The amount supplied - * @param referralCode The referral code used - **/ - event Supply( - address indexed reserve, - address user, - address indexed onBehalfOf, - uint256 amount, - uint16 indexed referralCode - ); - - /** - * @dev Emitted on withdraw() - * @param reserve The address of the underlying asset being withdrawn - * @param user The address initiating the withdrawal, owner of aTokens - * @param to The address that will receive the underlying - * @param amount The amount to be withdrawn - **/ - event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); - - /** - * @dev Emitted on borrow() and flashLoan() when debt needs to be opened - * @param reserve The address of the underlying asset being borrowed - * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just - * initiator of the transaction on flashLoan() - * @param onBehalfOf The address that will be getting the debt - * @param amount The amount borrowed out - * @param interestRateMode The rate mode: 1 for Stable, 2 for Variable - * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray - * @param referralCode The referral code used - **/ - event Borrow( - address indexed reserve, - address user, - address indexed onBehalfOf, - uint256 amount, - DataTypes.InterestRateMode interestRateMode, - uint256 borrowRate, - uint16 indexed referralCode - ); - - /** - * @dev Emitted on repay() - * @param reserve The address of the underlying asset of the reserve - * @param user The beneficiary of the repayment, getting his debt reduced - * @param repayer The address of the user initiating the repay(), providing the funds - * @param amount The amount repaid - * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly - **/ - event Repay( - address indexed reserve, - address indexed user, - address indexed repayer, - uint256 amount, - bool useATokens - ); - - /** - * @dev Emitted on swapBorrowRateMode() - * @param reserve The address of the underlying asset of the reserve - * @param user The address of the user swapping his rate mode - * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable - **/ - event SwapBorrowRateMode( - address indexed reserve, - address indexed user, - DataTypes.InterestRateMode interestRateMode - ); - - /** - * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets - * @param asset The address of the underlying asset of the reserve - * @param totalDebt The total isolation mode debt for the reserve - */ - event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); - - /** - * @dev Emitted when the user selects a certain asset category for eMode - * @param user The address of the user - * @param categoryId The category id - **/ - event UserEModeSet(address indexed user, uint8 categoryId); - - /** - * @dev Emitted on setUserUseReserveAsCollateral() - * @param reserve The address of the underlying asset of the reserve - * @param user The address of the user enabling the usage as collateral - **/ - event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); - - /** - * @dev Emitted on setUserUseReserveAsCollateral() - * @param reserve The address of the underlying asset of the reserve - * @param user The address of the user enabling the usage as collateral - **/ - event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); - - /** - * @dev Emitted on rebalanceStableBorrowRate() - * @param reserve The address of the underlying asset of the reserve - * @param user The address of the user for which the rebalance has been executed - **/ - event RebalanceStableBorrowRate(address indexed reserve, address indexed user); - - /** - * @dev Emitted on flashLoan() - * @param target The address of the flash loan receiver contract - * @param initiator The address initiating the flash loan - * @param asset The address of the asset being flash borrowed - * @param amount The amount flash borrowed - * @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt - * @param premium The fee flash borrowed - * @param referralCode The referral code used - **/ - event FlashLoan( - address indexed target, - address initiator, - address indexed asset, - uint256 amount, - DataTypes.InterestRateMode interestRateMode, - uint256 premium, - uint16 indexed referralCode - ); - - /** - * @dev Emitted when a borrower is liquidated. - * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation - * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation - * @param user The address of the borrower getting liquidated - * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover - * @param liquidatedCollateralAmount The amount of collateral received by the liquidator - * @param liquidator The address of the liquidator - * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants - * to receive the underlying collateral asset directly - **/ - event LiquidationCall( - address indexed collateralAsset, - address indexed debtAsset, - address indexed user, - uint256 debtToCover, - uint256 liquidatedCollateralAmount, - address liquidator, - bool receiveAToken - ); - - /** - * @dev Emitted when the state of a reserve is updated. - * @param reserve The address of the underlying asset of the reserve - * @param liquidityRate The next liquidity rate - * @param stableBorrowRate The next stable borrow rate - * @param variableBorrowRate The next variable borrow rate - * @param liquidityIndex The next liquidity index - * @param variableBorrowIndex The next variable borrow index - **/ - event ReserveDataUpdated( - address indexed reserve, - uint256 liquidityRate, - uint256 stableBorrowRate, - uint256 variableBorrowRate, - uint256 liquidityIndex, - uint256 variableBorrowIndex - ); - - /** - * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest. - * @param reserve The address of the reserve - * @param amountMinted The amount minted to the treasury - **/ - event MintedToTreasury(address indexed reserve, uint256 amountMinted); - - /** - * @dev Mints an `amount` of aTokens to the `onBehalfOf` - * @param asset The address of the underlying asset to mint - * @param amount The amount to mint - * @param onBehalfOf The address that will receive the aTokens - * @param referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - **/ - function mintUnbacked( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external; - - /** - * @dev Back the current unbacked underlying with `amount` and pay `fee`. - * @param asset The address of the underlying asset to back - * @param amount The amount to back - * @param fee The amount paid in fees - **/ - function backUnbacked( - address asset, - uint256 amount, - uint256 fee - ) external; - - /** - * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. - * - E.g. User supplies 100 USDC and gets in return 100 aUSDC - * @param asset The address of the underlying asset to supply - * @param amount The amount to be supplied - * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user - * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens - * is a different wallet - * @param referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - **/ - function supply( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external; - - /** - * @notice Supply with transfer approval of asset to be supplied done via permit function - * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 - * @param asset The address of the underlying asset to supply - * @param amount The amount to be supplied - * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user - * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens - * is a different wallet - * @param deadline The deadline timestamp that the permit is valid - * @param referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - * @param permitV The V parameter of ERC712 permit sig - * @param permitR The R parameter of ERC712 permit sig - * @param permitS The S parameter of ERC712 permit sig - **/ - function supplyWithPermit( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) external; - - /** - * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned - * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC - * @param asset The address of the underlying asset to withdraw - * @param amount The underlying amount to be withdrawn - * - Send the value type(uint256).max in order to withdraw the whole aToken balance - * @param to The address that will receive the underlying, same as msg.sender if the user - * wants to receive it on his own wallet, or a different address if the beneficiary is a - * different wallet - * @return The final amount withdrawn - **/ - function withdraw( - address asset, - uint256 amount, - address to - ) external returns (uint256); - - /** - * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower - * already supplied enough collateral, or he was given enough allowance by a credit delegator on the - * corresponding debt token (StableDebtToken or VariableDebtToken) - * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet - * and 100 stable/variable debt tokens, depending on the `interestRateMode` - * @param asset The address of the underlying asset to borrow - * @param amount The amount to be borrowed - * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable - * @param referralCode The code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself - * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator - * if he has been given credit delegation allowance - **/ - function borrow( - address asset, - uint256 amount, - uint256 interestRateMode, - uint16 referralCode, - address onBehalfOf - ) external; - - /** - * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned - * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address - * @param asset The address of the borrowed underlying asset previously borrowed - * @param amount The amount to repay - * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` - * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable - * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the - * user calling the function if he wants to reduce/remove his own debt, or the address of any other - * other borrower whose debt should be removed - * @return The final amount repaid - **/ - function repay( - address asset, - uint256 amount, - uint256 interestRateMode, - address onBehalfOf - ) external returns (uint256); - - /** - * @notice Repay with transfer approval of asset to be repaid done via permit function - * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 - * @param asset The address of the borrowed underlying asset previously borrowed - * @param amount The amount to repay - * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` - * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable - * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the - * user calling the function if he wants to reduce/remove his own debt, or the address of any other - * other borrower whose debt should be removed - * @param deadline The deadline timestamp that the permit is valid - * @param permitV The V parameter of ERC712 permit sig - * @param permitR The R parameter of ERC712 permit sig - * @param permitS The S parameter of ERC712 permit sig - * @return The final amount repaid - **/ - function repayWithPermit( - address asset, - uint256 amount, - uint256 interestRateMode, - address onBehalfOf, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) external returns (uint256); - - /** - * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the - * equivalent debt tokens - * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens - * @dev Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken - * balance is not enough to cover the whole debt - * @param asset The address of the borrowed underlying asset previously borrowed - * @param amount The amount to repay - * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` - * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable - * @return The final amount repaid - **/ - function repayWithATokens( - address asset, - uint256 amount, - uint256 interestRateMode - ) external returns (uint256); - - /** - * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa - * @param asset The address of the underlying asset borrowed - * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable - **/ - function swapBorrowRateMode(address asset, uint256 interestRateMode) external; - - /** - * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. - * - Users can be rebalanced if the following conditions are satisfied: - * 1. Usage ratio is above 95% - * 2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too - * much has been borrowed at a stable rate and suppliers are not earning enough - * @param asset The address of the underlying asset borrowed - * @param user The address of the user to be rebalanced - **/ - function rebalanceStableBorrowRate(address asset, address user) external; - - /** - * @notice Allows suppliers to enable/disable a specific supplied asset as collateral - * @param asset The address of the underlying asset supplied - * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise - **/ - function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; - - /** - * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 - * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives - * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk - * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation - * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation - * @param user The address of the borrower getting liquidated - * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover - * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants - * to receive the underlying collateral asset directly - **/ - function liquidationCall( - address collateralAsset, - address debtAsset, - address user, - uint256 debtToCover, - bool receiveAToken - ) external; - - /** - * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, - * as long as the amount taken plus a fee is returned. - * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept - * into consideration. For further details please visit https://developers.aave.com - * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface - * @param assets The addresses of the assets being flash-borrowed - * @param amounts The amounts of the assets being flash-borrowed - * @param interestRateModes Types of the debt to open if the flash loan is not returned: - * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver - * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address - * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address - * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 - * @param params Variadic packed params to pass to the receiver as extra information - * @param referralCode The code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - **/ - function flashLoan( - address receiverAddress, - address[] calldata assets, - uint256[] calldata amounts, - uint256[] calldata interestRateModes, - address onBehalfOf, - bytes calldata params, - uint16 referralCode - ) external; - - /** - * @notice Allows smartcontracts to access the liquidity of the pool within one transaction, - * as long as the amount taken plus a fee is returned. - * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept - * into consideration. For further details please visit https://developers.aave.com - * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface - * @param asset The address of the asset being flash-borrowed - * @param amount The amount of the asset being flash-borrowed - * @param params Variadic packed params to pass to the receiver as extra information - * @param referralCode The code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - **/ - function flashLoanSimple( - address receiverAddress, - address asset, - uint256 amount, - bytes calldata params, - uint16 referralCode - ) external; - - /** - * @notice Returns the user account data across all the reserves - * @param user The address of the user - * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed - * @return totalDebtBase The total debt of the user in the base currency used by the price feed - * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed - * @return currentLiquidationThreshold The liquidation threshold of the user - * @return ltv The loan to value of The user - * @return healthFactor The current health factor of the user - **/ - function getUserAccountData(address user) - external - view - returns ( - uint256 totalCollateralBase, - uint256 totalDebtBase, - uint256 availableBorrowsBase, - uint256 currentLiquidationThreshold, - uint256 ltv, - uint256 healthFactor - ); - - /** - * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an - * interest rate strategy - * @dev Only callable by the PoolConfigurator contract - * @param asset The address of the underlying asset of the reserve - * @param aTokenAddress The address of the aToken that will be assigned to the reserve - * @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve - * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve - * @param interestRateStrategyAddress The address of the interest rate strategy contract - **/ - function initReserve( - address asset, - address aTokenAddress, - address stableDebtAddress, - address variableDebtAddress, - address interestRateStrategyAddress - ) external; - - /** - * @notice Drop a reserve - * @dev Only callable by the PoolConfigurator contract - * @param asset The address of the underlying asset of the reserve - **/ - function dropReserve(address asset) external; - - /** - * @notice Updates the address of the interest rate strategy contract - * @dev Only callable by the PoolConfigurator contract - * @param asset The address of the underlying asset of the reserve - * @param rateStrategyAddress The address of the interest rate strategy contract - **/ - function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) - external; - - /** - * @notice Sets the configuration bitmap of the reserve as a whole - * @dev Only callable by the PoolConfigurator contract - * @param asset The address of the underlying asset of the reserve - * @param configuration The new configuration bitmap - **/ - function setConfiguration(address asset, DataTypes.ReserveConfigurationMap calldata configuration) - external; - - /** - * @notice Returns the configuration of the reserve - * @param asset The address of the underlying asset of the reserve - * @return The configuration of the reserve - **/ - function getConfiguration(address asset) - external - view - returns (DataTypes.ReserveConfigurationMap memory); - - /** - * @notice Returns the configuration of the user across all the reserves - * @param user The user address - * @return The configuration of the user - **/ - function getUserConfiguration(address user) - external - view - returns (DataTypes.UserConfigurationMap memory); - - /** - * @notice Returns the normalized income normalized income of the reserve - * @param asset The address of the underlying asset of the reserve - * @return The reserve's normalized income - */ - function getReserveNormalizedIncome(address asset) external view returns (uint256); - - /** - * @notice Returns the normalized variable debt per unit of asset - * @param asset The address of the underlying asset of the reserve - * @return The reserve normalized variable debt - */ - function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); - - /** - * @notice Returns the state and configuration of the reserve - * @param asset The address of the underlying asset of the reserve - * @return The state and configuration data of the reserve - **/ - function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); - - /** - * @notice Validates and finalizes an aToken transfer - * @dev Only callable by the overlying aToken of the `asset` - * @param asset The address of the underlying asset of the aToken - * @param from The user from which the aTokens are transferred - * @param to The user receiving the aTokens - * @param amount The amount being transferred/withdrawn - * @param balanceFromBefore The aToken balance of the `from` user before the transfer - * @param balanceToBefore The aToken balance of the `to` user before the transfer - */ - function finalizeTransfer( - address asset, - address from, - address to, - uint256 amount, - uint256 balanceFromBefore, - uint256 balanceToBefore - ) external; - - /** - * @notice Returns the list of the underlying assets of all the initialized reserves - * @dev It does not include dropped reserves - * @return The addresses of the underlying assets of the initialized reserves - **/ - function getReservesList() external view returns (address[] memory); - - /** - * @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct - * @param id The id of the reserve as stored in the DataTypes.ReserveData struct - * @return The address of the reserve associated with id - **/ - function getReserveAddressById(uint16 id) external view returns (address); - - /** - * @notice Returns the PoolAddressesProvider connected to this contract - * @return The address of the PoolAddressesProvider - **/ - function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); - - /** - * @notice Updates the protocol fee on the bridging - * @param bridgeProtocolFee The part of the premium sent to the protocol treasury - */ - function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external; - - /** - * @notice Updates flash loan premiums. Flash loan premium consists of two parts: - * - A part is sent to aToken holders as extra, one time accumulated interest - * - A part is collected by the protocol treasury - * @dev The total premium is calculated on the total borrowed amount - * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal` - * @dev Only callable by the PoolConfigurator contract - * @param flashLoanPremiumTotal The total premium, expressed in bps - * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps - */ - function updateFlashloanPremiums( - uint128 flashLoanPremiumTotal, - uint128 flashLoanPremiumToProtocol - ) external; - - /** - * @notice Configures a new category for the eMode. - * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category. - * The category 0 is reserved as it's the default for volatile assets - * @param id The id of the category - * @param config The configuration of the category - */ - function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory config) external; - - /** - * @notice Returns the data of an eMode category - * @param id The id of the category - * @return The configuration data of the category - */ - function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory); - - /** - * @notice Allows a user to use the protocol in eMode - * @param categoryId The id of the category - */ - function setUserEMode(uint8 categoryId) external; - - /** - * @notice Returns the eMode the user is using - * @param user The address of the user - * @return The eMode id - */ - function getUserEMode(address user) external view returns (uint256); - - /** - * @notice Resets the isolation mode total debt of the given asset to zero - * @dev It requires the given asset has zero debt ceiling - * @param asset The address of the underlying asset to reset the isolationModeTotalDebt - */ - function resetIsolationModeTotalDebt(address asset) external; - - /** - * @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate - * @return The percentage of available liquidity to borrow, expressed in bps - */ - function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256); - - /** - * @notice Returns the total fee on flash loans - * @return The total fee on flashloans - */ - function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128); - - /** - * @notice Returns the part of the bridge fees sent to protocol - * @return The bridge fee sent to the protocol treasury - */ - function BRIDGE_PROTOCOL_FEE() external view returns (uint256); - - /** - * @notice Returns the part of the flashloan fees sent to protocol - * @return The flashloan fee sent to the protocol treasury - */ - function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128); - - /** - * @notice Returns the maximum number of reserves supported to be listed in this Pool - * @return The maximum number of reserves supported - */ - function MAX_NUMBER_RESERVES() external view returns (uint16); - - /** - * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens - * @param assets The list of reserves for which the minting needs to be executed - **/ - function mintToTreasury(address[] calldata assets) external; - - /** - * @notice Rescue and transfer tokens locked in this contract - * @param token The address of the token - * @param to The address of the recipient - * @param amount The amount of token to transfer - */ - function rescueTokens( - address token, - address to, - uint256 amount - ) external; - - /** - * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. - * - E.g. User supplies 100 USDC and gets in return 100 aUSDC - * @dev Deprecated: Use the `supply` function instead - * @param asset The address of the underlying asset to supply - * @param amount The amount to be supplied - * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user - * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens - * is a different wallet - * @param referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - **/ - function deposit( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol deleted file mode 100644 index 01a126b..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title IPoolAddressesProvider - * @author Aave - * @notice Defines the basic interface for a Pool Addresses Provider. - **/ -interface IPoolAddressesProvider { - /** - * @dev Emitted when the market identifier is updated. - * @param oldMarketId The old id of the market - * @param newMarketId The new id of the market - */ - event MarketIdSet(string indexed oldMarketId, string indexed newMarketId); - - /** - * @dev Emitted when the pool is updated. - * @param oldAddress The old address of the Pool - * @param newAddress The new address of the Pool - */ - event PoolUpdated(address indexed oldAddress, address indexed newAddress); - - /** - * @dev Emitted when the pool configurator is updated. - * @param oldAddress The old address of the PoolConfigurator - * @param newAddress The new address of the PoolConfigurator - */ - event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress); - - /** - * @dev Emitted when the price oracle is updated. - * @param oldAddress The old address of the PriceOracle - * @param newAddress The new address of the PriceOracle - */ - event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress); - - /** - * @dev Emitted when the ACL manager is updated. - * @param oldAddress The old address of the ACLManager - * @param newAddress The new address of the ACLManager - */ - event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress); - - /** - * @dev Emitted when the ACL admin is updated. - * @param oldAddress The old address of the ACLAdmin - * @param newAddress The new address of the ACLAdmin - */ - event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress); - - /** - * @dev Emitted when the price oracle sentinel is updated. - * @param oldAddress The old address of the PriceOracleSentinel - * @param newAddress The new address of the PriceOracleSentinel - */ - event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress); - - /** - * @dev Emitted when the pool data provider is updated. - * @param oldAddress The old address of the PoolDataProvider - * @param newAddress The new address of the PoolDataProvider - */ - event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress); - - /** - * @dev Emitted when a new proxy is created. - * @param id The identifier of the proxy - * @param proxyAddress The address of the created proxy contract - * @param implementationAddress The address of the implementation contract - */ - event ProxyCreated( - bytes32 indexed id, - address indexed proxyAddress, - address indexed implementationAddress - ); - - /** - * @dev Emitted when a new non-proxied contract address is registered. - * @param id The identifier of the contract - * @param oldAddress The address of the old contract - * @param newAddress The address of the new contract - */ - event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress); - - /** - * @dev Emitted when the implementation of the proxy registered with id is updated - * @param id The identifier of the contract - * @param proxyAddress The address of the proxy contract - * @param oldImplementationAddress The address of the old implementation contract - * @param newImplementationAddress The address of the new implementation contract - */ - event AddressSetAsProxy( - bytes32 indexed id, - address indexed proxyAddress, - address oldImplementationAddress, - address indexed newImplementationAddress - ); - - /** - * @notice Returns the id of the Aave market to which this contract points to. - * @return The market id - **/ - function getMarketId() external view returns (string memory); - - /** - * @notice Associates an id with a specific PoolAddressesProvider. - * @dev This can be used to create an onchain registry of PoolAddressesProviders to - * identify and validate multiple Aave markets. - * @param newMarketId The market id - */ - function setMarketId(string calldata newMarketId) external; - - /** - * @notice Returns an address by its identifier. - * @dev The returned address might be an EOA or a contract, potentially proxied - * @dev It returns ZERO if there is no registered address with the given id - * @param id The id - * @return The address of the registered for the specified id - */ - function getAddress(bytes32 id) external view returns (address); - - /** - * @notice General function to update the implementation of a proxy registered with - * certain `id`. If there is no proxy registered, it will instantiate one and - * set as implementation the `newImplementationAddress`. - * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit - * setter function, in order to avoid unexpected consequences - * @param id The id - * @param newImplementationAddress The address of the new implementation - */ - function setAddressAsProxy(bytes32 id, address newImplementationAddress) external; - - /** - * @notice Sets an address for an id replacing the address saved in the addresses map. - * @dev IMPORTANT Use this function carefully, as it will do a hard replacement - * @param id The id - * @param newAddress The address to set - */ - function setAddress(bytes32 id, address newAddress) external; - - /** - * @notice Returns the address of the Pool proxy. - * @return The Pool proxy address - **/ - function getPool() external view returns (address); - - /** - * @notice Updates the implementation of the Pool, or creates a proxy - * setting the new `pool` implementation when the function is called for the first time. - * @param newPoolImpl The new Pool implementation - **/ - function setPoolImpl(address newPoolImpl) external; - - /** - * @notice Returns the address of the PoolConfigurator proxy. - * @return The PoolConfigurator proxy address - **/ - function getPoolConfigurator() external view returns (address); - - /** - * @notice Updates the implementation of the PoolConfigurator, or creates a proxy - * setting the new `PoolConfigurator` implementation when the function is called for the first time. - * @param newPoolConfiguratorImpl The new PoolConfigurator implementation - **/ - function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external; - - /** - * @notice Returns the address of the price oracle. - * @return The address of the PriceOracle - */ - function getPriceOracle() external view returns (address); - - /** - * @notice Updates the address of the price oracle. - * @param newPriceOracle The address of the new PriceOracle - */ - function setPriceOracle(address newPriceOracle) external; - - /** - * @notice Returns the address of the ACL manager. - * @return The address of the ACLManager - */ - function getACLManager() external view returns (address); - - /** - * @notice Updates the address of the ACL manager. - * @param newAclManager The address of the new ACLManager - **/ - function setACLManager(address newAclManager) external; - - /** - * @notice Returns the address of the ACL admin. - * @return The address of the ACL admin - */ - function getACLAdmin() external view returns (address); - - /** - * @notice Updates the address of the ACL admin. - * @param newAclAdmin The address of the new ACL admin - */ - function setACLAdmin(address newAclAdmin) external; - - /** - * @notice Returns the address of the price oracle sentinel. - * @return The address of the PriceOracleSentinel - */ - function getPriceOracleSentinel() external view returns (address); - - /** - * @notice Updates the address of the price oracle sentinel. - * @param newPriceOracleSentinel The address of the new PriceOracleSentinel - **/ - function setPriceOracleSentinel(address newPriceOracleSentinel) external; - - /** - * @notice Returns the address of the data provider. - * @return The address of the DataProvider - */ - function getPoolDataProvider() external view returns (address); - - /** - * @notice Updates the address of the data provider. - * @param newDataProvider The address of the new DataProvider - **/ - function setPoolDataProvider(address newDataProvider) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolAddressesProviderRegistry.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolAddressesProviderRegistry.sol deleted file mode 100644 index a48ff20..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolAddressesProviderRegistry.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title IPoolAddressesProviderRegistry - * @author Aave - * @notice Defines the basic interface for an Aave Pool Addresses Provider Registry. - **/ -interface IPoolAddressesProviderRegistry { - /** - * @dev Emitted when a new AddressesProvider is registered. - * @param addressesProvider The address of the registered PoolAddressesProvider - * @param id The id of the registered PoolAddressesProvider - */ - event AddressesProviderRegistered(address indexed addressesProvider, uint256 indexed id); - - /** - * @dev Emitted when an AddressesProvider is unregistered. - * @param addressesProvider The address of the unregistered PoolAddressesProvider - * @param id The id of the unregistered PoolAddressesProvider - */ - event AddressesProviderUnregistered(address indexed addressesProvider, uint256 indexed id); - - /** - * @notice Returns the list of registered addresses providers - * @return The list of addresses providers - **/ - function getAddressesProvidersList() external view returns (address[] memory); - - /** - * @notice Returns the id of a registered PoolAddressesProvider - * @param addressesProvider The address of the PoolAddressesProvider - * @return The id of the PoolAddressesProvider or 0 if is not registered - */ - function getAddressesProviderIdByAddress(address addressesProvider) - external - view - returns (uint256); - - /** - * @notice Returns the address of a registered PoolAddressesProvider - * @param id The id of the market - * @return The address of the PoolAddressesProvider with the given id or zero address if it is not registered - */ - function getAddressesProviderAddressById(uint256 id) external view returns (address); - - /** - * @notice Registers an addresses provider - * @dev The PoolAddressesProvider must not already be registered in the registry - * @dev The id must not be used by an already registered PoolAddressesProvider - * @param provider The address of the new PoolAddressesProvider - * @param id The id for the new PoolAddressesProvider, referring to the market it belongs to - **/ - function registerAddressesProvider(address provider, uint256 id) external; - - /** - * @notice Removes an addresses provider from the list of registered addresses providers - * @param provider The PoolAddressesProvider address - **/ - function unregisterAddressesProvider(address provider) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolConfigurator.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolConfigurator.sol deleted file mode 100644 index d84454a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolConfigurator.sol +++ /dev/null @@ -1,468 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {ConfiguratorInputTypes} from '../protocol/libraries/types/ConfiguratorInputTypes.sol'; - -/** - * @title IPoolConfigurator - * @author Aave - * @notice Defines the basic interface for a Pool configurator. - **/ -interface IPoolConfigurator { - /** - * @dev Emitted when a reserve is initialized. - * @param asset The address of the underlying asset of the reserve - * @param aToken The address of the associated aToken contract - * @param stableDebtToken The address of the associated stable rate debt token - * @param variableDebtToken The address of the associated variable rate debt token - * @param interestRateStrategyAddress The address of the interest rate strategy for the reserve - **/ - event ReserveInitialized( - address indexed asset, - address indexed aToken, - address stableDebtToken, - address variableDebtToken, - address interestRateStrategyAddress - ); - - /** - * @dev Emitted when borrowing is enabled or disabled on a reserve. - * @param asset The address of the underlying asset of the reserve - * @param enabled True if borrowing is enabled, false otherwise - **/ - event ReserveBorrowing(address indexed asset, bool enabled); - - /** - * @dev Emitted when the collateralization risk parameters for the specified asset are updated. - * @param asset The address of the underlying asset of the reserve - * @param ltv The loan to value of the asset when used as collateral - * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized - * @param liquidationBonus The bonus liquidators receive to liquidate this asset - **/ - event CollateralConfigurationChanged( - address indexed asset, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus - ); - - /** - * @dev Emitted when stable rate borrowing is enabled or disabled on a reserve - * @param asset The address of the underlying asset of the reserve - * @param enabled True if stable rate borrowing is enabled, false otherwise - **/ - event ReserveStableRateBorrowing(address indexed asset, bool enabled); - - /** - * @dev Emitted when a reserve is activated or deactivated - * @param asset The address of the underlying asset of the reserve - * @param active True if reserve is active, false otherwise - **/ - event ReserveActive(address indexed asset, bool active); - - /** - * @dev Emitted when a reserve is frozen or unfrozen - * @param asset The address of the underlying asset of the reserve - * @param frozen True if reserve is frozen, false otherwise - **/ - event ReserveFrozen(address indexed asset, bool frozen); - - /** - * @dev Emitted when a reserve is paused or unpaused - * @param asset The address of the underlying asset of the reserve - * @param paused True if reserve is paused, false otherwise - **/ - event ReservePaused(address indexed asset, bool paused); - - /** - * @dev Emitted when a reserve is dropped. - * @param asset The address of the underlying asset of the reserve - **/ - event ReserveDropped(address indexed asset); - - /** - * @dev Emitted when a reserve factor is updated. - * @param asset The address of the underlying asset of the reserve - * @param oldReserveFactor The old reserve factor, expressed in bps - * @param newReserveFactor The new reserve factor, expressed in bps - **/ - event ReserveFactorChanged( - address indexed asset, - uint256 oldReserveFactor, - uint256 newReserveFactor - ); - - /** - * @dev Emitted when the borrow cap of a reserve is updated. - * @param asset The address of the underlying asset of the reserve - * @param oldBorrowCap The old borrow cap - * @param newBorrowCap The new borrow cap - **/ - event BorrowCapChanged(address indexed asset, uint256 oldBorrowCap, uint256 newBorrowCap); - - /** - * @dev Emitted when the supply cap of a reserve is updated. - * @param asset The address of the underlying asset of the reserve - * @param oldSupplyCap The old supply cap - * @param newSupplyCap The new supply cap - **/ - event SupplyCapChanged(address indexed asset, uint256 oldSupplyCap, uint256 newSupplyCap); - - /** - * @dev Emitted when the liquidation protocol fee of a reserve is updated. - * @param asset The address of the underlying asset of the reserve - * @param oldFee The old liquidation protocol fee, expressed in bps - * @param newFee The new liquidation protocol fee, expressed in bps - **/ - event LiquidationProtocolFeeChanged(address indexed asset, uint256 oldFee, uint256 newFee); - - /** - * @dev Emitted when the unbacked mint cap of a reserve is updated. - * @param asset The address of the underlying asset of the reserve - * @param oldUnbackedMintCap The old unbacked mint cap - * @param newUnbackedMintCap The new unbacked mint cap - */ - event UnbackedMintCapChanged( - address indexed asset, - uint256 oldUnbackedMintCap, - uint256 newUnbackedMintCap - ); - - /** - * @dev Emitted when the category of an asset in eMode is changed. - * @param asset The address of the underlying asset of the reserve - * @param oldCategoryId The old eMode asset category - * @param newCategoryId The new eMode asset category - **/ - event EModeAssetCategoryChanged(address indexed asset, uint8 oldCategoryId, uint8 newCategoryId); - - /** - * @dev Emitted when a new eMode category is added. - * @param categoryId The new eMode category id - * @param ltv The ltv for the asset category in eMode - * @param liquidationThreshold The liquidationThreshold for the asset category in eMode - * @param liquidationBonus The liquidationBonus for the asset category in eMode - * @param oracle The optional address of the price oracle specific for this category - * @param label A human readable identifier for the category - **/ - event EModeCategoryAdded( - uint8 indexed categoryId, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus, - address oracle, - string label - ); - - /** - * @dev Emitted when a reserve interest strategy contract is updated. - * @param asset The address of the underlying asset of the reserve - * @param oldStrategy The address of the old interest strategy contract - * @param newStrategy The address of the new interest strategy contract - **/ - event ReserveInterestRateStrategyChanged( - address indexed asset, - address oldStrategy, - address newStrategy - ); - - /** - * @dev Emitted when an aToken implementation is upgraded. - * @param asset The address of the underlying asset of the reserve - * @param proxy The aToken proxy address - * @param implementation The new aToken implementation - **/ - event ATokenUpgraded( - address indexed asset, - address indexed proxy, - address indexed implementation - ); - - /** - * @dev Emitted when the implementation of a stable debt token is upgraded. - * @param asset The address of the underlying asset of the reserve - * @param proxy The stable debt token proxy address - * @param implementation The new aToken implementation - **/ - event StableDebtTokenUpgraded( - address indexed asset, - address indexed proxy, - address indexed implementation - ); - - /** - * @dev Emitted when the implementation of a variable debt token is upgraded. - * @param asset The address of the underlying asset of the reserve - * @param proxy The variable debt token proxy address - * @param implementation The new aToken implementation - **/ - event VariableDebtTokenUpgraded( - address indexed asset, - address indexed proxy, - address indexed implementation - ); - - /** - * @dev Emitted when the debt ceiling of an asset is set. - * @param asset The address of the underlying asset of the reserve - * @param oldDebtCeiling The old debt ceiling - * @param newDebtCeiling The new debt ceiling - **/ - event DebtCeilingChanged(address indexed asset, uint256 oldDebtCeiling, uint256 newDebtCeiling); - - /** - * @dev Emitted when the the siloed borrowing state for an asset is changed. - * @param asset The address of the underlying asset of the reserve - * @param oldState The old siloed borrowing state - * @param newState The new siloed borrowing state - **/ - event SiloedBorrowingChanged(address indexed asset, bool oldState, bool newState); - - /** - * @dev Emitted when the bridge protocol fee is updated. - * @param oldBridgeProtocolFee The old protocol fee, expressed in bps - * @param newBridgeProtocolFee The new protocol fee, expressed in bps - */ - event BridgeProtocolFeeUpdated(uint256 oldBridgeProtocolFee, uint256 newBridgeProtocolFee); - - /** - * @dev Emitted when the total premium on flashloans is updated. - * @param oldFlashloanPremiumTotal The old premium, expressed in bps - * @param newFlashloanPremiumTotal The new premium, expressed in bps - **/ - event FlashloanPremiumTotalUpdated( - uint128 oldFlashloanPremiumTotal, - uint128 newFlashloanPremiumTotal - ); - - /** - * @dev Emitted when the part of the premium that goes to protocol is updated. - * @param oldFlashloanPremiumToProtocol The old premium, expressed in bps - * @param newFlashloanPremiumToProtocol The new premium, expressed in bps - **/ - event FlashloanPremiumToProtocolUpdated( - uint128 oldFlashloanPremiumToProtocol, - uint128 newFlashloanPremiumToProtocol - ); - - /** - * @dev Emitted when the reserve is set as borrowable/non borrowable in isolation mode. - * @param asset The address of the underlying asset of the reserve - * @param borrowable True if the reserve is borrowable in isolation, false otherwise - **/ - event BorrowableInIsolationChanged(address asset, bool borrowable); - - /** - * @notice Initializes multiple reserves. - * @param input The array of initialization parameters - **/ - function initReserves(ConfiguratorInputTypes.InitReserveInput[] calldata input) external; - - /** - * @dev Updates the aToken implementation for the reserve. - * @param input The aToken update parameters - **/ - function updateAToken(ConfiguratorInputTypes.UpdateATokenInput calldata input) external; - - /** - * @notice Updates the stable debt token implementation for the reserve. - * @param input The stableDebtToken update parameters - **/ - function updateStableDebtToken(ConfiguratorInputTypes.UpdateDebtTokenInput calldata input) - external; - - /** - * @notice Updates the variable debt token implementation for the asset. - * @param input The variableDebtToken update parameters - **/ - function updateVariableDebtToken(ConfiguratorInputTypes.UpdateDebtTokenInput calldata input) - external; - - /** - * @notice Configures borrowing on a reserve. - * @dev Can only be disabled (set to false) if stable borrowing is disabled - * @param asset The address of the underlying asset of the reserve - * @param enabled True if borrowing needs to be enabled, false otherwise - **/ - function setReserveBorrowing(address asset, bool enabled) external; - - /** - * @notice Configures the reserve collateralization parameters. - * @dev All the values are expressed in bps. A value of 10000, results in 100.00% - * @dev The `liquidationBonus` is always above 100%. A value of 105% means the liquidator will receive a 5% bonus - * @param asset The address of the underlying asset of the reserve - * @param ltv The loan to value of the asset when used as collateral - * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized - * @param liquidationBonus The bonus liquidators receive to liquidate this asset - **/ - function configureReserveAsCollateral( - address asset, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus - ) external; - - /** - * @notice Enable or disable stable rate borrowing on a reserve. - * @dev Can only be enabled (set to true) if borrowing is enabled - * @param asset The address of the underlying asset of the reserve - * @param enabled True if stable rate borrowing needs to be enabled, false otherwise - **/ - function setReserveStableRateBorrowing(address asset, bool enabled) external; - - /** - * @notice Activate or deactivate a reserve - * @param asset The address of the underlying asset of the reserve - * @param active True if the reserve needs to be active, false otherwise - **/ - function setReserveActive(address asset, bool active) external; - - /** - * @notice Freeze or unfreeze a reserve. A frozen reserve doesn't allow any new supply, borrow - * or rate swap but allows repayments, liquidations, rate rebalances and withdrawals. - * @param asset The address of the underlying asset of the reserve - * @param freeze True if the reserve needs to be frozen, false otherwise - **/ - function setReserveFreeze(address asset, bool freeze) external; - - /** - * @notice Sets the borrowable in isolation flag for the reserve. - * @dev When this flag is set to true, the asset will be borrowable against isolated collaterals and the - * borrowed amount will be accumulated in the isolated collateral's total debt exposure - * @dev Only assets of the same family (e.g. USD stablecoins) should be borrowable in isolation mode to keep - * consistency in the debt ceiling calculations - * @param asset The address of the underlying asset of the reserve - * @param borrowable True if the asset should be borrowable in isolation, false otherwise - **/ - function setBorrowableInIsolation(address asset, bool borrowable) external; - - /** - * @notice Pauses a reserve. A paused reserve does not allow any interaction (supply, borrow, repay, - * swap interest rate, liquidate, atoken transfers). - * @param asset The address of the underlying asset of the reserve - * @param paused True if pausing the reserve, false if unpausing - **/ - function setReservePause(address asset, bool paused) external; - - /** - * @notice Updates the reserve factor of a reserve. - * @param asset The address of the underlying asset of the reserve - * @param newReserveFactor The new reserve factor of the reserve - **/ - function setReserveFactor(address asset, uint256 newReserveFactor) external; - - /** - * @notice Sets the interest rate strategy of a reserve. - * @param asset The address of the underlying asset of the reserve - * @param newRateStrategyAddress The address of the new interest strategy contract - **/ - function setReserveInterestRateStrategyAddress(address asset, address newRateStrategyAddress) - external; - - /** - * @notice Pauses or unpauses all the protocol reserves. In the paused state all the protocol interactions - * are suspended. - * @param paused True if protocol needs to be paused, false otherwise - **/ - function setPoolPause(bool paused) external; - - /** - * @notice Updates the borrow cap of a reserve. - * @param asset The address of the underlying asset of the reserve - * @param newBorrowCap The new borrow cap of the reserve - **/ - function setBorrowCap(address asset, uint256 newBorrowCap) external; - - /** - * @notice Updates the supply cap of a reserve. - * @param asset The address of the underlying asset of the reserve - * @param newSupplyCap The new supply cap of the reserve - **/ - function setSupplyCap(address asset, uint256 newSupplyCap) external; - - /** - * @notice Updates the liquidation protocol fee of reserve. - * @param asset The address of the underlying asset of the reserve - * @param newFee The new liquidation protocol fee of the reserve, expressed in bps - **/ - function setLiquidationProtocolFee(address asset, uint256 newFee) external; - - /** - * @notice Updates the unbacked mint cap of reserve. - * @param asset The address of the underlying asset of the reserve - * @param newUnbackedMintCap The new unbacked mint cap of the reserve - **/ - function setUnbackedMintCap(address asset, uint256 newUnbackedMintCap) external; - - /** - * @notice Assign an efficiency mode (eMode) category to asset. - * @param asset The address of the underlying asset of the reserve - * @param newCategoryId The new category id of the asset - **/ - function setAssetEModeCategory(address asset, uint8 newCategoryId) external; - - /** - * @notice Adds a new efficiency mode (eMode) category. - * @dev If zero is provided as oracle address, the default asset oracles will be used to compute the overall debt and - * overcollateralization of the users using this category. - * @dev The new ltv and liquidation threshold must be greater than the base - * ltvs and liquidation thresholds of all assets within the eMode category - * @param categoryId The id of the category to be configured - * @param ltv The ltv associated with the category - * @param liquidationThreshold The liquidation threshold associated with the category - * @param liquidationBonus The liquidation bonus associated with the category - * @param oracle The oracle associated with the category - * @param label A label identifying the category - **/ - function setEModeCategory( - uint8 categoryId, - uint16 ltv, - uint16 liquidationThreshold, - uint16 liquidationBonus, - address oracle, - string calldata label - ) external; - - /** - * @notice Drops a reserve entirely. - * @param asset The address of the reserve to drop - **/ - function dropReserve(address asset) external; - - /** - * @notice Updates the bridge fee collected by the protocol reserves. - * @param newBridgeProtocolFee The part of the fee sent to the protocol treasury, expressed in bps - */ - function updateBridgeProtocolFee(uint256 newBridgeProtocolFee) external; - - /** - * @notice Updates the total flash loan premium. - * Total flash loan premium consists of two parts: - * - A part is sent to aToken holders as extra balance - * - A part is collected by the protocol reserves - * @dev Expressed in bps - * @dev The premium is calculated on the total amount borrowed - * @param newFlashloanPremiumTotal The total flashloan premium - */ - function updateFlashloanPremiumTotal(uint128 newFlashloanPremiumTotal) external; - - /** - * @notice Updates the flash loan premium collected by protocol reserves - * @dev Expressed in bps - * @dev The premium to protocol is calculated on the total flashloan premium - * @param newFlashloanPremiumToProtocol The part of the flashloan premium sent to the protocol treasury - */ - function updateFlashloanPremiumToProtocol(uint128 newFlashloanPremiumToProtocol) external; - - /** - * @notice Sets the debt ceiling for an asset. - * @param newDebtCeiling The new debt ceiling - */ - function setDebtCeiling(address asset, uint256 newDebtCeiling) external; - - /** - * @notice Sets siloed borrowing for an asset - * @param siloed The new siloed borrowing state - */ - function setSiloedBorrowing(address asset, bool siloed) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolDataProvider.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolDataProvider.sol deleted file mode 100644 index 331653a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPoolDataProvider.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -interface IPoolDataProvider { - /** - * @notice Returns the reserve data - * @param asset The address of the underlying asset of the reserve - * @return unbacked The amount of unbacked tokens - * @return accruedToTreasuryScaled The scaled amount of tokens accrued to treasury that is to be minted - * @return totalAToken The total supply of the aToken - * @return totalStableDebt The total stable debt of the reserve - * @return totalVariableDebt The total variable debt of the reserve - * @return liquidityRate The liquidity rate of the reserve - * @return variableBorrowRate The variable borrow rate of the reserve - * @return stableBorrowRate The stable borrow rate of the reserve - * @return averageStableBorrowRate The average stable borrow rate of the reserve - * @return liquidityIndex The liquidity index of the reserve - * @return variableBorrowIndex The variable borrow index of the reserve - * @return lastUpdateTimestamp The timestamp of the last update of the reserve - **/ - function getReserveData(address asset) - external - view - returns ( - uint256 unbacked, - uint256 accruedToTreasuryScaled, - uint256 totalAToken, - uint256 totalStableDebt, - uint256 totalVariableDebt, - uint256 liquidityRate, - uint256 variableBorrowRate, - uint256 stableBorrowRate, - uint256 averageStableBorrowRate, - uint256 liquidityIndex, - uint256 variableBorrowIndex, - uint40 lastUpdateTimestamp - ); - - /** - * @notice Returns the total supply of aTokens for a given asset - * @param asset The address of the underlying asset of the reserve - * @return The total supply of the aToken - **/ - function getATokenTotalSupply(address asset) external view returns (uint256); - - /** - * @notice Returns the total debt for a given asset - * @param asset The address of the underlying asset of the reserve - * @return The total debt for asset - **/ - function getTotalDebt(address asset) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracle.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracle.sol deleted file mode 100644 index 1f51f18..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracle.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title IPriceOracle - * @author Aave - * @notice Defines the basic interface for a Price oracle. - **/ -interface IPriceOracle { - /** - * @notice Returns the asset price in the base currency - * @param asset The address of the asset - * @return The price of the asset - **/ - function getAssetPrice(address asset) external view returns (uint256); - - /** - * @notice Set the price of the asset - * @param asset The address of the asset - * @param price The price of the asset - **/ - function setAssetPrice(address asset, uint256 price) external; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracleGetter.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracleGetter.sol deleted file mode 100644 index 92c1c46..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracleGetter.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title IPriceOracleGetter - * @author Aave - * @notice Interface for the Aave price oracle. - **/ -interface IPriceOracleGetter { - /** - * @notice Returns the base currency address - * @dev Address 0x0 is reserved for USD as base currency. - * @return Returns the base currency address. - **/ - function BASE_CURRENCY() external view returns (address); - - /** - * @notice Returns the base currency unit - * @dev 1 ether for ETH, 1e8 for USD. - * @return Returns the base currency unit. - **/ - function BASE_CURRENCY_UNIT() external view returns (uint256); - - /** - * @notice Returns the asset price in the base currency - * @param asset The address of the asset - * @return The price of the asset - **/ - function getAssetPrice(address asset) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracleSentinel.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracleSentinel.sol deleted file mode 100644 index 6d05bf0..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IPriceOracleSentinel.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol'; - -/** - * @title IPriceOracleSentinel - * @author Aave - * @notice Defines the basic interface for the PriceOracleSentinel - */ -interface IPriceOracleSentinel { - /** - * @dev Emitted after the sequencer oracle is updated - * @param newSequencerOracle The new sequencer oracle - */ - event SequencerOracleUpdated(address newSequencerOracle); - - /** - * @dev Emitted after the grace period is updated - * @param newGracePeriod The new grace period value - */ - event GracePeriodUpdated(uint256 newGracePeriod); - - /** - * @notice Returns the PoolAddressesProvider - * @return The address of the PoolAddressesProvider contract - */ - function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider); - - /** - * @notice Returns true if the `borrow` operation is allowed. - * @dev Operation not allowed when PriceOracle is down or grace period not passed. - * @return True if the `borrow` operation is allowed, false otherwise. - */ - function isBorrowAllowed() external view returns (bool); - - /** - * @notice Returns true if the `liquidation` operation is allowed. - * @dev Operation not allowed when PriceOracle is down or grace period not passed. - * @return True if the `liquidation` operation is allowed, false otherwise. - */ - function isLiquidationAllowed() external view returns (bool); - - /** - * @notice Updates the address of the sequencer oracle - * @param newSequencerOracle The address of the new Sequencer Oracle to use - */ - function setSequencerOracle(address newSequencerOracle) external; - - /** - * @notice Updates the duration of the grace period - * @param newGracePeriod The value of the new grace period duration - */ - function setGracePeriod(uint256 newGracePeriod) external; - - /** - * @notice Returns the SequencerOracle - * @return The address of the sequencer oracle contract - */ - function getSequencerOracle() external view returns (address); - - /** - * @notice Returns the grace period - * @return The duration of the grace period - */ - function getGracePeriod() external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IReserveInterestRateStrategy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IReserveInterestRateStrategy.sol deleted file mode 100644 index 5c9cbdc..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IReserveInterestRateStrategy.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; - -/** - * @title IReserveInterestRateStrategy - * @author Aave - * @notice Interface for the calculation of the interest rates - */ -interface IReserveInterestRateStrategy { - /** - * @notice Returns the base variable borrow rate - * @return The base variable borrow rate, expressed in ray - **/ - function getBaseVariableBorrowRate() external view returns (uint256); - - /** - * @notice Returns the maximum variable borrow rate - * @return The maximum variable borrow rate, expressed in ray - **/ - function getMaxVariableBorrowRate() external view returns (uint256); - - /** - * @notice Calculates the interest rates depending on the reserve's state and configurations - * @param params The parameters needed to calculate interest rates - * @return liquidityRate The liquidity rate expressed in rays - * @return stableBorrowRate The stable borrow rate expressed in rays - * @return variableBorrowRate The variable borrow rate expressed in rays - **/ - function calculateInterestRates(DataTypes.CalculateInterestRatesParams memory params) - external - view - returns ( - uint256, - uint256, - uint256 - ); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IScaledBalanceToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IScaledBalanceToken.sol deleted file mode 100644 index 901e875..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IScaledBalanceToken.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title IScaledBalanceToken - * @author Aave - * @notice Defines the basic interface for a scaledbalance token. - **/ -interface IScaledBalanceToken { - /** - * @dev Emitted after the mint action - * @param caller The address performing the mint - * @param onBehalfOf The address of the user that will receive the minted scaled balance tokens - * @param value The amount being minted (user entered amount + balance increase from interest) - * @param balanceIncrease The increase in balance since the last action of the user - * @param index The next liquidity index of the reserve - **/ - event Mint( - address indexed caller, - address indexed onBehalfOf, - uint256 value, - uint256 balanceIncrease, - uint256 index - ); - - /** - * @dev Emitted after scaled balance tokens are burned - * @param from The address from which the scaled tokens will be burned - * @param target The address that will receive the underlying, if any - * @param value The amount being burned (user entered amount - balance increase from interest) - * @param balanceIncrease The increase in balance since the last action of the user - * @param index The next liquidity index of the reserve - **/ - event Burn( - address indexed from, - address indexed target, - uint256 value, - uint256 balanceIncrease, - uint256 index - ); - - /** - * @notice Returns the scaled balance of the user. - * @dev The scaled balance is the sum of all the updated stored balance divided by the reserve's liquidity index - * at the moment of the update - * @param user The user whose balance is calculated - * @return The scaled balance of the user - **/ - function scaledBalanceOf(address user) external view returns (uint256); - - /** - * @notice Returns the scaled balance of the user and the scaled total supply. - * @param user The address of the user - * @return The scaled balance of the user - * @return The scaled total supply - **/ - function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); - - /** - * @notice Returns the scaled total supply of the scaled balance token. Represents sum(debt/index) - * @return The scaled total supply - **/ - function scaledTotalSupply() external view returns (uint256); - - /** - * @notice Returns last index interest was accrued to the user's balance - * @param user The address of the user - * @return The last index interest was accrued to the user's balance, expressed in ray - **/ - function getPreviousIndex(address user) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/ISequencerOracle.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/ISequencerOracle.sol deleted file mode 100644 index afb4896..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/ISequencerOracle.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title ISequencerOracle - * @author Aave - * @notice Defines the basic interface for a Sequencer oracle. - */ -interface ISequencerOracle { - /** - * @notice Returns the health status of the sequencer. - * @return roundId The round ID from the aggregator for which the data was retrieved combined with a phase to ensure - * that round IDs get larger as time moves forward. - * @return answer The answer for the latest round: 0 if the sequencer is up, 1 if it is down. - * @return startedAt The timestamp when the round was started. - * @return updatedAt The timestamp of the block in which the answer was updated on L1. - * @return answeredInRound The round ID of the round in which the answer was computed. - */ - function latestRoundData() - external - view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IStableDebtToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IStableDebtToken.sol deleted file mode 100644 index ad5cdb4..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IStableDebtToken.sol +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IInitializableDebtToken} from './IInitializableDebtToken.sol'; - -/** - * @title IStableDebtToken - * @author Aave - * @notice Defines the interface for the stable debt token - * @dev It does not inherit from IERC20 to save in code size - **/ -interface IStableDebtToken is IInitializableDebtToken { - /** - * @dev Emitted when new stable debt is minted - * @param user The address of the user who triggered the minting - * @param onBehalfOf The recipient of stable debt tokens - * @param amount The amount minted (user entered amount + balance increase from interest) - * @param currentBalance The current balance of the user - * @param balanceIncrease The increase in balance since the last action of the user - * @param newRate The rate of the debt after the minting - * @param avgStableRate The next average stable rate after the minting - * @param newTotalSupply The next total supply of the stable debt token after the action - **/ - event Mint( - address indexed user, - address indexed onBehalfOf, - uint256 amount, - uint256 currentBalance, - uint256 balanceIncrease, - uint256 newRate, - uint256 avgStableRate, - uint256 newTotalSupply - ); - - /** - * @dev Emitted when new stable debt is burned - * @param from The address from which the debt will be burned - * @param amount The amount being burned (user entered amount - balance increase from interest) - * @param currentBalance The current balance of the user - * @param balanceIncrease The the increase in balance since the last action of the user - * @param avgStableRate The next average stable rate after the burning - * @param newTotalSupply The next total supply of the stable debt token after the action - **/ - event Burn( - address indexed from, - uint256 amount, - uint256 currentBalance, - uint256 balanceIncrease, - uint256 avgStableRate, - uint256 newTotalSupply - ); - - /** - * @notice Mints debt token to the `onBehalfOf` address. - * @dev The resulting rate is the weighted average between the rate of the new debt - * and the rate of the previous debt - * @param user The address receiving the borrowed underlying, being the delegatee in case - * of credit delegate, or same as `onBehalfOf` otherwise - * @param onBehalfOf The address receiving the debt tokens - * @param amount The amount of debt tokens to mint - * @param rate The rate of the debt being minted - * @return True if it is the first borrow, false otherwise - * @return The total stable debt - * @return The average stable borrow rate - **/ - function mint( - address user, - address onBehalfOf, - uint256 amount, - uint256 rate - ) - external - returns ( - bool, - uint256, - uint256 - ); - - /** - * @notice Burns debt of `user` - * @dev The resulting rate is the weighted average between the rate of the new debt - * and the rate of the previous debt - * @dev In some instances, a burn transaction will emit a mint event - * if the amount to burn is less than the interest the user earned - * @param from The address from which the debt will be burned - * @param amount The amount of debt tokens getting burned - * @return The total stable debt - * @return The average stable borrow rate - **/ - function burn(address from, uint256 amount) external returns (uint256, uint256); - - /** - * @notice Returns the average rate of all the stable rate loans. - * @return The average stable rate - **/ - function getAverageStableRate() external view returns (uint256); - - /** - * @notice Returns the stable rate of the user debt - * @param user The address of the user - * @return The stable rate of the user - **/ - function getUserStableRate(address user) external view returns (uint256); - - /** - * @notice Returns the timestamp of the last update of the user - * @param user The address of the user - * @return The timestamp - **/ - function getUserLastUpdated(address user) external view returns (uint40); - - /** - * @notice Returns the principal, the total supply, the average stable rate and the timestamp for the last update - * @return The principal - * @return The total supply - * @return The average stable rate - * @return The timestamp of the last update - **/ - function getSupplyData() - external - view - returns ( - uint256, - uint256, - uint256, - uint40 - ); - - /** - * @notice Returns the timestamp of the last update of the total supply - * @return The timestamp - **/ - function getTotalSupplyLastUpdated() external view returns (uint40); - - /** - * @notice Returns the total supply and the average stable rate - * @return The total supply - * @return The average rate - **/ - function getTotalSupplyAndAvgRate() external view returns (uint256, uint256); - - /** - * @notice Returns the principal debt balance of the user - * @return The debt balance of the user since the last burn/mint action - **/ - function principalBalanceOf(address user) external view returns (uint256); - - /** - * @notice Returns the address of the underlying asset of this stableDebtToken (E.g. WETH for stableDebtWETH) - * @return The address of the underlying asset - **/ - function UNDERLYING_ASSET_ADDRESS() external view returns (address); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IVariableDebtToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IVariableDebtToken.sol deleted file mode 100644 index 59facb7..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/IVariableDebtToken.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; -import {IInitializableDebtToken} from './IInitializableDebtToken.sol'; - -/** - * @title IVariableDebtToken - * @author Aave - * @notice Defines the basic interface for a variable debt token. - **/ -interface IVariableDebtToken is IScaledBalanceToken, IInitializableDebtToken { - /** - * @notice Mints debt token to the `onBehalfOf` address - * @param user The address receiving the borrowed underlying, being the delegatee in case - * of credit delegate, or same as `onBehalfOf` otherwise - * @param onBehalfOf The address receiving the debt tokens - * @param amount The amount of debt being minted - * @param index The variable debt index of the reserve - * @return True if the previous balance of the user is 0, false otherwise - * @return The scaled total debt of the reserve - **/ - function mint( - address user, - address onBehalfOf, - uint256 amount, - uint256 index - ) external returns (bool, uint256); - - /** - * @notice Burns user variable debt - * @dev In some instances, a burn transaction will emit a mint event - * if the amount to burn is less than the interest that the user accrued - * @param from The address from which the debt will be burned - * @param amount The amount getting burned - * @param index The variable debt index of the reserve - * @return The scaled total debt of the reserve - **/ - function burn( - address from, - uint256 amount, - uint256 index - ) external returns (uint256); - - /** - * @notice Returns the address of the underlying asset of this debtToken (E.g. WETH for variableDebtWETH) - * @return The address of the underlying asset - **/ - function UNDERLYING_ASSET_ADDRESS() external view returns (address); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/LICENSE.md b/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/LICENSE.md deleted file mode 100644 index 506d18e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/interfaces/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/AaveOracle.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/misc/AaveOracle.sol deleted file mode 100644 index 99afe28..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/AaveOracle.sol +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {AggregatorInterface} from '../dependencies/chainlink/AggregatorInterface.sol'; -import {Errors} from '../protocol/libraries/helpers/Errors.sol'; -import {IACLManager} from '../interfaces/IACLManager.sol'; -import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; -import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; -import {IAaveOracle} from '../interfaces/IAaveOracle.sol'; - -/** - * @title AaveOracle - * @author Aave - * @notice Contract to get asset prices, manage price sources and update the fallback oracle - * - Use of Chainlink Aggregators as first source of price - * - If the returned price by a Chainlink aggregator is <= 0, the call is forwarded to a fallback oracle - * - Owned by the Aave governance - */ -contract AaveOracle is IAaveOracle { - IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; - - // Map of asset price sources (asset => priceSource) - mapping(address => AggregatorInterface) private assetsSources; - - IPriceOracleGetter private _fallbackOracle; - address public immutable override BASE_CURRENCY; - uint256 public immutable override BASE_CURRENCY_UNIT; - - /** - * @dev Only asset listing or pool admin can call functions marked by this modifier. - **/ - modifier onlyAssetListingOrPoolAdmins() { - _onlyAssetListingOrPoolAdmins(); - _; - } - - /** - * @notice Constructor - * @param provider The address of the new PoolAddressesProvider - * @param assets The addresses of the assets - * @param sources The address of the source of each asset - * @param fallbackOracle The address of the fallback oracle to use if the data of an - * aggregator is not consistent - * @param baseCurrency The base currency used for the price quotes. If USD is used, base currency is 0x0 - * @param baseCurrencyUnit The unit of the base currency - */ - constructor( - IPoolAddressesProvider provider, - address[] memory assets, - address[] memory sources, - address fallbackOracle, - address baseCurrency, - uint256 baseCurrencyUnit - ) { - ADDRESSES_PROVIDER = provider; - _setFallbackOracle(fallbackOracle); - _setAssetsSources(assets, sources); - BASE_CURRENCY = baseCurrency; - BASE_CURRENCY_UNIT = baseCurrencyUnit; - emit BaseCurrencySet(baseCurrency, baseCurrencyUnit); - } - - /// @inheritdoc IAaveOracle - function setAssetSources(address[] calldata assets, address[] calldata sources) - external - override - onlyAssetListingOrPoolAdmins - { - _setAssetsSources(assets, sources); - } - - /// @inheritdoc IAaveOracle - function setFallbackOracle(address fallbackOracle) - external - override - onlyAssetListingOrPoolAdmins - { - _setFallbackOracle(fallbackOracle); - } - - /** - * @notice Internal function to set the sources for each asset - * @param assets The addresses of the assets - * @param sources The address of the source of each asset - */ - function _setAssetsSources(address[] memory assets, address[] memory sources) internal { - require(assets.length == sources.length, Errors.INCONSISTENT_PARAMS_LENGTH); - for (uint256 i = 0; i < assets.length; i++) { - assetsSources[assets[i]] = AggregatorInterface(sources[i]); - emit AssetSourceUpdated(assets[i], sources[i]); - } - } - - /** - * @notice Internal function to set the fallback oracle - * @param fallbackOracle The address of the fallback oracle - */ - function _setFallbackOracle(address fallbackOracle) internal { - _fallbackOracle = IPriceOracleGetter(fallbackOracle); - emit FallbackOracleUpdated(fallbackOracle); - } - - /// @inheritdoc IPriceOracleGetter - function getAssetPrice(address asset) public view override returns (uint256) { - AggregatorInterface source = assetsSources[asset]; - - if (asset == BASE_CURRENCY) { - return BASE_CURRENCY_UNIT; - } else if (address(source) == address(0)) { - return _fallbackOracle.getAssetPrice(asset); - } else { - int256 price = source.latestAnswer(); - if (price > 0) { - return uint256(price); - } else { - return _fallbackOracle.getAssetPrice(asset); - } - } - } - - /// @inheritdoc IAaveOracle - function getAssetsPrices(address[] calldata assets) - external - view - override - returns (uint256[] memory) - { - uint256[] memory prices = new uint256[](assets.length); - for (uint256 i = 0; i < assets.length; i++) { - prices[i] = getAssetPrice(assets[i]); - } - return prices; - } - - /// @inheritdoc IAaveOracle - function getSourceOfAsset(address asset) external view override returns (address) { - return address(assetsSources[asset]); - } - - /// @inheritdoc IAaveOracle - function getFallbackOracle() external view returns (address) { - return address(_fallbackOracle); - } - - function _onlyAssetListingOrPoolAdmins() internal view { - IACLManager aclManager = IACLManager(ADDRESSES_PROVIDER.getACLManager()); - require( - aclManager.isAssetListingAdmin(msg.sender) || aclManager.isPoolAdmin(msg.sender), - Errors.CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN - ); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol deleted file mode 100644 index 21bef5d..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/AaveProtocolDataProvider.sol +++ /dev/null @@ -1,377 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; -import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; -import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; -import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol'; -import {IStableDebtToken} from '../interfaces/IStableDebtToken.sol'; -import {IVariableDebtToken} from '../interfaces/IVariableDebtToken.sol'; -import {IPool} from '../interfaces/IPool.sol'; -import {IPoolDataProvider} from '../interfaces/IPoolDataProvider.sol'; - -/** - * @title AaveProtocolDataProvider - * @author Aave - * @notice Peripheral contract to collect and pre-process information from the Pool. - */ -contract AaveProtocolDataProvider is IPoolDataProvider { - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using UserConfiguration for DataTypes.UserConfigurationMap; - using WadRayMath for uint256; - - address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2; - address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; - - struct TokenData { - string symbol; - address tokenAddress; - } - - IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; - - constructor(IPoolAddressesProvider addressesProvider) { - ADDRESSES_PROVIDER = addressesProvider; - } - - /** - * @notice Returns the list of the existing reserves in the pool. - * @dev Handling MKR and ETH in a different way since they do not have standard `symbol` functions. - * @return The list of reserves, pairs of symbols and addresses - */ - function getAllReservesTokens() external view returns (TokenData[] memory) { - IPool pool = IPool(ADDRESSES_PROVIDER.getPool()); - address[] memory reserves = pool.getReservesList(); - TokenData[] memory reservesTokens = new TokenData[](reserves.length); - for (uint256 i = 0; i < reserves.length; i++) { - if (reserves[i] == MKR) { - reservesTokens[i] = TokenData({symbol: 'MKR', tokenAddress: reserves[i]}); - continue; - } - if (reserves[i] == ETH) { - reservesTokens[i] = TokenData({symbol: 'ETH', tokenAddress: reserves[i]}); - continue; - } - reservesTokens[i] = TokenData({ - symbol: IERC20Detailed(reserves[i]).symbol(), - tokenAddress: reserves[i] - }); - } - return reservesTokens; - } - - /** - * @notice Returns the list of the existing ATokens in the pool. - * @return The list of ATokens, pairs of symbols and addresses - */ - function getAllATokens() external view returns (TokenData[] memory) { - IPool pool = IPool(ADDRESSES_PROVIDER.getPool()); - address[] memory reserves = pool.getReservesList(); - TokenData[] memory aTokens = new TokenData[](reserves.length); - for (uint256 i = 0; i < reserves.length; i++) { - DataTypes.ReserveData memory reserveData = pool.getReserveData(reserves[i]); - aTokens[i] = TokenData({ - symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(), - tokenAddress: reserveData.aTokenAddress - }); - } - return aTokens; - } - - /** - * @notice Returns the configuration data of the reserve - * @dev Not returning borrow and supply caps for compatibility, nor pause flag - * @param asset The address of the underlying asset of the reserve - * @return decimals The number of decimals of the reserve - * @return ltv The ltv of the reserve - * @return liquidationThreshold The liquidationThreshold of the reserve - * @return liquidationBonus The liquidationBonus of the reserve - * @return reserveFactor The reserveFactor of the reserve - * @return usageAsCollateralEnabled True if the usage as collateral is enabled, false otherwise - * @return borrowingEnabled True if borrowing is enabled, false otherwise - * @return stableBorrowRateEnabled True if stable rate borrowing is enabled, false otherwise - * @return isActive True if it is active, false otherwise - * @return isFrozen True if it is frozen, false otherwise - **/ - function getReserveConfigurationData(address asset) - external - view - returns ( - uint256 decimals, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus, - uint256 reserveFactor, - bool usageAsCollateralEnabled, - bool borrowingEnabled, - bool stableBorrowRateEnabled, - bool isActive, - bool isFrozen - ) - { - DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) - .getConfiguration(asset); - - (ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor, ) = configuration - .getParams(); - - (isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled, ) = configuration.getFlags(); - - usageAsCollateralEnabled = liquidationThreshold != 0; - } - - /** - * Returns the efficiency mode category of the reserve - * @param asset The address of the underlying asset of the reserve - * @return The eMode id of the reserve - */ - function getReserveEModeCategory(address asset) external view returns (uint256) { - DataTypes.ReserveConfigurationMap memory configuration = IPool(ADDRESSES_PROVIDER.getPool()) - .getConfiguration(asset); - return configuration.getEModeCategory(); - } - - /** - * @notice Returns the caps parameters of the reserve - * @param asset The address of the underlying asset of the reserve - * @return borrowCap The borrow cap of the reserve - * @return supplyCap The supply cap of the reserve - **/ - function getReserveCaps(address asset) - external - view - returns (uint256 borrowCap, uint256 supplyCap) - { - (borrowCap, supplyCap) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getCaps(); - } - - /** - * @notice Returns if the pool is paused - * @param asset The address of the underlying asset of the reserve - * @return isPaused True if the pool is paused, false otherwise - **/ - function getPaused(address asset) external view returns (bool isPaused) { - (, , , , isPaused) = IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getFlags(); - } - - /** - * @notice Returns the siloed borrowing flag - * @param asset The address of the underlying asset of the reserve - * @return True if the asset is siloed for borrowing - **/ - function getSiloedBorrowing(address asset) external view returns (bool) { - return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getSiloedBorrowing(); - } - - /** - * @notice Returns the protocol fee on the liquidation bonus - * @param asset The address of the underlying asset of the reserve - * @return The protocol fee on liquidation - **/ - function getLiquidationProtocolFee(address asset) external view returns (uint256) { - return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getLiquidationProtocolFee(); - } - - /** - * @notice Returns the unbacked mint cap of the reserve - * @param asset The address of the underlying asset of the reserve - * @return The unbacked mint cap of the reserve - **/ - function getUnbackedMintCap(address asset) external view returns (uint256) { - return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getUnbackedMintCap(); - } - - /** - * @notice Returns the debt ceiling of the reserve - * @param asset The address of the underlying asset of the reserve - * @return The debt ceiling of the reserve - **/ - function getDebtCeiling(address asset) external view returns (uint256) { - return IPool(ADDRESSES_PROVIDER.getPool()).getConfiguration(asset).getDebtCeiling(); - } - - /** - * @notice Returns the debt ceiling decimals - * @return The debt ceiling decimals - **/ - function getDebtCeilingDecimals() external pure returns (uint256) { - return ReserveConfiguration.DEBT_CEILING_DECIMALS; - } - - /** - * @notice Returns the reserve data - * @param asset The address of the underlying asset of the reserve - * @return unbacked The amount of unbacked tokens - * @return accruedToTreasuryScaled The scaled amount of tokens accrued to treasury that is to be minted - * @return totalAToken The total supply of the aToken - * @return totalStableDebt The total stable debt of the reserve - * @return totalVariableDebt The total variable debt of the reserve - * @return liquidityRate The liquidity rate of the reserve - * @return variableBorrowRate The variable borrow rate of the reserve - * @return stableBorrowRate The stable borrow rate of the reserve - * @return averageStableBorrowRate The average stable borrow rate of the reserve - * @return liquidityIndex The liquidity index of the reserve - * @return variableBorrowIndex The variable borrow index of the reserve - * @return lastUpdateTimestamp The timestamp of the last update of the reserve - **/ - function getReserveData(address asset) - external - view - override - returns ( - uint256 unbacked, - uint256 accruedToTreasuryScaled, - uint256 totalAToken, - uint256 totalStableDebt, - uint256 totalVariableDebt, - uint256 liquidityRate, - uint256 variableBorrowRate, - uint256 stableBorrowRate, - uint256 averageStableBorrowRate, - uint256 liquidityIndex, - uint256 variableBorrowIndex, - uint40 lastUpdateTimestamp - ) - { - DataTypes.ReserveData memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( - asset - ); - - return ( - reserve.unbacked, - reserve.accruedToTreasury, - IERC20Detailed(reserve.aTokenAddress).totalSupply(), - IERC20Detailed(reserve.stableDebtTokenAddress).totalSupply(), - IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply(), - reserve.currentLiquidityRate, - reserve.currentVariableBorrowRate, - reserve.currentStableBorrowRate, - IStableDebtToken(reserve.stableDebtTokenAddress).getAverageStableRate(), - reserve.liquidityIndex, - reserve.variableBorrowIndex, - reserve.lastUpdateTimestamp - ); - } - - /** - * @notice Returns the total supply of aTokens for a given asset - * @param asset The address of the underlying asset of the reserve - * @return The total supply of the aToken - **/ - function getATokenTotalSupply(address asset) external view override returns (uint256) { - DataTypes.ReserveData memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( - asset - ); - return IERC20Detailed(reserve.aTokenAddress).totalSupply(); - } - - /** - * @notice Returns the total debt for a given asset - * @param asset The address of the underlying asset of the reserve - * @return The total debt for asset - **/ - function getTotalDebt(address asset) external view override returns (uint256) { - DataTypes.ReserveData memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( - asset - ); - return - IERC20Detailed(reserve.stableDebtTokenAddress).totalSupply() + - IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply(); - } - - /** - * @notice Returns the user data in a reserve - * @param asset The address of the underlying asset of the reserve - * @param user The address of the user - * @return currentATokenBalance The current AToken balance of the user - * @return currentStableDebt The current stable debt of the user - * @return currentVariableDebt The current variable debt of the user - * @return principalStableDebt The principal stable debt of the user - * @return scaledVariableDebt The scaled variable debt of the user - * @return stableBorrowRate The stable borrow rate of the user - * @return liquidityRate The liquidity rate of the reserve - * @return stableRateLastUpdated The timestamp of the last update of the user stable rate - * @return usageAsCollateralEnabled True if the user is using the asset as collateral, false - * otherwise - **/ - function getUserReserveData(address asset, address user) - external - view - returns ( - uint256 currentATokenBalance, - uint256 currentStableDebt, - uint256 currentVariableDebt, - uint256 principalStableDebt, - uint256 scaledVariableDebt, - uint256 stableBorrowRate, - uint256 liquidityRate, - uint40 stableRateLastUpdated, - bool usageAsCollateralEnabled - ) - { - DataTypes.ReserveData memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( - asset - ); - - DataTypes.UserConfigurationMap memory userConfig = IPool(ADDRESSES_PROVIDER.getPool()) - .getUserConfiguration(user); - - currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user); - currentVariableDebt = IERC20Detailed(reserve.variableDebtTokenAddress).balanceOf(user); - currentStableDebt = IERC20Detailed(reserve.stableDebtTokenAddress).balanceOf(user); - principalStableDebt = IStableDebtToken(reserve.stableDebtTokenAddress).principalBalanceOf(user); - scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user); - liquidityRate = reserve.currentLiquidityRate; - stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(user); - stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated( - user - ); - usageAsCollateralEnabled = userConfig.isUsingAsCollateral(reserve.id); - } - - /** - * @notice Returns the token addresses of the reserve - * @param asset The address of the underlying asset of the reserve - * @return aTokenAddress The AToken address of the reserve - * @return stableDebtTokenAddress The StableDebtToken address of the reserve - * @return variableDebtTokenAddress The VariableDebtToken address of the reserve - */ - function getReserveTokensAddresses(address asset) - external - view - returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ) - { - DataTypes.ReserveData memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( - asset - ); - - return ( - reserve.aTokenAddress, - reserve.stableDebtTokenAddress, - reserve.variableDebtTokenAddress - ); - } - - /** - * @notice Returns the address of the Interest Rate strategy - * @param asset The address of the underlying asset of the reserve - * @return irStrategyAddress The address of the Interest Rate strategy - */ - function getInterestRateStrategyAddress(address asset) - external - view - returns (address irStrategyAddress) - { - DataTypes.ReserveData memory reserve = IPool(ADDRESSES_PROVIDER.getPool()).getReserveData( - asset - ); - - return (reserve.interestRateStrategyAddress); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/L2Encoder.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/misc/L2Encoder.sol deleted file mode 100644 index 0f73b11..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/L2Encoder.sol +++ /dev/null @@ -1,355 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {SafeCast} from '../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {IPool} from '../interfaces/IPool.sol'; -import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; - -/** - * @title L2Encoder - * @author Aave - * @notice Helper contract to encode calldata, used to optimize calldata size in L2Pool for transaction cost reduction - * only indented to help generate calldata for uses/frontends. - */ -contract L2Encoder { - using SafeCast for uint256; - IPool public immutable POOL; - - /** - * @dev Constructor. - * @param pool The address of the Pool contract - */ - constructor(IPool pool) { - POOL = pool; - } - - /** - * @notice Encodes supply parameters from standard input to compact representation of 1 bytes32 - * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf - * @param asset The address of the underlying asset to supply - * @param amount The amount to be supplied - * @param referralCode referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - * @return compact representation of supply parameters - */ - function encodeSupplyParams( - address asset, - uint256 amount, - uint16 referralCode - ) external view returns (bytes32) { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - - uint16 assetId = data.id; - uint128 shortenedAmount = amount.toUint128(); - bytes32 res; - - assembly { - res := add(assetId, add(shl(16, shortenedAmount), shl(144, referralCode))) - } - return res; - } - - /** - * @notice Encodes supplyWithPermit parameters from standard input to compact representation of 3 bytes32 - * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf - * @param asset The address of the underlying asset to supply - * @param amount The amount to be supplied - * @param referralCode referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - * @param deadline The deadline timestamp that the permit is valid - * @param permitV The V parameter of ERC712 permit sig - * @param permitR The R parameter of ERC712 permit sig - * @param permitS The S parameter of ERC712 permit sig - * @return compact representation of supplyWithPermit parameters - * @return The R parameter of ERC712 permit sig - * @return The S parameter of ERC712 permit sig - */ - function encodeSupplyWithPermitParams( - address asset, - uint256 amount, - uint16 referralCode, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) - external - view - returns ( - bytes32, - bytes32, - bytes32 - ) - { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - - uint16 assetId = data.id; - uint128 shortenedAmount = amount.toUint128(); - uint32 shortenedDeadline = deadline.toUint32(); - - bytes32 res; - assembly { - res := add( - assetId, - add( - shl(16, shortenedAmount), - add(shl(144, referralCode), add(shl(160, shortenedDeadline), shl(192, permitV))) - ) - ) - } - - return (res, permitR, permitS); - } - - /** - * @notice Encodes withdraw parameters from standard input to compact representation of 1 bytes32 - * @dev Without a to parameter as the compact calls to L2Pool will use msg.sender as to - * @param asset The address of the underlying asset to withdraw - * @param amount The underlying amount to be withdrawn - * @return compact representation of withdraw parameters - */ - function encodeWithdrawParams(address asset, uint256 amount) external view returns (bytes32) { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - - uint16 assetId = data.id; - uint128 shortenedAmount = amount == type(uint256).max ? type(uint128).max : amount.toUint128(); - - bytes32 res; - assembly { - res := add(assetId, shl(16, shortenedAmount)) - } - return res; - } - - /** - * @notice Encodes borrow parameters from standard input to compact representation of 1 bytes32 - * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf - * @param asset The address of the underlying asset to borrow - * @param amount The amount to be borrowed - * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable - * @param referralCode The code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - * @return compact representation of withdraw parameters - */ - function encodeBorrowParams( - address asset, - uint256 amount, - uint256 interestRateMode, - uint16 referralCode - ) external view returns (bytes32) { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - - uint16 assetId = data.id; - uint128 shortenedAmount = amount.toUint128(); - uint8 shortenedInterestRateMode = interestRateMode.toUint8(); - bytes32 res; - assembly { - res := add( - assetId, - add( - shl(16, shortenedAmount), - add(shl(144, shortenedInterestRateMode), shl(152, referralCode)) - ) - ) - } - return res; - } - - /** - * @notice Encodes repay parameters from standard input to compact representation of 1 bytes32 - * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf - * @param asset The address of the borrowed underlying asset previously borrowed - * @param amount The amount to repay - * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `interestRateMode` - * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable - * @return compact representation of repay parameters - */ - function encodeRepayParams( - address asset, - uint256 amount, - uint256 interestRateMode - ) public view returns (bytes32) { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - - uint16 assetId = data.id; - uint128 shortenedAmount = amount == type(uint256).max ? type(uint128).max : amount.toUint128(); - uint8 shortenedInterestRateMode = interestRateMode.toUint8(); - - bytes32 res; - assembly { - res := add(assetId, add(shl(16, shortenedAmount), shl(144, shortenedInterestRateMode))) - } - return res; - } - - /** - * @notice Encodes repayWithPermit parameters from standard input to compact representation of 3 bytes32 - * @dev Without an onBehalfOf parameter as the compact calls to L2Pool will use msg.sender as onBehalfOf - * @param asset The address of the borrowed underlying asset previously borrowed - * @param amount The amount to repay - * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` - * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable - * @param deadline The deadline timestamp that the permit is valid - * @param permitV The V parameter of ERC712 permit sig - * @param permitR The R parameter of ERC712 permit sig - * @param permitS The S parameter of ERC712 permit sig - * @return compact representation of repayWithPermit parameters - * @return The R parameter of ERC712 permit sig - * @return The S parameter of ERC712 permit sig - */ - function encodeRepayWithPermitParams( - address asset, - uint256 amount, - uint256 interestRateMode, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) - external - view - returns ( - bytes32, - bytes32, - bytes32 - ) - { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - - uint16 assetId = data.id; - uint128 shortenedAmount = amount == type(uint256).max ? type(uint128).max : amount.toUint128(); - uint8 shortenedInterestRateMode = interestRateMode.toUint8(); - uint32 shortenedDeadline = deadline.toUint32(); - - bytes32 res; - assembly { - res := add( - assetId, - add( - shl(16, shortenedAmount), - add( - shl(144, shortenedInterestRateMode), - add(shl(152, shortenedDeadline), shl(184, permitV)) - ) - ) - ) - } - return (res, permitR, permitS); - } - - /** - * @notice Encodes repay with aToken parameters from standard input to compact representation of 1 bytes32 - * @param asset The address of the borrowed underlying asset previously borrowed - * @param amount The amount to repay - * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` - * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable - * @return compact representation of repay with aToken parameters - */ - function encodeRepayWithATokensParams( - address asset, - uint256 amount, - uint256 interestRateMode - ) external view returns (bytes32) { - return encodeRepayParams(asset, amount, interestRateMode); - } - - /** - * @notice Encodes swap borrow rate mode parameters from standard input to compact representation of 1 bytes32 - * @param asset The address of the underlying asset borrowed - * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable - * @return compact representation of swap borrow rate mode parameters - */ - function encodeSwapBorrowRateMode(address asset, uint256 interestRateMode) - external - view - returns (bytes32) - { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - uint16 assetId = data.id; - uint8 shortenedInterestRateMode = interestRateMode.toUint8(); - bytes32 res; - assembly { - res := add(assetId, shl(16, shortenedInterestRateMode)) - } - return res; - } - - /** - * @notice Encodes rebalance stable borrow rate parameters from standard input to compact representation of 1 bytes32 - * @param asset The address of the underlying asset borrowed - * @param user The address of the user to be rebalanced - * @return compact representation of rebalance stable borrow rate parameters - */ - function encodeRebalanceStableBorrowRate(address asset, address user) - external - view - returns (bytes32) - { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - uint16 assetId = data.id; - - bytes32 res; - assembly { - res := add(assetId, shl(16, user)) - } - return res; - } - - /** - * @notice Encodes set user use reserve as collateral parameters from standard input to compact representation of 1 bytes32 - * @param asset The address of the underlying asset borrowed - * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise - * @return compact representation of set user use reserve as collateral parameters - */ - function encodeSetUserUseReserveAsCollateral(address asset, bool useAsCollateral) - external - view - returns (bytes32) - { - DataTypes.ReserveData memory data = POOL.getReserveData(asset); - uint16 assetId = data.id; - bytes32 res; - assembly { - res := add(assetId, shl(16, useAsCollateral)) - } - return res; - } - - /** - * @notice Encodes liquidation call parameters from standard input to compact representation of 2 bytes32 - * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation - * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation - * @param user The address of the borrower getting liquidated - * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover - * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants - * to receive the underlying collateral asset directly - * @return First half ot compact representation of liquidation call parameters - * @return Second half ot compact representation of liquidation call parameters - */ - function encodeLiquidationCall( - address collateralAsset, - address debtAsset, - address user, - uint256 debtToCover, - bool receiveAToken - ) external view returns (bytes32, bytes32) { - DataTypes.ReserveData memory collateralData = POOL.getReserveData(collateralAsset); - uint16 collateralAssetId = collateralData.id; - - DataTypes.ReserveData memory debtData = POOL.getReserveData(debtAsset); - uint16 debtAssetId = debtData.id; - - uint128 shortenedDebtToCover = debtToCover == type(uint256).max - ? type(uint128).max - : debtToCover.toUint128(); - - bytes32 res1; - bytes32 res2; - - assembly { - res1 := add(add(collateralAssetId, shl(16, debtAssetId)), shl(32, user)) - res2 := add(shortenedDebtToCover, shl(128, receiveAToken)) - } - return (res1, res2); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/interfaces/IWETH.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/misc/interfaces/IWETH.sol deleted file mode 100644 index 2ab87da..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/interfaces/IWETH.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -interface IWETH { - function deposit() external payable; - - function withdraw(uint256) external; - - function approve(address guy, uint256 wad) external returns (bool); - - function transferFrom( - address src, - address dst, - uint256 wad - ) external returns (bool); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/interfaces/LICENSE.md b/lib/morpho-utils/lib/aave-v3-core/contracts/misc/interfaces/LICENSE.md deleted file mode 100644 index 506d18e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/misc/interfaces/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (C) 2022 Aave - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -[GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) -for more details diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/flashloan/MockFlashLoanReceiver.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/flashloan/MockFlashLoanReceiver.sol deleted file mode 100644 index 7202f1a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/flashloan/MockFlashLoanReceiver.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {FlashLoanReceiverBase} from '../../flashloan/base/FlashLoanReceiverBase.sol'; -import {MintableERC20} from '../tokens/MintableERC20.sol'; - -contract MockFlashLoanReceiver is FlashLoanReceiverBase { - using GPv2SafeERC20 for IERC20; - - event ExecutedWithFail(address[] _assets, uint256[] _amounts, uint256[] _premiums); - event ExecutedWithSuccess(address[] _assets, uint256[] _amounts, uint256[] _premiums); - - bool internal _failExecution; - uint256 internal _amountToApprove; - bool internal _simulateEOA; - - constructor(IPoolAddressesProvider provider) FlashLoanReceiverBase(provider) {} - - function setFailExecutionTransfer(bool fail) public { - _failExecution = fail; - } - - function setAmountToApprove(uint256 amountToApprove) public { - _amountToApprove = amountToApprove; - } - - function setSimulateEOA(bool flag) public { - _simulateEOA = flag; - } - - function getAmountToApprove() public view returns (uint256) { - return _amountToApprove; - } - - function simulateEOA() public view returns (bool) { - return _simulateEOA; - } - - function executeOperation( - address[] memory assets, - uint256[] memory amounts, - uint256[] memory premiums, - address, // initiator - bytes memory // params - ) public override returns (bool) { - if (_failExecution) { - emit ExecutedWithFail(assets, amounts, premiums); - return !_simulateEOA; - } - - for (uint256 i = 0; i < assets.length; i++) { - //mint to this contract the specific amount - MintableERC20 token = MintableERC20(assets[i]); - - //check the contract has the specified balance - require( - amounts[i] <= IERC20(assets[i]).balanceOf(address(this)), - 'Invalid balance for the contract' - ); - - uint256 amountToReturn = (_amountToApprove != 0) - ? _amountToApprove - : amounts[i] + premiums[i]; - //execution does not fail - mint tokens and return them to the _destination - - token.mint(premiums[i]); - - IERC20(assets[i]).approve(address(POOL), amountToReturn); - } - - emit ExecutedWithSuccess(assets, amounts, premiums); - - return true; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol deleted file mode 100644 index 27d6658..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/flashloan/MockSimpleFlashLoanReceiver.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {FlashLoanSimpleReceiverBase} from '../../flashloan/base/FlashLoanSimpleReceiverBase.sol'; -import {MintableERC20} from '../tokens/MintableERC20.sol'; - -contract MockFlashLoanSimpleReceiver is FlashLoanSimpleReceiverBase { - using GPv2SafeERC20 for IERC20; - using SafeMath for uint256; - - event ExecutedWithFail(address asset, uint256 amount, uint256 premium); - event ExecutedWithSuccess(address asset, uint256 amount, uint256 premium); - - bool internal _failExecution; - uint256 internal _amountToApprove; - bool internal _simulateEOA; - - constructor(IPoolAddressesProvider provider) FlashLoanSimpleReceiverBase(provider) {} - - function setFailExecutionTransfer(bool fail) public { - _failExecution = fail; - } - - function setAmountToApprove(uint256 amountToApprove) public { - _amountToApprove = amountToApprove; - } - - function setSimulateEOA(bool flag) public { - _simulateEOA = flag; - } - - function getAmountToApprove() public view returns (uint256) { - return _amountToApprove; - } - - function simulateEOA() public view returns (bool) { - return _simulateEOA; - } - - function executeOperation( - address asset, - uint256 amount, - uint256 premium, - address, // initiator - bytes memory // params - ) public override returns (bool) { - if (_failExecution) { - emit ExecutedWithFail(asset, amount, premium); - return !_simulateEOA; - } - - //mint to this contract the specific amount - MintableERC20 token = MintableERC20(asset); - - //check the contract has the specified balance - require(amount <= IERC20(asset).balanceOf(address(this)), 'Invalid balance for the contract'); - - uint256 amountToReturn = (_amountToApprove != 0) ? _amountToApprove : amount.add(premium); - //execution does not fail - mint tokens and return them to the _destination - - token.mint(premium); - - IERC20(asset).approve(address(POOL), amountToReturn); - - emit ExecutedWithSuccess(asset, amount, premium); - - return true; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockIncentivesController.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockIncentivesController.sol deleted file mode 100644 index a20feae..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockIncentivesController.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; - -contract MockIncentivesController is IAaveIncentivesController { - function getAssetData(address) - external - pure - override - returns ( - uint256, - uint256, - uint256 - ) - { - return (0, 0, 0); - } - - function assets(address) - external - pure - override - returns ( - uint128, - uint128, - uint256 - ) - { - return (0, 0, 0); - } - - function setClaimer(address, address) external override {} - - function getClaimer(address) external pure override returns (address) { - return address(1); - } - - function configureAssets(address[] calldata, uint256[] calldata) external override {} - - function handleAction( - address, - uint256, - uint256 - ) external override {} - - function getRewardsBalance(address[] calldata, address) external pure override returns (uint256) { - return 0; - } - - function claimRewards( - address[] calldata, - uint256, - address - ) external pure override returns (uint256) { - return 0; - } - - function claimRewardsOnBehalf( - address[] calldata, - uint256, - address, - address - ) external pure override returns (uint256) { - return 0; - } - - function getUserUnclaimedRewards(address) external pure override returns (uint256) { - return 0; - } - - function getUserAssetData(address, address) external pure override returns (uint256) { - return 0; - } - - function REWARD_TOKEN() external pure override returns (address) { - return address(0); - } - - function PRECISION() external pure override returns (uint8) { - return 0; - } - - function DISTRIBUTION_END() external pure override returns (uint256) { - return 0; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockL2Pool.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockL2Pool.sol deleted file mode 100644 index 08ac0a2..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockL2Pool.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {L2Pool} from '../../protocol/pool/L2Pool.sol'; - -contract MockL2Pool is L2Pool { - function getRevision() internal pure override returns (uint256) { - return 0x3; - } - - constructor(IPoolAddressesProvider provider) L2Pool(provider) {} -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockPeripheryContract.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockPeripheryContract.sol deleted file mode 100644 index ed2821d..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockPeripheryContract.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -contract MockPeripheryContractV1 { - address private _manager; - uint256 private _value; - - function initialize(address manager, uint256 value) external { - _manager = manager; - _value = value; - } - - function getManager() external view returns (address) { - return _manager; - } - - function setManager(address newManager) external { - _manager = newManager; - } -} - -contract MockPeripheryContractV2 { - address private _manager; - uint256 private _value; - address private _addressesProvider; - - function initialize(address addressesProvider) external { - _addressesProvider = addressesProvider; - } - - function getManager() external view returns (address) { - return _manager; - } - - function setManager(address newManager) external { - _manager = newManager; - } - - function getAddressesProvider() external view returns (address) { - return _addressesProvider; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockPool.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockPool.sol deleted file mode 100644 index 258b963..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockPool.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; - -contract MockPool { - // Reserved storage space to avoid layout collisions. - uint256[100] private ______gap; - - address internal _addressesProvider; - address[] internal _reserveList; - - function initialize(address provider) external { - _addressesProvider = provider; - } - - function addReserveToReservesList(address reserve) external { - _reserveList.push(reserve); - } - - function getReservesList() external view returns (address[] memory) { - address[] memory reservesList = new address[](_reserveList.length); - for (uint256 i; i < _reserveList.length; i++) { - reservesList[i] = _reserveList[i]; - } - return reservesList; - } -} - -import {Pool} from '../../protocol/pool/Pool.sol'; - -contract MockPoolInherited is Pool { - uint16 internal _maxNumberOfReserves = 128; - - function getRevision() internal pure override returns (uint256) { - return 0x3; - } - - constructor(IPoolAddressesProvider provider) Pool(provider) {} - - function setMaxNumberOfReserves(uint16 newMaxNumberOfReserves) public { - _maxNumberOfReserves = newMaxNumberOfReserves; - } - - function MAX_NUMBER_RESERVES() public view override returns (uint16) { - return _maxNumberOfReserves; - } - - function dropReserve(address asset) external override { - _reservesList[_reserves[asset].id] = address(0); - delete _reserves[asset]; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockReserveConfiguration.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockReserveConfiguration.sol deleted file mode 100644 index 4774da4..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/MockReserveConfiguration.sol +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {ReserveConfiguration} from '../../protocol/libraries/configuration/ReserveConfiguration.sol'; -import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; - -contract MockReserveConfiguration { - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - - DataTypes.ReserveConfigurationMap public configuration; - - function setLtv(uint256 ltv) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setLtv(ltv); - configuration = config; - } - - function getLtv() external view returns (uint256) { - return configuration.getLtv(); - } - - function setLiquidationBonus(uint256 bonus) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setLiquidationBonus(bonus); - configuration = config; - } - - function getLiquidationBonus() external view returns (uint256) { - return configuration.getLiquidationBonus(); - } - - function setLiquidationThreshold(uint256 threshold) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setLiquidationThreshold(threshold); - configuration = config; - } - - function getLiquidationThreshold() external view returns (uint256) { - return configuration.getLiquidationThreshold(); - } - - function setDecimals(uint256 decimals) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setDecimals(decimals); - configuration = config; - } - - function getDecimals() external view returns (uint256) { - return configuration.getDecimals(); - } - - function setFrozen(bool frozen) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setFrozen(frozen); - configuration = config; - } - - function getFrozen() external view returns (bool) { - return configuration.getFrozen(); - } - - function setBorrowingEnabled(bool enabled) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setBorrowingEnabled(enabled); - configuration = config; - } - - function getBorrowingEnabled() external view returns (bool) { - return configuration.getBorrowingEnabled(); - } - - function setStableRateBorrowingEnabled(bool enabled) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setStableRateBorrowingEnabled(enabled); - configuration = config; - } - - function getStableRateBorrowingEnabled() external view returns (bool) { - return configuration.getStableRateBorrowingEnabled(); - } - - function setReserveFactor(uint256 reserveFactor) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setReserveFactor(reserveFactor); - configuration = config; - } - - function getReserveFactor() external view returns (uint256) { - return configuration.getReserveFactor(); - } - - function setBorrowCap(uint256 borrowCap) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setBorrowCap(borrowCap); - configuration = config; - } - - function getBorrowCap() external view returns (uint256) { - return configuration.getBorrowCap(); - } - - function getEModeCategory() external view returns (uint256) { - return configuration.getEModeCategory(); - } - - function setEModeCategory(uint256 categoryId) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setEModeCategory(categoryId); - configuration = config; - } - - function setSupplyCap(uint256 supplyCap) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setSupplyCap(supplyCap); - configuration = config; - } - - function getSupplyCap() external view returns (uint256) { - return configuration.getSupplyCap(); - } - - function setLiquidationProtocolFee(uint256 liquidationProtocolFee) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setLiquidationProtocolFee(liquidationProtocolFee); - configuration = config; - } - - function getLiquidationProtocolFee() external view returns (uint256) { - return configuration.getLiquidationProtocolFee(); - } - - function setUnbackedMintCap(uint256 unbackedMintCap) external { - DataTypes.ReserveConfigurationMap memory config = configuration; - config.setUnbackedMintCap(unbackedMintCap); - configuration = config; - } - - function getUnbackedMintCap() external view returns (uint256) { - return configuration.getUnbackedMintCap(); - } - - function getFlags() - external - view - returns ( - bool, - bool, - bool, - bool, - bool - ) - { - return configuration.getFlags(); - } - - function getParams() - external - view - returns ( - uint256, - uint256, - uint256, - uint256, - uint256, - uint256 - ) - { - return configuration.getParams(); - } - - function getCaps() external view returns (uint256, uint256) { - return configuration.getCaps(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/SelfDestructTransfer.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/SelfDestructTransfer.sol deleted file mode 100644 index 9aa10ad..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/helpers/SelfDestructTransfer.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -contract SelfdestructTransfer { - function destroyAndTransfer(address payable to) external payable { - selfdestruct(to); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol deleted file mode 100644 index e21b546..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/CLAggregators/MockAggregator.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -contract MockAggregator { - int256 private _latestAnswer; - - event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); - - constructor(int256 initialAnswer) { - _latestAnswer = initialAnswer; - emit AnswerUpdated(initialAnswer, 0, block.timestamp); - } - - function latestAnswer() external view returns (int256) { - return _latestAnswer; - } - - function getTokenType() external pure returns (uint256) { - return 1; - } - - function decimals() external pure returns (uint8) { - return 8; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/PriceOracle.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/PriceOracle.sol deleted file mode 100644 index e8d2b2b..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/PriceOracle.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IPriceOracle} from '../../interfaces/IPriceOracle.sol'; - -contract PriceOracle is IPriceOracle { - // Map of asset prices (asset => price) - mapping(address => uint256) internal prices; - - uint256 internal ethPriceUsd; - - event AssetPriceUpdated(address asset, uint256 price, uint256 timestamp); - event EthPriceUpdated(uint256 price, uint256 timestamp); - - function getAssetPrice(address asset) external view override returns (uint256) { - return prices[asset]; - } - - function setAssetPrice(address asset, uint256 price) external override { - prices[asset] = price; - emit AssetPriceUpdated(asset, price, block.timestamp); - } - - function getEthUsdPrice() external view returns (uint256) { - return ethPriceUsd; - } - - function setEthUsdPrice(uint256 price) external { - ethPriceUsd = price; - emit EthPriceUpdated(price, block.timestamp); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol deleted file mode 100644 index 64608f0..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/oracle/SequencerOracle.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; -import {ISequencerOracle} from '../../interfaces/ISequencerOracle.sol'; - -contract SequencerOracle is ISequencerOracle, Ownable { - bool internal _isDown; - uint256 internal _timestampGotUp; - - /** - * @dev Constructor. - * @param owner The owner address of this contract - */ - constructor(address owner) { - transferOwnership(owner); - } - - /** - * @notice Updates the health status of the sequencer. - * @param isDown True if the sequencer is down, false otherwise - * @param timestamp The timestamp of last time the sequencer got up - */ - function setAnswer(bool isDown, uint256 timestamp) external onlyOwner { - _isDown = isDown; - _timestampGotUp = timestamp; - } - - /// @inheritdoc ISequencerOracle - function latestRoundData() - external - view - override - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ) - { - int256 isDown; - if (_isDown) { - isDown = 1; - } - return (0, isDown, 0, _timestampGotUp, 0); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/FlashloanAttacker.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/FlashloanAttacker.sol deleted file mode 100644 index 58d8218..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/FlashloanAttacker.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {FlashLoanSimpleReceiverBase} from '../../flashloan/base/FlashLoanSimpleReceiverBase.sol'; -import {MintableERC20} from '../tokens/MintableERC20.sol'; -import {IPool} from '../../interfaces/IPool.sol'; -import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; - -contract FlashloanAttacker is FlashLoanSimpleReceiverBase { - using GPv2SafeERC20 for IERC20; - using SafeMath for uint256; - - IPoolAddressesProvider internal _provider; - IPool internal _pool; - - constructor(IPoolAddressesProvider provider) FlashLoanSimpleReceiverBase(provider) { - _pool = IPool(provider.getPool()); - } - - function supplyAsset(address asset, uint256 amount) public { - MintableERC20 token = MintableERC20(asset); - token.mint(amount); - token.approve(address(_pool), type(uint256).max); - _pool.supply(asset, amount, address(this), 0); - } - - function _innerBorrow(address asset) internal { - DataTypes.ReserveData memory config = _pool.getReserveData(asset); - IERC20 token = IERC20(asset); - uint256 avail = token.balanceOf(config.aTokenAddress); - _pool.borrow(asset, avail, 2, 0, address(this)); - } - - function executeOperation( - address asset, - uint256 amount, - uint256 premium, - address, // initiator - bytes memory // params - ) public override returns (bool) { - MintableERC20 token = MintableERC20(asset); - uint256 amountToReturn = amount.add(premium); - - // Also do a normal borrow here in the middle - _innerBorrow(asset); - - token.mint(premium); - IERC20(asset).approve(address(POOL), amountToReturn); - - return true; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/MockReserveInterestRateStrategy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/MockReserveInterestRateStrategy.sol deleted file mode 100644 index 973ed79..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/MockReserveInterestRateStrategy.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {WadRayMath} from '../../protocol/libraries/math/WadRayMath.sol'; -import {DataTypes} from '../../protocol/libraries/types/DataTypes.sol'; - -contract MockReserveInterestRateStrategy is IReserveInterestRateStrategy { - uint256 public immutable OPTIMAL_USAGE_RATIO; - IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; - uint256 internal immutable _baseVariableBorrowRate; - uint256 internal immutable _variableRateSlope1; - uint256 internal immutable _variableRateSlope2; - uint256 internal immutable _stableRateSlope1; - uint256 internal immutable _stableRateSlope2; - - uint256 internal _liquidityRate; - uint256 internal _stableBorrowRate; - uint256 internal _variableBorrowRate; - - constructor( - IPoolAddressesProvider provider, - uint256 optimalUsageRatio, - uint256 baseVariableBorrowRate, - uint256 variableRateSlope1, - uint256 variableRateSlope2, - uint256 stableRateSlope1, - uint256 stableRateSlope2 - ) { - OPTIMAL_USAGE_RATIO = optimalUsageRatio; - ADDRESSES_PROVIDER = provider; - _baseVariableBorrowRate = baseVariableBorrowRate; - _variableRateSlope1 = variableRateSlope1; - _variableRateSlope2 = variableRateSlope2; - _stableRateSlope1 = stableRateSlope1; - _stableRateSlope2 = stableRateSlope2; - } - - function setLiquidityRate(uint256 liquidityRate) public { - _liquidityRate = liquidityRate; - } - - function setStableBorrowRate(uint256 stableBorrowRate) public { - _stableBorrowRate = stableBorrowRate; - } - - function setVariableBorrowRate(uint256 variableBorrowRate) public { - _variableBorrowRate = variableBorrowRate; - } - - function calculateInterestRates(DataTypes.CalculateInterestRatesParams memory) - external - view - override - returns ( - uint256 liquidityRate, - uint256 stableBorrowRate, - uint256 variableBorrowRate - ) - { - return (_liquidityRate, _stableBorrowRate, _variableBorrowRate); - } - - function getVariableRateSlope1() external view returns (uint256) { - return _variableRateSlope1; - } - - function getVariableRateSlope2() external view returns (uint256) { - return _variableRateSlope2; - } - - function getStableRateSlope1() external view returns (uint256) { - return _stableRateSlope1; - } - - function getStableRateSlope2() external view returns (uint256) { - return _stableRateSlope2; - } - - function getBaseVariableBorrowRate() external view override returns (uint256) { - return _baseVariableBorrowRate; - } - - function getMaxVariableBorrowRate() external view override returns (uint256) { - return _baseVariableBorrowRate + _variableRateSlope1 + _variableRateSlope2; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/WadRayMathWrapper.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/WadRayMathWrapper.sol deleted file mode 100644 index 9db4fcf..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tests/WadRayMathWrapper.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {WadRayMath} from '../../protocol/libraries/math/WadRayMath.sol'; - -contract WadRayMathWrapper { - function wad() public pure returns (uint256) { - return WadRayMath.WAD; - } - - function ray() public pure returns (uint256) { - return WadRayMath.RAY; - } - - function halfRay() public pure returns (uint256) { - return WadRayMath.HALF_RAY; - } - - function halfWad() public pure returns (uint256) { - return WadRayMath.HALF_WAD; - } - - function wadMul(uint256 a, uint256 b) public pure returns (uint256) { - return WadRayMath.wadMul(a, b); - } - - function wadDiv(uint256 a, uint256 b) public pure returns (uint256) { - return WadRayMath.wadDiv(a, b); - } - - function rayMul(uint256 a, uint256 b) public pure returns (uint256) { - return WadRayMath.rayMul(a, b); - } - - function rayDiv(uint256 a, uint256 b) public pure returns (uint256) { - return WadRayMath.rayDiv(a, b); - } - - function rayToWad(uint256 a) public pure returns (uint256) { - return WadRayMath.rayToWad(a); - } - - function wadToRay(uint256 a) public pure returns (uint256) { - return WadRayMath.wadToRay(a); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/MintableDelegationERC20.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/MintableDelegationERC20.sol deleted file mode 100644 index 0fbdb63..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/MintableDelegationERC20.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol'; -import {IDelegationToken} from '../../interfaces/IDelegationToken.sol'; - -/** - * @title MintableDelegationERC20 - * @dev ERC20 minting logic with delegation - */ -contract MintableDelegationERC20 is IDelegationToken, ERC20 { - address public delegatee; - - constructor( - string memory name, - string memory symbol, - uint8 decimals - ) ERC20(name, symbol) { - _setupDecimals(decimals); - } - - /** - * @dev Function to mint tokens - * @param value The amount of tokens to mint. - * @return A boolean that indicates if the operation was successful. - */ - function mint(uint256 value) public returns (bool) { - _mint(msg.sender, value); - return true; - } - - function delegate(address delegateeAddress) external override { - delegatee = delegateeAddress; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/MintableERC20.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/MintableERC20.sol deleted file mode 100644 index 37fa2be..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/MintableERC20.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol'; -import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; - -/** - * @title ERC20Mintable - * @dev ERC20 minting logic - */ -contract MintableERC20 is IERC20WithPermit, ERC20 { - bytes public constant EIP712_REVISION = bytes('1'); - bytes32 internal constant EIP712_DOMAIN = - keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'); - bytes32 public constant PERMIT_TYPEHASH = - keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'); - - // Map of address nonces (address => nonce) - mapping(address => uint256) internal _nonces; - - bytes32 public DOMAIN_SEPARATOR; - - constructor( - string memory name, - string memory symbol, - uint8 decimals - ) ERC20(name, symbol) { - uint256 chainId = block.chainid; - - DOMAIN_SEPARATOR = keccak256( - abi.encode( - EIP712_DOMAIN, - keccak256(bytes(name)), - keccak256(EIP712_REVISION), - chainId, - address(this) - ) - ); - _setupDecimals(decimals); - } - - /// @inheritdoc IERC20WithPermit - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external override { - require(owner != address(0), 'INVALID_OWNER'); - //solium-disable-next-line - require(block.timestamp <= deadline, 'INVALID_EXPIRATION'); - uint256 currentValidNonce = _nonces[owner]; - bytes32 digest = keccak256( - abi.encodePacked( - '\x19\x01', - DOMAIN_SEPARATOR, - keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline)) - ) - ); - require(owner == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE'); - _nonces[owner] = currentValidNonce + 1; - _approve(owner, spender, value); - } - - /** - * @dev Function to mint tokens - * @param value The amount of tokens to mint. - * @return A boolean that indicates if the operation was successful. - */ - function mint(uint256 value) public returns (bool) { - _mint(_msgSender(), value); - return true; - } - - /** - * @dev Function to mint tokens to address - * @param account The account to mint tokens. - * @param value The amount of tokens to mint. - * @return A boolean that indicates if the operation was successful. - */ - function mint(address account, uint256 value) public returns (bool) { - _mint(account, value); - return true; - } - - function nonces(address owner) public view virtual returns (uint256) { - return _nonces[owner]; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/WETH9Mocked.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/WETH9Mocked.sol deleted file mode 100644 index 9a42566..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/tokens/WETH9Mocked.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {WETH9} from '../../dependencies/weth/WETH9.sol'; - -contract WETH9Mocked is WETH9 { - // Mint not backed by Ether: only for testing purposes - function mint(uint256 value) public returns (bool) { - balanceOf[msg.sender] += value; - emit Transfer(address(0), msg.sender, value); - return true; - } - - function mint(address account, uint256 value) public returns (bool) { - balanceOf[account] += value; - emit Transfer(address(0), account, value); - return true; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockAToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockAToken.sol deleted file mode 100644 index 7a105fb..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockAToken.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {AToken} from '../../protocol/tokenization/AToken.sol'; -import {IPool} from '../../interfaces/IPool.sol'; -import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; - -contract MockAToken is AToken { - constructor(IPool pool) AToken(pool) {} - - function getRevision() internal pure override returns (uint256) { - return 0x2; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockInitializableImplementation.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockInitializableImplementation.sol deleted file mode 100644 index e70eab1..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockInitializableImplementation.sol +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {VersionedInitializable} from '../../protocol/libraries/aave-upgradeability/VersionedInitializable.sol'; - -contract MockInitializableImple is VersionedInitializable { - uint256 public value; - string public text; - uint256[] public values; - - uint256 public constant REVISION = 1; - - /** - * @dev returns the revision number of the contract - * Needs to be defined in the inherited class as a constant. - **/ - function getRevision() internal pure override returns (uint256) { - return REVISION; - } - - function initialize( - uint256 val, - string memory txt, - uint256[] memory vals - ) external initializer { - value = val; - text = txt; - values = vals; - } - - function setValue(uint256 newValue) public { - value = newValue; - } - - function setValueViaProxy(uint256 newValue) public { - value = newValue; - } -} - -contract MockInitializableImpleV2 is VersionedInitializable { - uint256 public value; - string public text; - uint256[] public values; - - uint256 public constant REVISION = 2; - - /** - * @dev returns the revision number of the contract - * Needs to be defined in the inherited class as a constant. - **/ - function getRevision() internal pure override returns (uint256) { - return REVISION; - } - - function initialize( - uint256 val, - string memory txt, - uint256[] memory vals - ) public initializer { - value = val; - text = txt; - values = vals; - } - - function setValue(uint256 newValue) public { - value = newValue; - } - - function setValueViaProxy(uint256 newValue) public { - value = newValue; - } -} - -contract MockInitializableFromConstructorImple is VersionedInitializable { - uint256 public value; - - uint256 public constant REVISION = 2; - - /** - * @dev returns the revision number of the contract - * Needs to be defined in the inherited class as a constant. - **/ - function getRevision() internal pure override returns (uint256) { - return REVISION; - } - - constructor(uint256 val) { - initialize(val); - } - - function initialize(uint256 val) public initializer { - value = val; - } -} - -contract MockReentrantInitializableImple is VersionedInitializable { - uint256 public value; - - uint256 public constant REVISION = 2; - - /** - * @dev returns the revision number of the contract - * Needs to be defined in the inherited class as a constant. - **/ - function getRevision() internal pure override returns (uint256) { - return REVISION; - } - - function initialize(uint256 val) public initializer { - value = val; - if (value < 2) { - initialize(value + 1); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockStableDebtToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockStableDebtToken.sol deleted file mode 100644 index 3c93bfe..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockStableDebtToken.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {StableDebtToken} from '../../protocol/tokenization/StableDebtToken.sol'; -import {IPool} from '../../interfaces/IPool.sol'; - -contract MockStableDebtToken is StableDebtToken { - constructor(IPool pool) StableDebtToken(pool) {} - - function getRevision() internal pure override returns (uint256) { - return 0x3; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockVariableDebtToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockVariableDebtToken.sol deleted file mode 100644 index 3c30202..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/mocks/upgradeability/MockVariableDebtToken.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {VariableDebtToken} from '../../protocol/tokenization/VariableDebtToken.sol'; -import {IPool} from '../../interfaces/IPool.sol'; - -contract MockVariableDebtToken is VariableDebtToken { - constructor(IPool pool) VariableDebtToken(pool) {} - - function getRevision() internal pure override returns (uint256) { - return 0x3; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/ACLManager.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/ACLManager.sol deleted file mode 100644 index 7b03541..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/ACLManager.sol +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {AccessControl} from '../../dependencies/openzeppelin/contracts/AccessControl.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IACLManager} from '../../interfaces/IACLManager.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; - -/** - * @title ACLManager - * @author Aave - * @notice Access Control List Manager. Main registry of system roles and permissions. - */ -contract ACLManager is AccessControl, IACLManager { - bytes32 public constant override POOL_ADMIN_ROLE = keccak256('POOL_ADMIN'); - bytes32 public constant override EMERGENCY_ADMIN_ROLE = keccak256('EMERGENCY_ADMIN'); - bytes32 public constant override RISK_ADMIN_ROLE = keccak256('RISK_ADMIN'); - bytes32 public constant override FLASH_BORROWER_ROLE = keccak256('FLASH_BORROWER'); - bytes32 public constant override BRIDGE_ROLE = keccak256('BRIDGE'); - bytes32 public constant override ASSET_LISTING_ADMIN_ROLE = keccak256('ASSET_LISTING_ADMIN'); - - IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; - - /** - * @dev Constructor - * @dev The ACL admin should be initialized at the addressesProvider beforehand - * @param provider The address of the PoolAddressesProvider - */ - constructor(IPoolAddressesProvider provider) { - ADDRESSES_PROVIDER = provider; - address aclAdmin = provider.getACLAdmin(); - require(aclAdmin != address(0), Errors.ACL_ADMIN_CANNOT_BE_ZERO); - _setupRole(DEFAULT_ADMIN_ROLE, aclAdmin); - } - - /// @inheritdoc IACLManager - function setRoleAdmin(bytes32 role, bytes32 adminRole) - external - override - onlyRole(DEFAULT_ADMIN_ROLE) - { - _setRoleAdmin(role, adminRole); - } - - /// @inheritdoc IACLManager - function addPoolAdmin(address admin) external override { - grantRole(POOL_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function removePoolAdmin(address admin) external override { - revokeRole(POOL_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function isPoolAdmin(address admin) external view override returns (bool) { - return hasRole(POOL_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function addEmergencyAdmin(address admin) external override { - grantRole(EMERGENCY_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function removeEmergencyAdmin(address admin) external override { - revokeRole(EMERGENCY_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function isEmergencyAdmin(address admin) external view override returns (bool) { - return hasRole(EMERGENCY_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function addRiskAdmin(address admin) external override { - grantRole(RISK_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function removeRiskAdmin(address admin) external override { - revokeRole(RISK_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function isRiskAdmin(address admin) external view override returns (bool) { - return hasRole(RISK_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function addFlashBorrower(address borrower) external override { - grantRole(FLASH_BORROWER_ROLE, borrower); - } - - /// @inheritdoc IACLManager - function removeFlashBorrower(address borrower) external override { - revokeRole(FLASH_BORROWER_ROLE, borrower); - } - - /// @inheritdoc IACLManager - function isFlashBorrower(address borrower) external view override returns (bool) { - return hasRole(FLASH_BORROWER_ROLE, borrower); - } - - /// @inheritdoc IACLManager - function addBridge(address bridge) external override { - grantRole(BRIDGE_ROLE, bridge); - } - - /// @inheritdoc IACLManager - function removeBridge(address bridge) external override { - revokeRole(BRIDGE_ROLE, bridge); - } - - /// @inheritdoc IACLManager - function isBridge(address bridge) external view override returns (bool) { - return hasRole(BRIDGE_ROLE, bridge); - } - - /// @inheritdoc IACLManager - function addAssetListingAdmin(address admin) external override { - grantRole(ASSET_LISTING_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function removeAssetListingAdmin(address admin) external override { - revokeRole(ASSET_LISTING_ADMIN_ROLE, admin); - } - - /// @inheritdoc IACLManager - function isAssetListingAdmin(address admin) external view override returns (bool) { - return hasRole(ASSET_LISTING_ADMIN_ROLE, admin); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PoolAddressesProvider.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PoolAddressesProvider.sol deleted file mode 100644 index 073e92f..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PoolAddressesProvider.sol +++ /dev/null @@ -1,210 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {InitializableImmutableAdminUpgradeabilityProxy} from '../libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; - -/** - * @title PoolAddressesProvider - * @author Aave - * @notice Main registry of addresses part of or connected to the protocol, including permissioned roles - * @dev Acts as factory of proxies and admin of those, so with right to change its implementations - * @dev Owned by the Aave Governance - **/ -contract PoolAddressesProvider is Ownable, IPoolAddressesProvider { - // Identifier of the Aave Market - string private _marketId; - - // Map of registered addresses (identifier => registeredAddress) - mapping(bytes32 => address) private _addresses; - - // Main identifiers - bytes32 private constant POOL = 'POOL'; - bytes32 private constant POOL_CONFIGURATOR = 'POOL_CONFIGURATOR'; - bytes32 private constant PRICE_ORACLE = 'PRICE_ORACLE'; - bytes32 private constant ACL_MANAGER = 'ACL_MANAGER'; - bytes32 private constant ACL_ADMIN = 'ACL_ADMIN'; - bytes32 private constant PRICE_ORACLE_SENTINEL = 'PRICE_ORACLE_SENTINEL'; - bytes32 private constant DATA_PROVIDER = 'DATA_PROVIDER'; - - /** - * @dev Constructor. - * @param marketId The identifier of the market. - * @param owner The owner address of this contract. - */ - constructor(string memory marketId, address owner) { - _setMarketId(marketId); - transferOwnership(owner); - } - - /// @inheritdoc IPoolAddressesProvider - function getMarketId() external view override returns (string memory) { - return _marketId; - } - - /// @inheritdoc IPoolAddressesProvider - function setMarketId(string memory newMarketId) external override onlyOwner { - _setMarketId(newMarketId); - } - - /// @inheritdoc IPoolAddressesProvider - function getAddress(bytes32 id) public view override returns (address) { - return _addresses[id]; - } - - /// @inheritdoc IPoolAddressesProvider - function setAddress(bytes32 id, address newAddress) external override onlyOwner { - address oldAddress = _addresses[id]; - _addresses[id] = newAddress; - emit AddressSet(id, oldAddress, newAddress); - } - - /// @inheritdoc IPoolAddressesProvider - function setAddressAsProxy(bytes32 id, address newImplementationAddress) - external - override - onlyOwner - { - address proxyAddress = _addresses[id]; - address oldImplementationAddress = _getProxyImplementation(id); - _updateImpl(id, newImplementationAddress); - emit AddressSetAsProxy(id, proxyAddress, oldImplementationAddress, newImplementationAddress); - } - - /// @inheritdoc IPoolAddressesProvider - function getPool() external view override returns (address) { - return getAddress(POOL); - } - - /// @inheritdoc IPoolAddressesProvider - function setPoolImpl(address newPoolImpl) external override onlyOwner { - address oldPoolImpl = _getProxyImplementation(POOL); - _updateImpl(POOL, newPoolImpl); - emit PoolUpdated(oldPoolImpl, newPoolImpl); - } - - /// @inheritdoc IPoolAddressesProvider - function getPoolConfigurator() external view override returns (address) { - return getAddress(POOL_CONFIGURATOR); - } - - /// @inheritdoc IPoolAddressesProvider - function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external override onlyOwner { - address oldPoolConfiguratorImpl = _getProxyImplementation(POOL_CONFIGURATOR); - _updateImpl(POOL_CONFIGURATOR, newPoolConfiguratorImpl); - emit PoolConfiguratorUpdated(oldPoolConfiguratorImpl, newPoolConfiguratorImpl); - } - - /// @inheritdoc IPoolAddressesProvider - function getPriceOracle() external view override returns (address) { - return getAddress(PRICE_ORACLE); - } - - /// @inheritdoc IPoolAddressesProvider - function setPriceOracle(address newPriceOracle) external override onlyOwner { - address oldPriceOracle = _addresses[PRICE_ORACLE]; - _addresses[PRICE_ORACLE] = newPriceOracle; - emit PriceOracleUpdated(oldPriceOracle, newPriceOracle); - } - - /// @inheritdoc IPoolAddressesProvider - function getACLManager() external view override returns (address) { - return getAddress(ACL_MANAGER); - } - - /// @inheritdoc IPoolAddressesProvider - function setACLManager(address newAclManager) external override onlyOwner { - address oldAclManager = _addresses[ACL_MANAGER]; - _addresses[ACL_MANAGER] = newAclManager; - emit ACLManagerUpdated(oldAclManager, newAclManager); - } - - /// @inheritdoc IPoolAddressesProvider - function getACLAdmin() external view override returns (address) { - return getAddress(ACL_ADMIN); - } - - /// @inheritdoc IPoolAddressesProvider - function setACLAdmin(address newAclAdmin) external override onlyOwner { - address oldAclAdmin = _addresses[ACL_ADMIN]; - _addresses[ACL_ADMIN] = newAclAdmin; - emit ACLAdminUpdated(oldAclAdmin, newAclAdmin); - } - - /// @inheritdoc IPoolAddressesProvider - function getPriceOracleSentinel() external view override returns (address) { - return getAddress(PRICE_ORACLE_SENTINEL); - } - - /// @inheritdoc IPoolAddressesProvider - function setPriceOracleSentinel(address newPriceOracleSentinel) external override onlyOwner { - address oldPriceOracleSentinel = _addresses[PRICE_ORACLE_SENTINEL]; - _addresses[PRICE_ORACLE_SENTINEL] = newPriceOracleSentinel; - emit PriceOracleSentinelUpdated(oldPriceOracleSentinel, newPriceOracleSentinel); - } - - /// @inheritdoc IPoolAddressesProvider - function getPoolDataProvider() external view override returns (address) { - return getAddress(DATA_PROVIDER); - } - - /// @inheritdoc IPoolAddressesProvider - function setPoolDataProvider(address newDataProvider) external override onlyOwner { - address oldDataProvider = _addresses[DATA_PROVIDER]; - _addresses[DATA_PROVIDER] = newDataProvider; - emit PoolDataProviderUpdated(oldDataProvider, newDataProvider); - } - - /** - * @notice Internal function to update the implementation of a specific proxied component of the protocol. - * @dev If there is no proxy registered with the given identifier, it creates the proxy setting `newAddress` - * as implementation and calls the initialize() function on the proxy - * @dev If there is already a proxy registered, it just updates the implementation to `newAddress` and - * calls the initialize() function via upgradeToAndCall() in the proxy - * @param id The id of the proxy to be updated - * @param newAddress The address of the new implementation - **/ - function _updateImpl(bytes32 id, address newAddress) internal { - address proxyAddress = _addresses[id]; - InitializableImmutableAdminUpgradeabilityProxy proxy; - bytes memory params = abi.encodeWithSignature('initialize(address)', address(this)); - - if (proxyAddress == address(0)) { - proxy = new InitializableImmutableAdminUpgradeabilityProxy(address(this)); - _addresses[id] = proxyAddress = address(proxy); - proxy.initialize(newAddress, params); - emit ProxyCreated(id, proxyAddress, newAddress); - } else { - proxy = InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress)); - proxy.upgradeToAndCall(newAddress, params); - } - } - - /** - * @notice Updates the identifier of the Aave market. - * @param newMarketId The new id of the market - **/ - function _setMarketId(string memory newMarketId) internal { - string memory oldMarketId = _marketId; - _marketId = newMarketId; - emit MarketIdSet(oldMarketId, newMarketId); - } - - /** - * @notice Returns the the implementation contract of the proxy contract by its identifier. - * @dev It returns ZERO if there is no registered address with the given id - * @dev It reverts if the registered address with the given id is not `InitializableImmutableAdminUpgradeabilityProxy` - * @param id The id - * @return The address of the implementation contract - */ - function _getProxyImplementation(bytes32 id) internal returns (address) { - address proxyAddress = _addresses[id]; - if (proxyAddress == address(0)) { - return address(0); - } else { - address payable payableProxyAddress = payable(proxyAddress); - return InitializableImmutableAdminUpgradeabilityProxy(payableProxyAddress).implementation(); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol deleted file mode 100644 index f5cb3d3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PoolAddressesProviderRegistry.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; -import {IPoolAddressesProviderRegistry} from '../../interfaces/IPoolAddressesProviderRegistry.sol'; - -/** - * @title PoolAddressesProviderRegistry - * @author Aave - * @notice Main registry of PoolAddressesProvider of Aave markets. - * @dev Used for indexing purposes of Aave protocol's markets. The id assigned to a PoolAddressesProvider refers to the - * market it is connected with, for example with `1` for the Aave main market and `2` for the next created. - **/ -contract PoolAddressesProviderRegistry is Ownable, IPoolAddressesProviderRegistry { - // Map of address provider ids (addressesProvider => id) - mapping(address => uint256) private _addressesProviderToId; - // Map of id to address provider (id => addressesProvider) - mapping(uint256 => address) private _idToAddressesProvider; - // List of addresses providers - address[] private _addressesProvidersList; - // Map of address provider list indexes (addressesProvider => indexInList) - mapping(address => uint256) private _addressesProvidersIndexes; - - /** - * @dev Constructor. - * @param owner The owner address of this contract. - */ - constructor(address owner) { - transferOwnership(owner); - } - - /// @inheritdoc IPoolAddressesProviderRegistry - function getAddressesProvidersList() external view override returns (address[] memory) { - return _addressesProvidersList; - } - - /// @inheritdoc IPoolAddressesProviderRegistry - function registerAddressesProvider(address provider, uint256 id) external override onlyOwner { - require(id != 0, Errors.INVALID_ADDRESSES_PROVIDER_ID); - require(_idToAddressesProvider[id] == address(0), Errors.INVALID_ADDRESSES_PROVIDER_ID); - require(_addressesProviderToId[provider] == 0, Errors.ADDRESSES_PROVIDER_ALREADY_ADDED); - - _addressesProviderToId[provider] = id; - _idToAddressesProvider[id] = provider; - - _addToAddressesProvidersList(provider); - emit AddressesProviderRegistered(provider, id); - } - - /// @inheritdoc IPoolAddressesProviderRegistry - function unregisterAddressesProvider(address provider) external override onlyOwner { - require(_addressesProviderToId[provider] != 0, Errors.ADDRESSES_PROVIDER_NOT_REGISTERED); - uint256 oldId = _addressesProviderToId[provider]; - _idToAddressesProvider[oldId] = address(0); - _addressesProviderToId[provider] = 0; - - _removeFromAddressesProvidersList(provider); - - emit AddressesProviderUnregistered(provider, oldId); - } - - /// @inheritdoc IPoolAddressesProviderRegistry - function getAddressesProviderIdByAddress(address addressesProvider) - external - view - override - returns (uint256) - { - return _addressesProviderToId[addressesProvider]; - } - - /// @inheritdoc IPoolAddressesProviderRegistry - function getAddressesProviderAddressById(uint256 id) external view override returns (address) { - return _idToAddressesProvider[id]; - } - - /** - * @notice Adds the addresses provider address to the list. - * @param provider The address of the PoolAddressesProvider - */ - function _addToAddressesProvidersList(address provider) internal { - _addressesProvidersIndexes[provider] = _addressesProvidersList.length; - _addressesProvidersList.push(provider); - } - - /** - * @notice Removes the addresses provider address from the list. - * @param provider The address of the PoolAddressesProvider - */ - function _removeFromAddressesProvidersList(address provider) internal { - uint256 index = _addressesProvidersIndexes[provider]; - - _addressesProvidersIndexes[provider] = 0; - - // Swap the index of the last addresses provider in the list with the index of the provider to remove - uint256 lastIndex = _addressesProvidersList.length - 1; - if (index < lastIndex) { - address lastProvider = _addressesProvidersList[lastIndex]; - _addressesProvidersList[index] = lastProvider; - _addressesProvidersIndexes[lastProvider] = index; - } - _addressesProvidersList.pop(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PriceOracleSentinel.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PriceOracleSentinel.sol deleted file mode 100644 index 81b22d8..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/configuration/PriceOracleSentinel.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {Errors} from '../libraries/helpers/Errors.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPriceOracleSentinel} from '../../interfaces/IPriceOracleSentinel.sol'; -import {ISequencerOracle} from '../../interfaces/ISequencerOracle.sol'; -import {IACLManager} from '../../interfaces/IACLManager.sol'; - -/** - * @title PriceOracleSentinel - * @author Aave - * @notice It validates if operations are allowed depending on the PriceOracle health. - * @dev Once the PriceOracle gets up after an outage/downtime, users can make their positions healthy during a grace - * period. So the PriceOracle is considered completely up once its up and the grace period passed. - */ -contract PriceOracleSentinel is IPriceOracleSentinel { - /** - * @dev Only pool admin can call functions marked by this modifier. - **/ - modifier onlyPoolAdmin() { - IACLManager aclManager = IACLManager(ADDRESSES_PROVIDER.getACLManager()); - require(aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_POOL_ADMIN); - _; - } - - /** - * @dev Only risk or pool admin can call functions marked by this modifier. - **/ - modifier onlyRiskOrPoolAdmins() { - IACLManager aclManager = IACLManager(ADDRESSES_PROVIDER.getACLManager()); - require( - aclManager.isRiskAdmin(msg.sender) || aclManager.isPoolAdmin(msg.sender), - Errors.CALLER_NOT_RISK_OR_POOL_ADMIN - ); - _; - } - - IPoolAddressesProvider public immutable override ADDRESSES_PROVIDER; - - ISequencerOracle internal _sequencerOracle; - - uint256 internal _gracePeriod; - - /** - * @dev Constructor - * @param provider The address of the PoolAddressesProvider - * @param oracle The address of the SequencerOracle - * @param gracePeriod The duration of the grace period in seconds - */ - constructor( - IPoolAddressesProvider provider, - ISequencerOracle oracle, - uint256 gracePeriod - ) { - ADDRESSES_PROVIDER = provider; - _sequencerOracle = oracle; - _gracePeriod = gracePeriod; - } - - /// @inheritdoc IPriceOracleSentinel - function isBorrowAllowed() public view override returns (bool) { - return _isUpAndGracePeriodPassed(); - } - - /// @inheritdoc IPriceOracleSentinel - function isLiquidationAllowed() public view override returns (bool) { - return _isUpAndGracePeriodPassed(); - } - - /** - * @notice Checks the sequencer oracle is healthy: is up and grace period passed. - * @return True if the SequencerOracle is up and the grace period passed, false otherwise - */ - function _isUpAndGracePeriodPassed() internal view returns (bool) { - (, int256 answer, , uint256 lastUpdateTimestamp, ) = _sequencerOracle.latestRoundData(); - return answer == 0 && block.timestamp - lastUpdateTimestamp > _gracePeriod; - } - - /// @inheritdoc IPriceOracleSentinel - function setSequencerOracle(address newSequencerOracle) public onlyPoolAdmin { - _sequencerOracle = ISequencerOracle(newSequencerOracle); - emit SequencerOracleUpdated(newSequencerOracle); - } - - /// @inheritdoc IPriceOracleSentinel - function setGracePeriod(uint256 newGracePeriod) public onlyRiskOrPoolAdmins { - _gracePeriod = newGracePeriod; - emit GracePeriodUpdated(newGracePeriod); - } - - /// @inheritdoc IPriceOracleSentinel - function getSequencerOracle() public view returns (address) { - return address(_sequencerOracle); - } - - /// @inheritdoc IPriceOracleSentinel - function getGracePeriod() public view returns (uint256) { - return _gracePeriod; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol deleted file mode 100644 index 87550c2..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {BaseUpgradeabilityProxy} from '../../../dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol'; - -/** - * @title BaseImmutableAdminUpgradeabilityProxy - * @author Aave, inspired by the OpenZeppelin upgradeability proxy pattern - * @notice This contract combines an upgradeability proxy with an authorization - * mechanism for administrative tasks. - * @dev The admin role is stored in an immutable, which helps saving transactions costs - * All external functions in this contract must be guarded by the - * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity - * feature proposal that would enable this to be done automatically. - */ -contract BaseImmutableAdminUpgradeabilityProxy is BaseUpgradeabilityProxy { - address internal immutable _admin; - - /** - * @dev Constructor. - * @param admin The address of the admin - */ - constructor(address admin) { - _admin = admin; - } - - modifier ifAdmin() { - if (msg.sender == _admin) { - _; - } else { - _fallback(); - } - } - - /** - * @notice Return the admin address - * @return The address of the proxy admin. - */ - function admin() external ifAdmin returns (address) { - return _admin; - } - - /** - * @notice Return the implementation address - * @return The address of the implementation. - */ - function implementation() external ifAdmin returns (address) { - return _implementation(); - } - - /** - * @notice Upgrade the backing implementation of the proxy. - * @dev Only the admin can call this function. - * @param newImplementation The address of the new implementation. - */ - function upgradeTo(address newImplementation) external ifAdmin { - _upgradeTo(newImplementation); - } - - /** - * @notice Upgrade the backing implementation of the proxy and call a function - * on the new implementation. - * @dev This is useful to initialize the proxied contract. - * @param newImplementation The address of the new implementation. - * @param data Data to send as msg.data in the low level call. - * It should include the signature and the parameters of the function to be called, as described in - * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. - */ - function upgradeToAndCall(address newImplementation, bytes calldata data) - external - payable - ifAdmin - { - _upgradeTo(newImplementation); - (bool success, ) = newImplementation.delegatecall(data); - require(success); - } - - /** - * @notice Only fall back when the sender is not the admin. - */ - function _willFallback() internal virtual override { - require(msg.sender != _admin, 'Cannot call fallback function from the proxy admin'); - super._willFallback(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol deleted file mode 100644 index 655e5f9..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -import {InitializableUpgradeabilityProxy} from '../../../dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol'; -import {Proxy} from '../../../dependencies/openzeppelin/upgradeability/Proxy.sol'; -import {BaseImmutableAdminUpgradeabilityProxy} from './BaseImmutableAdminUpgradeabilityProxy.sol'; - -/** - * @title InitializableAdminUpgradeabilityProxy - * @author Aave - * @dev Extends BaseAdminUpgradeabilityProxy with an initializer function - */ -contract InitializableImmutableAdminUpgradeabilityProxy is - BaseImmutableAdminUpgradeabilityProxy, - InitializableUpgradeabilityProxy -{ - /** - * @dev Constructor. - * @param admin The address of the admin - */ - constructor(address admin) BaseImmutableAdminUpgradeabilityProxy(admin) { - // Intentionally left blank - } - - /// @inheritdoc BaseImmutableAdminUpgradeabilityProxy - function _willFallback() internal override(BaseImmutableAdminUpgradeabilityProxy, Proxy) { - BaseImmutableAdminUpgradeabilityProxy._willFallback(); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol deleted file mode 100644 index 570c319..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.10; - -/** - * @title VersionedInitializable - * @author Aave, inspired by the OpenZeppelin Initializable contract - * @notice Helper contract to implement initializer functions. To use it, replace - * the constructor with a function that has the `initializer` modifier. - * @dev WARNING: Unlike constructors, initializer functions must be manually - * invoked. This applies both to deploying an Initializable contract, as well - * as extending an Initializable contract via inheritance. - * WARNING: When used with inheritance, manual care must be taken to not invoke - * a parent initializer twice, or ensure that all initializers are idempotent, - * because this is not dealt with automatically as with constructors. - */ -abstract contract VersionedInitializable { - /** - * @dev Indicates that the contract has been initialized. - */ - uint256 private lastInitializedRevision = 0; - - /** - * @dev Indicates that the contract is in the process of being initialized. - */ - bool private initializing; - - /** - * @dev Modifier to use in the initializer function of a contract. - */ - modifier initializer() { - uint256 revision = getRevision(); - require( - initializing || isConstructor() || revision > lastInitializedRevision, - 'Contract instance has already been initialized' - ); - - bool isTopLevelCall = !initializing; - if (isTopLevelCall) { - initializing = true; - lastInitializedRevision = revision; - } - - _; - - if (isTopLevelCall) { - initializing = false; - } - } - - /** - * @notice Returns the revision number of the contract - * @dev Needs to be defined in the inherited class as a constant. - * @return The revision number - **/ - function getRevision() internal pure virtual returns (uint256); - - /** - * @notice Returns true if and only if the function is running in the constructor - * @return True if the function is running in the constructor - **/ - function isConstructor() private view returns (bool) { - // extcodesize checks the size of the code stored in an address, and - // address returns the current address. Since the code is still not - // deployed when running a constructor, any checks on its code size will - // yield zero, making it an effective way to detect if a contract is - // under construction or not. - uint256 cs; - //solium-disable-next-line - assembly { - cs := extcodesize(address()) - } - return cs == 0; - } - - // Reserved storage space to allow for layout changes in the future. - uint256[50] private ______gap; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol deleted file mode 100644 index ed38c5c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/configuration/ReserveConfiguration.sol +++ /dev/null @@ -1,633 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {Errors} from '../helpers/Errors.sol'; -import {DataTypes} from '../types/DataTypes.sol'; - -/** - * @title ReserveConfiguration library - * @author Aave - * @notice Implements the bitmap logic to handle the reserve configuration - */ -library ReserveConfiguration { - uint256 internal constant LTV_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000; // prettier-ignore - uint256 internal constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF; // prettier-ignore - uint256 internal constant LIQUIDATION_BONUS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF; // prettier-ignore - uint256 internal constant DECIMALS_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF; // prettier-ignore - uint256 internal constant ACTIVE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant FROZEN_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant PAUSED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant SILOED_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant LIQUIDATION_PROTOCOL_FEE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant EMODE_CATEGORY_MASK = 0xFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant UNBACKED_MINT_CAP_MASK = 0xFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore - uint256 internal constant DEBT_CEILING_MASK = 0xF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore - - /// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed - uint256 internal constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16; - uint256 internal constant LIQUIDATION_BONUS_START_BIT_POSITION = 32; - uint256 internal constant RESERVE_DECIMALS_START_BIT_POSITION = 48; - uint256 internal constant IS_ACTIVE_START_BIT_POSITION = 56; - uint256 internal constant IS_FROZEN_START_BIT_POSITION = 57; - uint256 internal constant BORROWING_ENABLED_START_BIT_POSITION = 58; - uint256 internal constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59; - uint256 internal constant IS_PAUSED_START_BIT_POSITION = 60; - uint256 internal constant BORROWABLE_IN_ISOLATION_START_BIT_POSITION = 61; - uint256 internal constant SILOED_BORROWING_START_BIT_POSITION = 62; - /// @dev bit 63 reserved - - uint256 internal constant RESERVE_FACTOR_START_BIT_POSITION = 64; - uint256 internal constant BORROW_CAP_START_BIT_POSITION = 80; - uint256 internal constant SUPPLY_CAP_START_BIT_POSITION = 116; - uint256 internal constant LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION = 152; - uint256 internal constant EMODE_CATEGORY_START_BIT_POSITION = 168; - uint256 internal constant UNBACKED_MINT_CAP_START_BIT_POSITION = 176; - uint256 internal constant DEBT_CEILING_START_BIT_POSITION = 212; - - uint256 internal constant MAX_VALID_LTV = 65535; - uint256 internal constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535; - uint256 internal constant MAX_VALID_LIQUIDATION_BONUS = 65535; - uint256 internal constant MAX_VALID_DECIMALS = 255; - uint256 internal constant MAX_VALID_RESERVE_FACTOR = 65535; - uint256 internal constant MAX_VALID_BORROW_CAP = 68719476735; - uint256 internal constant MAX_VALID_SUPPLY_CAP = 68719476735; - uint256 internal constant MAX_VALID_LIQUIDATION_PROTOCOL_FEE = 65535; - uint256 internal constant MAX_VALID_EMODE_CATEGORY = 255; - uint256 internal constant MAX_VALID_UNBACKED_MINT_CAP = 68719476735; - uint256 internal constant MAX_VALID_DEBT_CEILING = 1099511627775; - - uint256 public constant DEBT_CEILING_DECIMALS = 2; - uint16 public constant MAX_RESERVES_COUNT = 128; - - /** - * @notice Sets the Loan to Value of the reserve - * @param self The reserve configuration - * @param ltv The new ltv - **/ - function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure { - require(ltv <= MAX_VALID_LTV, Errors.INVALID_LTV); - - self.data = (self.data & LTV_MASK) | ltv; - } - - /** - * @notice Gets the Loan to Value of the reserve - * @param self The reserve configuration - * @return The loan to value - **/ - function getLtv(DataTypes.ReserveConfigurationMap memory self) internal pure returns (uint256) { - return self.data & ~LTV_MASK; - } - - /** - * @notice Sets the liquidation threshold of the reserve - * @param self The reserve configuration - * @param threshold The new liquidation threshold - **/ - function setLiquidationThreshold(DataTypes.ReserveConfigurationMap memory self, uint256 threshold) - internal - pure - { - require(threshold <= MAX_VALID_LIQUIDATION_THRESHOLD, Errors.INVALID_LIQ_THRESHOLD); - - self.data = - (self.data & LIQUIDATION_THRESHOLD_MASK) | - (threshold << LIQUIDATION_THRESHOLD_START_BIT_POSITION); - } - - /** - * @notice Gets the liquidation threshold of the reserve - * @param self The reserve configuration - * @return The liquidation threshold - **/ - function getLiquidationThreshold(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION; - } - - /** - * @notice Sets the liquidation bonus of the reserve - * @param self The reserve configuration - * @param bonus The new liquidation bonus - **/ - function setLiquidationBonus(DataTypes.ReserveConfigurationMap memory self, uint256 bonus) - internal - pure - { - require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.INVALID_LIQ_BONUS); - - self.data = - (self.data & LIQUIDATION_BONUS_MASK) | - (bonus << LIQUIDATION_BONUS_START_BIT_POSITION); - } - - /** - * @notice Gets the liquidation bonus of the reserve - * @param self The reserve configuration - * @return The liquidation bonus - **/ - function getLiquidationBonus(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION; - } - - /** - * @notice Sets the decimals of the underlying asset of the reserve - * @param self The reserve configuration - * @param decimals The decimals - **/ - function setDecimals(DataTypes.ReserveConfigurationMap memory self, uint256 decimals) - internal - pure - { - require(decimals <= MAX_VALID_DECIMALS, Errors.INVALID_DECIMALS); - - self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION); - } - - /** - * @notice Gets the decimals of the underlying asset of the reserve - * @param self The reserve configuration - * @return The decimals of the asset - **/ - function getDecimals(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION; - } - - /** - * @notice Sets the active state of the reserve - * @param self The reserve configuration - * @param active The active state - **/ - function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure { - self.data = - (self.data & ACTIVE_MASK) | - (uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION); - } - - /** - * @notice Gets the active state of the reserve - * @param self The reserve configuration - * @return The active state - **/ - function getActive(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { - return (self.data & ~ACTIVE_MASK) != 0; - } - - /** - * @notice Sets the frozen state of the reserve - * @param self The reserve configuration - * @param frozen The frozen state - **/ - function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure { - self.data = - (self.data & FROZEN_MASK) | - (uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION); - } - - /** - * @notice Gets the frozen state of the reserve - * @param self The reserve configuration - * @return The frozen state - **/ - function getFrozen(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { - return (self.data & ~FROZEN_MASK) != 0; - } - - /** - * @notice Sets the paused state of the reserve - * @param self The reserve configuration - * @param paused The paused state - **/ - function setPaused(DataTypes.ReserveConfigurationMap memory self, bool paused) internal pure { - self.data = - (self.data & PAUSED_MASK) | - (uint256(paused ? 1 : 0) << IS_PAUSED_START_BIT_POSITION); - } - - /** - * @notice Gets the paused state of the reserve - * @param self The reserve configuration - * @return The paused state - **/ - function getPaused(DataTypes.ReserveConfigurationMap memory self) internal pure returns (bool) { - return (self.data & ~PAUSED_MASK) != 0; - } - - /** - * @notice Sets the borrowable in isolation flag for the reserve. - * @dev When this flag is set to true, the asset will be borrowable against isolated collaterals and the borrowed - * amount will be accumulated in the isolated collateral's total debt exposure. - * @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep - * consistency in the debt ceiling calculations. - * @param self The reserve configuration - * @param borrowable True if the asset is borrowable - **/ - function setBorrowableInIsolation(DataTypes.ReserveConfigurationMap memory self, bool borrowable) - internal - pure - { - self.data = - (self.data & BORROWABLE_IN_ISOLATION_MASK) | - (uint256(borrowable ? 1 : 0) << BORROWABLE_IN_ISOLATION_START_BIT_POSITION); - } - - /** - * @notice Gets the borrowable in isolation flag for the reserve. - * @dev If the returned flag is true, the asset is borrowable against isolated collateral. Assets borrowed with - * isolated collateral is accounted for in the isolated collateral's total debt exposure. - * @dev Only assets of the same family (eg USD stablecoins) should be borrowable in isolation mode to keep - * consistency in the debt ceiling calculations. - * @param self The reserve configuration - * @return The borrowable in isolation flag - **/ - function getBorrowableInIsolation(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (bool) - { - return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0; - } - - /** - * @notice Sets the siloed borrowing flag for the reserve. - * @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset. - * @param self The reserve configuration - * @param siloed True if the asset is siloed - **/ - function setSiloedBorrowing(DataTypes.ReserveConfigurationMap memory self, bool siloed) - internal - pure - { - self.data = - (self.data & SILOED_BORROWING_MASK) | - (uint256(siloed ? 1 : 0) << SILOED_BORROWING_START_BIT_POSITION); - } - - /** - * @notice Gets the siloed borrowing flag for the reserve. - * @dev When this flag is set to true, users borrowing this asset will not be allowed to borrow any other asset. - * @param self The reserve configuration - * @return The siloed borrowing flag - **/ - function getSiloedBorrowing(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (bool) - { - return (self.data & ~SILOED_BORROWING_MASK) != 0; - } - - /** - * @notice Enables or disables borrowing on the reserve - * @param self The reserve configuration - * @param enabled True if the borrowing needs to be enabled, false otherwise - **/ - function setBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled) - internal - pure - { - self.data = - (self.data & BORROWING_MASK) | - (uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION); - } - - /** - * @notice Gets the borrowing state of the reserve - * @param self The reserve configuration - * @return The borrowing state - **/ - function getBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (bool) - { - return (self.data & ~BORROWING_MASK) != 0; - } - - /** - * @notice Enables or disables stable rate borrowing on the reserve - * @param self The reserve configuration - * @param enabled True if the stable rate borrowing needs to be enabled, false otherwise - **/ - function setStableRateBorrowingEnabled( - DataTypes.ReserveConfigurationMap memory self, - bool enabled - ) internal pure { - self.data = - (self.data & STABLE_BORROWING_MASK) | - (uint256(enabled ? 1 : 0) << STABLE_BORROWING_ENABLED_START_BIT_POSITION); - } - - /** - * @notice Gets the stable rate borrowing state of the reserve - * @param self The reserve configuration - * @return The stable rate borrowing state - **/ - function getStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (bool) - { - return (self.data & ~STABLE_BORROWING_MASK) != 0; - } - - /** - * @notice Sets the reserve factor of the reserve - * @param self The reserve configuration - * @param reserveFactor The reserve factor - **/ - function setReserveFactor(DataTypes.ReserveConfigurationMap memory self, uint256 reserveFactor) - internal - pure - { - require(reserveFactor <= MAX_VALID_RESERVE_FACTOR, Errors.INVALID_RESERVE_FACTOR); - - self.data = - (self.data & RESERVE_FACTOR_MASK) | - (reserveFactor << RESERVE_FACTOR_START_BIT_POSITION); - } - - /** - * @notice Gets the reserve factor of the reserve - * @param self The reserve configuration - * @return The reserve factor - **/ - function getReserveFactor(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION; - } - - /** - * @notice Sets the borrow cap of the reserve - * @param self The reserve configuration - * @param borrowCap The borrow cap - **/ - function setBorrowCap(DataTypes.ReserveConfigurationMap memory self, uint256 borrowCap) - internal - pure - { - require(borrowCap <= MAX_VALID_BORROW_CAP, Errors.INVALID_BORROW_CAP); - - self.data = (self.data & BORROW_CAP_MASK) | (borrowCap << BORROW_CAP_START_BIT_POSITION); - } - - /** - * @notice Gets the borrow cap of the reserve - * @param self The reserve configuration - * @return The borrow cap - **/ - function getBorrowCap(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION; - } - - /** - * @notice Sets the supply cap of the reserve - * @param self The reserve configuration - * @param supplyCap The supply cap - **/ - function setSupplyCap(DataTypes.ReserveConfigurationMap memory self, uint256 supplyCap) - internal - pure - { - require(supplyCap <= MAX_VALID_SUPPLY_CAP, Errors.INVALID_SUPPLY_CAP); - - self.data = (self.data & SUPPLY_CAP_MASK) | (supplyCap << SUPPLY_CAP_START_BIT_POSITION); - } - - /** - * @notice Gets the supply cap of the reserve - * @param self The reserve configuration - * @return The supply cap - **/ - function getSupplyCap(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION; - } - - /** - * @notice Sets the debt ceiling in isolation mode for the asset - * @param self The reserve configuration - * @param ceiling The maximum debt ceiling for the asset - **/ - function setDebtCeiling(DataTypes.ReserveConfigurationMap memory self, uint256 ceiling) - internal - pure - { - require(ceiling <= MAX_VALID_DEBT_CEILING, Errors.INVALID_DEBT_CEILING); - - self.data = (self.data & DEBT_CEILING_MASK) | (ceiling << DEBT_CEILING_START_BIT_POSITION); - } - - /** - * @notice Gets the debt ceiling for the asset if the asset is in isolation mode - * @param self The reserve configuration - * @return The debt ceiling (0 = isolation mode disabled) - **/ - function getDebtCeiling(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~DEBT_CEILING_MASK) >> DEBT_CEILING_START_BIT_POSITION; - } - - /** - * @notice Sets the liquidation protocol fee of the reserve - * @param self The reserve configuration - * @param liquidationProtocolFee The liquidation protocol fee - **/ - function setLiquidationProtocolFee( - DataTypes.ReserveConfigurationMap memory self, - uint256 liquidationProtocolFee - ) internal pure { - require( - liquidationProtocolFee <= MAX_VALID_LIQUIDATION_PROTOCOL_FEE, - Errors.INVALID_LIQUIDATION_PROTOCOL_FEE - ); - - self.data = - (self.data & LIQUIDATION_PROTOCOL_FEE_MASK) | - (liquidationProtocolFee << LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION); - } - - /** - * @dev Gets the liquidation protocol fee - * @param self The reserve configuration - * @return The liquidation protocol fee - **/ - function getLiquidationProtocolFee(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return - (self.data & ~LIQUIDATION_PROTOCOL_FEE_MASK) >> LIQUIDATION_PROTOCOL_FEE_START_BIT_POSITION; - } - - /** - * @notice Sets the unbacked mint cap of the reserve - * @param self The reserve configuration - * @param unbackedMintCap The unbacked mint cap - **/ - function setUnbackedMintCap( - DataTypes.ReserveConfigurationMap memory self, - uint256 unbackedMintCap - ) internal pure { - require(unbackedMintCap <= MAX_VALID_UNBACKED_MINT_CAP, Errors.INVALID_UNBACKED_MINT_CAP); - - self.data = - (self.data & UNBACKED_MINT_CAP_MASK) | - (unbackedMintCap << UNBACKED_MINT_CAP_START_BIT_POSITION); - } - - /** - * @dev Gets the unbacked mint cap of the reserve - * @param self The reserve configuration - * @return The unbacked mint cap - **/ - function getUnbackedMintCap(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~UNBACKED_MINT_CAP_MASK) >> UNBACKED_MINT_CAP_START_BIT_POSITION; - } - - /** - * @notice Sets the eMode asset category - * @param self The reserve configuration - * @param category The asset category when the user selects the eMode - **/ - function setEModeCategory(DataTypes.ReserveConfigurationMap memory self, uint256 category) - internal - pure - { - require(category <= MAX_VALID_EMODE_CATEGORY, Errors.INVALID_EMODE_CATEGORY); - - self.data = (self.data & EMODE_CATEGORY_MASK) | (category << EMODE_CATEGORY_START_BIT_POSITION); - } - - /** - * @dev Gets the eMode asset category - * @param self The reserve configuration - * @return The eMode category for the asset - **/ - function getEModeCategory(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256) - { - return (self.data & ~EMODE_CATEGORY_MASK) >> EMODE_CATEGORY_START_BIT_POSITION; - } - - /** - * @notice Gets the configuration flags of the reserve - * @param self The reserve configuration - * @return The state flag representing active - * @return The state flag representing frozen - * @return The state flag representing borrowing enabled - * @return The state flag representing stableRateBorrowing enabled - * @return The state flag representing paused - **/ - function getFlags(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns ( - bool, - bool, - bool, - bool, - bool - ) - { - uint256 dataLocal = self.data; - - return ( - (dataLocal & ~ACTIVE_MASK) != 0, - (dataLocal & ~FROZEN_MASK) != 0, - (dataLocal & ~BORROWING_MASK) != 0, - (dataLocal & ~STABLE_BORROWING_MASK) != 0, - (dataLocal & ~PAUSED_MASK) != 0 - ); - } - - /** - * @notice Gets the configuration parameters of the reserve from storage - * @param self The reserve configuration - * @return The state param representing ltv - * @return The state param representing liquidation threshold - * @return The state param representing liquidation bonus - * @return The state param representing reserve decimals - * @return The state param representing reserve factor - * @return The state param representing eMode category - **/ - function getParams(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns ( - uint256, - uint256, - uint256, - uint256, - uint256, - uint256 - ) - { - uint256 dataLocal = self.data; - - return ( - dataLocal & ~LTV_MASK, - (dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, - (dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, - (dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, - (dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION, - (dataLocal & ~EMODE_CATEGORY_MASK) >> EMODE_CATEGORY_START_BIT_POSITION - ); - } - - /** - * @notice Gets the caps parameters of the reserve from storage - * @param self The reserve configuration - * @return The state param representing borrow cap - * @return The state param representing supply cap. - **/ - function getCaps(DataTypes.ReserveConfigurationMap memory self) - internal - pure - returns (uint256, uint256) - { - uint256 dataLocal = self.data; - - return ( - (dataLocal & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION, - (dataLocal & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION - ); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol deleted file mode 100644 index cc9df47..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/configuration/UserConfiguration.sol +++ /dev/null @@ -1,251 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {Errors} from '../helpers/Errors.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ReserveConfiguration} from './ReserveConfiguration.sol'; - -/** - * @title UserConfiguration library - * @author Aave - * @notice Implements the bitmap logic to handle the user configuration - */ -library UserConfiguration { - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - - uint256 internal constant BORROWING_MASK = - 0x5555555555555555555555555555555555555555555555555555555555555555; - uint256 internal constant COLLATERAL_MASK = - 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; - - /** - * @notice Sets if the user is borrowing the reserve identified by reserveIndex - * @param self The configuration object - * @param reserveIndex The index of the reserve in the bitmap - * @param borrowing True if the user is borrowing the reserve, false otherwise - **/ - function setBorrowing( - DataTypes.UserConfigurationMap storage self, - uint256 reserveIndex, - bool borrowing - ) internal { - unchecked { - require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); - uint256 bit = 1 << (reserveIndex << 1); - if (borrowing) { - self.data |= bit; - } else { - self.data &= ~bit; - } - } - } - - /** - * @notice Sets if the user is using as collateral the reserve identified by reserveIndex - * @param self The configuration object - * @param reserveIndex The index of the reserve in the bitmap - * @param usingAsCollateral True if the user is using the reserve as collateral, false otherwise - **/ - function setUsingAsCollateral( - DataTypes.UserConfigurationMap storage self, - uint256 reserveIndex, - bool usingAsCollateral - ) internal { - unchecked { - require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); - uint256 bit = 1 << ((reserveIndex << 1) + 1); - if (usingAsCollateral) { - self.data |= bit; - } else { - self.data &= ~bit; - } - } - } - - /** - * @notice Returns if a user has been using the reserve for borrowing or as collateral - * @param self The configuration object - * @param reserveIndex The index of the reserve in the bitmap - * @return True if the user has been using a reserve for borrowing or as collateral, false otherwise - **/ - function isUsingAsCollateralOrBorrowing( - DataTypes.UserConfigurationMap memory self, - uint256 reserveIndex - ) internal pure returns (bool) { - unchecked { - require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); - return (self.data >> (reserveIndex << 1)) & 3 != 0; - } - } - - /** - * @notice Validate a user has been using the reserve for borrowing - * @param self The configuration object - * @param reserveIndex The index of the reserve in the bitmap - * @return True if the user has been using a reserve for borrowing, false otherwise - **/ - function isBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex) - internal - pure - returns (bool) - { - unchecked { - require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); - return (self.data >> (reserveIndex << 1)) & 1 != 0; - } - } - - /** - * @notice Validate a user has been using the reserve as collateral - * @param self The configuration object - * @param reserveIndex The index of the reserve in the bitmap - * @return True if the user has been using a reserve as collateral, false otherwise - **/ - function isUsingAsCollateral(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex) - internal - pure - returns (bool) - { - unchecked { - require(reserveIndex < ReserveConfiguration.MAX_RESERVES_COUNT, Errors.INVALID_RESERVE_INDEX); - return (self.data >> ((reserveIndex << 1) + 1)) & 1 != 0; - } - } - - /** - * @notice Checks if a user has been supplying only one reserve as collateral - * @dev this uses a simple trick - if a number is a power of two (only one bit set) then n & (n - 1) == 0 - * @param self The configuration object - * @return True if the user has been supplying as collateral one reserve, false otherwise - **/ - function isUsingAsCollateralOne(DataTypes.UserConfigurationMap memory self) - internal - pure - returns (bool) - { - uint256 collateralData = self.data & COLLATERAL_MASK; - return collateralData != 0 && (collateralData & (collateralData - 1) == 0); - } - - /** - * @notice Checks if a user has been supplying any reserve as collateral - * @param self The configuration object - * @return True if the user has been supplying as collateral any reserve, false otherwise - **/ - function isUsingAsCollateralAny(DataTypes.UserConfigurationMap memory self) - internal - pure - returns (bool) - { - return self.data & COLLATERAL_MASK != 0; - } - - /** - * @notice Checks if a user has been borrowing only one asset - * @dev this uses a simple trick - if a number is a power of two (only one bit set) then n & (n - 1) == 0 - * @param self The configuration object - * @return True if the user has been supplying as collateral one reserve, false otherwise - **/ - function isBorrowingOne(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { - uint256 borrowingData = self.data & BORROWING_MASK; - return borrowingData != 0 && (borrowingData & (borrowingData - 1) == 0); - } - - /** - * @notice Checks if a user has been borrowing from any reserve - * @param self The configuration object - * @return True if the user has been borrowing any reserve, false otherwise - **/ - function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { - return self.data & BORROWING_MASK != 0; - } - - /** - * @notice Checks if a user has not been using any reserve for borrowing or supply - * @param self The configuration object - * @return True if the user has not been borrowing or supplying any reserve, false otherwise - **/ - function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { - return self.data == 0; - } - - /** - * @notice Returns the Isolation Mode state of the user - * @param self The configuration object - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @return True if the user is in isolation mode, false otherwise - * @return The address of the only asset used as collateral - * @return The debt ceiling of the reserve - */ - function getIsolationModeState( - DataTypes.UserConfigurationMap memory self, - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList - ) - internal - view - returns ( - bool, - address, - uint256 - ) - { - if (isUsingAsCollateralOne(self)) { - uint256 assetId = _getFirstAssetIdByMask(self, COLLATERAL_MASK); - - address assetAddress = reservesList[assetId]; - uint256 ceiling = reservesData[assetAddress].configuration.getDebtCeiling(); - if (ceiling != 0) { - return (true, assetAddress, ceiling); - } - } - return (false, address(0), 0); - } - - /** - * @notice Returns the siloed borrowing state for the user - * @param self The configuration object - * @param reservesData The data of all the reserves - * @param reservesList The reserve list - * @return True if the user has borrowed a siloed asset, false otherwise - * @return The address of the only borrowed asset - */ - function getSiloedBorrowingState( - DataTypes.UserConfigurationMap memory self, - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList - ) internal view returns (bool, address) { - if (isBorrowingOne(self)) { - uint256 assetId = _getFirstAssetIdByMask(self, BORROWING_MASK); - address assetAddress = reservesList[assetId]; - if (reservesData[assetAddress].configuration.getSiloedBorrowing()) { - return (true, assetAddress); - } - } - - return (false, address(0)); - } - - /** - * @notice Returns the address of the first asset flagged in the bitmap given the corresponding bitmask - * @param self The configuration object - * @return The index of the first asset flagged in the bitmap once the corresponding mask is applied - */ - function _getFirstAssetIdByMask(DataTypes.UserConfigurationMap memory self, uint256 mask) - internal - pure - returns (uint256) - { - unchecked { - uint256 bitmapData = self.data & mask; - uint256 firstAssetPosition = bitmapData & ~(bitmapData - 1); - uint256 id; - - while ((firstAssetPosition >>= 2) != 0) { - id += 1; - } - return id; - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol deleted file mode 100644 index 640e463..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/helpers/Errors.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -/** - * @title Errors library - * @author Aave - * @notice Defines the error messages emitted by the different contracts of the Aave protocol - */ -library Errors { - string public constant CALLER_NOT_POOL_ADMIN = '1'; // 'The caller of the function is not a pool admin' - string public constant CALLER_NOT_EMERGENCY_ADMIN = '2'; // 'The caller of the function is not an emergency admin' - string public constant CALLER_NOT_POOL_OR_EMERGENCY_ADMIN = '3'; // 'The caller of the function is not a pool or emergency admin' - string public constant CALLER_NOT_RISK_OR_POOL_ADMIN = '4'; // 'The caller of the function is not a risk or pool admin' - string public constant CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN = '5'; // 'The caller of the function is not an asset listing or pool admin' - string public constant CALLER_NOT_BRIDGE = '6'; // 'The caller of the function is not a bridge' - string public constant ADDRESSES_PROVIDER_NOT_REGISTERED = '7'; // 'Pool addresses provider is not registered' - string public constant INVALID_ADDRESSES_PROVIDER_ID = '8'; // 'Invalid id for the pool addresses provider' - string public constant NOT_CONTRACT = '9'; // 'Address is not a contract' - string public constant CALLER_NOT_POOL_CONFIGURATOR = '10'; // 'The caller of the function is not the pool configurator' - string public constant CALLER_NOT_ATOKEN = '11'; // 'The caller of the function is not an AToken' - string public constant INVALID_ADDRESSES_PROVIDER = '12'; // 'The address of the pool addresses provider is invalid' - string public constant INVALID_FLASHLOAN_EXECUTOR_RETURN = '13'; // 'Invalid return value of the flashloan executor function' - string public constant RESERVE_ALREADY_ADDED = '14'; // 'Reserve has already been added to reserve list' - string public constant NO_MORE_RESERVES_ALLOWED = '15'; // 'Maximum amount of reserves in the pool reached' - string public constant EMODE_CATEGORY_RESERVED = '16'; // 'Zero eMode category is reserved for volatile heterogeneous assets' - string public constant INVALID_EMODE_CATEGORY_ASSIGNMENT = '17'; // 'Invalid eMode category assignment to asset' - string public constant RESERVE_LIQUIDITY_NOT_ZERO = '18'; // 'The liquidity of the reserve needs to be 0' - string public constant FLASHLOAN_PREMIUM_INVALID = '19'; // 'Invalid flashloan premium' - string public constant INVALID_RESERVE_PARAMS = '20'; // 'Invalid risk parameters for the reserve' - string public constant INVALID_EMODE_CATEGORY_PARAMS = '21'; // 'Invalid risk parameters for the eMode category' - string public constant BRIDGE_PROTOCOL_FEE_INVALID = '22'; // 'Invalid bridge protocol fee' - string public constant CALLER_MUST_BE_POOL = '23'; // 'The caller of this function must be a pool' - string public constant INVALID_MINT_AMOUNT = '24'; // 'Invalid amount to mint' - string public constant INVALID_BURN_AMOUNT = '25'; // 'Invalid amount to burn' - string public constant INVALID_AMOUNT = '26'; // 'Amount must be greater than 0' - string public constant RESERVE_INACTIVE = '27'; // 'Action requires an active reserve' - string public constant RESERVE_FROZEN = '28'; // 'Action cannot be performed because the reserve is frozen' - string public constant RESERVE_PAUSED = '29'; // 'Action cannot be performed because the reserve is paused' - string public constant BORROWING_NOT_ENABLED = '30'; // 'Borrowing is not enabled' - string public constant STABLE_BORROWING_NOT_ENABLED = '31'; // 'Stable borrowing is not enabled' - string public constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '32'; // 'User cannot withdraw more than the available balance' - string public constant INVALID_INTEREST_RATE_MODE_SELECTED = '33'; // 'Invalid interest rate mode selected' - string public constant COLLATERAL_BALANCE_IS_ZERO = '34'; // 'The collateral balance is 0' - string public constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '35'; // 'Health factor is lesser than the liquidation threshold' - string public constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '36'; // 'There is not enough collateral to cover a new borrow' - string public constant COLLATERAL_SAME_AS_BORROWING_CURRENCY = '37'; // 'Collateral is (mostly) the same currency that is being borrowed' - string public constant AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '38'; // 'The requested amount is greater than the max loan size in stable rate mode' - string public constant NO_DEBT_OF_SELECTED_TYPE = '39'; // 'For repayment of a specific type of debt, the user needs to have debt that type' - string public constant NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '40'; // 'To repay on behalf of a user an explicit amount to repay is needed' - string public constant NO_OUTSTANDING_STABLE_DEBT = '41'; // 'User does not have outstanding stable rate debt on this reserve' - string public constant NO_OUTSTANDING_VARIABLE_DEBT = '42'; // 'User does not have outstanding variable rate debt on this reserve' - string public constant UNDERLYING_BALANCE_ZERO = '43'; // 'The underlying balance needs to be greater than 0' - string public constant INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '44'; // 'Interest rate rebalance conditions were not met' - string public constant HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '45'; // 'Health factor is not below the threshold' - string public constant COLLATERAL_CANNOT_BE_LIQUIDATED = '46'; // 'The collateral chosen cannot be liquidated' - string public constant SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '47'; // 'User did not borrow the specified currency' - string public constant SAME_BLOCK_BORROW_REPAY = '48'; // 'Borrow and repay in same block is not allowed' - string public constant INCONSISTENT_FLASHLOAN_PARAMS = '49'; // 'Inconsistent flashloan parameters' - string public constant BORROW_CAP_EXCEEDED = '50'; // 'Borrow cap is exceeded' - string public constant SUPPLY_CAP_EXCEEDED = '51'; // 'Supply cap is exceeded' - string public constant UNBACKED_MINT_CAP_EXCEEDED = '52'; // 'Unbacked mint cap is exceeded' - string public constant DEBT_CEILING_EXCEEDED = '53'; // 'Debt ceiling is exceeded' - string public constant ATOKEN_SUPPLY_NOT_ZERO = '54'; // 'AToken supply is not zero' - string public constant STABLE_DEBT_NOT_ZERO = '55'; // 'Stable debt supply is not zero' - string public constant VARIABLE_DEBT_SUPPLY_NOT_ZERO = '56'; // 'Variable debt supply is not zero' - string public constant LTV_VALIDATION_FAILED = '57'; // 'Ltv validation failed' - string public constant INCONSISTENT_EMODE_CATEGORY = '58'; // 'Inconsistent eMode category' - string public constant PRICE_ORACLE_SENTINEL_CHECK_FAILED = '59'; // 'Price oracle sentinel validation failed' - string public constant ASSET_NOT_BORROWABLE_IN_ISOLATION = '60'; // 'Asset is not borrowable in isolation mode' - string public constant RESERVE_ALREADY_INITIALIZED = '61'; // 'Reserve has already been initialized' - string public constant USER_IN_ISOLATION_MODE = '62'; // 'User is in isolation mode' - string public constant INVALID_LTV = '63'; // 'Invalid ltv parameter for the reserve' - string public constant INVALID_LIQ_THRESHOLD = '64'; // 'Invalid liquidity threshold parameter for the reserve' - string public constant INVALID_LIQ_BONUS = '65'; // 'Invalid liquidity bonus parameter for the reserve' - string public constant INVALID_DECIMALS = '66'; // 'Invalid decimals parameter of the underlying asset of the reserve' - string public constant INVALID_RESERVE_FACTOR = '67'; // 'Invalid reserve factor parameter for the reserve' - string public constant INVALID_BORROW_CAP = '68'; // 'Invalid borrow cap for the reserve' - string public constant INVALID_SUPPLY_CAP = '69'; // 'Invalid supply cap for the reserve' - string public constant INVALID_LIQUIDATION_PROTOCOL_FEE = '70'; // 'Invalid liquidation protocol fee for the reserve' - string public constant INVALID_EMODE_CATEGORY = '71'; // 'Invalid eMode category for the reserve' - string public constant INVALID_UNBACKED_MINT_CAP = '72'; // 'Invalid unbacked mint cap for the reserve' - string public constant INVALID_DEBT_CEILING = '73'; // 'Invalid debt ceiling for the reserve - string public constant INVALID_RESERVE_INDEX = '74'; // 'Invalid reserve index' - string public constant ACL_ADMIN_CANNOT_BE_ZERO = '75'; // 'ACL admin cannot be set to the zero address' - string public constant INCONSISTENT_PARAMS_LENGTH = '76'; // 'Array parameters that should be equal length are not' - string public constant ZERO_ADDRESS_NOT_VALID = '77'; // 'Zero address not valid' - string public constant INVALID_EXPIRATION = '78'; // 'Invalid expiration' - string public constant INVALID_SIGNATURE = '79'; // 'Invalid signature' - string public constant OPERATION_NOT_SUPPORTED = '80'; // 'Operation not supported' - string public constant DEBT_CEILING_NOT_ZERO = '81'; // 'Debt ceiling is not zero' - string public constant ASSET_NOT_LISTED = '82'; // 'Asset is not listed' - string public constant INVALID_OPTIMAL_USAGE_RATIO = '83'; // 'Invalid optimal usage ratio' - string public constant INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = '84'; // 'Invalid optimal stable to total debt ratio' - string public constant UNDERLYING_CANNOT_BE_RESCUED = '85'; // 'The underlying asset cannot be rescued' - string public constant ADDRESSES_PROVIDER_ALREADY_ADDED = '86'; // 'Reserve has already been added to reserve list' - string public constant POOL_ADDRESSES_DO_NOT_MATCH = '87'; // 'The token implementation pool address and the pool address provided by the initializing pool do not match' - string public constant STABLE_BORROWING_ENABLED = '88'; // 'Stable borrowing is enabled' - string public constant SILOED_BORROWING_VIOLATION = '89'; // 'User is trying to borrow multiple assets including a siloed one' - string public constant RESERVE_DEBT_NOT_ZERO = '90'; // the total debt of the reserve needs to be 0 -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/helpers/Helpers.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/helpers/Helpers.sol deleted file mode 100644 index 180d72a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/helpers/Helpers.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {DataTypes} from '../types/DataTypes.sol'; - -/** - * @title Helpers library - * @author Aave - */ -library Helpers { - /** - * @notice Fetches the user current stable and variable debt balances - * @param user The user address - * @param reserveCache The reserve cache data object - * @return The stable debt balance - * @return The variable debt balance - **/ - function getUserCurrentDebt(address user, DataTypes.ReserveCache memory reserveCache) - internal - view - returns (uint256, uint256) - { - return ( - IERC20(reserveCache.stableDebtTokenAddress).balanceOf(user), - IERC20(reserveCache.variableDebtTokenAddress).balanceOf(user) - ); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol deleted file mode 100644 index 0559305..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/BorrowLogic.sol +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IStableDebtToken} from '../../../interfaces/IStableDebtToken.sol'; -import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {Helpers} from '../helpers/Helpers.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ValidationLogic} from './ValidationLogic.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; -import {IsolationModeLogic} from './IsolationModeLogic.sol'; - -/** - * @title BorrowLogic library - * @author Aave - * @notice Implements the base logic for all the actions related to borrowing - */ -library BorrowLogic { - using ReserveLogic for DataTypes.ReserveCache; - using ReserveLogic for DataTypes.ReserveData; - using GPv2SafeERC20 for IERC20; - using UserConfiguration for DataTypes.UserConfigurationMap; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using SafeCast for uint256; - - // See `IPool` for descriptions - event Borrow( - address indexed reserve, - address user, - address indexed onBehalfOf, - uint256 amount, - DataTypes.InterestRateMode interestRateMode, - uint256 borrowRate, - uint16 indexed referralCode - ); - event Repay( - address indexed reserve, - address indexed user, - address indexed repayer, - uint256 amount, - bool useATokens - ); - event RebalanceStableBorrowRate(address indexed reserve, address indexed user); - event SwapBorrowRateMode( - address indexed reserve, - address indexed user, - DataTypes.InterestRateMode interestRateMode - ); - event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); - - /** - * @notice Implements the borrow feature. Borrowing allows users that provided collateral to draw liquidity from the - * Aave protocol proportionally to their collateralization power. For isolated positions, it also increases the - * isolated debt. - * @dev Emits the `Borrow()` event - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param userConfig The user configuration mapping that tracks the supplied/borrowed assets - * @param params The additional parameters needed to execute the borrow function - */ - function executeBorrow( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.ExecuteBorrowParams memory params - ) public { - DataTypes.ReserveData storage reserve = reservesData[params.asset]; - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - - reserve.updateState(reserveCache); - - ( - bool isolationModeActive, - address isolationModeCollateralAddress, - uint256 isolationModeDebtCeiling - ) = userConfig.getIsolationModeState(reservesData, reservesList); - - ValidationLogic.validateBorrow( - reservesData, - reservesList, - eModeCategories, - DataTypes.ValidateBorrowParams({ - reserveCache: reserveCache, - userConfig: userConfig, - asset: params.asset, - userAddress: params.onBehalfOf, - amount: params.amount, - interestRateMode: params.interestRateMode, - maxStableLoanPercent: params.maxStableRateBorrowSizePercent, - reservesCount: params.reservesCount, - oracle: params.oracle, - userEModeCategory: params.userEModeCategory, - priceOracleSentinel: params.priceOracleSentinel, - isolationModeActive: isolationModeActive, - isolationModeCollateralAddress: isolationModeCollateralAddress, - isolationModeDebtCeiling: isolationModeDebtCeiling - }) - ); - - uint256 currentStableRate = 0; - bool isFirstBorrowing = false; - - if (params.interestRateMode == DataTypes.InterestRateMode.STABLE) { - currentStableRate = reserve.currentStableBorrowRate; - - ( - isFirstBorrowing, - reserveCache.nextTotalStableDebt, - reserveCache.nextAvgStableBorrowRate - ) = IStableDebtToken(reserveCache.stableDebtTokenAddress).mint( - params.user, - params.onBehalfOf, - params.amount, - currentStableRate - ); - } else { - (isFirstBorrowing, reserveCache.nextScaledVariableDebt) = IVariableDebtToken( - reserveCache.variableDebtTokenAddress - ).mint(params.user, params.onBehalfOf, params.amount, reserveCache.nextVariableBorrowIndex); - } - - if (isFirstBorrowing) { - userConfig.setBorrowing(reserve.id, true); - } - - if (isolationModeActive) { - uint256 nextIsolationModeTotalDebt = reservesData[isolationModeCollateralAddress] - .isolationModeTotalDebt += (params.amount / - 10 ** - (reserveCache.reserveConfiguration.getDecimals() - - ReserveConfiguration.DEBT_CEILING_DECIMALS)).toUint128(); - emit IsolationModeTotalDebtUpdated( - isolationModeCollateralAddress, - nextIsolationModeTotalDebt - ); - } - - reserve.updateInterestRates( - reserveCache, - params.asset, - 0, - params.releaseUnderlying ? params.amount : 0 - ); - - if (params.releaseUnderlying) { - IAToken(reserveCache.aTokenAddress).transferUnderlyingTo(params.user, params.amount); - } - - emit Borrow( - params.asset, - params.user, - params.onBehalfOf, - params.amount, - params.interestRateMode, - params.interestRateMode == DataTypes.InterestRateMode.STABLE - ? currentStableRate - : reserve.currentVariableBorrowRate, - params.referralCode - ); - } - - /** - * @notice Implements the repay feature. Repaying transfers the underlying back to the aToken and clears the - * equivalent amount of debt for the user by burning the corresponding debt token. For isolated positions, it also - * reduces the isolated debt. - * @dev Emits the `Repay()` event - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param userConfig The user configuration mapping that tracks the supplied/borrowed assets - * @param params The additional parameters needed to execute the repay function - * @return The actual amount being repaid - */ - function executeRepay( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.ExecuteRepayParams memory params - ) external returns (uint256) { - DataTypes.ReserveData storage reserve = reservesData[params.asset]; - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - reserve.updateState(reserveCache); - - (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt( - params.onBehalfOf, - reserveCache - ); - - ValidationLogic.validateRepay( - reserveCache, - params.amount, - params.interestRateMode, - params.onBehalfOf, - stableDebt, - variableDebt - ); - - uint256 paybackAmount = params.interestRateMode == DataTypes.InterestRateMode.STABLE - ? stableDebt - : variableDebt; - - // Allows a user to repay with aTokens without leaving dust from interest. - if (params.useATokens && params.amount == type(uint256).max) { - params.amount = IAToken(reserveCache.aTokenAddress).balanceOf(msg.sender); - } - - if (params.amount < paybackAmount) { - paybackAmount = params.amount; - } - - if (params.interestRateMode == DataTypes.InterestRateMode.STABLE) { - (reserveCache.nextTotalStableDebt, reserveCache.nextAvgStableBorrowRate) = IStableDebtToken( - reserveCache.stableDebtTokenAddress - ).burn(params.onBehalfOf, paybackAmount); - } else { - reserveCache.nextScaledVariableDebt = IVariableDebtToken( - reserveCache.variableDebtTokenAddress - ).burn(params.onBehalfOf, paybackAmount, reserveCache.nextVariableBorrowIndex); - } - - reserve.updateInterestRates( - reserveCache, - params.asset, - params.useATokens ? 0 : paybackAmount, - 0 - ); - - if (stableDebt + variableDebt - paybackAmount == 0) { - userConfig.setBorrowing(reserve.id, false); - } - - IsolationModeLogic.updateIsolatedDebtIfIsolated( - reservesData, - reservesList, - userConfig, - reserveCache, - paybackAmount - ); - - if (params.useATokens) { - IAToken(reserveCache.aTokenAddress).burn( - msg.sender, - reserveCache.aTokenAddress, - paybackAmount, - reserveCache.nextLiquidityIndex - ); - } else { - IERC20(params.asset).safeTransferFrom(msg.sender, reserveCache.aTokenAddress, paybackAmount); - IAToken(reserveCache.aTokenAddress).handleRepayment(msg.sender, paybackAmount); - } - - emit Repay(params.asset, params.onBehalfOf, msg.sender, paybackAmount, params.useATokens); - - return paybackAmount; - } - - /** - * @notice Implements the rebalance stable borrow rate feature. In case of liquidity crunches on the protocol, stable - * rate borrows might need to be rebalanced to bring back equilibrium between the borrow and supply APYs. - * @dev The rules that define if a position can be rebalanced are implemented in `ValidationLogic.validateRebalanceStableBorrowRate()` - * @dev Emits the `RebalanceStableBorrowRate()` event - * @param reserve The state of the reserve of the asset being repaid - * @param asset The asset of the position being rebalanced - * @param user The user being rebalanced - */ - function executeRebalanceStableBorrowRate( - DataTypes.ReserveData storage reserve, - address asset, - address user - ) external { - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - reserve.updateState(reserveCache); - - ValidationLogic.validateRebalanceStableBorrowRate(reserve, reserveCache, asset); - - IStableDebtToken stableDebtToken = IStableDebtToken(reserveCache.stableDebtTokenAddress); - uint256 stableDebt = IERC20(address(stableDebtToken)).balanceOf(user); - - stableDebtToken.burn(user, stableDebt); - - (, reserveCache.nextTotalStableDebt, reserveCache.nextAvgStableBorrowRate) = stableDebtToken - .mint(user, user, stableDebt, reserve.currentStableBorrowRate); - - reserve.updateInterestRates(reserveCache, asset, 0, 0); - - emit RebalanceStableBorrowRate(asset, user); - } - - /** - * @notice Implements the swap borrow rate feature. Borrowers can swap from variable to stable positions at any time. - * @dev Emits the `Swap()` event - * @param reserve The of the reserve of the asset being repaid - * @param userConfig The user configuration mapping that tracks the supplied/borrowed assets - * @param asset The asset of the position being swapped - * @param interestRateMode The current interest rate mode of the position being swapped - */ - function executeSwapBorrowRateMode( - DataTypes.ReserveData storage reserve, - DataTypes.UserConfigurationMap storage userConfig, - address asset, - DataTypes.InterestRateMode interestRateMode - ) external { - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - - reserve.updateState(reserveCache); - - (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt( - msg.sender, - reserveCache - ); - - ValidationLogic.validateSwapRateMode( - reserve, - reserveCache, - userConfig, - stableDebt, - variableDebt, - interestRateMode - ); - - if (interestRateMode == DataTypes.InterestRateMode.STABLE) { - (reserveCache.nextTotalStableDebt, reserveCache.nextAvgStableBorrowRate) = IStableDebtToken( - reserveCache.stableDebtTokenAddress - ).burn(msg.sender, stableDebt); - - (, reserveCache.nextScaledVariableDebt) = IVariableDebtToken( - reserveCache.variableDebtTokenAddress - ).mint(msg.sender, msg.sender, stableDebt, reserveCache.nextVariableBorrowIndex); - } else { - reserveCache.nextScaledVariableDebt = IVariableDebtToken( - reserveCache.variableDebtTokenAddress - ).burn(msg.sender, variableDebt, reserveCache.nextVariableBorrowIndex); - - (, reserveCache.nextTotalStableDebt, reserveCache.nextAvgStableBorrowRate) = IStableDebtToken( - reserveCache.stableDebtTokenAddress - ).mint(msg.sender, msg.sender, variableDebt, reserve.currentStableBorrowRate); - } - - reserve.updateInterestRates(reserveCache, asset, 0, 0); - - emit SwapBorrowRateMode(asset, msg.sender, interestRateMode); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/BridgeLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/BridgeLogic.sol deleted file mode 100644 index d5f1ce9..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/BridgeLogic.sol +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {ValidationLogic} from './ValidationLogic.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; - -library BridgeLogic { - using ReserveLogic for DataTypes.ReserveCache; - using ReserveLogic for DataTypes.ReserveData; - using UserConfiguration for DataTypes.UserConfigurationMap; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using WadRayMath for uint256; - using PercentageMath for uint256; - using SafeCast for uint256; - using GPv2SafeERC20 for IERC20; - - // See `IPool` for descriptions - event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); - event MintUnbacked( - address indexed reserve, - address user, - address indexed onBehalfOf, - uint256 amount, - uint16 indexed referralCode - ); - event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee); - - /** - * @notice Mint unbacked aTokens to a user and updates the unbacked for the reserve. - * @dev Essentially a supply without transferring the underlying. - * @dev Emits the `MintUnbacked` event - * @dev Emits the `ReserveUsedAsCollateralEnabled` if asset is set as collateral - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param userConfig The user configuration mapping that tracks the supplied/borrowed assets - * @param asset The address of the underlying asset to mint aTokens of - * @param amount The amount to mint - * @param onBehalfOf The address that will receive the aTokens - * @param referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - **/ - function executeMintUnbacked( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - DataTypes.UserConfigurationMap storage userConfig, - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external { - DataTypes.ReserveData storage reserve = reservesData[asset]; - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - - reserve.updateState(reserveCache); - - ValidationLogic.validateSupply(reserveCache, amount); - - uint256 unbackedMintCap = reserveCache.reserveConfiguration.getUnbackedMintCap(); - uint256 reserveDecimals = reserveCache.reserveConfiguration.getDecimals(); - - uint256 unbacked = reserve.unbacked += amount.toUint128(); - - require(unbacked <= unbackedMintCap * (10**reserveDecimals), Errors.UNBACKED_MINT_CAP_EXCEEDED); - - reserve.updateInterestRates(reserveCache, asset, 0, 0); - - bool isFirstSupply = IAToken(reserveCache.aTokenAddress).mint( - msg.sender, - onBehalfOf, - amount, - reserveCache.nextLiquidityIndex - ); - - if (isFirstSupply) { - if ( - ValidationLogic.validateUseAsCollateral( - reservesData, - reservesList, - userConfig, - reserveCache.reserveConfiguration - ) - ) { - userConfig.setUsingAsCollateral(reserve.id, true); - emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf); - } - } - - emit MintUnbacked(asset, msg.sender, onBehalfOf, amount, referralCode); - } - - /** - * @notice Back the current unbacked with `amount` and pay `fee`. - * @dev Emits the `BackUnbacked` event - * @param reserve The reserve to back unbacked for - * @param asset The address of the underlying asset to repay - * @param amount The amount to back - * @param fee The amount paid in fees - * @param protocolFeeBps The fraction of fees in basis points paid to the protocol - **/ - function executeBackUnbacked( - DataTypes.ReserveData storage reserve, - address asset, - uint256 amount, - uint256 fee, - uint256 protocolFeeBps - ) external { - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - - reserve.updateState(reserveCache); - - uint256 backingAmount = (amount < reserve.unbacked) ? amount : reserve.unbacked; - - uint256 feeToProtocol = fee.percentMul(protocolFeeBps); - uint256 feeToLP = fee - feeToProtocol; - uint256 added = backingAmount + fee; - - reserveCache.nextLiquidityIndex = reserve.cumulateToLiquidityIndex( - IERC20(reserveCache.aTokenAddress).totalSupply(), - feeToLP - ); - - reserve.accruedToTreasury += feeToProtocol.rayDiv(reserveCache.nextLiquidityIndex).toUint128(); - - reserve.unbacked -= backingAmount.toUint128(); - reserve.updateInterestRates(reserveCache, asset, added, 0); - - IERC20(asset).safeTransferFrom(msg.sender, reserveCache.aTokenAddress, added); - - emit BackUnbacked(asset, msg.sender, backingAmount, fee); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/CalldataLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/CalldataLogic.sol deleted file mode 100644 index 5ef53e0..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/CalldataLogic.sol +++ /dev/null @@ -1,322 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -/** - * @title CalldataLogic library - * @author Aave - * @notice Library to decode calldata, used to optimize calldata size in L2Pool for transaction cost reduction - */ -library CalldataLogic { - /** - * @notice Decodes compressed supply params to standard params - * @param reservesList The addresses of all the active reserves - * @param args The packed supply params - * @return The address of the underlying reserve - * @return The amount to supply - * @return The referralCode - */ - function decodeSupplyParams(mapping(uint256 => address) storage reservesList, bytes32 args) - internal - view - returns ( - address, - uint256, - uint16 - ) - { - uint16 assetId; - uint256 amount; - uint16 referralCode; - - assembly { - assetId := and(args, 0xFFFF) - amount := and(shr(16, args), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - referralCode := and(shr(144, args), 0xFFFF) - } - return (reservesList[assetId], amount, referralCode); - } - - /** - * @notice Decodes compressed supply params to standard params along with permit params - * @param reservesList The addresses of all the active reserves - * @param args The packed supply with permit params - * @return The address of the underlying reserve - * @return The amount to supply - * @return The referralCode - * @return The deadline of the permit - * @return The V value of the permit signature - */ - function decodeSupplyWithPermitParams( - mapping(uint256 => address) storage reservesList, - bytes32 args - ) - internal - view - returns ( - address, - uint256, - uint16, - uint256, - uint8 - ) - { - uint256 deadline; - uint8 permitV; - - assembly { - deadline := and(shr(160, args), 0xFFFFFFFF) - permitV := and(shr(192, args), 0xFF) - } - (address asset, uint256 amount, uint16 referralCode) = decodeSupplyParams(reservesList, args); - - return (asset, amount, referralCode, deadline, permitV); - } - - /** - * @notice Decodes compressed withdraw params to standard params - * @param reservesList The addresses of all the active reserves - * @param args The packed withdraw params - * @return The address of the underlying reserve - * @return The amount to withdraw - */ - function decodeWithdrawParams(mapping(uint256 => address) storage reservesList, bytes32 args) - internal - view - returns (address, uint256) - { - uint16 assetId; - uint256 amount; - assembly { - assetId := and(args, 0xFFFF) - amount := and(shr(16, args), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - } - if (amount == type(uint128).max) { - amount = type(uint256).max; - } - return (reservesList[assetId], amount); - } - - /** - * @notice Decodes compressed borrow params to standard params - * @param reservesList The addresses of all the active reserves - * @param args The packed borrow params - * @return The address of the underlying reserve - * @return The amount to borrow - * @return The interestRateMode, 1 for stable or 2 for variable debt - * @return The referralCode - */ - function decodeBorrowParams(mapping(uint256 => address) storage reservesList, bytes32 args) - internal - view - returns ( - address, - uint256, - uint256, - uint16 - ) - { - uint16 assetId; - uint256 amount; - uint256 interestRateMode; - uint16 referralCode; - - assembly { - assetId := and(args, 0xFFFF) - amount := and(shr(16, args), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - interestRateMode := and(shr(144, args), 0xFF) - referralCode := and(shr(152, args), 0xFFFF) - } - - return (reservesList[assetId], amount, interestRateMode, referralCode); - } - - /** - * @notice Decodes compressed repay params to standard params - * @param reservesList The addresses of all the active reserves - * @param args The packed repay params - * @return The address of the underlying reserve - * @return The amount to repay - * @return The interestRateMode, 1 for stable or 2 for variable debt - */ - function decodeRepayParams(mapping(uint256 => address) storage reservesList, bytes32 args) - internal - view - returns ( - address, - uint256, - uint256 - ) - { - uint16 assetId; - uint256 amount; - uint256 interestRateMode; - - assembly { - assetId := and(args, 0xFFFF) - amount := and(shr(16, args), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - interestRateMode := and(shr(144, args), 0xFF) - } - - if (amount == type(uint128).max) { - amount = type(uint256).max; - } - - return (reservesList[assetId], amount, interestRateMode); - } - - /** - * @notice Decodes compressed repay params to standard params along with permit params - * @param reservesList The addresses of all the active reserves - * @param args The packed repay with permit params - * @return The address of the underlying reserve - * @return The amount to repay - * @return The interestRateMode, 1 for stable or 2 for variable debt - * @return The deadline of the permit - * @return The V value of the permit signature - */ - function decodeRepayWithPermitParams( - mapping(uint256 => address) storage reservesList, - bytes32 args - ) - internal - view - returns ( - address, - uint256, - uint256, - uint256, - uint8 - ) - { - uint256 deadline; - uint8 permitV; - - (address asset, uint256 amount, uint256 interestRateMode) = decodeRepayParams( - reservesList, - args - ); - - assembly { - deadline := and(shr(152, args), 0xFFFFFFFF) - permitV := and(shr(184, args), 0xFF) - } - - return (asset, amount, interestRateMode, deadline, permitV); - } - - /** - * @notice Decodes compressed swap borrow rate mode params to standard params - * @param reservesList The addresses of all the active reserves - * @param args The packed swap borrow rate mode params - * @return The address of the underlying reserve - * @return The interest rate mode, 1 for stable 2 for variable debt - */ - function decodeSwapBorrowRateModeParams( - mapping(uint256 => address) storage reservesList, - bytes32 args - ) internal view returns (address, uint256) { - uint16 assetId; - uint256 interestRateMode; - - assembly { - assetId := and(args, 0xFFFF) - interestRateMode := and(shr(16, args), 0xFF) - } - - return (reservesList[assetId], interestRateMode); - } - - /** - * @notice Decodes compressed rebalance stable borrow rate params to standard params - * @param reservesList The addresses of all the active reserves - * @param args The packed rabalance stable borrow rate params - * @return The address of the underlying reserve - * @return The address of the user to rebalance - */ - function decodeRebalanceStableBorrowRateParams( - mapping(uint256 => address) storage reservesList, - bytes32 args - ) internal view returns (address, address) { - uint16 assetId; - address user; - assembly { - assetId := and(args, 0xFFFF) - user := and(shr(16, args), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - } - return (reservesList[assetId], user); - } - - /** - * @notice Decodes compressed set user use reserve as collateral params to standard params - * @param reservesList The addresses of all the active reserves - * @param args The packed set user use reserve as collateral params - * @return The address of the underlying reserve - * @return True if to set using as collateral, false otherwise - */ - function decodeSetUserUseReserveAsCollateralParams( - mapping(uint256 => address) storage reservesList, - bytes32 args - ) internal view returns (address, bool) { - uint16 assetId; - bool useAsCollateral; - assembly { - assetId := and(args, 0xFFFF) - useAsCollateral := and(shr(16, args), 0x1) - } - return (reservesList[assetId], useAsCollateral); - } - - /** - * @notice Decodes compressed liquidation call params to standard params - * @param reservesList The addresses of all the active reserves - * @param args1 The first half of packed liquidation call params - * @param args2 The second half of the packed liquidation call params - * @return The address of the underlying collateral asset - * @return The address of the underlying debt asset - * @return The address of the user to liquidate - * @return The amount of debt to cover - * @return True if receiving aTokens, false otherwise - */ - function decodeLiquidationCallParams( - mapping(uint256 => address) storage reservesList, - bytes32 args1, - bytes32 args2 - ) - internal - view - returns ( - address, - address, - address, - uint256, - bool - ) - { - uint16 collateralAssetId; - uint16 debtAssetId; - address user; - uint256 debtToCover; - bool receiveAToken; - - assembly { - collateralAssetId := and(args1, 0xFFFF) - debtAssetId := and(shr(16, args1), 0xFFFF) - user := and(shr(32, args1), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - - debtToCover := and(args2, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) - receiveAToken := and(shr(128, args2), 0x1) - } - - if (debtToCover == type(uint128).max) { - debtToCover = type(uint256).max; - } - - return ( - reservesList[collateralAssetId], - reservesList[debtAssetId], - user, - debtToCover, - receiveAToken - ); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol deleted file mode 100644 index c29afa0..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ConfiguratorLogic.sol +++ /dev/null @@ -1,268 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IPool} from '../../../interfaces/IPool.sol'; -import {IInitializableAToken} from '../../../interfaces/IInitializableAToken.sol'; -import {IInitializableDebtToken} from '../../../interfaces/IInitializableDebtToken.sol'; -import {IAaveIncentivesController} from '../../../interfaces/IAaveIncentivesController.sol'; -import {InitializableImmutableAdminUpgradeabilityProxy} from '../aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ConfiguratorInputTypes} from '../types/ConfiguratorInputTypes.sol'; - -/** - * @title ConfiguratorLogic library - * @author Aave - * @notice Implements the functions to initialize reserves and update aTokens and debtTokens - */ -library ConfiguratorLogic { - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - - // See `IPoolConfigurator` for descriptions - event ReserveInitialized( - address indexed asset, - address indexed aToken, - address stableDebtToken, - address variableDebtToken, - address interestRateStrategyAddress - ); - event ATokenUpgraded( - address indexed asset, - address indexed proxy, - address indexed implementation - ); - event StableDebtTokenUpgraded( - address indexed asset, - address indexed proxy, - address indexed implementation - ); - event VariableDebtTokenUpgraded( - address indexed asset, - address indexed proxy, - address indexed implementation - ); - - /** - * @notice Initialize a reserve by creating and initializing aToken, stable debt token and variable debt token - * @dev Emits the `ReserveInitialized` event - * @param pool The Pool in which the reserve will be initialized - * @param input The needed parameters for the initialization - */ - function executeInitReserve(IPool pool, ConfiguratorInputTypes.InitReserveInput calldata input) - public - { - address aTokenProxyAddress = _initTokenWithProxy( - input.aTokenImpl, - abi.encodeWithSelector( - IInitializableAToken.initialize.selector, - pool, - input.treasury, - input.underlyingAsset, - input.incentivesController, - input.underlyingAssetDecimals, - input.aTokenName, - input.aTokenSymbol, - input.params - ) - ); - - address stableDebtTokenProxyAddress = _initTokenWithProxy( - input.stableDebtTokenImpl, - abi.encodeWithSelector( - IInitializableDebtToken.initialize.selector, - pool, - input.underlyingAsset, - input.incentivesController, - input.underlyingAssetDecimals, - input.stableDebtTokenName, - input.stableDebtTokenSymbol, - input.params - ) - ); - - address variableDebtTokenProxyAddress = _initTokenWithProxy( - input.variableDebtTokenImpl, - abi.encodeWithSelector( - IInitializableDebtToken.initialize.selector, - pool, - input.underlyingAsset, - input.incentivesController, - input.underlyingAssetDecimals, - input.variableDebtTokenName, - input.variableDebtTokenSymbol, - input.params - ) - ); - - pool.initReserve( - input.underlyingAsset, - aTokenProxyAddress, - stableDebtTokenProxyAddress, - variableDebtTokenProxyAddress, - input.interestRateStrategyAddress - ); - - DataTypes.ReserveConfigurationMap memory currentConfig = DataTypes.ReserveConfigurationMap(0); - - currentConfig.setDecimals(input.underlyingAssetDecimals); - - currentConfig.setActive(true); - currentConfig.setPaused(false); - currentConfig.setFrozen(false); - - pool.setConfiguration(input.underlyingAsset, currentConfig); - - emit ReserveInitialized( - input.underlyingAsset, - aTokenProxyAddress, - stableDebtTokenProxyAddress, - variableDebtTokenProxyAddress, - input.interestRateStrategyAddress - ); - } - - /** - * @notice Updates the aToken implementation and initializes it - * @dev Emits the `ATokenUpgraded` event - * @param cachedPool The Pool containing the reserve with the aToken - * @param input The parameters needed for the initialize call - */ - function executeUpdateAToken( - IPool cachedPool, - ConfiguratorInputTypes.UpdateATokenInput calldata input - ) public { - DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset); - - (, , , uint256 decimals, , ) = cachedPool.getConfiguration(input.asset).getParams(); - - bytes memory encodedCall = abi.encodeWithSelector( - IInitializableAToken.initialize.selector, - cachedPool, - input.treasury, - input.asset, - input.incentivesController, - decimals, - input.name, - input.symbol, - input.params - ); - - _upgradeTokenImplementation(reserveData.aTokenAddress, input.implementation, encodedCall); - - emit ATokenUpgraded(input.asset, reserveData.aTokenAddress, input.implementation); - } - - /** - * @notice Updates the stable debt token implementation and initializes it - * @dev Emits the `StableDebtTokenUpgraded` event - * @param cachedPool The Pool containing the reserve with the stable debt token - * @param input The parameters needed for the initialize call - */ - function executeUpdateStableDebtToken( - IPool cachedPool, - ConfiguratorInputTypes.UpdateDebtTokenInput calldata input - ) public { - DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset); - - (, , , uint256 decimals, , ) = cachedPool.getConfiguration(input.asset).getParams(); - - bytes memory encodedCall = abi.encodeWithSelector( - IInitializableDebtToken.initialize.selector, - cachedPool, - input.asset, - input.incentivesController, - decimals, - input.name, - input.symbol, - input.params - ); - - _upgradeTokenImplementation( - reserveData.stableDebtTokenAddress, - input.implementation, - encodedCall - ); - - emit StableDebtTokenUpgraded( - input.asset, - reserveData.stableDebtTokenAddress, - input.implementation - ); - } - - /** - * @notice Updates the variable debt token implementation and initializes it - * @dev Emits the `VariableDebtTokenUpgraded` event - * @param cachedPool The Pool containing the reserve with the variable debt token - * @param input The parameters needed for the initialize call - */ - function executeUpdateVariableDebtToken( - IPool cachedPool, - ConfiguratorInputTypes.UpdateDebtTokenInput calldata input - ) public { - DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset); - - (, , , uint256 decimals, , ) = cachedPool.getConfiguration(input.asset).getParams(); - - bytes memory encodedCall = abi.encodeWithSelector( - IInitializableDebtToken.initialize.selector, - cachedPool, - input.asset, - input.incentivesController, - decimals, - input.name, - input.symbol, - input.params - ); - - _upgradeTokenImplementation( - reserveData.variableDebtTokenAddress, - input.implementation, - encodedCall - ); - - emit VariableDebtTokenUpgraded( - input.asset, - reserveData.variableDebtTokenAddress, - input.implementation - ); - } - - /** - * @notice Creates a new proxy and initializes the implementation - * @param implementation The address of the implementation - * @param initParams The parameters that is passed to the implementation to initialize - * @return The address of initialized proxy - */ - function _initTokenWithProxy(address implementation, bytes memory initParams) - internal - returns (address) - { - InitializableImmutableAdminUpgradeabilityProxy proxy = new InitializableImmutableAdminUpgradeabilityProxy( - address(this) - ); - - proxy.initialize(implementation, initParams); - - return address(proxy); - } - - /** - * @notice Upgrades the implementation and makes call to the proxy - * @dev The call is used to initialize the new implementation. - * @param proxyAddress The address of the proxy - * @param implementation The address of the new implementation - * @param initParams The parameters to the call after the upgrade - */ - function _upgradeTokenImplementation( - address proxyAddress, - address implementation, - bytes memory initParams - ) internal { - InitializableImmutableAdminUpgradeabilityProxy proxy = InitializableImmutableAdminUpgradeabilityProxy( - payable(proxyAddress) - ); - - proxy.upgradeToAndCall(implementation, initParams); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/EModeLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/EModeLogic.sol deleted file mode 100644 index e329828..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/EModeLogic.sol +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ValidationLogic} from './ValidationLogic.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; - -/** - * @title EModeLogic library - * @author Aave - * @notice Implements the base logic for all the actions related to the eMode - */ -library EModeLogic { - using ReserveLogic for DataTypes.ReserveCache; - using ReserveLogic for DataTypes.ReserveData; - using GPv2SafeERC20 for IERC20; - using UserConfiguration for DataTypes.UserConfigurationMap; - using WadRayMath for uint256; - using PercentageMath for uint256; - - // See `IPool` for descriptions - event UserEModeSet(address indexed user, uint8 categoryId); - - /** - * @notice Updates the user efficiency mode category - * @dev Will revert if user is borrowing non-compatible asset or change will drop HF < HEALTH_FACTOR_LIQUIDATION_THRESHOLD - * @dev Emits the `UserEModeSet` event - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param usersEModeCategory The state of all users efficiency mode category - * @param userConfig The user configuration mapping that tracks the supplied/borrowed assets - * @param params The additional parameters needed to execute the setUserEMode function - */ - function executeSetUserEMode( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - mapping(address => uint8) storage usersEModeCategory, - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.ExecuteSetUserEModeParams memory params - ) external { - ValidationLogic.validateSetUserEMode( - reservesData, - reservesList, - eModeCategories, - userConfig, - params.reservesCount, - params.categoryId - ); - - uint8 prevCategoryId = usersEModeCategory[msg.sender]; - usersEModeCategory[msg.sender] = params.categoryId; - - if (prevCategoryId != 0) { - ValidationLogic.validateHealthFactor( - reservesData, - reservesList, - eModeCategories, - userConfig, - msg.sender, - params.categoryId, - params.reservesCount, - params.oracle - ); - } - emit UserEModeSet(msg.sender, params.categoryId); - } - - /** - * @notice Gets the eMode configuration and calculates the eMode asset price if a custom oracle is configured - * @dev The eMode asset price returned is 0 if no oracle is specified - * @param category The user eMode category - * @param oracle The price oracle - * @return The eMode ltv - * @return The eMode liquidation threshold - * @return The eMode asset price - **/ - function getEModeConfiguration( - DataTypes.EModeCategory storage category, - IPriceOracleGetter oracle - ) - internal - view - returns ( - uint256, - uint256, - uint256 - ) - { - uint256 eModeAssetPrice = 0; - address eModePriceSource = category.priceSource; - - if (eModePriceSource != address(0)) { - eModeAssetPrice = oracle.getAssetPrice(eModePriceSource); - } - - return (category.ltv, category.liquidationThreshold, eModeAssetPrice); - } - - /** - * @notice Checks if eMode is active for a user and if yes, if the asset belongs to the eMode category chosen - * @param eModeUserCategory The user eMode category - * @param eModeAssetCategory The asset eMode category - * @return True if eMode is active and the asset belongs to the eMode category chosen by the user, false otherwise - **/ - function isInEModeCategory(uint256 eModeUserCategory, uint256 eModeAssetCategory) - internal - pure - returns (bool) - { - return (eModeUserCategory != 0 && eModeAssetCategory == eModeUserCategory); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/FlashLoanLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/FlashLoanLogic.sol deleted file mode 100644 index fa800e3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/FlashLoanLogic.sol +++ /dev/null @@ -1,262 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {IFlashLoanReceiver} from '../../../flashloan/interfaces/IFlashLoanReceiver.sol'; -import {IFlashLoanSimpleReceiver} from '../../../flashloan/interfaces/IFlashLoanSimpleReceiver.sol'; -import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ValidationLogic} from './ValidationLogic.sol'; -import {BorrowLogic} from './BorrowLogic.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; - -/** - * @title FlashLoanLogic library - * @author Aave - * @notice Implements the logic for the flash loans - */ -library FlashLoanLogic { - using ReserveLogic for DataTypes.ReserveCache; - using ReserveLogic for DataTypes.ReserveData; - using GPv2SafeERC20 for IERC20; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using WadRayMath for uint256; - using PercentageMath for uint256; - using SafeCast for uint256; - - // See `IPool` for descriptions - event FlashLoan( - address indexed target, - address initiator, - address indexed asset, - uint256 amount, - DataTypes.InterestRateMode interestRateMode, - uint256 premium, - uint16 indexed referralCode - ); - - // Helper struct for internal variables used in the `executeFlashLoan` function - struct FlashLoanLocalVars { - IFlashLoanReceiver receiver; - uint256 i; - address currentAsset; - uint256 currentAmount; - uint256[] totalPremiums; - uint256 flashloanPremiumTotal; - uint256 flashloanPremiumToProtocol; - } - - /** - * @notice Implements the flashloan feature that allow users to access liquidity of the pool for one transaction - * as long as the amount taken plus fee is returned or debt is opened. - * @dev For authorized flashborrowers the fee is waived - * @dev At the end of the transaction the pool will pull amount borrowed + fee from the receiver, - * if the receiver have not approved the pool the transaction will revert. - * @dev Emits the `FlashLoan()` event - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param userConfig The user configuration mapping that tracks the supplied/borrowed assets - * @param params The additional parameters needed to execute the flashloan function - */ - function executeFlashLoan( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.FlashloanParams memory params - ) external { - // The usual action flow (cache -> updateState -> validation -> changeState -> updateRates) - // is altered to (validation -> user payload -> cache -> updateState -> changeState -> updateRates) for flashloans. - // This is done to protect against reentrance and rate manipulation within the user specified payload. - - ValidationLogic.validateFlashloan(reservesData, params.assets, params.amounts); - - FlashLoanLocalVars memory vars; - - vars.totalPremiums = new uint256[](params.assets.length); - - vars.receiver = IFlashLoanReceiver(params.receiverAddress); - (vars.flashloanPremiumTotal, vars.flashloanPremiumToProtocol) = params.isAuthorizedFlashBorrower - ? (0, 0) - : (params.flashLoanPremiumTotal, params.flashLoanPremiumToProtocol); - - for (vars.i = 0; vars.i < params.assets.length; vars.i++) { - vars.currentAmount = params.amounts[vars.i]; - vars.totalPremiums[vars.i] = vars.currentAmount.percentMul(vars.flashloanPremiumTotal); - IAToken(reservesData[params.assets[vars.i]].aTokenAddress).transferUnderlyingTo( - params.receiverAddress, - vars.currentAmount - ); - } - - require( - vars.receiver.executeOperation( - params.assets, - params.amounts, - vars.totalPremiums, - msg.sender, - params.params - ), - Errors.INVALID_FLASHLOAN_EXECUTOR_RETURN - ); - - for (vars.i = 0; vars.i < params.assets.length; vars.i++) { - vars.currentAsset = params.assets[vars.i]; - vars.currentAmount = params.amounts[vars.i]; - - if ( - DataTypes.InterestRateMode(params.interestRateModes[vars.i]) == - DataTypes.InterestRateMode.NONE - ) { - _handleFlashLoanRepayment( - reservesData[vars.currentAsset], - DataTypes.FlashLoanRepaymentParams({ - asset: vars.currentAsset, - receiverAddress: params.receiverAddress, - amount: vars.currentAmount, - totalPremium: vars.totalPremiums[vars.i], - flashLoanPremiumToProtocol: vars.flashloanPremiumToProtocol, - referralCode: params.referralCode - }) - ); - } else { - // If the user chose to not return the funds, the system checks if there is enough collateral and - // eventually opens a debt position - BorrowLogic.executeBorrow( - reservesData, - reservesList, - eModeCategories, - userConfig, - DataTypes.ExecuteBorrowParams({ - asset: vars.currentAsset, - user: msg.sender, - onBehalfOf: params.onBehalfOf, - amount: vars.currentAmount, - interestRateMode: DataTypes.InterestRateMode(params.interestRateModes[vars.i]), - referralCode: params.referralCode, - releaseUnderlying: false, - maxStableRateBorrowSizePercent: params.maxStableRateBorrowSizePercent, - reservesCount: params.reservesCount, - oracle: IPoolAddressesProvider(params.addressesProvider).getPriceOracle(), - userEModeCategory: params.userEModeCategory, - priceOracleSentinel: IPoolAddressesProvider(params.addressesProvider) - .getPriceOracleSentinel() - }) - ); - // no premium is paid when taking on the flashloan as debt - emit FlashLoan( - params.receiverAddress, - msg.sender, - vars.currentAsset, - vars.currentAmount, - DataTypes.InterestRateMode(params.interestRateModes[vars.i]), - 0, - params.referralCode - ); - } - } - } - - /** - * @notice Implements the simple flashloan feature that allow users to access liquidity of ONE reserve for one - * transaction as long as the amount taken plus fee is returned. - * @dev Does not waive fee for approved flashborrowers nor allow taking on debt instead of repaying to save gas - * @dev At the end of the transaction the pool will pull amount borrowed + fee from the receiver, - * if the receiver have not approved the pool the transaction will revert. - * @dev Emits the `FlashLoan()` event - * @param reserve The state of the flashloaned reserve - * @param params The additional parameters needed to execute the simple flashloan function - */ - function executeFlashLoanSimple( - DataTypes.ReserveData storage reserve, - DataTypes.FlashloanSimpleParams memory params - ) external { - // The usual action flow (cache -> updateState -> validation -> changeState -> updateRates) - // is altered to (validation -> user payload -> cache -> updateState -> changeState -> updateRates) for flashloans. - // This is done to protect against reentrance and rate manipulation within the user specified payload. - - ValidationLogic.validateFlashloanSimple(reserve); - - IFlashLoanSimpleReceiver receiver = IFlashLoanSimpleReceiver(params.receiverAddress); - uint256 totalPremium = params.amount.percentMul(params.flashLoanPremiumTotal); - IAToken(reserve.aTokenAddress).transferUnderlyingTo(params.receiverAddress, params.amount); - - require( - receiver.executeOperation( - params.asset, - params.amount, - totalPremium, - msg.sender, - params.params - ), - Errors.INVALID_FLASHLOAN_EXECUTOR_RETURN - ); - - _handleFlashLoanRepayment( - reserve, - DataTypes.FlashLoanRepaymentParams({ - asset: params.asset, - receiverAddress: params.receiverAddress, - amount: params.amount, - totalPremium: totalPremium, - flashLoanPremiumToProtocol: params.flashLoanPremiumToProtocol, - referralCode: params.referralCode - }) - ); - } - - /** - * @notice Handles repayment of flashloaned assets + premium - * @dev Will pull the amount + premium from the receiver, so must have approved pool - * @param reserve The state of the flashloaned reserve - * @param params The additional parameters needed to execute the repayment function - */ - function _handleFlashLoanRepayment( - DataTypes.ReserveData storage reserve, - DataTypes.FlashLoanRepaymentParams memory params - ) internal { - uint256 premiumToProtocol = params.totalPremium.percentMul(params.flashLoanPremiumToProtocol); - uint256 premiumToLP = params.totalPremium - premiumToProtocol; - uint256 amountPlusPremium = params.amount + params.totalPremium; - - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - reserve.updateState(reserveCache); - reserveCache.nextLiquidityIndex = reserve.cumulateToLiquidityIndex( - IERC20(reserveCache.aTokenAddress).totalSupply(), - premiumToLP - ); - - reserve.accruedToTreasury += premiumToProtocol - .rayDiv(reserveCache.nextLiquidityIndex) - .toUint128(); - - reserve.updateInterestRates(reserveCache, params.asset, amountPlusPremium, 0); - - IERC20(params.asset).safeTransferFrom( - params.receiverAddress, - reserveCache.aTokenAddress, - amountPlusPremium - ); - - IAToken(reserveCache.aTokenAddress).handleRepayment(params.receiverAddress, amountPlusPremium); - - emit FlashLoan( - params.receiverAddress, - msg.sender, - params.asset, - params.amount, - DataTypes.InterestRateMode(0), - params.totalPremium, - params.referralCode - ); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/GenericLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/GenericLogic.sol deleted file mode 100644 index a03fc3c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/GenericLogic.sol +++ /dev/null @@ -1,280 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IScaledBalanceToken} from '../../../interfaces/IScaledBalanceToken.sol'; -import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; -import {EModeLogic} from './EModeLogic.sol'; - -/** - * @title GenericLogic library - * @author Aave - * @notice Implements protocol-level logic to calculate and validate the state of a user - */ -library GenericLogic { - using ReserveLogic for DataTypes.ReserveData; - using WadRayMath for uint256; - using PercentageMath for uint256; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using UserConfiguration for DataTypes.UserConfigurationMap; - - struct CalculateUserAccountDataVars { - uint256 assetPrice; - uint256 assetUnit; - uint256 userBalanceInBaseCurrency; - uint256 decimals; - uint256 ltv; - uint256 liquidationThreshold; - uint256 i; - uint256 healthFactor; - uint256 totalCollateralInBaseCurrency; - uint256 totalDebtInBaseCurrency; - uint256 avgLtv; - uint256 avgLiquidationThreshold; - uint256 eModeAssetPrice; - uint256 eModeLtv; - uint256 eModeLiqThreshold; - uint256 eModeAssetCategory; - address currentReserveAddress; - bool hasZeroLtvCollateral; - bool isInEModeCategory; - } - - /** - * @notice Calculates the user data across the reserves. - * @dev It includes the total liquidity/collateral/borrow balances in the base currency used by the price feed, - * the average Loan To Value, the average Liquidation Ratio, and the Health factor. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param params Additional parameters needed for the calculation - * @return The total collateral of the user in the base currency used by the price feed - * @return The total debt of the user in the base currency used by the price feed - * @return The average ltv of the user - * @return The average liquidation threshold of the user - * @return The health factor of the user - * @return True if the ltv is zero, false otherwise - **/ - function calculateUserAccountData( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.CalculateUserAccountDataParams memory params - ) - internal - view - returns ( - uint256, - uint256, - uint256, - uint256, - uint256, - bool - ) - { - if (params.userConfig.isEmpty()) { - return (0, 0, 0, 0, type(uint256).max, false); - } - - CalculateUserAccountDataVars memory vars; - - if (params.userEModeCategory != 0) { - (vars.eModeLtv, vars.eModeLiqThreshold, vars.eModeAssetPrice) = EModeLogic - .getEModeConfiguration( - eModeCategories[params.userEModeCategory], - IPriceOracleGetter(params.oracle) - ); - } - - while (vars.i < params.reservesCount) { - if (!params.userConfig.isUsingAsCollateralOrBorrowing(vars.i)) { - unchecked { - ++vars.i; - } - continue; - } - - vars.currentReserveAddress = reservesList[vars.i]; - - if (vars.currentReserveAddress == address(0)) { - unchecked { - ++vars.i; - } - continue; - } - - DataTypes.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress]; - - ( - vars.ltv, - vars.liquidationThreshold, - , - vars.decimals, - , - vars.eModeAssetCategory - ) = currentReserve.configuration.getParams(); - - unchecked { - vars.assetUnit = 10**vars.decimals; - } - - vars.assetPrice = vars.eModeAssetPrice != 0 && - params.userEModeCategory == vars.eModeAssetCategory - ? vars.eModeAssetPrice - : IPriceOracleGetter(params.oracle).getAssetPrice(vars.currentReserveAddress); - - if (vars.liquidationThreshold != 0 && params.userConfig.isUsingAsCollateral(vars.i)) { - vars.userBalanceInBaseCurrency = _getUserBalanceInBaseCurrency( - params.user, - currentReserve, - vars.assetPrice, - vars.assetUnit - ); - - vars.totalCollateralInBaseCurrency += vars.userBalanceInBaseCurrency; - - vars.isInEModeCategory = EModeLogic.isInEModeCategory( - params.userEModeCategory, - vars.eModeAssetCategory - ); - - if (vars.ltv != 0) { - vars.avgLtv += - vars.userBalanceInBaseCurrency * - (vars.isInEModeCategory ? vars.eModeLtv : vars.ltv); - } else { - vars.hasZeroLtvCollateral = true; - } - - vars.avgLiquidationThreshold += - vars.userBalanceInBaseCurrency * - (vars.isInEModeCategory ? vars.eModeLiqThreshold : vars.liquidationThreshold); - } - - if (params.userConfig.isBorrowing(vars.i)) { - vars.totalDebtInBaseCurrency += _getUserDebtInBaseCurrency( - params.user, - currentReserve, - vars.assetPrice, - vars.assetUnit - ); - } - - unchecked { - ++vars.i; - } - } - - unchecked { - vars.avgLtv = vars.totalCollateralInBaseCurrency != 0 - ? vars.avgLtv / vars.totalCollateralInBaseCurrency - : 0; - vars.avgLiquidationThreshold = vars.totalCollateralInBaseCurrency != 0 - ? vars.avgLiquidationThreshold / vars.totalCollateralInBaseCurrency - : 0; - } - - vars.healthFactor = (vars.totalDebtInBaseCurrency == 0) - ? type(uint256).max - : (vars.totalCollateralInBaseCurrency.percentMul(vars.avgLiquidationThreshold)).wadDiv( - vars.totalDebtInBaseCurrency - ); - return ( - vars.totalCollateralInBaseCurrency, - vars.totalDebtInBaseCurrency, - vars.avgLtv, - vars.avgLiquidationThreshold, - vars.healthFactor, - vars.hasZeroLtvCollateral - ); - } - - /** - * @notice Calculates the maximum amount that can be borrowed depending on the available collateral, the total debt - * and the average Loan To Value - * @param totalCollateralInBaseCurrency The total collateral in the base currency used by the price feed - * @param totalDebtInBaseCurrency The total borrow balance in the base currency used by the price feed - * @param ltv The average loan to value - * @return The amount available to borrow in the base currency of the used by the price feed - **/ - function calculateAvailableBorrows( - uint256 totalCollateralInBaseCurrency, - uint256 totalDebtInBaseCurrency, - uint256 ltv - ) internal pure returns (uint256) { - uint256 availableBorrowsInBaseCurrency = totalCollateralInBaseCurrency.percentMul(ltv); - - if (availableBorrowsInBaseCurrency < totalDebtInBaseCurrency) { - return 0; - } - - availableBorrowsInBaseCurrency = availableBorrowsInBaseCurrency - totalDebtInBaseCurrency; - return availableBorrowsInBaseCurrency; - } - - /** - * @notice Calculates total debt of the user in the based currency used to normalize the values of the assets - * @dev This fetches the `balanceOf` of the stable and variable debt tokens for the user. For gas reasons, the - * variable debt balance is calculated by fetching `scaledBalancesOf` normalized debt, which is cheaper than - * fetching `balanceOf` - * @param user The address of the user - * @param reserve The data of the reserve for which the total debt of the user is being calculated - * @param assetPrice The price of the asset for which the total debt of the user is being calculated - * @param assetUnit The value representing one full unit of the asset (10^decimals) - * @return The total debt of the user normalized to the base currency - **/ - function _getUserDebtInBaseCurrency( - address user, - DataTypes.ReserveData storage reserve, - uint256 assetPrice, - uint256 assetUnit - ) private view returns (uint256) { - // fetching variable debt - uint256 userTotalDebt = IScaledBalanceToken(reserve.variableDebtTokenAddress).scaledBalanceOf( - user - ); - if (userTotalDebt != 0) { - userTotalDebt = userTotalDebt.rayMul(reserve.getNormalizedDebt()); - } - - userTotalDebt = userTotalDebt + IERC20(reserve.stableDebtTokenAddress).balanceOf(user); - - userTotalDebt = assetPrice * userTotalDebt; - - unchecked { - return userTotalDebt / assetUnit; - } - } - - /** - * @notice Calculates total aToken balance of the user in the based currency used by the price oracle - * @dev For gas reasons, the aToken balance is calculated by fetching `scaledBalancesOf` normalized debt, which - * is cheaper than fetching `balanceOf` - * @param user The address of the user - * @param reserve The data of the reserve for which the total aToken balance of the user is being calculated - * @param assetPrice The price of the asset for which the total aToken balance of the user is being calculated - * @param assetUnit The value representing one full unit of the asset (10^decimals) - * @return The total aToken balance of the user normalized to the base currency of the price oracle - **/ - function _getUserBalanceInBaseCurrency( - address user, - DataTypes.ReserveData storage reserve, - uint256 assetPrice, - uint256 assetUnit - ) private view returns (uint256) { - uint256 normalizedIncome = reserve.getNormalizedIncome(); - uint256 balance = ( - IScaledBalanceToken(reserve.aTokenAddress).scaledBalanceOf(user).rayMul(normalizedIncome) - ) * assetPrice; - - unchecked { - return balance / assetUnit; - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/IsolationModeLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/IsolationModeLogic.sol deleted file mode 100644 index e2995c1..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/IsolationModeLogic.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {DataTypes} from '../types/DataTypes.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; - -/** - * @title IsolationModeLogic library - * @author Aave - * @notice Implements the base logic for handling repayments for assets borrowed in isolation mode - */ -library IsolationModeLogic { - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using UserConfiguration for DataTypes.UserConfigurationMap; - using SafeCast for uint256; - - // See `IPool` for descriptions - event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); - - /** - * @notice updated the isolated debt whenever a position collateralized by an isolated asset is repaid or liquidated - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param userConfig The user configuration mapping - * @param reserveCache The cached data of the reserve - * @param repayAmount The amount being repaid - */ - function updateIsolatedDebtIfIsolated( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.ReserveCache memory reserveCache, - uint256 repayAmount - ) internal { - (bool isolationModeActive, address isolationModeCollateralAddress, ) = userConfig - .getIsolationModeState(reservesData, reservesList); - - if (isolationModeActive) { - uint128 isolationModeTotalDebt = reservesData[isolationModeCollateralAddress] - .isolationModeTotalDebt; - - uint128 isolatedDebtRepaid = (repayAmount / - 10 ** - (reserveCache.reserveConfiguration.getDecimals() - - ReserveConfiguration.DEBT_CEILING_DECIMALS)).toUint128(); - - // since the debt ceiling does not take into account the interest accrued, it might happen that amount - // repaid > debt in isolation mode - if (isolationModeTotalDebt <= isolatedDebtRepaid) { - reservesData[isolationModeCollateralAddress].isolationModeTotalDebt = 0; - emit IsolationModeTotalDebtUpdated(isolationModeCollateralAddress, 0); - } else { - uint256 nextIsolationModeTotalDebt = reservesData[isolationModeCollateralAddress] - .isolationModeTotalDebt = isolationModeTotalDebt - isolatedDebtRepaid; - emit IsolationModeTotalDebtUpdated( - isolationModeCollateralAddress, - nextIsolationModeTotalDebt - ); - } - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/LiquidationLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/LiquidationLogic.sol deleted file mode 100644 index 7d91d33..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/LiquidationLogic.sol +++ /dev/null @@ -1,538 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../../dependencies/openzeppelin/contracts//IERC20.sol'; -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {PercentageMath} from '../../libraries/math/PercentageMath.sol'; -import {WadRayMath} from '../../libraries/math/WadRayMath.sol'; -import {Helpers} from '../../libraries/helpers/Helpers.sol'; -import {DataTypes} from '../../libraries/types/DataTypes.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; -import {ValidationLogic} from './ValidationLogic.sol'; -import {GenericLogic} from './GenericLogic.sol'; -import {IsolationModeLogic} from './IsolationModeLogic.sol'; -import {EModeLogic} from './EModeLogic.sol'; -import {UserConfiguration} from '../../libraries/configuration/UserConfiguration.sol'; -import {ReserveConfiguration} from '../../libraries/configuration/ReserveConfiguration.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {IStableDebtToken} from '../../../interfaces/IStableDebtToken.sol'; -import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol'; -import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol'; - -/** - * @title LiquidationLogic library - * @author Aave - * @notice Implements actions involving management of collateral in the protocol, the main one being the liquidations - **/ -library LiquidationLogic { - using WadRayMath for uint256; - using PercentageMath for uint256; - using ReserveLogic for DataTypes.ReserveCache; - using ReserveLogic for DataTypes.ReserveData; - using UserConfiguration for DataTypes.UserConfigurationMap; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using GPv2SafeERC20 for IERC20; - - // See `IPool` for descriptions - event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); - event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); - event LiquidationCall( - address indexed collateralAsset, - address indexed debtAsset, - address indexed user, - uint256 debtToCover, - uint256 liquidatedCollateralAmount, - address liquidator, - bool receiveAToken - ); - - /** - * @dev Default percentage of borrower's debt to be repaid in a liquidation. - * @dev Percentage applied when the users health factor is above `CLOSE_FACTOR_HF_THRESHOLD` - * Expressed in bps, a value of 0.5e4 results in 50.00% - */ - uint256 internal constant DEFAULT_LIQUIDATION_CLOSE_FACTOR = 0.5e4; - - /** - * @dev Maximum percentage of borrower's debt to be repaid in a liquidation - * @dev Percentage applied when the users health factor is below `CLOSE_FACTOR_HF_THRESHOLD` - * Expressed in bps, a value of 1e4 results in 100.00% - */ - uint256 public constant MAX_LIQUIDATION_CLOSE_FACTOR = 1e4; - - /** - * @dev This constant represents below which health factor value it is possible to liquidate - * an amount of debt corresponding to `MAX_LIQUIDATION_CLOSE_FACTOR`. - * A value of 0.95e18 results in 0.95 - */ - uint256 public constant CLOSE_FACTOR_HF_THRESHOLD = 0.95e18; - - struct LiquidationCallLocalVars { - uint256 userCollateralBalance; - uint256 userVariableDebt; - uint256 userTotalDebt; - uint256 actualDebtToLiquidate; - uint256 actualCollateralToLiquidate; - uint256 liquidationBonus; - uint256 healthFactor; - uint256 liquidationProtocolFeeAmount; - address collateralPriceSource; - address debtPriceSource; - IAToken collateralAToken; - DataTypes.ReserveCache debtReserveCache; - } - - /** - * @notice Function to liquidate a position if its Health Factor drops below 1. The caller (liquidator) - * covers `debtToCover` amount of debt of the user getting liquidated, and receives - * a proportional amount of the `collateralAsset` plus a bonus to cover market risk - * @dev Emits the `LiquidationCall()` event - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param usersConfig The users configuration mapping that track the supplied/borrowed assets - * @param eModeCategories The configuration of all the efficiency mode categories - * @param params The additional parameters needed to execute the liquidation function - **/ - function executeLiquidationCall( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(address => DataTypes.UserConfigurationMap) storage usersConfig, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.ExecuteLiquidationCallParams memory params - ) external { - LiquidationCallLocalVars memory vars; - - DataTypes.ReserveData storage collateralReserve = reservesData[params.collateralAsset]; - DataTypes.ReserveData storage debtReserve = reservesData[params.debtAsset]; - DataTypes.UserConfigurationMap storage userConfig = usersConfig[params.user]; - vars.debtReserveCache = debtReserve.cache(); - debtReserve.updateState(vars.debtReserveCache); - - (, , , , vars.healthFactor, ) = GenericLogic.calculateUserAccountData( - reservesData, - reservesList, - eModeCategories, - DataTypes.CalculateUserAccountDataParams({ - userConfig: userConfig, - reservesCount: params.reservesCount, - user: params.user, - oracle: params.priceOracle, - userEModeCategory: params.userEModeCategory - }) - ); - - (vars.userVariableDebt, vars.userTotalDebt, vars.actualDebtToLiquidate) = _calculateDebt( - vars.debtReserveCache, - params, - vars.healthFactor - ); - - ValidationLogic.validateLiquidationCall( - userConfig, - collateralReserve, - DataTypes.ValidateLiquidationCallParams({ - debtReserveCache: vars.debtReserveCache, - totalDebt: vars.userTotalDebt, - healthFactor: vars.healthFactor, - priceOracleSentinel: params.priceOracleSentinel - }) - ); - - ( - vars.collateralAToken, - vars.collateralPriceSource, - vars.debtPriceSource, - vars.liquidationBonus - ) = _getConfigurationData(eModeCategories, collateralReserve, params); - - vars.userCollateralBalance = vars.collateralAToken.balanceOf(params.user); - - ( - vars.actualCollateralToLiquidate, - vars.actualDebtToLiquidate, - vars.liquidationProtocolFeeAmount - ) = _calculateAvailableCollateralToLiquidate( - collateralReserve, - vars.debtReserveCache, - vars.collateralPriceSource, - vars.debtPriceSource, - vars.actualDebtToLiquidate, - vars.userCollateralBalance, - vars.liquidationBonus, - IPriceOracleGetter(params.priceOracle) - ); - - if (vars.userTotalDebt == vars.actualDebtToLiquidate) { - userConfig.setBorrowing(debtReserve.id, false); - } - - _burnDebtTokens(params, vars); - - debtReserve.updateInterestRates( - vars.debtReserveCache, - params.debtAsset, - vars.actualDebtToLiquidate, - 0 - ); - - IsolationModeLogic.updateIsolatedDebtIfIsolated( - reservesData, - reservesList, - userConfig, - vars.debtReserveCache, - vars.actualDebtToLiquidate - ); - - if (params.receiveAToken) { - _liquidateATokens(reservesData, reservesList, usersConfig, collateralReserve, params, vars); - } else { - _burnCollateralATokens(collateralReserve, params, vars); - } - - // Transfer fee to treasury if it is non-zero - if (vars.liquidationProtocolFeeAmount != 0) { - vars.collateralAToken.transferOnLiquidation( - params.user, - vars.collateralAToken.RESERVE_TREASURY_ADDRESS(), - vars.liquidationProtocolFeeAmount - ); - } - - // If the collateral being liquidated is equal to the user balance, - // we set the currency as not being used as collateral anymore - if (vars.actualCollateralToLiquidate == vars.userCollateralBalance) { - userConfig.setUsingAsCollateral(collateralReserve.id, false); - emit ReserveUsedAsCollateralDisabled(params.collateralAsset, params.user); - } - - // Transfers the debt asset being repaid to the aToken, where the liquidity is kept - IERC20(params.debtAsset).safeTransferFrom( - msg.sender, - vars.debtReserveCache.aTokenAddress, - vars.actualDebtToLiquidate - ); - - IAToken(vars.debtReserveCache.aTokenAddress).handleRepayment( - msg.sender, - vars.actualDebtToLiquidate - ); - - emit LiquidationCall( - params.collateralAsset, - params.debtAsset, - params.user, - vars.actualDebtToLiquidate, - vars.actualCollateralToLiquidate, - msg.sender, - params.receiveAToken - ); - } - - /** - * @notice Burns the collateral aTokens and transfers the underlying to the liquidator. - * @dev The function also updates the state and the interest rate of the collateral reserve. - * @param collateralReserve The data of the collateral reserve - * @param params The additional parameters needed to execute the liquidation function - * @param vars The executeLiquidationCall() function local vars - */ - function _burnCollateralATokens( - DataTypes.ReserveData storage collateralReserve, - DataTypes.ExecuteLiquidationCallParams memory params, - LiquidationCallLocalVars memory vars - ) internal { - DataTypes.ReserveCache memory collateralReserveCache = collateralReserve.cache(); - collateralReserve.updateState(collateralReserveCache); - collateralReserve.updateInterestRates( - collateralReserveCache, - params.collateralAsset, - 0, - vars.actualCollateralToLiquidate - ); - - // Burn the equivalent amount of aToken, sending the underlying to the liquidator - vars.collateralAToken.burn( - params.user, - msg.sender, - vars.actualCollateralToLiquidate, - collateralReserveCache.nextLiquidityIndex - ); - } - - /** - * @notice Liquidates the user aTokens by transferring them to the liquidator. - * @dev The function also checks the state of the liquidator and activates the aToken as collateral - * as in standard transfers if the isolation mode constraints are respected. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param usersConfig The users configuration mapping that track the supplied/borrowed assets - * @param collateralReserve The data of the collateral reserve - * @param params The additional parameters needed to execute the liquidation function - * @param vars The executeLiquidationCall() function local vars - */ - function _liquidateATokens( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(address => DataTypes.UserConfigurationMap) storage usersConfig, - DataTypes.ReserveData storage collateralReserve, - DataTypes.ExecuteLiquidationCallParams memory params, - LiquidationCallLocalVars memory vars - ) internal { - uint256 liquidatorPreviousATokenBalance = IERC20(vars.collateralAToken).balanceOf(msg.sender); - vars.collateralAToken.transferOnLiquidation( - params.user, - msg.sender, - vars.actualCollateralToLiquidate - ); - - if (liquidatorPreviousATokenBalance == 0) { - DataTypes.UserConfigurationMap storage liquidatorConfig = usersConfig[msg.sender]; - if ( - ValidationLogic.validateUseAsCollateral( - reservesData, - reservesList, - liquidatorConfig, - collateralReserve.configuration - ) - ) { - liquidatorConfig.setUsingAsCollateral(collateralReserve.id, true); - emit ReserveUsedAsCollateralEnabled(params.collateralAsset, msg.sender); - } - } - } - - /** - * @notice Burns the debt tokens of the user up to the amount being repaid by the liquidator. - * @dev The function alters the `debtReserveCache` state in `vars` to update the debt related data. - * @param params The additional parameters needed to execute the liquidation function - * @param vars the executeLiquidationCall() function local vars - */ - function _burnDebtTokens( - DataTypes.ExecuteLiquidationCallParams memory params, - LiquidationCallLocalVars memory vars - ) internal { - if (vars.userVariableDebt >= vars.actualDebtToLiquidate) { - vars.debtReserveCache.nextScaledVariableDebt = IVariableDebtToken( - vars.debtReserveCache.variableDebtTokenAddress - ).burn( - params.user, - vars.actualDebtToLiquidate, - vars.debtReserveCache.nextVariableBorrowIndex - ); - } else { - // If the user doesn't have variable debt, no need to try to burn variable debt tokens - if (vars.userVariableDebt != 0) { - vars.debtReserveCache.nextScaledVariableDebt = IVariableDebtToken( - vars.debtReserveCache.variableDebtTokenAddress - ).burn(params.user, vars.userVariableDebt, vars.debtReserveCache.nextVariableBorrowIndex); - } - ( - vars.debtReserveCache.nextTotalStableDebt, - vars.debtReserveCache.nextAvgStableBorrowRate - ) = IStableDebtToken(vars.debtReserveCache.stableDebtTokenAddress).burn( - params.user, - vars.actualDebtToLiquidate - vars.userVariableDebt - ); - } - } - - /** - * @notice Calculates the total debt of the user and the actual amount to liquidate depending on the health factor - * and corresponding close factor. - * @dev If the Health Factor is below CLOSE_FACTOR_HF_THRESHOLD, the close factor is increased to MAX_LIQUIDATION_CLOSE_FACTOR - * @param debtReserveCache The reserve cache data object of the debt reserve - * @param params The additional parameters needed to execute the liquidation function - * @param healthFactor The health factor of the position - * @return The variable debt of the user - * @return The total debt of the user - * @return The actual debt to liquidate as a function of the closeFactor - */ - function _calculateDebt( - DataTypes.ReserveCache memory debtReserveCache, - DataTypes.ExecuteLiquidationCallParams memory params, - uint256 healthFactor - ) - internal - view - returns ( - uint256, - uint256, - uint256 - ) - { - (uint256 userStableDebt, uint256 userVariableDebt) = Helpers.getUserCurrentDebt( - params.user, - debtReserveCache - ); - - uint256 userTotalDebt = userStableDebt + userVariableDebt; - - uint256 closeFactor = healthFactor > CLOSE_FACTOR_HF_THRESHOLD - ? DEFAULT_LIQUIDATION_CLOSE_FACTOR - : MAX_LIQUIDATION_CLOSE_FACTOR; - - uint256 maxLiquidatableDebt = userTotalDebt.percentMul(closeFactor); - - uint256 actualDebtToLiquidate = params.debtToCover > maxLiquidatableDebt - ? maxLiquidatableDebt - : params.debtToCover; - - return (userVariableDebt, userTotalDebt, actualDebtToLiquidate); - } - - /** - * @notice Returns the configuration data for the debt and the collateral reserves. - * @param eModeCategories The configuration of all the efficiency mode categories - * @param collateralReserve The data of the collateral reserve - * @param params The additional parameters needed to execute the liquidation function - * @return The collateral aToken - * @return The address to use as price source for the collateral - * @return The address to use as price source for the debt - * @return The liquidation bonus to apply to the collateral - */ - function _getConfigurationData( - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.ReserveData storage collateralReserve, - DataTypes.ExecuteLiquidationCallParams memory params - ) - internal - view - returns ( - IAToken, - address, - address, - uint256 - ) - { - IAToken collateralAToken = IAToken(collateralReserve.aTokenAddress); - uint256 liquidationBonus = collateralReserve.configuration.getLiquidationBonus(); - - address collateralPriceSource = params.collateralAsset; - address debtPriceSource = params.debtAsset; - - if (params.userEModeCategory != 0) { - address eModePriceSource = eModeCategories[params.userEModeCategory].priceSource; - - if ( - EModeLogic.isInEModeCategory( - params.userEModeCategory, - collateralReserve.configuration.getEModeCategory() - ) - ) { - liquidationBonus = eModeCategories[params.userEModeCategory].liquidationBonus; - - if (eModePriceSource != address(0)) { - collateralPriceSource = eModePriceSource; - } - } - - // when in eMode, debt will always be in the same eMode category, can skip matching category check - if (eModePriceSource != address(0)) { - debtPriceSource = eModePriceSource; - } - } - - return (collateralAToken, collateralPriceSource, debtPriceSource, liquidationBonus); - } - - struct AvailableCollateralToLiquidateLocalVars { - uint256 collateralPrice; - uint256 debtAssetPrice; - uint256 maxCollateralToLiquidate; - uint256 baseCollateral; - uint256 bonusCollateral; - uint256 debtAssetDecimals; - uint256 collateralDecimals; - uint256 collateralAssetUnit; - uint256 debtAssetUnit; - uint256 collateralAmount; - uint256 debtAmountNeeded; - uint256 liquidationProtocolFeePercentage; - uint256 liquidationProtocolFee; - } - - /** - * @notice Calculates how much of a specific collateral can be liquidated, given - * a certain amount of debt asset. - * @dev This function needs to be called after all the checks to validate the liquidation have been performed, - * otherwise it might fail. - * @param collateralReserve The data of the collateral reserve - * @param debtReserveCache The cached data of the debt reserve - * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation - * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation - * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover - * @param userCollateralBalance The collateral balance for the specific `collateralAsset` of the user being liquidated - * @param liquidationBonus The collateral bonus percentage to receive as result of the liquidation - * @return The maximum amount that is possible to liquidate given all the liquidation constraints (user balance, close factor) - * @return The amount to repay with the liquidation - * @return The fee taken from the liquidation bonus amount to be paid to the protocol - **/ - function _calculateAvailableCollateralToLiquidate( - DataTypes.ReserveData storage collateralReserve, - DataTypes.ReserveCache memory debtReserveCache, - address collateralAsset, - address debtAsset, - uint256 debtToCover, - uint256 userCollateralBalance, - uint256 liquidationBonus, - IPriceOracleGetter oracle - ) - internal - view - returns ( - uint256, - uint256, - uint256 - ) - { - AvailableCollateralToLiquidateLocalVars memory vars; - - vars.collateralPrice = oracle.getAssetPrice(collateralAsset); - vars.debtAssetPrice = oracle.getAssetPrice(debtAsset); - - vars.collateralDecimals = collateralReserve.configuration.getDecimals(); - vars.debtAssetDecimals = debtReserveCache.reserveConfiguration.getDecimals(); - - unchecked { - vars.collateralAssetUnit = 10**vars.collateralDecimals; - vars.debtAssetUnit = 10**vars.debtAssetDecimals; - } - - vars.liquidationProtocolFeePercentage = collateralReserve - .configuration - .getLiquidationProtocolFee(); - - // This is the base collateral to liquidate based on the given debt to cover - vars.baseCollateral = - ((vars.debtAssetPrice * debtToCover * vars.collateralAssetUnit)) / - (vars.collateralPrice * vars.debtAssetUnit); - - vars.maxCollateralToLiquidate = vars.baseCollateral.percentMul(liquidationBonus); - - if (vars.maxCollateralToLiquidate > userCollateralBalance) { - vars.collateralAmount = userCollateralBalance; - vars.debtAmountNeeded = ((vars.collateralPrice * vars.collateralAmount * vars.debtAssetUnit) / - (vars.debtAssetPrice * vars.collateralAssetUnit)).percentDiv(liquidationBonus); - } else { - vars.collateralAmount = vars.maxCollateralToLiquidate; - vars.debtAmountNeeded = debtToCover; - } - - if (vars.liquidationProtocolFeePercentage != 0) { - vars.bonusCollateral = - vars.collateralAmount - - vars.collateralAmount.percentDiv(liquidationBonus); - - vars.liquidationProtocolFee = vars.bonusCollateral.percentMul( - vars.liquidationProtocolFeePercentage - ); - - return ( - vars.collateralAmount - vars.liquidationProtocolFee, - vars.debtAmountNeeded, - vars.liquidationProtocolFee - ); - } else { - return (vars.collateralAmount, vars.debtAmountNeeded, 0); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/PoolLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/PoolLogic.sol deleted file mode 100644 index 954066f..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/PoolLogic.sol +++ /dev/null @@ -1,192 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {Address} from '../../../dependencies/openzeppelin/contracts/Address.sol'; -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; -import {ValidationLogic} from './ValidationLogic.sol'; -import {GenericLogic} from './GenericLogic.sol'; - -/** - * @title PoolLogic library - * @author Aave - * @notice Implements the logic for Pool specific functions - */ -library PoolLogic { - using GPv2SafeERC20 for IERC20; - using WadRayMath for uint256; - using ReserveLogic for DataTypes.ReserveData; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - - // See `IPool` for descriptions - event MintedToTreasury(address indexed reserve, uint256 amountMinted); - event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); - - /** - * @notice Initialize an asset reserve and add the reserve to the list of reserves - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param params Additional parameters needed for initiation - * @return true if appended, false if inserted at existing empty spot - **/ - function executeInitReserve( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - DataTypes.InitReserveParams memory params - ) external returns (bool) { - require(Address.isContract(params.asset), Errors.NOT_CONTRACT); - reservesData[params.asset].init( - params.aTokenAddress, - params.stableDebtAddress, - params.variableDebtAddress, - params.interestRateStrategyAddress - ); - - bool reserveAlreadyAdded = reservesData[params.asset].id != 0 || - reservesList[0] == params.asset; - require(!reserveAlreadyAdded, Errors.RESERVE_ALREADY_ADDED); - - for (uint16 i = 0; i < params.reservesCount; i++) { - if (reservesList[i] == address(0)) { - reservesData[params.asset].id = i; - reservesList[i] = params.asset; - return false; - } - } - - require(params.reservesCount < params.maxNumberReserves, Errors.NO_MORE_RESERVES_ALLOWED); - reservesData[params.asset].id = params.reservesCount; - reservesList[params.reservesCount] = params.asset; - return true; - } - - /** - * @notice Rescue and transfer tokens locked in this contract - * @param token The address of the token - * @param to The address of the recipient - * @param amount The amount of token to transfer - */ - function executeRescueTokens( - address token, - address to, - uint256 amount - ) external { - IERC20(token).safeTransfer(to, amount); - } - - /** - * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens - * @param reservesData The state of all the reserves - * @param assets The list of reserves for which the minting needs to be executed - **/ - function executeMintToTreasury( - mapping(address => DataTypes.ReserveData) storage reservesData, - address[] calldata assets - ) external { - for (uint256 i = 0; i < assets.length; i++) { - address assetAddress = assets[i]; - - DataTypes.ReserveData storage reserve = reservesData[assetAddress]; - - // this cover both inactive reserves and invalid reserves since the flag will be 0 for both - if (!reserve.configuration.getActive()) { - continue; - } - - uint256 accruedToTreasury = reserve.accruedToTreasury; - - if (accruedToTreasury != 0) { - reserve.accruedToTreasury = 0; - uint256 normalizedIncome = reserve.getNormalizedIncome(); - uint256 amountToMint = accruedToTreasury.rayMul(normalizedIncome); - IAToken(reserve.aTokenAddress).mintToTreasury(amountToMint, normalizedIncome); - - emit MintedToTreasury(assetAddress, amountToMint); - } - } - } - - /** - * @notice Resets the isolation mode total debt of the given asset to zero - * @dev It requires the given asset has zero debt ceiling - * @param reservesData The state of all the reserves - * @param asset The address of the underlying asset to reset the isolationModeTotalDebt - */ - function executeResetIsolationModeTotalDebt( - mapping(address => DataTypes.ReserveData) storage reservesData, - address asset - ) external { - require(reservesData[asset].configuration.getDebtCeiling() == 0, Errors.DEBT_CEILING_NOT_ZERO); - reservesData[asset].isolationModeTotalDebt = 0; - emit IsolationModeTotalDebtUpdated(asset, 0); - } - - /** - * @notice Drop a reserve - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param asset The address of the underlying asset of the reserve - **/ - function executeDropReserve( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - address asset - ) external { - DataTypes.ReserveData storage reserve = reservesData[asset]; - ValidationLogic.validateDropReserve(reservesList, reserve, asset); - reservesList[reservesData[asset].id] = address(0); - delete reservesData[asset]; - } - - /** - * @notice Returns the user account data across all the reserves - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param params Additional params needed for the calculation - * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed - * @return totalDebtBase The total debt of the user in the base currency used by the price feed - * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed - * @return currentLiquidationThreshold The liquidation threshold of the user - * @return ltv The loan to value of The user - * @return healthFactor The current health factor of the user - **/ - function executeGetUserAccountData( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.CalculateUserAccountDataParams memory params - ) - external - view - returns ( - uint256 totalCollateralBase, - uint256 totalDebtBase, - uint256 availableBorrowsBase, - uint256 currentLiquidationThreshold, - uint256 ltv, - uint256 healthFactor - ) - { - ( - totalCollateralBase, - totalDebtBase, - ltv, - currentLiquidationThreshold, - healthFactor, - - ) = GenericLogic.calculateUserAccountData(reservesData, reservesList, eModeCategories, params); - - availableBorrowsBase = GenericLogic.calculateAvailableBorrows( - totalCollateralBase, - totalDebtBase, - ltv - ); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol deleted file mode 100644 index a946c38..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ReserveLogic.sol +++ /dev/null @@ -1,362 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IStableDebtToken} from '../../../interfaces/IStableDebtToken.sol'; -import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol'; -import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {MathUtils} from '../math/MathUtils.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; - -/** - * @title ReserveLogic library - * @author Aave - * @notice Implements the logic to update the reserves state - */ -library ReserveLogic { - using WadRayMath for uint256; - using PercentageMath for uint256; - using SafeCast for uint256; - using GPv2SafeERC20 for IERC20; - using ReserveLogic for DataTypes.ReserveData; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - - // See `IPool` for descriptions - event ReserveDataUpdated( - address indexed reserve, - uint256 liquidityRate, - uint256 stableBorrowRate, - uint256 variableBorrowRate, - uint256 liquidityIndex, - uint256 variableBorrowIndex - ); - - /** - * @notice Returns the ongoing normalized income for the reserve. - * @dev A value of 1e27 means there is no income. As time passes, the income is accrued - * @dev A value of 2*1e27 means for each unit of asset one unit of income has been accrued - * @param reserve The reserve object - * @return The normalized income, expressed in ray - **/ - function getNormalizedIncome(DataTypes.ReserveData storage reserve) - internal - view - returns (uint256) - { - uint40 timestamp = reserve.lastUpdateTimestamp; - - //solium-disable-next-line - if (timestamp == block.timestamp) { - //if the index was updated in the same block, no need to perform any calculation - return reserve.liquidityIndex; - } else { - return - MathUtils.calculateLinearInterest(reserve.currentLiquidityRate, timestamp).rayMul( - reserve.liquidityIndex - ); - } - } - - /** - * @notice Returns the ongoing normalized variable debt for the reserve. - * @dev A value of 1e27 means there is no debt. As time passes, the debt is accrued - * @dev A value of 2*1e27 means that for each unit of debt, one unit worth of interest has been accumulated - * @param reserve The reserve object - * @return The normalized variable debt, expressed in ray - **/ - function getNormalizedDebt(DataTypes.ReserveData storage reserve) - internal - view - returns (uint256) - { - uint40 timestamp = reserve.lastUpdateTimestamp; - - //solium-disable-next-line - if (timestamp == block.timestamp) { - //if the index was updated in the same block, no need to perform any calculation - return reserve.variableBorrowIndex; - } else { - return - MathUtils.calculateCompoundedInterest(reserve.currentVariableBorrowRate, timestamp).rayMul( - reserve.variableBorrowIndex - ); - } - } - - /** - * @notice Updates the liquidity cumulative index and the variable borrow index. - * @param reserve The reserve object - * @param reserveCache The caching layer for the reserve data - **/ - function updateState( - DataTypes.ReserveData storage reserve, - DataTypes.ReserveCache memory reserveCache - ) internal { - _updateIndexes(reserve, reserveCache); - _accrueToTreasury(reserve, reserveCache); - } - - /** - * @notice Accumulates a predefined amount of asset to the reserve as a fixed, instantaneous income. Used for example - * to accumulate the flashloan fee to the reserve, and spread it between all the suppliers. - * @param reserve The reserve object - * @param totalLiquidity The total liquidity available in the reserve - * @param amount The amount to accumulate - * @return The next liquidity index of the reserve - **/ - function cumulateToLiquidityIndex( - DataTypes.ReserveData storage reserve, - uint256 totalLiquidity, - uint256 amount - ) internal returns (uint256) { - //next liquidity index is calculated this way: `((amount / totalLiquidity) + 1) * liquidityIndex` - //division `amount / totalLiquidity` done in ray for precision - uint256 result = (amount.wadToRay().rayDiv(totalLiquidity.wadToRay()) + WadRayMath.RAY).rayMul( - reserve.liquidityIndex - ); - reserve.liquidityIndex = result.toUint128(); - return result; - } - - /** - * @notice Initializes a reserve. - * @param reserve The reserve object - * @param aTokenAddress The address of the overlying atoken contract - * @param stableDebtTokenAddress The address of the overlying stable debt token contract - * @param variableDebtTokenAddress The address of the overlying variable debt token contract - * @param interestRateStrategyAddress The address of the interest rate strategy contract - **/ - function init( - DataTypes.ReserveData storage reserve, - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress, - address interestRateStrategyAddress - ) internal { - require(reserve.aTokenAddress == address(0), Errors.RESERVE_ALREADY_INITIALIZED); - - reserve.liquidityIndex = uint128(WadRayMath.RAY); - reserve.variableBorrowIndex = uint128(WadRayMath.RAY); - reserve.aTokenAddress = aTokenAddress; - reserve.stableDebtTokenAddress = stableDebtTokenAddress; - reserve.variableDebtTokenAddress = variableDebtTokenAddress; - reserve.interestRateStrategyAddress = interestRateStrategyAddress; - } - - struct UpdateInterestRatesLocalVars { - uint256 nextLiquidityRate; - uint256 nextStableRate; - uint256 nextVariableRate; - uint256 totalVariableDebt; - } - - /** - * @notice Updates the reserve current stable borrow rate, the current variable borrow rate and the current liquidity rate. - * @param reserve The reserve reserve to be updated - * @param reserveCache The caching layer for the reserve data - * @param reserveAddress The address of the reserve to be updated - * @param liquidityAdded The amount of liquidity added to the protocol (supply or repay) in the previous action - * @param liquidityTaken The amount of liquidity taken from the protocol (redeem or borrow) - **/ - function updateInterestRates( - DataTypes.ReserveData storage reserve, - DataTypes.ReserveCache memory reserveCache, - address reserveAddress, - uint256 liquidityAdded, - uint256 liquidityTaken - ) internal { - UpdateInterestRatesLocalVars memory vars; - - vars.totalVariableDebt = reserveCache.nextScaledVariableDebt.rayMul( - reserveCache.nextVariableBorrowIndex - ); - - ( - vars.nextLiquidityRate, - vars.nextStableRate, - vars.nextVariableRate - ) = IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).calculateInterestRates( - DataTypes.CalculateInterestRatesParams({ - unbacked: reserveCache.reserveConfiguration.getUnbackedMintCap() != 0 - ? reserve.unbacked - : 0, - liquidityAdded: liquidityAdded, - liquidityTaken: liquidityTaken, - totalStableDebt: reserveCache.nextTotalStableDebt, - totalVariableDebt: vars.totalVariableDebt, - averageStableBorrowRate: reserveCache.nextAvgStableBorrowRate, - reserveFactor: reserveCache.reserveFactor, - reserve: reserveAddress, - aToken: reserveCache.aTokenAddress - }) - ); - - reserve.currentLiquidityRate = vars.nextLiquidityRate.toUint128(); - reserve.currentStableBorrowRate = vars.nextStableRate.toUint128(); - reserve.currentVariableBorrowRate = vars.nextVariableRate.toUint128(); - - emit ReserveDataUpdated( - reserveAddress, - vars.nextLiquidityRate, - vars.nextStableRate, - vars.nextVariableRate, - reserveCache.nextLiquidityIndex, - reserveCache.nextVariableBorrowIndex - ); - } - - struct AccrueToTreasuryLocalVars { - uint256 prevTotalStableDebt; - uint256 prevTotalVariableDebt; - uint256 currTotalVariableDebt; - uint256 cumulatedStableInterest; - uint256 totalDebtAccrued; - uint256 amountToMint; - } - - /** - * @notice Mints part of the repaid interest to the reserve treasury as a function of the reserve factor for the - * specific asset. - * @param reserve The reserve to be updated - * @param reserveCache The caching layer for the reserve data - **/ - function _accrueToTreasury( - DataTypes.ReserveData storage reserve, - DataTypes.ReserveCache memory reserveCache - ) internal { - AccrueToTreasuryLocalVars memory vars; - - if (reserveCache.reserveFactor == 0) { - return; - } - - //calculate the total variable debt at moment of the last interaction - vars.prevTotalVariableDebt = reserveCache.currScaledVariableDebt.rayMul( - reserveCache.currVariableBorrowIndex - ); - - //calculate the new total variable debt after accumulation of the interest on the index - vars.currTotalVariableDebt = reserveCache.currScaledVariableDebt.rayMul( - reserveCache.nextVariableBorrowIndex - ); - - //calculate the stable debt until the last timestamp update - vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest( - reserveCache.currAvgStableBorrowRate, - reserveCache.stableDebtLastUpdateTimestamp, - reserveCache.reserveLastUpdateTimestamp - ); - - vars.prevTotalStableDebt = reserveCache.currPrincipalStableDebt.rayMul( - vars.cumulatedStableInterest - ); - - //debt accrued is the sum of the current debt minus the sum of the debt at the last update - vars.totalDebtAccrued = - vars.currTotalVariableDebt + - reserveCache.currTotalStableDebt - - vars.prevTotalVariableDebt - - vars.prevTotalStableDebt; - - vars.amountToMint = vars.totalDebtAccrued.percentMul(reserveCache.reserveFactor); - - if (vars.amountToMint != 0) { - reserve.accruedToTreasury += vars - .amountToMint - .rayDiv(reserveCache.nextLiquidityIndex) - .toUint128(); - } - } - - /** - * @notice Updates the reserve indexes and the timestamp of the update. - * @param reserve The reserve reserve to be updated - * @param reserveCache The cache layer holding the cached protocol data - **/ - function _updateIndexes( - DataTypes.ReserveData storage reserve, - DataTypes.ReserveCache memory reserveCache - ) internal { - reserveCache.nextLiquidityIndex = reserveCache.currLiquidityIndex; - reserveCache.nextVariableBorrowIndex = reserveCache.currVariableBorrowIndex; - - //only cumulating if there is any income being produced - if (reserveCache.currLiquidityRate != 0) { - uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest( - reserveCache.currLiquidityRate, - reserveCache.reserveLastUpdateTimestamp - ); - reserveCache.nextLiquidityIndex = cumulatedLiquidityInterest.rayMul( - reserveCache.currLiquidityIndex - ); - reserve.liquidityIndex = reserveCache.nextLiquidityIndex.toUint128(); - - //as the liquidity rate might come only from stable rate loans, we need to ensure - //that there is actual variable debt before accumulating - if (reserveCache.currScaledVariableDebt != 0) { - uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest( - reserveCache.currVariableBorrowRate, - reserveCache.reserveLastUpdateTimestamp - ); - reserveCache.nextVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul( - reserveCache.currVariableBorrowIndex - ); - reserve.variableBorrowIndex = reserveCache.nextVariableBorrowIndex.toUint128(); - } - } - - //solium-disable-next-line - reserve.lastUpdateTimestamp = uint40(block.timestamp); - } - - /** - * @notice Creates a cache object to avoid repeated storage reads and external contract calls when updating state and - * interest rates. - * @param reserve The reserve object for which the cache will be filled - * @return The cache object - */ - function cache(DataTypes.ReserveData storage reserve) - internal - view - returns (DataTypes.ReserveCache memory) - { - DataTypes.ReserveCache memory reserveCache; - - reserveCache.reserveConfiguration = reserve.configuration; - reserveCache.reserveFactor = reserveCache.reserveConfiguration.getReserveFactor(); - reserveCache.currLiquidityIndex = reserve.liquidityIndex; - reserveCache.currVariableBorrowIndex = reserve.variableBorrowIndex; - reserveCache.currLiquidityRate = reserve.currentLiquidityRate; - reserveCache.currVariableBorrowRate = reserve.currentVariableBorrowRate; - - reserveCache.aTokenAddress = reserve.aTokenAddress; - reserveCache.stableDebtTokenAddress = reserve.stableDebtTokenAddress; - reserveCache.variableDebtTokenAddress = reserve.variableDebtTokenAddress; - - reserveCache.reserveLastUpdateTimestamp = reserve.lastUpdateTimestamp; - - reserveCache.currScaledVariableDebt = reserveCache.nextScaledVariableDebt = IVariableDebtToken( - reserveCache.variableDebtTokenAddress - ).scaledTotalSupply(); - - ( - reserveCache.currPrincipalStableDebt, - reserveCache.currTotalStableDebt, - reserveCache.currAvgStableBorrowRate, - reserveCache.stableDebtLastUpdateTimestamp - ) = IStableDebtToken(reserveCache.stableDebtTokenAddress).getSupplyData(); - - // by default the actions are considered as not affecting the debt balances. - // if the action involves mint/burn of debt, the cache needs to be updated - reserveCache.nextTotalStableDebt = reserveCache.currTotalStableDebt; - reserveCache.nextAvgStableBorrowRate = reserveCache.currAvgStableBorrowRate; - - return reserveCache; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/SupplyLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/SupplyLogic.sol deleted file mode 100644 index 98ad8e8..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/SupplyLogic.sol +++ /dev/null @@ -1,290 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {ValidationLogic} from './ValidationLogic.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; - -/** - * @title SupplyLogic library - * @author Aave - * @notice Implements the base logic for supply/withdraw - */ -library SupplyLogic { - using ReserveLogic for DataTypes.ReserveCache; - using ReserveLogic for DataTypes.ReserveData; - using GPv2SafeERC20 for IERC20; - using UserConfiguration for DataTypes.UserConfigurationMap; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using WadRayMath for uint256; - using PercentageMath for uint256; - - // See `IPool` for descriptions - event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); - event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); - event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); - event Supply( - address indexed reserve, - address user, - address indexed onBehalfOf, - uint256 amount, - uint16 indexed referralCode - ); - - /** - * @notice Implements the supply feature. Through `supply()`, users supply assets to the Aave protocol. - * @dev Emits the `Supply()` event. - * @dev In the first supply action, `ReserveUsedAsCollateralEnabled()` is emitted, if the asset can be enabled as - * collateral. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param userConfig The user configuration mapping that tracks the supplied/borrowed assets - * @param params The additional parameters needed to execute the supply function - */ - function executeSupply( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.ExecuteSupplyParams memory params - ) external { - DataTypes.ReserveData storage reserve = reservesData[params.asset]; - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - - reserve.updateState(reserveCache); - - ValidationLogic.validateSupply(reserveCache, params.amount); - - reserve.updateInterestRates(reserveCache, params.asset, params.amount, 0); - - IERC20(params.asset).safeTransferFrom(msg.sender, reserveCache.aTokenAddress, params.amount); - - bool isFirstSupply = IAToken(reserveCache.aTokenAddress).mint( - msg.sender, - params.onBehalfOf, - params.amount, - reserveCache.nextLiquidityIndex - ); - - if (isFirstSupply) { - if ( - ValidationLogic.validateUseAsCollateral( - reservesData, - reservesList, - userConfig, - reserveCache.reserveConfiguration - ) - ) { - userConfig.setUsingAsCollateral(reserve.id, true); - emit ReserveUsedAsCollateralEnabled(params.asset, params.onBehalfOf); - } - } - - emit Supply(params.asset, msg.sender, params.onBehalfOf, params.amount, params.referralCode); - } - - /** - * @notice Implements the withdraw feature. Through `withdraw()`, users redeem their aTokens for the underlying asset - * previously supplied in the Aave protocol. - * @dev Emits the `Withdraw()` event. - * @dev If the user withdraws everything, `ReserveUsedAsCollateralDisabled()` is emitted. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param userConfig The user configuration mapping that tracks the supplied/borrowed assets - * @param params The additional parameters needed to execute the withdraw function - * @return The actual amount withdrawn - */ - function executeWithdraw( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.ExecuteWithdrawParams memory params - ) external returns (uint256) { - DataTypes.ReserveData storage reserve = reservesData[params.asset]; - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - - reserve.updateState(reserveCache); - - uint256 userBalance = IAToken(reserveCache.aTokenAddress).scaledBalanceOf(msg.sender).rayMul( - reserveCache.nextLiquidityIndex - ); - - uint256 amountToWithdraw = params.amount; - - if (params.amount == type(uint256).max) { - amountToWithdraw = userBalance; - } - - ValidationLogic.validateWithdraw(reserveCache, amountToWithdraw, userBalance); - - reserve.updateInterestRates(reserveCache, params.asset, 0, amountToWithdraw); - - IAToken(reserveCache.aTokenAddress).burn( - msg.sender, - params.to, - amountToWithdraw, - reserveCache.nextLiquidityIndex - ); - - if (userConfig.isUsingAsCollateral(reserve.id)) { - if (userConfig.isBorrowingAny()) { - ValidationLogic.validateHFAndLtv( - reservesData, - reservesList, - eModeCategories, - userConfig, - params.asset, - msg.sender, - params.reservesCount, - params.oracle, - params.userEModeCategory - ); - } - - if (amountToWithdraw == userBalance) { - userConfig.setUsingAsCollateral(reserve.id, false); - emit ReserveUsedAsCollateralDisabled(params.asset, msg.sender); - } - } - - emit Withdraw(params.asset, msg.sender, params.to, amountToWithdraw); - - return amountToWithdraw; - } - - /** - * @notice Validates a transfer of aTokens. The sender is subjected to health factor validation to avoid - * collateralization constraints violation. - * @dev Emits the `ReserveUsedAsCollateralEnabled()` event for the `to` account, if the asset is being activated as - * collateral. - * @dev In case the `from` user transfers everything, `ReserveUsedAsCollateralDisabled()` is emitted for `from`. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param usersConfig The users configuration mapping that track the supplied/borrowed assets - * @param params The additional parameters needed to execute the finalizeTransfer function - */ - function executeFinalizeTransfer( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - mapping(address => DataTypes.UserConfigurationMap) storage usersConfig, - DataTypes.FinalizeTransferParams memory params - ) external { - DataTypes.ReserveData storage reserve = reservesData[params.asset]; - - ValidationLogic.validateTransfer(reserve); - - uint256 reserveId = reserve.id; - - if (params.from != params.to && params.amount != 0) { - DataTypes.UserConfigurationMap storage fromConfig = usersConfig[params.from]; - - if (fromConfig.isUsingAsCollateral(reserveId)) { - if (fromConfig.isBorrowingAny()) { - ValidationLogic.validateHFAndLtv( - reservesData, - reservesList, - eModeCategories, - usersConfig[params.from], - params.asset, - params.from, - params.reservesCount, - params.oracle, - params.fromEModeCategory - ); - } - if (params.balanceFromBefore == params.amount) { - fromConfig.setUsingAsCollateral(reserveId, false); - emit ReserveUsedAsCollateralDisabled(params.asset, params.from); - } - } - - if (params.balanceToBefore == 0) { - DataTypes.UserConfigurationMap storage toConfig = usersConfig[params.to]; - if ( - ValidationLogic.validateUseAsCollateral( - reservesData, - reservesList, - toConfig, - reserve.configuration - ) - ) { - toConfig.setUsingAsCollateral(reserveId, true); - emit ReserveUsedAsCollateralEnabled(params.asset, params.to); - } - } - } - } - - /** - * @notice Executes the 'set as collateral' feature. A user can choose to activate or deactivate an asset as - * collateral at any point in time. Deactivating an asset as collateral is subjected to the usual health factor - * checks to ensure collateralization. - * @dev Emits the `ReserveUsedAsCollateralEnabled()` event if the asset can be activated as collateral. - * @dev In case the asset is being deactivated as collateral, `ReserveUsedAsCollateralDisabled()` is emitted. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param userConfig The users configuration mapping that track the supplied/borrowed assets - * @param asset The address of the asset being configured as collateral - * @param useAsCollateral True if the user wants to set the asset as collateral, false otherwise - * @param reservesCount The number of initialized reserves - * @param priceOracle The address of the price oracle - * @param userEModeCategory The eMode category chosen by the user - */ - function executeUseReserveAsCollateral( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.UserConfigurationMap storage userConfig, - address asset, - bool useAsCollateral, - uint256 reservesCount, - address priceOracle, - uint8 userEModeCategory - ) external { - DataTypes.ReserveData storage reserve = reservesData[asset]; - DataTypes.ReserveCache memory reserveCache = reserve.cache(); - - uint256 userBalance = IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender); - - ValidationLogic.validateSetUseReserveAsCollateral(reserveCache, userBalance); - - if (useAsCollateral == userConfig.isUsingAsCollateral(reserve.id)) return; - - if (useAsCollateral) { - require( - ValidationLogic.validateUseAsCollateral(reservesData, reservesList, userConfig, reserveCache.reserveConfiguration), - Errors.USER_IN_ISOLATION_MODE - ); - - userConfig.setUsingAsCollateral(reserve.id, true); - emit ReserveUsedAsCollateralEnabled(asset, msg.sender); - } else { - userConfig.setUsingAsCollateral(reserve.id, false); - ValidationLogic.validateHFAndLtv( - reservesData, - reservesList, - eModeCategories, - userConfig, - asset, - msg.sender, - reservesCount, - priceOracle, - userEModeCategory - ); - - emit ReserveUsedAsCollateralDisabled(asset, msg.sender); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ValidationLogic.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ValidationLogic.sol deleted file mode 100644 index fb2eda0..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/logic/ValidationLogic.sol +++ /dev/null @@ -1,726 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {Address} from '../../../dependencies/openzeppelin/contracts/Address.sol'; -import {GPv2SafeERC20} from '../../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol'; -import {IStableDebtToken} from '../../../interfaces/IStableDebtToken.sol'; -import {IScaledBalanceToken} from '../../../interfaces/IScaledBalanceToken.sol'; -import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol'; -import {IAToken} from '../../../interfaces/IAToken.sol'; -import {IPriceOracleSentinel} from '../../../interfaces/IPriceOracleSentinel.sol'; -import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../configuration/UserConfiguration.sol'; -import {Errors} from '../helpers/Errors.sol'; -import {WadRayMath} from '../math/WadRayMath.sol'; -import {PercentageMath} from '../math/PercentageMath.sol'; -import {DataTypes} from '../types/DataTypes.sol'; -import {ReserveLogic} from './ReserveLogic.sol'; -import {GenericLogic} from './GenericLogic.sol'; -import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; - -/** - * @title ReserveLogic library - * @author Aave - * @notice Implements functions to validate the different actions of the protocol - */ -library ValidationLogic { - using ReserveLogic for DataTypes.ReserveData; - using WadRayMath for uint256; - using PercentageMath for uint256; - using SafeCast for uint256; - using GPv2SafeERC20 for IERC20; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using UserConfiguration for DataTypes.UserConfigurationMap; - using Address for address; - - // Factor to apply to "only-variable-debt" liquidity rate to get threshold for rebalancing, expressed in bps - // A value of 0.9e4 results in 90% - uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 0.9e4; - - // Minimum health factor allowed under any circumstance - // A value of 0.95e18 results in 0.95 - uint256 public constant MINIMUM_HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 0.95e18; - - /** - * @dev Minimum health factor to consider a user position healthy - * A value of 1e18 results in 1 - */ - uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1e18; - - /** - * @notice Validates a supply action. - * @param reserveCache The cached data of the reserve - * @param amount The amount to be supplied - */ - function validateSupply(DataTypes.ReserveCache memory reserveCache, uint256 amount) - internal - view - { - require(amount != 0, Errors.INVALID_AMOUNT); - - (bool isActive, bool isFrozen, , , bool isPaused) = reserveCache - .reserveConfiguration - .getFlags(); - require(isActive, Errors.RESERVE_INACTIVE); - require(!isPaused, Errors.RESERVE_PAUSED); - require(!isFrozen, Errors.RESERVE_FROZEN); - - uint256 supplyCap = reserveCache.reserveConfiguration.getSupplyCap(); - require( - supplyCap == 0 || - (IAToken(reserveCache.aTokenAddress).scaledTotalSupply().rayMul( - reserveCache.nextLiquidityIndex - ) + amount) <= - supplyCap * (10**reserveCache.reserveConfiguration.getDecimals()), - Errors.SUPPLY_CAP_EXCEEDED - ); - } - - /** - * @notice Validates a withdraw action. - * @param reserveCache The cached data of the reserve - * @param amount The amount to be withdrawn - * @param userBalance The balance of the user - */ - function validateWithdraw( - DataTypes.ReserveCache memory reserveCache, - uint256 amount, - uint256 userBalance - ) internal pure { - require(amount != 0, Errors.INVALID_AMOUNT); - require(amount <= userBalance, Errors.NOT_ENOUGH_AVAILABLE_USER_BALANCE); - - (bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlags(); - require(isActive, Errors.RESERVE_INACTIVE); - require(!isPaused, Errors.RESERVE_PAUSED); - } - - struct ValidateBorrowLocalVars { - uint256 currentLtv; - uint256 collateralNeededInBaseCurrency; - uint256 userCollateralInBaseCurrency; - uint256 userDebtInBaseCurrency; - uint256 availableLiquidity; - uint256 healthFactor; - uint256 totalDebt; - uint256 totalSupplyVariableDebt; - uint256 reserveDecimals; - uint256 borrowCap; - uint256 amountInBaseCurrency; - uint256 assetUnit; - address eModePriceSource; - address siloedBorrowingAddress; - bool isActive; - bool isFrozen; - bool isPaused; - bool borrowingEnabled; - bool stableRateBorrowingEnabled; - bool siloedBorrowingEnabled; - } - - /** - * @notice Validates a borrow action. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param params Additional params needed for the validation - */ - function validateBorrow( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.ValidateBorrowParams memory params - ) internal view { - require(params.amount != 0, Errors.INVALID_AMOUNT); - - ValidateBorrowLocalVars memory vars; - - ( - vars.isActive, - vars.isFrozen, - vars.borrowingEnabled, - vars.stableRateBorrowingEnabled, - vars.isPaused - ) = params.reserveCache.reserveConfiguration.getFlags(); - - require(vars.isActive, Errors.RESERVE_INACTIVE); - require(!vars.isPaused, Errors.RESERVE_PAUSED); - require(!vars.isFrozen, Errors.RESERVE_FROZEN); - require(vars.borrowingEnabled, Errors.BORROWING_NOT_ENABLED); - - require( - params.priceOracleSentinel == address(0) || - IPriceOracleSentinel(params.priceOracleSentinel).isBorrowAllowed(), - Errors.PRICE_ORACLE_SENTINEL_CHECK_FAILED - ); - - //validate interest rate mode - require( - params.interestRateMode == DataTypes.InterestRateMode.VARIABLE || - params.interestRateMode == DataTypes.InterestRateMode.STABLE, - Errors.INVALID_INTEREST_RATE_MODE_SELECTED - ); - - vars.reserveDecimals = params.reserveCache.reserveConfiguration.getDecimals(); - vars.borrowCap = params.reserveCache.reserveConfiguration.getBorrowCap(); - unchecked { - vars.assetUnit = 10**vars.reserveDecimals; - } - - if (vars.borrowCap != 0) { - vars.totalSupplyVariableDebt = params.reserveCache.currScaledVariableDebt.rayMul( - params.reserveCache.nextVariableBorrowIndex - ); - - vars.totalDebt = - params.reserveCache.currTotalStableDebt + - vars.totalSupplyVariableDebt + - params.amount; - - unchecked { - require(vars.totalDebt <= vars.borrowCap * vars.assetUnit, Errors.BORROW_CAP_EXCEEDED); - } - } - - if (params.isolationModeActive) { - // check that the asset being borrowed is borrowable in isolation mode AND - // the total exposure is no bigger than the collateral debt ceiling - require( - params.reserveCache.reserveConfiguration.getBorrowableInIsolation(), - Errors.ASSET_NOT_BORROWABLE_IN_ISOLATION - ); - - require( - reservesData[params.isolationModeCollateralAddress].isolationModeTotalDebt + - (params.amount / 10**(vars.reserveDecimals - ReserveConfiguration.DEBT_CEILING_DECIMALS)) - .toUint128() <= - params.isolationModeDebtCeiling, - Errors.DEBT_CEILING_EXCEEDED - ); - } - - if (params.userEModeCategory != 0) { - require( - params.reserveCache.reserveConfiguration.getEModeCategory() == params.userEModeCategory, - Errors.INCONSISTENT_EMODE_CATEGORY - ); - vars.eModePriceSource = eModeCategories[params.userEModeCategory].priceSource; - } - - ( - vars.userCollateralInBaseCurrency, - vars.userDebtInBaseCurrency, - vars.currentLtv, - , - vars.healthFactor, - - ) = GenericLogic.calculateUserAccountData( - reservesData, - reservesList, - eModeCategories, - DataTypes.CalculateUserAccountDataParams({ - userConfig: params.userConfig, - reservesCount: params.reservesCount, - user: params.userAddress, - oracle: params.oracle, - userEModeCategory: params.userEModeCategory - }) - ); - - require(vars.userCollateralInBaseCurrency != 0, Errors.COLLATERAL_BALANCE_IS_ZERO); - require(vars.currentLtv != 0, Errors.LTV_VALIDATION_FAILED); - - require( - vars.healthFactor > HEALTH_FACTOR_LIQUIDATION_THRESHOLD, - Errors.HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD - ); - - vars.amountInBaseCurrency = - IPriceOracleGetter(params.oracle).getAssetPrice( - vars.eModePriceSource != address(0) ? vars.eModePriceSource : params.asset - ) * - params.amount; - unchecked { - vars.amountInBaseCurrency /= vars.assetUnit; - } - - //add the current already borrowed amount to the amount requested to calculate the total collateral needed. - vars.collateralNeededInBaseCurrency = (vars.userDebtInBaseCurrency + vars.amountInBaseCurrency) - .percentDiv(vars.currentLtv); //LTV is calculated in percentage - - require( - vars.collateralNeededInBaseCurrency <= vars.userCollateralInBaseCurrency, - Errors.COLLATERAL_CANNOT_COVER_NEW_BORROW - ); - - /** - * Following conditions need to be met if the user is borrowing at a stable rate: - * 1. Reserve must be enabled for stable rate borrowing - * 2. Users cannot borrow from the reserve if their collateral is (mostly) the same currency - * they are borrowing, to prevent abuses. - * 3. Users will be able to borrow only a portion of the total available liquidity - **/ - - if (params.interestRateMode == DataTypes.InterestRateMode.STABLE) { - //check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve - - require(vars.stableRateBorrowingEnabled, Errors.STABLE_BORROWING_NOT_ENABLED); - - require( - !params.userConfig.isUsingAsCollateral(reservesData[params.asset].id) || - params.reserveCache.reserveConfiguration.getLtv() == 0 || - params.amount > IERC20(params.reserveCache.aTokenAddress).balanceOf(params.userAddress), - Errors.COLLATERAL_SAME_AS_BORROWING_CURRENCY - ); - - vars.availableLiquidity = IERC20(params.asset).balanceOf(params.reserveCache.aTokenAddress); - - //calculate the max available loan size in stable rate mode as a percentage of the - //available liquidity - uint256 maxLoanSizeStable = vars.availableLiquidity.percentMul(params.maxStableLoanPercent); - - require(params.amount <= maxLoanSizeStable, Errors.AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE); - } - - if (params.userConfig.isBorrowingAny()) { - (vars.siloedBorrowingEnabled, vars.siloedBorrowingAddress) = params - .userConfig - .getSiloedBorrowingState(reservesData, reservesList); - - if (vars.siloedBorrowingEnabled) { - require(vars.siloedBorrowingAddress == params.asset, Errors.SILOED_BORROWING_VIOLATION); - } else { - require( - !params.reserveCache.reserveConfiguration.getSiloedBorrowing(), - Errors.SILOED_BORROWING_VIOLATION - ); - } - } - } - - /** - * @notice Validates a repay action. - * @param reserveCache The cached data of the reserve - * @param amountSent The amount sent for the repayment. Can be an actual value or uint(-1) - * @param interestRateMode The interest rate mode of the debt being repaid - * @param onBehalfOf The address of the user msg.sender is repaying for - * @param stableDebt The borrow balance of the user - * @param variableDebt The borrow balance of the user - */ - function validateRepay( - DataTypes.ReserveCache memory reserveCache, - uint256 amountSent, - DataTypes.InterestRateMode interestRateMode, - address onBehalfOf, - uint256 stableDebt, - uint256 variableDebt - ) internal view { - require(amountSent != 0, Errors.INVALID_AMOUNT); - require( - amountSent != type(uint256).max || msg.sender == onBehalfOf, - Errors.NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF - ); - - (bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlags(); - require(isActive, Errors.RESERVE_INACTIVE); - require(!isPaused, Errors.RESERVE_PAUSED); - - uint256 variableDebtPreviousIndex = IScaledBalanceToken(reserveCache.variableDebtTokenAddress) - .getPreviousIndex(onBehalfOf); - - uint40 stableRatePreviousTimestamp = IStableDebtToken(reserveCache.stableDebtTokenAddress) - .getUserLastUpdated(onBehalfOf); - - require( - (stableRatePreviousTimestamp < uint40(block.timestamp) && - interestRateMode == DataTypes.InterestRateMode.STABLE) || - (variableDebtPreviousIndex < reserveCache.nextVariableBorrowIndex && - interestRateMode == DataTypes.InterestRateMode.VARIABLE), - Errors.SAME_BLOCK_BORROW_REPAY - ); - - require( - (stableDebt != 0 && interestRateMode == DataTypes.InterestRateMode.STABLE) || - (variableDebt != 0 && interestRateMode == DataTypes.InterestRateMode.VARIABLE), - Errors.NO_DEBT_OF_SELECTED_TYPE - ); - } - - /** - * @notice Validates a swap of borrow rate mode. - * @param reserve The reserve state on which the user is swapping the rate - * @param reserveCache The cached data of the reserve - * @param userConfig The user reserves configuration - * @param stableDebt The stable debt of the user - * @param variableDebt The variable debt of the user - * @param currentRateMode The rate mode of the debt being swapped - */ - function validateSwapRateMode( - DataTypes.ReserveData storage reserve, - DataTypes.ReserveCache memory reserveCache, - DataTypes.UserConfigurationMap storage userConfig, - uint256 stableDebt, - uint256 variableDebt, - DataTypes.InterestRateMode currentRateMode - ) internal view { - (bool isActive, bool isFrozen, , bool stableRateEnabled, bool isPaused) = reserveCache - .reserveConfiguration - .getFlags(); - require(isActive, Errors.RESERVE_INACTIVE); - require(!isPaused, Errors.RESERVE_PAUSED); - require(!isFrozen, Errors.RESERVE_FROZEN); - - if (currentRateMode == DataTypes.InterestRateMode.STABLE) { - require(stableDebt != 0, Errors.NO_OUTSTANDING_STABLE_DEBT); - } else if (currentRateMode == DataTypes.InterestRateMode.VARIABLE) { - require(variableDebt != 0, Errors.NO_OUTSTANDING_VARIABLE_DEBT); - /** - * user wants to swap to stable, before swapping we need to ensure that - * 1. stable borrow rate is enabled on the reserve - * 2. user is not trying to abuse the reserve by supplying - * more collateral than he is borrowing, artificially lowering - * the interest rate, borrowing at variable, and switching to stable - **/ - require(stableRateEnabled, Errors.STABLE_BORROWING_NOT_ENABLED); - - require( - !userConfig.isUsingAsCollateral(reserve.id) || - reserveCache.reserveConfiguration.getLtv() == 0 || - stableDebt + variableDebt > IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender), - Errors.COLLATERAL_SAME_AS_BORROWING_CURRENCY - ); - } else { - revert(Errors.INVALID_INTEREST_RATE_MODE_SELECTED); - } - } - - /** - * @notice Validates a stable borrow rate rebalance action. - * @dev Rebalancing is accepted when depositors are earning <= 90% of their earnings in pure supply/demand market (variable rate only) - * For this to be the case, there has to be quite large stable debt with an interest rate below the current variable rate. - * @param reserve The reserve state on which the user is getting rebalanced - * @param reserveCache The cached state of the reserve - * @param reserveAddress The address of the reserve - */ - function validateRebalanceStableBorrowRate( - DataTypes.ReserveData storage reserve, - DataTypes.ReserveCache memory reserveCache, - address reserveAddress - ) internal view { - (bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlags(); - require(isActive, Errors.RESERVE_INACTIVE); - require(!isPaused, Errors.RESERVE_PAUSED); - - uint256 totalDebt = IERC20(reserveCache.stableDebtTokenAddress).totalSupply() + - IERC20(reserveCache.variableDebtTokenAddress).totalSupply(); - - (uint256 liquidityRateVariableDebtOnly, , ) = IReserveInterestRateStrategy( - reserve.interestRateStrategyAddress - ).calculateInterestRates( - DataTypes.CalculateInterestRatesParams({ - unbacked: reserve.unbacked, - liquidityAdded: 0, - liquidityTaken: 0, - totalStableDebt: 0, - totalVariableDebt: totalDebt, - averageStableBorrowRate: 0, - reserveFactor: reserveCache.reserveFactor, - reserve: reserveAddress, - aToken: reserveCache.aTokenAddress - }) - ); - - require( - reserveCache.currLiquidityRate <= - liquidityRateVariableDebtOnly.percentMul(REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD), - Errors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET - ); - } - - /** - * @notice Validates the action of setting an asset as collateral. - * @param reserveCache The cached data of the reserve - * @param userBalance The balance of the user - */ - function validateSetUseReserveAsCollateral( - DataTypes.ReserveCache memory reserveCache, - uint256 userBalance - ) internal pure { - require(userBalance != 0, Errors.UNDERLYING_BALANCE_ZERO); - - (bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlags(); - require(isActive, Errors.RESERVE_INACTIVE); - require(!isPaused, Errors.RESERVE_PAUSED); - } - - /** - * @notice Validates a flashloan action. - * @param reservesData The state of all the reserves - * @param assets The assets being flash-borrowed - * @param amounts The amounts for each asset being borrowed - */ - function validateFlashloan( - mapping(address => DataTypes.ReserveData) storage reservesData, - address[] memory assets, - uint256[] memory amounts - ) internal view { - require(assets.length == amounts.length, Errors.INCONSISTENT_FLASHLOAN_PARAMS); - for (uint256 i = 0; i < assets.length; i++) { - DataTypes.ReserveConfigurationMap memory configuration = reservesData[assets[i]] - .configuration; - require(!configuration.getPaused(), Errors.RESERVE_PAUSED); - require(configuration.getActive(), Errors.RESERVE_INACTIVE); - } - } - - /** - * @notice Validates a flashloan action. - * @param reserve The state of the reserve - */ - function validateFlashloanSimple(DataTypes.ReserveData storage reserve) internal view { - DataTypes.ReserveConfigurationMap memory configuration = reserve.configuration; - require(!configuration.getPaused(), Errors.RESERVE_PAUSED); - require(configuration.getActive(), Errors.RESERVE_INACTIVE); - } - - struct ValidateLiquidationCallLocalVars { - bool collateralReserveActive; - bool collateralReservePaused; - bool principalReserveActive; - bool principalReservePaused; - bool isCollateralEnabled; - } - - /** - * @notice Validates the liquidation action. - * @param userConfig The user configuration mapping - * @param collateralReserve The reserve data of the collateral - * @param params Additional parameters needed for the validation - */ - function validateLiquidationCall( - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.ReserveData storage collateralReserve, - DataTypes.ValidateLiquidationCallParams memory params - ) internal view { - ValidateLiquidationCallLocalVars memory vars; - - (vars.collateralReserveActive, , , , vars.collateralReservePaused) = collateralReserve - .configuration - .getFlags(); - - (vars.principalReserveActive, , , , vars.principalReservePaused) = params - .debtReserveCache - .reserveConfiguration - .getFlags(); - - require(vars.collateralReserveActive && vars.principalReserveActive, Errors.RESERVE_INACTIVE); - require(!vars.collateralReservePaused && !vars.principalReservePaused, Errors.RESERVE_PAUSED); - - require( - params.priceOracleSentinel == address(0) || - params.healthFactor < MINIMUM_HEALTH_FACTOR_LIQUIDATION_THRESHOLD || - IPriceOracleSentinel(params.priceOracleSentinel).isLiquidationAllowed(), - Errors.PRICE_ORACLE_SENTINEL_CHECK_FAILED - ); - - require( - params.healthFactor < HEALTH_FACTOR_LIQUIDATION_THRESHOLD, - Errors.HEALTH_FACTOR_NOT_BELOW_THRESHOLD - ); - - vars.isCollateralEnabled = - collateralReserve.configuration.getLiquidationThreshold() != 0 && - userConfig.isUsingAsCollateral(collateralReserve.id); - - //if collateral isn't enabled as collateral by user, it cannot be liquidated - require(vars.isCollateralEnabled, Errors.COLLATERAL_CANNOT_BE_LIQUIDATED); - require(params.totalDebt != 0, Errors.SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER); - } - - /** - * @notice Validates the health factor of a user. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param userConfig The state of the user for the specific reserve - * @param user The user to validate health factor of - * @param userEModeCategory The users active efficiency mode category - * @param reservesCount The number of available reserves - * @param oracle The price oracle - */ - function validateHealthFactor( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.UserConfigurationMap memory userConfig, - address user, - uint8 userEModeCategory, - uint256 reservesCount, - address oracle - ) internal view returns (uint256, bool) { - (, , , , uint256 healthFactor, bool hasZeroLtvCollateral) = GenericLogic - .calculateUserAccountData( - reservesData, - reservesList, - eModeCategories, - DataTypes.CalculateUserAccountDataParams({ - userConfig: userConfig, - reservesCount: reservesCount, - user: user, - oracle: oracle, - userEModeCategory: userEModeCategory - }) - ); - - require( - healthFactor >= HEALTH_FACTOR_LIQUIDATION_THRESHOLD, - Errors.HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD - ); - - return (healthFactor, hasZeroLtvCollateral); - } - - /** - * @notice Validates the health factor of a user and the ltv of the asset being withdrawn. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories The configuration of all the efficiency mode categories - * @param userConfig The state of the user for the specific reserve - * @param asset The asset for which the ltv will be validated - * @param from The user from which the aTokens are being transferred - * @param reservesCount The number of available reserves - * @param oracle The price oracle - * @param userEModeCategory The users active efficiency mode category - */ - function validateHFAndLtv( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.UserConfigurationMap memory userConfig, - address asset, - address from, - uint256 reservesCount, - address oracle, - uint8 userEModeCategory - ) internal view { - DataTypes.ReserveData memory reserve = reservesData[asset]; - - (, bool hasZeroLtvCollateral) = validateHealthFactor( - reservesData, - reservesList, - eModeCategories, - userConfig, - from, - userEModeCategory, - reservesCount, - oracle - ); - - require( - !hasZeroLtvCollateral || reserve.configuration.getLtv() == 0, - Errors.LTV_VALIDATION_FAILED - ); - } - - /** - * @notice Validates a transfer action. - * @param reserve The reserve object - */ - function validateTransfer(DataTypes.ReserveData storage reserve) internal view { - require(!reserve.configuration.getPaused(), Errors.RESERVE_PAUSED); - } - - /** - * @notice Validates a drop reserve action. - * @param reservesList The addresses of all the active reserves - * @param reserve The reserve object - * @param asset The address of the reserve's underlying asset - **/ - function validateDropReserve( - mapping(uint256 => address) storage reservesList, - DataTypes.ReserveData storage reserve, - address asset - ) internal view { - require(asset != address(0), Errors.ZERO_ADDRESS_NOT_VALID); - require(reserve.id != 0 || reservesList[0] == asset, Errors.ASSET_NOT_LISTED); - require(IERC20(reserve.stableDebtTokenAddress).totalSupply() == 0, Errors.STABLE_DEBT_NOT_ZERO); - require( - IERC20(reserve.variableDebtTokenAddress).totalSupply() == 0, - Errors.VARIABLE_DEBT_SUPPLY_NOT_ZERO - ); - require(IERC20(reserve.aTokenAddress).totalSupply() == 0, Errors.ATOKEN_SUPPLY_NOT_ZERO); - } - - /** - * @notice Validates the action of setting efficiency mode. - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param eModeCategories a mapping storing configurations for all efficiency mode categories - * @param userConfig the user configuration - * @param reservesCount The total number of valid reserves - * @param categoryId The id of the category - **/ - function validateSetUserEMode( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, - DataTypes.UserConfigurationMap memory userConfig, - uint256 reservesCount, - uint8 categoryId - ) internal view { - // category is invalid if the liq threshold is not set - require( - categoryId == 0 || eModeCategories[categoryId].liquidationThreshold != 0, - Errors.INCONSISTENT_EMODE_CATEGORY - ); - - //eMode can always be enabled if the user hasn't supplied anything - if (userConfig.isEmpty()) { - return; - } - - // if user is trying to set another category than default we require that - // either the user is not borrowing, or it's borrowing assets of categoryId - if (categoryId != 0) { - unchecked { - for (uint256 i = 0; i < reservesCount; i++) { - if (userConfig.isBorrowing(i)) { - DataTypes.ReserveConfigurationMap memory configuration = reservesData[reservesList[i]] - .configuration; - require( - configuration.getEModeCategory() == categoryId, - Errors.INCONSISTENT_EMODE_CATEGORY - ); - } - } - } - } - } - - /** - * @notice Validates if an asset can be activated as collateral in the following actions: supply, transfer, - * set as collateral, mint unbacked, and liquidate - * @dev This is used to ensure that the constraints for isolated assets are respected by all the actions that - * generate transfers of aTokens - * @param reservesData The state of all the reserves - * @param reservesList The addresses of all the active reserves - * @param userConfig the user configuration - * @param reserveConfig The reserve configuration - * @return True if the asset can be activated as collateral, false otherwise - **/ - function validateUseAsCollateral( - mapping(address => DataTypes.ReserveData) storage reservesData, - mapping(uint256 => address) storage reservesList, - DataTypes.UserConfigurationMap storage userConfig, - DataTypes.ReserveConfigurationMap memory reserveConfig - ) internal view returns (bool) { - if (!userConfig.isUsingAsCollateralAny()) { - return true; - } - (bool isolationModeActive, , ) = userConfig.getIsolationModeState(reservesData, reservesList); - - return (!isolationModeActive && reserveConfig.getDebtCeiling() == 0); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/MathUtils.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/MathUtils.sol deleted file mode 100644 index bd6e083..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/MathUtils.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {WadRayMath} from './WadRayMath.sol'; - -/** - * @title MathUtils library - * @author Aave - * @notice Provides functions to perform linear and compounded interest calculations - */ -library MathUtils { - using WadRayMath for uint256; - - /// @dev Ignoring leap years - uint256 internal constant SECONDS_PER_YEAR = 365 days; - - /** - * @dev Function to calculate the interest accumulated using a linear interest rate formula - * @param rate The interest rate, in ray - * @param lastUpdateTimestamp The timestamp of the last update of the interest - * @return The interest rate linearly accumulated during the timeDelta, in ray - **/ - function calculateLinearInterest(uint256 rate, uint40 lastUpdateTimestamp) - internal - view - returns (uint256) - { - //solium-disable-next-line - uint256 result = rate * (block.timestamp - uint256(lastUpdateTimestamp)); - unchecked { - result = result / SECONDS_PER_YEAR; - } - - return WadRayMath.RAY + result; - } - - /** - * @dev Function to calculate the interest using a compounded interest rate formula - * To avoid expensive exponentiation, the calculation is performed using a binomial approximation: - * - * (1+x)^n = 1+n*x+[n/2*(n-1)]*x^2+[n/6*(n-1)*(n-2)*x^3... - * - * The approximation slightly underpays liquidity providers and undercharges borrowers, with the advantage of great - * gas cost reductions. The whitepaper contains reference to the approximation and a table showing the margin of - * error per different time periods - * - * @param rate The interest rate, in ray - * @param lastUpdateTimestamp The timestamp of the last update of the interest - * @return The interest rate compounded during the timeDelta, in ray - **/ - function calculateCompoundedInterest( - uint256 rate, - uint40 lastUpdateTimestamp, - uint256 currentTimestamp - ) internal pure returns (uint256) { - //solium-disable-next-line - uint256 exp = currentTimestamp - uint256(lastUpdateTimestamp); - - if (exp == 0) { - return WadRayMath.RAY; - } - - uint256 expMinusOne; - uint256 expMinusTwo; - uint256 basePowerTwo; - uint256 basePowerThree; - unchecked { - expMinusOne = exp - 1; - - expMinusTwo = exp > 2 ? exp - 2 : 0; - - basePowerTwo = rate.rayMul(rate) / (SECONDS_PER_YEAR * SECONDS_PER_YEAR); - basePowerThree = basePowerTwo.rayMul(rate) / SECONDS_PER_YEAR; - } - - uint256 secondTerm = exp * expMinusOne * basePowerTwo; - unchecked { - secondTerm /= 2; - } - uint256 thirdTerm = exp * expMinusOne * expMinusTwo * basePowerThree; - unchecked { - thirdTerm /= 6; - } - - return WadRayMath.RAY + (rate * exp) / SECONDS_PER_YEAR + secondTerm + thirdTerm; - } - - /** - * @dev Calculates the compounded interest between the timestamp of the last update and the current block timestamp - * @param rate The interest rate (in ray) - * @param lastUpdateTimestamp The timestamp from which the interest accumulation needs to be calculated - * @return The interest rate compounded between lastUpdateTimestamp and current block timestamp, in ray - **/ - function calculateCompoundedInterest(uint256 rate, uint40 lastUpdateTimestamp) - internal - view - returns (uint256) - { - return calculateCompoundedInterest(rate, lastUpdateTimestamp, block.timestamp); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol deleted file mode 100644 index 5306105..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/PercentageMath.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -/** - * @title PercentageMath library - * @author Aave - * @notice Provides functions to perform percentage calculations - * @dev Percentages are defined by default with 2 decimals of precision (100.00). The precision is indicated by PERCENTAGE_FACTOR - * @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down. - **/ -library PercentageMath { - // Maximum percentage factor (100.00%) - uint256 internal constant PERCENTAGE_FACTOR = 1e4; - - // Half percentage factor (50.00%) - uint256 internal constant HALF_PERCENTAGE_FACTOR = 0.5e4; - - /** - * @notice Executes a percentage multiplication - * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 - * @param value The value of which the percentage needs to be calculated - * @param percentage The percentage of the value to be calculated - * @return result value percentmul percentage - **/ - function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256 result) { - // to avoid overflow, value <= (type(uint256).max - HALF_PERCENTAGE_FACTOR) / percentage - assembly { - if iszero( - or( - iszero(percentage), - iszero(gt(value, div(sub(not(0), HALF_PERCENTAGE_FACTOR), percentage))) - ) - ) { - revert(0, 0) - } - - result := div(add(mul(value, percentage), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR) - } - } - - /** - * @notice Executes a percentage division - * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 - * @param value The value of which the percentage needs to be calculated - * @param percentage The percentage of the value to be calculated - * @return result value percentdiv percentage - **/ - function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256 result) { - // to avoid overflow, value <= (type(uint256).max - halfPercentage) / PERCENTAGE_FACTOR - assembly { - if or( - iszero(percentage), - iszero(iszero(gt(value, div(sub(not(0), div(percentage, 2)), PERCENTAGE_FACTOR)))) - ) { - revert(0, 0) - } - - result := div(add(mul(value, PERCENTAGE_FACTOR), div(percentage, 2)), percentage) - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol deleted file mode 100644 index dbe1a40..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/math/WadRayMath.sol +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -/** - * @title WadRayMath library - * @author Aave - * @notice Provides functions to perform calculations with Wad and Ray units - * @dev Provides mul and div function for wads (decimal numbers with 18 digits of precision) and rays (decimal numbers - * with 27 digits of precision) - * @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down. - **/ -library WadRayMath { - // HALF_WAD and HALF_RAY expressed with extended notation as constant with operations are not supported in Yul assembly - uint256 internal constant WAD = 1e18; - uint256 internal constant HALF_WAD = 0.5e18; - - uint256 internal constant RAY = 1e27; - uint256 internal constant HALF_RAY = 0.5e27; - - uint256 internal constant WAD_RAY_RATIO = 1e9; - - /** - * @dev Multiplies two wad, rounding half up to the nearest wad - * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 - * @param a Wad - * @param b Wad - * @return c = a*b, in wad - **/ - function wadMul(uint256 a, uint256 b) internal pure returns (uint256 c) { - // to avoid overflow, a <= (type(uint256).max - HALF_WAD) / b - assembly { - if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_WAD), b))))) { - revert(0, 0) - } - - c := div(add(mul(a, b), HALF_WAD), WAD) - } - } - - /** - * @dev Divides two wad, rounding half up to the nearest wad - * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 - * @param a Wad - * @param b Wad - * @return c = a/b, in wad - **/ - function wadDiv(uint256 a, uint256 b) internal pure returns (uint256 c) { - // to avoid overflow, a <= (type(uint256).max - halfB) / WAD - assembly { - if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), WAD))))) { - revert(0, 0) - } - - c := div(add(mul(a, WAD), div(b, 2)), b) - } - } - - /** - * @notice Multiplies two ray, rounding half up to the nearest ray - * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 - * @param a Ray - * @param b Ray - * @return c = a raymul b - **/ - function rayMul(uint256 a, uint256 b) internal pure returns (uint256 c) { - // to avoid overflow, a <= (type(uint256).max - HALF_RAY) / b - assembly { - if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_RAY), b))))) { - revert(0, 0) - } - - c := div(add(mul(a, b), HALF_RAY), RAY) - } - } - - /** - * @notice Divides two ray, rounding half up to the nearest ray - * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 - * @param a Ray - * @param b Ray - * @return c = a raydiv b - **/ - function rayDiv(uint256 a, uint256 b) internal pure returns (uint256 c) { - // to avoid overflow, a <= (type(uint256).max - halfB) / RAY - assembly { - if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), RAY))))) { - revert(0, 0) - } - - c := div(add(mul(a, RAY), div(b, 2)), b) - } - } - - /** - * @dev Casts ray down to wad - * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 - * @param a Ray - * @return b = a converted to wad, rounded half up to the nearest wad - **/ - function rayToWad(uint256 a) internal pure returns (uint256 b) { - assembly { - b := div(a, WAD_RAY_RATIO) - let remainder := mod(a, WAD_RAY_RATIO) - if iszero(lt(remainder, div(WAD_RAY_RATIO, 2))) { - b := add(b, 1) - } - } - } - - /** - * @dev Converts wad up to ray - * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328 - * @param a Wad - * @return b = a converted in ray - **/ - function wadToRay(uint256 a) internal pure returns (uint256 b) { - // to avoid overflow, b/WAD_RAY_RATIO == a - assembly { - b := mul(a, WAD_RAY_RATIO) - - if iszero(eq(div(b, WAD_RAY_RATIO), a)) { - revert(0, 0) - } - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol deleted file mode 100644 index 61de06a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/types/ConfiguratorInputTypes.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -library ConfiguratorInputTypes { - struct InitReserveInput { - address aTokenImpl; - address stableDebtTokenImpl; - address variableDebtTokenImpl; - uint8 underlyingAssetDecimals; - address interestRateStrategyAddress; - address underlyingAsset; - address treasury; - address incentivesController; - string aTokenName; - string aTokenSymbol; - string variableDebtTokenName; - string variableDebtTokenSymbol; - string stableDebtTokenName; - string stableDebtTokenSymbol; - bytes params; - } - - struct UpdateATokenInput { - address asset; - address treasury; - address incentivesController; - string name; - string symbol; - address implementation; - bytes params; - } - - struct UpdateDebtTokenInput { - address asset; - address incentivesController; - string name; - string symbol; - address implementation; - bytes params; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol deleted file mode 100644 index 7113a0a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol +++ /dev/null @@ -1,268 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -library DataTypes { - struct ReserveData { - //stores the reserve configuration - ReserveConfigurationMap configuration; - //the liquidity index. Expressed in ray - uint128 liquidityIndex; - //the current supply rate. Expressed in ray - uint128 currentLiquidityRate; - //variable borrow index. Expressed in ray - uint128 variableBorrowIndex; - //the current variable borrow rate. Expressed in ray - uint128 currentVariableBorrowRate; - //the current stable borrow rate. Expressed in ray - uint128 currentStableBorrowRate; - //timestamp of last update - uint40 lastUpdateTimestamp; - //the id of the reserve. Represents the position in the list of the active reserves - uint16 id; - //aToken address - address aTokenAddress; - //stableDebtToken address - address stableDebtTokenAddress; - //variableDebtToken address - address variableDebtTokenAddress; - //address of the interest rate strategy - address interestRateStrategyAddress; - //the current treasury balance, scaled - uint128 accruedToTreasury; - //the outstanding unbacked aTokens minted through the bridging feature - uint128 unbacked; - //the outstanding debt borrowed against this asset in isolation mode - uint128 isolationModeTotalDebt; - } - - struct ReserveConfigurationMap { - //bit 0-15: LTV - //bit 16-31: Liq. threshold - //bit 32-47: Liq. bonus - //bit 48-55: Decimals - //bit 56: reserve is active - //bit 57: reserve is frozen - //bit 58: borrowing is enabled - //bit 59: stable rate borrowing enabled - //bit 60: asset is paused - //bit 61: borrowing in isolation mode is enabled - //bit 62-63: reserved - //bit 64-79: reserve factor - //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap - //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap - //bit 152-167 liquidation protocol fee - //bit 168-175 eMode category - //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled - //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals - //bit 252-255 unused - - uint256 data; - } - - struct UserConfigurationMap { - /** - * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset. - * The first bit indicates if an asset is used as collateral by the user, the second whether an - * asset is borrowed by the user. - */ - uint256 data; - } - - struct EModeCategory { - // each eMode category has a custom ltv and liquidation threshold - uint16 ltv; - uint16 liquidationThreshold; - uint16 liquidationBonus; - // each eMode category may or may not have a custom oracle to override the individual assets price oracles - address priceSource; - string label; - } - - enum InterestRateMode { - NONE, - STABLE, - VARIABLE - } - - struct ReserveCache { - uint256 currScaledVariableDebt; - uint256 nextScaledVariableDebt; - uint256 currPrincipalStableDebt; - uint256 currAvgStableBorrowRate; - uint256 currTotalStableDebt; - uint256 nextAvgStableBorrowRate; - uint256 nextTotalStableDebt; - uint256 currLiquidityIndex; - uint256 nextLiquidityIndex; - uint256 currVariableBorrowIndex; - uint256 nextVariableBorrowIndex; - uint256 currLiquidityRate; - uint256 currVariableBorrowRate; - uint256 reserveFactor; - ReserveConfigurationMap reserveConfiguration; - address aTokenAddress; - address stableDebtTokenAddress; - address variableDebtTokenAddress; - uint40 reserveLastUpdateTimestamp; - uint40 stableDebtLastUpdateTimestamp; - } - - struct ExecuteLiquidationCallParams { - uint256 reservesCount; - uint256 debtToCover; - address collateralAsset; - address debtAsset; - address user; - bool receiveAToken; - address priceOracle; - uint8 userEModeCategory; - address priceOracleSentinel; - } - - struct ExecuteSupplyParams { - address asset; - uint256 amount; - address onBehalfOf; - uint16 referralCode; - } - - struct ExecuteBorrowParams { - address asset; - address user; - address onBehalfOf; - uint256 amount; - InterestRateMode interestRateMode; - uint16 referralCode; - bool releaseUnderlying; - uint256 maxStableRateBorrowSizePercent; - uint256 reservesCount; - address oracle; - uint8 userEModeCategory; - address priceOracleSentinel; - } - - struct ExecuteRepayParams { - address asset; - uint256 amount; - InterestRateMode interestRateMode; - address onBehalfOf; - bool useATokens; - } - - struct ExecuteWithdrawParams { - address asset; - uint256 amount; - address to; - uint256 reservesCount; - address oracle; - uint8 userEModeCategory; - } - - struct ExecuteSetUserEModeParams { - uint256 reservesCount; - address oracle; - uint8 categoryId; - } - - struct FinalizeTransferParams { - address asset; - address from; - address to; - uint256 amount; - uint256 balanceFromBefore; - uint256 balanceToBefore; - uint256 reservesCount; - address oracle; - uint8 fromEModeCategory; - } - - struct FlashloanParams { - address receiverAddress; - address[] assets; - uint256[] amounts; - uint256[] interestRateModes; - address onBehalfOf; - bytes params; - uint16 referralCode; - uint256 flashLoanPremiumToProtocol; - uint256 flashLoanPremiumTotal; - uint256 maxStableRateBorrowSizePercent; - uint256 reservesCount; - address addressesProvider; - uint8 userEModeCategory; - bool isAuthorizedFlashBorrower; - } - - struct FlashloanSimpleParams { - address receiverAddress; - address asset; - uint256 amount; - bytes params; - uint16 referralCode; - uint256 flashLoanPremiumToProtocol; - uint256 flashLoanPremiumTotal; - } - - struct FlashLoanRepaymentParams { - uint256 amount; - uint256 totalPremium; - uint256 flashLoanPremiumToProtocol; - address asset; - address receiverAddress; - uint16 referralCode; - } - - struct CalculateUserAccountDataParams { - UserConfigurationMap userConfig; - uint256 reservesCount; - address user; - address oracle; - uint8 userEModeCategory; - } - - struct ValidateBorrowParams { - ReserveCache reserveCache; - UserConfigurationMap userConfig; - address asset; - address userAddress; - uint256 amount; - InterestRateMode interestRateMode; - uint256 maxStableLoanPercent; - uint256 reservesCount; - address oracle; - uint8 userEModeCategory; - address priceOracleSentinel; - bool isolationModeActive; - address isolationModeCollateralAddress; - uint256 isolationModeDebtCeiling; - } - - struct ValidateLiquidationCallParams { - ReserveCache debtReserveCache; - uint256 totalDebt; - uint256 healthFactor; - address priceOracleSentinel; - } - - struct CalculateInterestRatesParams { - uint256 unbacked; - uint256 liquidityAdded; - uint256 liquidityTaken; - uint256 totalStableDebt; - uint256 totalVariableDebt; - uint256 averageStableBorrowRate; - uint256 reserveFactor; - address reserve; - address aToken; - } - - struct InitReserveParams { - address asset; - address aTokenAddress; - address stableDebtAddress; - address variableDebtAddress; - address interestRateStrategyAddress; - uint16 reservesCount; - uint16 maxNumberReserves; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol deleted file mode 100644 index 7d082a9..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/DefaultReserveInterestRateStrategy.sol +++ /dev/null @@ -1,299 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {WadRayMath} from '../libraries/math/WadRayMath.sol'; -import {PercentageMath} from '../libraries/math/PercentageMath.sol'; -import {DataTypes} from '../libraries/types/DataTypes.sol'; -import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; - -/** - * @title DefaultReserveInterestRateStrategy contract - * @author Aave - * @notice Implements the calculation of the interest rates depending on the reserve state - * @dev The model of interest rate is based on 2 slopes, one before the `OPTIMAL_USAGE_RATIO` - * point of usage and another from that one to 100%. - * - An instance of this same contract, can't be used across different Aave markets, due to the caching - * of the PoolAddressesProvider - **/ -contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { - using WadRayMath for uint256; - using PercentageMath for uint256; - - /** - * @dev This constant represents the usage ratio at which the pool aims to obtain most competitive borrow rates. - * Expressed in ray - **/ - uint256 public immutable OPTIMAL_USAGE_RATIO; - - /** - * @dev This constant represents the optimal stable debt to total debt ratio of the reserve. - * Expressed in ray - */ - uint256 public immutable OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO; - - /** - * @dev This constant represents the excess usage ratio above the optimal. It's always equal to - * 1-optimal usage ratio. Added as a constant here for gas optimizations. - * Expressed in ray - **/ - uint256 public immutable MAX_EXCESS_USAGE_RATIO; - - /** - * @dev This constant represents the excess stable debt ratio above the optimal. It's always equal to - * 1-optimal stable to total debt ratio. Added as a constant here for gas optimizations. - * Expressed in ray - **/ - uint256 public immutable MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO; - - IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; - - // Base variable borrow rate when usage rate = 0. Expressed in ray - uint256 internal immutable _baseVariableBorrowRate; - - // Slope of the variable interest curve when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO. Expressed in ray - uint256 internal immutable _variableRateSlope1; - - // Slope of the variable interest curve when usage ratio > OPTIMAL_USAGE_RATIO. Expressed in ray - uint256 internal immutable _variableRateSlope2; - - // Slope of the stable interest curve when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO. Expressed in ray - uint256 internal immutable _stableRateSlope1; - - // Slope of the stable interest curve when usage ratio > OPTIMAL_USAGE_RATIO. Expressed in ray - uint256 internal immutable _stableRateSlope2; - - // Premium on top of `_variableRateSlope1` for base stable borrowing rate - uint256 internal immutable _baseStableRateOffset; - - // Additional premium applied to stable rate when stable debt surpass `OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO` - uint256 internal immutable _stableRateExcessOffset; - - /** - * @dev Constructor. - * @param provider The address of the PoolAddressesProvider contract - * @param optimalUsageRatio The optimal usage ratio - * @param baseVariableBorrowRate The base variable borrow rate - * @param variableRateSlope1 The variable rate slope below optimal usage ratio - * @param variableRateSlope2 The variable rate slope above optimal usage ratio - * @param stableRateSlope1 The stable rate slope below optimal usage ratio - * @param stableRateSlope2 The stable rate slope above optimal usage ratio - * @param baseStableRateOffset The premium on top of variable rate for base stable borrowing rate - * @param stableRateExcessOffset The premium on top of stable rate when there stable debt surpass the threshold - * @param optimalStableToTotalDebtRatio The optimal stable debt to total debt ratio of the reserve - */ - constructor( - IPoolAddressesProvider provider, - uint256 optimalUsageRatio, - uint256 baseVariableBorrowRate, - uint256 variableRateSlope1, - uint256 variableRateSlope2, - uint256 stableRateSlope1, - uint256 stableRateSlope2, - uint256 baseStableRateOffset, - uint256 stableRateExcessOffset, - uint256 optimalStableToTotalDebtRatio - ) { - require(WadRayMath.RAY >= optimalUsageRatio, Errors.INVALID_OPTIMAL_USAGE_RATIO); - require( - WadRayMath.RAY >= optimalStableToTotalDebtRatio, - Errors.INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO - ); - OPTIMAL_USAGE_RATIO = optimalUsageRatio; - MAX_EXCESS_USAGE_RATIO = WadRayMath.RAY - optimalUsageRatio; - OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = optimalStableToTotalDebtRatio; - MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO = WadRayMath.RAY - optimalStableToTotalDebtRatio; - ADDRESSES_PROVIDER = provider; - _baseVariableBorrowRate = baseVariableBorrowRate; - _variableRateSlope1 = variableRateSlope1; - _variableRateSlope2 = variableRateSlope2; - _stableRateSlope1 = stableRateSlope1; - _stableRateSlope2 = stableRateSlope2; - _baseStableRateOffset = baseStableRateOffset; - _stableRateExcessOffset = stableRateExcessOffset; - } - - /** - * @notice Returns the variable rate slope below optimal usage ratio - * @dev Its the variable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO - * @return The variable rate slope - **/ - function getVariableRateSlope1() external view returns (uint256) { - return _variableRateSlope1; - } - - /** - * @notice Returns the variable rate slope above optimal usage ratio - * @dev Its the variable rate when usage ratio > OPTIMAL_USAGE_RATIO - * @return The variable rate slope - **/ - function getVariableRateSlope2() external view returns (uint256) { - return _variableRateSlope2; - } - - /** - * @notice Returns the stable rate slope below optimal usage ratio - * @dev Its the stable rate when usage ratio > 0 and <= OPTIMAL_USAGE_RATIO - * @return The stable rate slope - **/ - function getStableRateSlope1() external view returns (uint256) { - return _stableRateSlope1; - } - - /** - * @notice Returns the stable rate slope above optimal usage ratio - * @dev Its the variable rate when usage ratio > OPTIMAL_USAGE_RATIO - * @return The stable rate slope - **/ - function getStableRateSlope2() external view returns (uint256) { - return _stableRateSlope2; - } - - /** - * @notice Returns the stable rate excess offset - * @dev An additional premium applied to the stable when stable debt > OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO - * @return The stable rate excess offset - */ - function getStableRateExcessOffset() external view returns (uint256) { - return _stableRateExcessOffset; - } - - /** - * @notice Returns the base stable borrow rate - * @return The base stable borrow rate - **/ - function getBaseStableBorrowRate() public view returns (uint256) { - return _variableRateSlope1 + _baseStableRateOffset; - } - - /// @inheritdoc IReserveInterestRateStrategy - function getBaseVariableBorrowRate() external view override returns (uint256) { - return _baseVariableBorrowRate; - } - - /// @inheritdoc IReserveInterestRateStrategy - function getMaxVariableBorrowRate() external view override returns (uint256) { - return _baseVariableBorrowRate + _variableRateSlope1 + _variableRateSlope2; - } - - struct CalcInterestRatesLocalVars { - uint256 availableLiquidity; - uint256 totalDebt; - uint256 currentVariableBorrowRate; - uint256 currentStableBorrowRate; - uint256 currentLiquidityRate; - uint256 borrowUsageRatio; - uint256 supplyUsageRatio; - uint256 stableToTotalDebtRatio; - uint256 availableLiquidityPlusDebt; - } - - /// @inheritdoc IReserveInterestRateStrategy - function calculateInterestRates(DataTypes.CalculateInterestRatesParams calldata params) - external - view - override - returns ( - uint256, - uint256, - uint256 - ) - { - CalcInterestRatesLocalVars memory vars; - - vars.totalDebt = params.totalStableDebt + params.totalVariableDebt; - - vars.currentLiquidityRate = 0; - vars.currentVariableBorrowRate = _baseVariableBorrowRate; - vars.currentStableBorrowRate = getBaseStableBorrowRate(); - - if (vars.totalDebt != 0) { - vars.stableToTotalDebtRatio = params.totalStableDebt.rayDiv(vars.totalDebt); - vars.availableLiquidity = - IERC20(params.reserve).balanceOf(params.aToken) + - params.liquidityAdded - - params.liquidityTaken; - - vars.availableLiquidityPlusDebt = vars.availableLiquidity + vars.totalDebt; - vars.borrowUsageRatio = vars.totalDebt.rayDiv(vars.availableLiquidityPlusDebt); - vars.supplyUsageRatio = vars.totalDebt.rayDiv( - vars.availableLiquidityPlusDebt + params.unbacked - ); - } - - if (vars.borrowUsageRatio > OPTIMAL_USAGE_RATIO) { - uint256 excessBorrowUsageRatio = (vars.borrowUsageRatio - OPTIMAL_USAGE_RATIO).rayDiv( - MAX_EXCESS_USAGE_RATIO - ); - - vars.currentStableBorrowRate += - _stableRateSlope1 + - _stableRateSlope2.rayMul(excessBorrowUsageRatio); - - vars.currentVariableBorrowRate += - _variableRateSlope1 + - _variableRateSlope2.rayMul(excessBorrowUsageRatio); - } else { - vars.currentStableBorrowRate += _stableRateSlope1.rayMul(vars.borrowUsageRatio).rayDiv( - OPTIMAL_USAGE_RATIO - ); - - vars.currentVariableBorrowRate += _variableRateSlope1.rayMul(vars.borrowUsageRatio).rayDiv( - OPTIMAL_USAGE_RATIO - ); - } - - if (vars.stableToTotalDebtRatio > OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO) { - uint256 excessStableDebtRatio = (vars.stableToTotalDebtRatio - - OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO).rayDiv(MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO); - vars.currentStableBorrowRate += _stableRateExcessOffset.rayMul(excessStableDebtRatio); - } - - vars.currentLiquidityRate = _getOverallBorrowRate( - params.totalStableDebt, - params.totalVariableDebt, - vars.currentVariableBorrowRate, - params.averageStableBorrowRate - ).rayMul(vars.supplyUsageRatio).percentMul( - PercentageMath.PERCENTAGE_FACTOR - params.reserveFactor - ); - - return ( - vars.currentLiquidityRate, - vars.currentStableBorrowRate, - vars.currentVariableBorrowRate - ); - } - - /** - * @dev Calculates the overall borrow rate as the weighted average between the total variable debt and total stable - * debt - * @param totalStableDebt The total borrowed from the reserve at a stable rate - * @param totalVariableDebt The total borrowed from the reserve at a variable rate - * @param currentVariableBorrowRate The current variable borrow rate of the reserve - * @param currentAverageStableBorrowRate The current weighted average of all the stable rate loans - * @return The weighted averaged borrow rate - **/ - function _getOverallBorrowRate( - uint256 totalStableDebt, - uint256 totalVariableDebt, - uint256 currentVariableBorrowRate, - uint256 currentAverageStableBorrowRate - ) internal pure returns (uint256) { - uint256 totalDebt = totalStableDebt + totalVariableDebt; - - if (totalDebt == 0) return 0; - - uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate); - - uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate); - - uint256 overallBorrowRate = (weightedVariableRate + weightedStableRate).rayDiv( - totalDebt.wadToRay() - ); - - return overallBorrowRate; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/L2Pool.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/L2Pool.sol deleted file mode 100644 index 0e2b5a1..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/L2Pool.sol +++ /dev/null @@ -1,135 +0,0 @@ -pragma solidity ^0.8.10; - -import {Pool} from './Pool.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IL2Pool} from '../../interfaces/IL2Pool.sol'; -import {CalldataLogic} from '../libraries/logic/CalldataLogic.sol'; - -/** - * @title L2Pool - * @author Aave - * @notice Calldata optimized extension of the Pool contract allowing users to pass compact calldata representation - * to reduce transaction costs on rollups. - */ -contract L2Pool is Pool, IL2Pool { - /** - * @dev Constructor. - * @param provider The address of the PoolAddressesProvider contract - */ - constructor(IPoolAddressesProvider provider) Pool(provider) { - // Intentionally left blank - } - - /// @inheritdoc IL2Pool - function supply(bytes32 args) external override { - (address asset, uint256 amount, uint16 referralCode) = CalldataLogic.decodeSupplyParams( - _reservesList, - args - ); - - supply(asset, amount, msg.sender, referralCode); - } - - /// @inheritdoc IL2Pool - function supplyWithPermit( - bytes32 args, - bytes32 r, - bytes32 s - ) external override { - (address asset, uint256 amount, uint16 referralCode, uint256 deadline, uint8 v) = CalldataLogic - .decodeSupplyWithPermitParams(_reservesList, args); - - supplyWithPermit(asset, amount, msg.sender, referralCode, deadline, v, r, s); - } - - /// @inheritdoc IL2Pool - function withdraw(bytes32 args) external override { - (address asset, uint256 amount) = CalldataLogic.decodeWithdrawParams(_reservesList, args); - - withdraw(asset, amount, msg.sender); - } - - /// @inheritdoc IL2Pool - function borrow(bytes32 args) external override { - (address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode) = CalldataLogic - .decodeBorrowParams(_reservesList, args); - - borrow(asset, amount, interestRateMode, referralCode, msg.sender); - } - - /// @inheritdoc IL2Pool - function repay(bytes32 args) external override returns (uint256) { - (address asset, uint256 amount, uint256 interestRateMode) = CalldataLogic.decodeRepayParams( - _reservesList, - args - ); - - return repay(asset, amount, interestRateMode, msg.sender); - } - - /// @inheritdoc IL2Pool - function repayWithPermit( - bytes32 args, - bytes32 r, - bytes32 s - ) external override returns (uint256) { - ( - address asset, - uint256 amount, - uint256 interestRateMode, - uint256 deadline, - uint8 v - ) = CalldataLogic.decodeRepayWithPermitParams(_reservesList, args); - - return repayWithPermit(asset, amount, interestRateMode, msg.sender, deadline, v, r, s); - } - - /// @inheritdoc IL2Pool - function repayWithATokens(bytes32 args) external override returns (uint256) { - (address asset, uint256 amount, uint256 interestRateMode) = CalldataLogic.decodeRepayParams( - _reservesList, - args - ); - - return repayWithATokens(asset, amount, interestRateMode); - } - - /// @inheritdoc IL2Pool - function swapBorrowRateMode(bytes32 args) external override { - (address asset, uint256 interestRateMode) = CalldataLogic.decodeSwapBorrowRateModeParams( - _reservesList, - args - ); - swapBorrowRateMode(asset, interestRateMode); - } - - /// @inheritdoc IL2Pool - function rebalanceStableBorrowRate(bytes32 args) external override { - (address asset, address user) = CalldataLogic.decodeRebalanceStableBorrowRateParams( - _reservesList, - args - ); - rebalanceStableBorrowRate(asset, user); - } - - /// @inheritdoc IL2Pool - function setUserUseReserveAsCollateral(bytes32 args) external override { - (address asset, bool useAsCollateral) = CalldataLogic.decodeSetUserUseReserveAsCollateralParams( - _reservesList, - args - ); - setUserUseReserveAsCollateral(asset, useAsCollateral); - } - - /// @inheritdoc IL2Pool - function liquidationCall(bytes32 args1, bytes32 args2) external override { - ( - address collateralAsset, - address debtAsset, - address user, - uint256 debtToCover, - bool receiveAToken - ) = CalldataLogic.decodeLiquidationCallParams(_reservesList, args1, args2); - liquidationCall(collateralAsset, debtAsset, user, debtToCover, receiveAToken); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/Pool.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/Pool.sol deleted file mode 100644 index b89b3b6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/Pool.sol +++ /dev/null @@ -1,773 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; -import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; -import {PoolLogic} from '../libraries/logic/PoolLogic.sol'; -import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; -import {EModeLogic} from '../libraries/logic/EModeLogic.sol'; -import {SupplyLogic} from '../libraries/logic/SupplyLogic.sol'; -import {FlashLoanLogic} from '../libraries/logic/FlashLoanLogic.sol'; -import {BorrowLogic} from '../libraries/logic/BorrowLogic.sol'; -import {LiquidationLogic} from '../libraries/logic/LiquidationLogic.sol'; -import {DataTypes} from '../libraries/types/DataTypes.sol'; -import {BridgeLogic} from '../libraries/logic/BridgeLogic.sol'; -import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../interfaces/IPool.sol'; -import {IACLManager} from '../../interfaces/IACLManager.sol'; -import {PoolStorage} from './PoolStorage.sol'; - -/** - * @title Pool contract - * @author Aave - * @notice Main point of interaction with an Aave protocol's market - * - Users can: - * # Supply - * # Withdraw - * # Borrow - * # Repay - * # Swap their loans between variable and stable rate - * # Enable/disable their supplied assets as collateral rebalance stable rate borrow positions - * # Liquidate positions - * # Execute Flash Loans - * @dev To be covered by a proxy contract, owned by the PoolAddressesProvider of the specific market - * @dev All admin functions are callable by the PoolConfigurator contract defined also in the - * PoolAddressesProvider - **/ -contract Pool is VersionedInitializable, PoolStorage, IPool { - using ReserveLogic for DataTypes.ReserveData; - - uint256 public constant POOL_REVISION = 0x1; - IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; - - /** - * @dev Only pool configurator can call functions marked by this modifier. - **/ - modifier onlyPoolConfigurator() { - _onlyPoolConfigurator(); - _; - } - - /** - * @dev Only pool admin can call functions marked by this modifier. - **/ - modifier onlyPoolAdmin() { - _onlyPoolAdmin(); - _; - } - - /** - * @dev Only bridge can call functions marked by this modifier. - **/ - modifier onlyBridge() { - _onlyBridge(); - _; - } - - function _onlyPoolConfigurator() internal view virtual { - require( - ADDRESSES_PROVIDER.getPoolConfigurator() == msg.sender, - Errors.CALLER_NOT_POOL_CONFIGURATOR - ); - } - - function _onlyPoolAdmin() internal view virtual { - require( - IACLManager(ADDRESSES_PROVIDER.getACLManager()).isPoolAdmin(msg.sender), - Errors.CALLER_NOT_POOL_ADMIN - ); - } - - function _onlyBridge() internal view virtual { - require( - IACLManager(ADDRESSES_PROVIDER.getACLManager()).isBridge(msg.sender), - Errors.CALLER_NOT_BRIDGE - ); - } - - function getRevision() internal pure virtual override returns (uint256) { - return POOL_REVISION; - } - - /** - * @dev Constructor. - * @param provider The address of the PoolAddressesProvider contract - */ - constructor(IPoolAddressesProvider provider) { - ADDRESSES_PROVIDER = provider; - } - - /** - * @notice Initializes the Pool. - * @dev Function is invoked by the proxy contract when the Pool contract is added to the - * PoolAddressesProvider of the market. - * @dev Caching the address of the PoolAddressesProvider in order to reduce gas consumption on subsequent operations - * @param provider The address of the PoolAddressesProvider - **/ - function initialize(IPoolAddressesProvider provider) external virtual initializer { - require(provider == ADDRESSES_PROVIDER, Errors.INVALID_ADDRESSES_PROVIDER); - _maxStableRateBorrowSizePercent = 0.25e4; - _flashLoanPremiumTotal = 0.0009e4; - _flashLoanPremiumToProtocol = 0; - } - - /// @inheritdoc IPool - function mintUnbacked( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external virtual override onlyBridge { - BridgeLogic.executeMintUnbacked( - _reserves, - _reservesList, - _usersConfig[onBehalfOf], - asset, - amount, - onBehalfOf, - referralCode - ); - } - - /// @inheritdoc IPool - function backUnbacked( - address asset, - uint256 amount, - uint256 fee - ) external virtual override onlyBridge { - BridgeLogic.executeBackUnbacked(_reserves[asset], asset, amount, fee, _bridgeProtocolFee); - } - - /// @inheritdoc IPool - function supply( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) public virtual override { - SupplyLogic.executeSupply( - _reserves, - _reservesList, - _usersConfig[onBehalfOf], - DataTypes.ExecuteSupplyParams({ - asset: asset, - amount: amount, - onBehalfOf: onBehalfOf, - referralCode: referralCode - }) - ); - } - - /// @inheritdoc IPool - function supplyWithPermit( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) public virtual override { - IERC20WithPermit(asset).permit( - msg.sender, - address(this), - amount, - deadline, - permitV, - permitR, - permitS - ); - SupplyLogic.executeSupply( - _reserves, - _reservesList, - _usersConfig[onBehalfOf], - DataTypes.ExecuteSupplyParams({ - asset: asset, - amount: amount, - onBehalfOf: onBehalfOf, - referralCode: referralCode - }) - ); - } - - /// @inheritdoc IPool - function withdraw( - address asset, - uint256 amount, - address to - ) public virtual override returns (uint256) { - return - SupplyLogic.executeWithdraw( - _reserves, - _reservesList, - _eModeCategories, - _usersConfig[msg.sender], - DataTypes.ExecuteWithdrawParams({ - asset: asset, - amount: amount, - to: to, - reservesCount: _reservesCount, - oracle: ADDRESSES_PROVIDER.getPriceOracle(), - userEModeCategory: _usersEModeCategory[msg.sender] - }) - ); - } - - /// @inheritdoc IPool - function borrow( - address asset, - uint256 amount, - uint256 interestRateMode, - uint16 referralCode, - address onBehalfOf - ) public virtual override { - BorrowLogic.executeBorrow( - _reserves, - _reservesList, - _eModeCategories, - _usersConfig[onBehalfOf], - DataTypes.ExecuteBorrowParams({ - asset: asset, - user: msg.sender, - onBehalfOf: onBehalfOf, - amount: amount, - interestRateMode: DataTypes.InterestRateMode(interestRateMode), - referralCode: referralCode, - releaseUnderlying: true, - maxStableRateBorrowSizePercent: _maxStableRateBorrowSizePercent, - reservesCount: _reservesCount, - oracle: ADDRESSES_PROVIDER.getPriceOracle(), - userEModeCategory: _usersEModeCategory[onBehalfOf], - priceOracleSentinel: ADDRESSES_PROVIDER.getPriceOracleSentinel() - }) - ); - } - - /// @inheritdoc IPool - function repay( - address asset, - uint256 amount, - uint256 interestRateMode, - address onBehalfOf - ) public virtual override returns (uint256) { - return - BorrowLogic.executeRepay( - _reserves, - _reservesList, - _usersConfig[onBehalfOf], - DataTypes.ExecuteRepayParams({ - asset: asset, - amount: amount, - interestRateMode: DataTypes.InterestRateMode(interestRateMode), - onBehalfOf: onBehalfOf, - useATokens: false - }) - ); - } - - /// @inheritdoc IPool - function repayWithPermit( - address asset, - uint256 amount, - uint256 interestRateMode, - address onBehalfOf, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) public virtual override returns (uint256) { - { - IERC20WithPermit(asset).permit( - msg.sender, - address(this), - amount, - deadline, - permitV, - permitR, - permitS - ); - } - { - DataTypes.ExecuteRepayParams memory params = DataTypes.ExecuteRepayParams({ - asset: asset, - amount: amount, - interestRateMode: DataTypes.InterestRateMode(interestRateMode), - onBehalfOf: onBehalfOf, - useATokens: false - }); - return BorrowLogic.executeRepay(_reserves, _reservesList, _usersConfig[onBehalfOf], params); - } - } - - /// @inheritdoc IPool - function repayWithATokens( - address asset, - uint256 amount, - uint256 interestRateMode - ) public virtual override returns (uint256) { - return - BorrowLogic.executeRepay( - _reserves, - _reservesList, - _usersConfig[msg.sender], - DataTypes.ExecuteRepayParams({ - asset: asset, - amount: amount, - interestRateMode: DataTypes.InterestRateMode(interestRateMode), - onBehalfOf: msg.sender, - useATokens: true - }) - ); - } - - /// @inheritdoc IPool - function swapBorrowRateMode(address asset, uint256 interestRateMode) public virtual override { - BorrowLogic.executeSwapBorrowRateMode( - _reserves[asset], - _usersConfig[msg.sender], - asset, - DataTypes.InterestRateMode(interestRateMode) - ); - } - - /// @inheritdoc IPool - function rebalanceStableBorrowRate(address asset, address user) public virtual override { - BorrowLogic.executeRebalanceStableBorrowRate(_reserves[asset], asset, user); - } - - /// @inheritdoc IPool - function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) - public - virtual - override - { - SupplyLogic.executeUseReserveAsCollateral( - _reserves, - _reservesList, - _eModeCategories, - _usersConfig[msg.sender], - asset, - useAsCollateral, - _reservesCount, - ADDRESSES_PROVIDER.getPriceOracle(), - _usersEModeCategory[msg.sender] - ); - } - - /// @inheritdoc IPool - function liquidationCall( - address collateralAsset, - address debtAsset, - address user, - uint256 debtToCover, - bool receiveAToken - ) public virtual override { - LiquidationLogic.executeLiquidationCall( - _reserves, - _reservesList, - _usersConfig, - _eModeCategories, - DataTypes.ExecuteLiquidationCallParams({ - reservesCount: _reservesCount, - debtToCover: debtToCover, - collateralAsset: collateralAsset, - debtAsset: debtAsset, - user: user, - receiveAToken: receiveAToken, - priceOracle: ADDRESSES_PROVIDER.getPriceOracle(), - userEModeCategory: _usersEModeCategory[user], - priceOracleSentinel: ADDRESSES_PROVIDER.getPriceOracleSentinel() - }) - ); - } - - /// @inheritdoc IPool - function flashLoan( - address receiverAddress, - address[] calldata assets, - uint256[] calldata amounts, - uint256[] calldata interestRateModes, - address onBehalfOf, - bytes calldata params, - uint16 referralCode - ) public virtual override { - DataTypes.FlashloanParams memory flashParams = DataTypes.FlashloanParams({ - receiverAddress: receiverAddress, - assets: assets, - amounts: amounts, - interestRateModes: interestRateModes, - onBehalfOf: onBehalfOf, - params: params, - referralCode: referralCode, - flashLoanPremiumToProtocol: _flashLoanPremiumToProtocol, - flashLoanPremiumTotal: _flashLoanPremiumTotal, - maxStableRateBorrowSizePercent: _maxStableRateBorrowSizePercent, - reservesCount: _reservesCount, - addressesProvider: address(ADDRESSES_PROVIDER), - userEModeCategory: _usersEModeCategory[onBehalfOf], - isAuthorizedFlashBorrower: IACLManager(ADDRESSES_PROVIDER.getACLManager()).isFlashBorrower( - msg.sender - ) - }); - - FlashLoanLogic.executeFlashLoan( - _reserves, - _reservesList, - _eModeCategories, - _usersConfig[onBehalfOf], - flashParams - ); - } - - /// @inheritdoc IPool - function flashLoanSimple( - address receiverAddress, - address asset, - uint256 amount, - bytes calldata params, - uint16 referralCode - ) public virtual override { - DataTypes.FlashloanSimpleParams memory flashParams = DataTypes.FlashloanSimpleParams({ - receiverAddress: receiverAddress, - asset: asset, - amount: amount, - params: params, - referralCode: referralCode, - flashLoanPremiumToProtocol: _flashLoanPremiumToProtocol, - flashLoanPremiumTotal: _flashLoanPremiumTotal - }); - FlashLoanLogic.executeFlashLoanSimple(_reserves[asset], flashParams); - } - - /// @inheritdoc IPool - function mintToTreasury(address[] calldata assets) external virtual override { - PoolLogic.executeMintToTreasury(_reserves, assets); - } - - /// @inheritdoc IPool - function getReserveData(address asset) - external - view - virtual - override - returns (DataTypes.ReserveData memory) - { - return _reserves[asset]; - } - - /// @inheritdoc IPool - function getUserAccountData(address user) - external - view - virtual - override - returns ( - uint256 totalCollateralBase, - uint256 totalDebtBase, - uint256 availableBorrowsBase, - uint256 currentLiquidationThreshold, - uint256 ltv, - uint256 healthFactor - ) - { - return - PoolLogic.executeGetUserAccountData( - _reserves, - _reservesList, - _eModeCategories, - DataTypes.CalculateUserAccountDataParams({ - userConfig: _usersConfig[user], - reservesCount: _reservesCount, - user: user, - oracle: ADDRESSES_PROVIDER.getPriceOracle(), - userEModeCategory: _usersEModeCategory[user] - }) - ); - } - - /// @inheritdoc IPool - function getConfiguration(address asset) - external - view - virtual - override - returns (DataTypes.ReserveConfigurationMap memory) - { - return _reserves[asset].configuration; - } - - /// @inheritdoc IPool - function getUserConfiguration(address user) - external - view - virtual - override - returns (DataTypes.UserConfigurationMap memory) - { - return _usersConfig[user]; - } - - /// @inheritdoc IPool - function getReserveNormalizedIncome(address asset) - external - view - virtual - override - returns (uint256) - { - return _reserves[asset].getNormalizedIncome(); - } - - /// @inheritdoc IPool - function getReserveNormalizedVariableDebt(address asset) - external - view - virtual - override - returns (uint256) - { - return _reserves[asset].getNormalizedDebt(); - } - - /// @inheritdoc IPool - function getReservesList() external view virtual override returns (address[] memory) { - uint256 reservesListCount = _reservesCount; - uint256 droppedReservesCount = 0; - address[] memory reservesList = new address[](reservesListCount); - - for (uint256 i = 0; i < reservesListCount; i++) { - if (_reservesList[i] != address(0)) { - reservesList[i - droppedReservesCount] = _reservesList[i]; - } else { - droppedReservesCount++; - } - } - - // Reduces the length of the reserves array by `droppedReservesCount` - assembly { - mstore(reservesList, sub(reservesListCount, droppedReservesCount)) - } - return reservesList; - } - - /// @inheritdoc IPool - function getReserveAddressById(uint16 id) external view returns (address) { - return _reservesList[id]; - } - - /// @inheritdoc IPool - function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() public view virtual override returns (uint256) { - return _maxStableRateBorrowSizePercent; - } - - /// @inheritdoc IPool - function BRIDGE_PROTOCOL_FEE() public view virtual override returns (uint256) { - return _bridgeProtocolFee; - } - - /// @inheritdoc IPool - function FLASHLOAN_PREMIUM_TOTAL() public view virtual override returns (uint128) { - return _flashLoanPremiumTotal; - } - - /// @inheritdoc IPool - function FLASHLOAN_PREMIUM_TO_PROTOCOL() public view virtual override returns (uint128) { - return _flashLoanPremiumToProtocol; - } - - /// @inheritdoc IPool - function MAX_NUMBER_RESERVES() public view virtual override returns (uint16) { - return ReserveConfiguration.MAX_RESERVES_COUNT; - } - - /// @inheritdoc IPool - function finalizeTransfer( - address asset, - address from, - address to, - uint256 amount, - uint256 balanceFromBefore, - uint256 balanceToBefore - ) external virtual override { - require(msg.sender == _reserves[asset].aTokenAddress, Errors.CALLER_NOT_ATOKEN); - SupplyLogic.executeFinalizeTransfer( - _reserves, - _reservesList, - _eModeCategories, - _usersConfig, - DataTypes.FinalizeTransferParams({ - asset: asset, - from: from, - to: to, - amount: amount, - balanceFromBefore: balanceFromBefore, - balanceToBefore: balanceToBefore, - reservesCount: _reservesCount, - oracle: ADDRESSES_PROVIDER.getPriceOracle(), - fromEModeCategory: _usersEModeCategory[from] - }) - ); - } - - /// @inheritdoc IPool - function initReserve( - address asset, - address aTokenAddress, - address stableDebtAddress, - address variableDebtAddress, - address interestRateStrategyAddress - ) external virtual override onlyPoolConfigurator { - if ( - PoolLogic.executeInitReserve( - _reserves, - _reservesList, - DataTypes.InitReserveParams({ - asset: asset, - aTokenAddress: aTokenAddress, - stableDebtAddress: stableDebtAddress, - variableDebtAddress: variableDebtAddress, - interestRateStrategyAddress: interestRateStrategyAddress, - reservesCount: _reservesCount, - maxNumberReserves: MAX_NUMBER_RESERVES() - }) - ) - ) { - _reservesCount++; - } - } - - /// @inheritdoc IPool - function dropReserve(address asset) external virtual override onlyPoolConfigurator { - PoolLogic.executeDropReserve(_reserves, _reservesList, asset); - } - - /// @inheritdoc IPool - function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) - external - virtual - override - onlyPoolConfigurator - { - require(asset != address(0), Errors.ZERO_ADDRESS_NOT_VALID); - require(_reserves[asset].id != 0 || _reservesList[0] == asset, Errors.ASSET_NOT_LISTED); - _reserves[asset].interestRateStrategyAddress = rateStrategyAddress; - } - - /// @inheritdoc IPool - function setConfiguration(address asset, DataTypes.ReserveConfigurationMap calldata configuration) - external - virtual - override - onlyPoolConfigurator - { - require(asset != address(0), Errors.ZERO_ADDRESS_NOT_VALID); - require(_reserves[asset].id != 0 || _reservesList[0] == asset, Errors.ASSET_NOT_LISTED); - _reserves[asset].configuration = configuration; - } - - /// @inheritdoc IPool - function updateBridgeProtocolFee(uint256 protocolFee) - external - virtual - override - onlyPoolConfigurator - { - _bridgeProtocolFee = protocolFee; - } - - /// @inheritdoc IPool - function updateFlashloanPremiums( - uint128 flashLoanPremiumTotal, - uint128 flashLoanPremiumToProtocol - ) external virtual override onlyPoolConfigurator { - _flashLoanPremiumTotal = flashLoanPremiumTotal; - _flashLoanPremiumToProtocol = flashLoanPremiumToProtocol; - } - - /// @inheritdoc IPool - function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory category) - external - virtual - override - onlyPoolConfigurator - { - // category 0 is reserved for volatile heterogeneous assets and it's always disabled - require(id != 0, Errors.EMODE_CATEGORY_RESERVED); - _eModeCategories[id] = category; - } - - /// @inheritdoc IPool - function getEModeCategoryData(uint8 id) - external - view - virtual - override - returns (DataTypes.EModeCategory memory) - { - return _eModeCategories[id]; - } - - /// @inheritdoc IPool - function setUserEMode(uint8 categoryId) external virtual override { - EModeLogic.executeSetUserEMode( - _reserves, - _reservesList, - _eModeCategories, - _usersEModeCategory, - _usersConfig[msg.sender], - DataTypes.ExecuteSetUserEModeParams({ - reservesCount: _reservesCount, - oracle: ADDRESSES_PROVIDER.getPriceOracle(), - categoryId: categoryId - }) - ); - } - - /// @inheritdoc IPool - function getUserEMode(address user) external view virtual override returns (uint256) { - return _usersEModeCategory[user]; - } - - /// @inheritdoc IPool - function resetIsolationModeTotalDebt(address asset) - external - virtual - override - onlyPoolConfigurator - { - PoolLogic.executeResetIsolationModeTotalDebt(_reserves, asset); - } - - /// @inheritdoc IPool - function rescueTokens( - address token, - address to, - uint256 amount - ) external virtual override onlyPoolAdmin { - PoolLogic.executeRescueTokens(token, to, amount); - } - - /// @inheritdoc IPool - /// @dev Deprecated: maintained for compatibility purposes - function deposit( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode - ) external virtual override { - SupplyLogic.executeSupply( - _reserves, - _reservesList, - _usersConfig[onBehalfOf], - DataTypes.ExecuteSupplyParams({ - asset: asset, - amount: amount, - onBehalfOf: onBehalfOf, - referralCode: referralCode - }) - ); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol deleted file mode 100644 index b99610c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/PoolConfigurator.sol +++ /dev/null @@ -1,528 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; -import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; -import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; -import {PercentageMath} from '../libraries/math/PercentageMath.sol'; -import {DataTypes} from '../libraries/types/DataTypes.sol'; -import {ConfiguratorLogic} from '../libraries/logic/ConfiguratorLogic.sol'; -import {ConfiguratorInputTypes} from '../libraries/types/ConfiguratorInputTypes.sol'; -import {IPoolConfigurator} from '../../interfaces/IPoolConfigurator.sol'; -import {IPool} from '../../interfaces/IPool.sol'; -import {IACLManager} from '../../interfaces/IACLManager.sol'; -import {IPoolDataProvider} from '../../interfaces/IPoolDataProvider.sol'; - -/** - * @title PoolConfigurator - * @author Aave - * @dev Implements the configuration methods for the Aave protocol - **/ -contract PoolConfigurator is VersionedInitializable, IPoolConfigurator { - using PercentageMath for uint256; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - - IPoolAddressesProvider internal _addressesProvider; - IPool internal _pool; - - /** - * @dev Only pool admin can call functions marked by this modifier. - **/ - modifier onlyPoolAdmin() { - _onlyPoolAdmin(); - _; - } - - /** - * @dev Only emergency admin can call functions marked by this modifier. - **/ - modifier onlyEmergencyAdmin() { - _onlyEmergencyAdmin(); - _; - } - - /** - * @dev Only emergency or pool admin can call functions marked by this modifier. - **/ - modifier onlyEmergencyOrPoolAdmin() { - _onlyPoolOrEmergencyAdmin(); - _; - } - - /** - * @dev Only asset listing or pool admin can call functions marked by this modifier. - **/ - modifier onlyAssetListingOrPoolAdmins() { - _onlyAssetListingOrPoolAdmins(); - _; - } - - /** - * @dev Only risk or pool admin can call functions marked by this modifier. - **/ - modifier onlyRiskOrPoolAdmins() { - _onlyRiskOrPoolAdmins(); - _; - } - - uint256 public constant CONFIGURATOR_REVISION = 0x1; - - /// @inheritdoc VersionedInitializable - function getRevision() internal pure virtual override returns (uint256) { - return CONFIGURATOR_REVISION; - } - - function initialize(IPoolAddressesProvider provider) public initializer { - _addressesProvider = provider; - _pool = IPool(_addressesProvider.getPool()); - } - - /// @inheritdoc IPoolConfigurator - function initReserves(ConfiguratorInputTypes.InitReserveInput[] calldata input) - external - override - onlyAssetListingOrPoolAdmins - { - IPool cachedPool = _pool; - for (uint256 i = 0; i < input.length; i++) { - ConfiguratorLogic.executeInitReserve(cachedPool, input[i]); - } - } - - /// @inheritdoc IPoolConfigurator - function dropReserve(address asset) external override onlyPoolAdmin { - _pool.dropReserve(asset); - emit ReserveDropped(asset); - } - - /// @inheritdoc IPoolConfigurator - function updateAToken(ConfiguratorInputTypes.UpdateATokenInput calldata input) - external - override - onlyPoolAdmin - { - ConfiguratorLogic.executeUpdateAToken(_pool, input); - } - - /// @inheritdoc IPoolConfigurator - function updateStableDebtToken(ConfiguratorInputTypes.UpdateDebtTokenInput calldata input) - external - override - onlyPoolAdmin - { - ConfiguratorLogic.executeUpdateStableDebtToken(_pool, input); - } - - /// @inheritdoc IPoolConfigurator - function updateVariableDebtToken(ConfiguratorInputTypes.UpdateDebtTokenInput calldata input) - external - override - onlyPoolAdmin - { - ConfiguratorLogic.executeUpdateVariableDebtToken(_pool, input); - } - - /// @inheritdoc IPoolConfigurator - function setReserveBorrowing(address asset, bool enabled) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - if (!enabled) { - require(!currentConfig.getStableRateBorrowingEnabled(), Errors.STABLE_BORROWING_ENABLED); - } - currentConfig.setBorrowingEnabled(enabled); - _pool.setConfiguration(asset, currentConfig); - emit ReserveBorrowing(asset, enabled); - } - - /// @inheritdoc IPoolConfigurator - function configureReserveAsCollateral( - address asset, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus - ) external override onlyRiskOrPoolAdmins { - //validation of the parameters: the LTV can - //only be lower or equal than the liquidation threshold - //(otherwise a loan against the asset would cause instantaneous liquidation) - require(ltv <= liquidationThreshold, Errors.INVALID_RESERVE_PARAMS); - - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - if (liquidationThreshold != 0) { - //liquidation bonus must be bigger than 100.00%, otherwise the liquidator would receive less - //collateral than needed to cover the debt - require(liquidationBonus > PercentageMath.PERCENTAGE_FACTOR, Errors.INVALID_RESERVE_PARAMS); - - //if threshold * bonus is less than PERCENTAGE_FACTOR, it's guaranteed that at the moment - //a loan is taken there is enough collateral available to cover the liquidation bonus - require( - liquidationThreshold.percentMul(liquidationBonus) <= PercentageMath.PERCENTAGE_FACTOR, - Errors.INVALID_RESERVE_PARAMS - ); - } else { - require(liquidationBonus == 0, Errors.INVALID_RESERVE_PARAMS); - //if the liquidation threshold is being set to 0, - // the reserve is being disabled as collateral. To do so, - //we need to ensure no liquidity is supplied - _checkNoSuppliers(asset); - } - - currentConfig.setLtv(ltv); - currentConfig.setLiquidationThreshold(liquidationThreshold); - currentConfig.setLiquidationBonus(liquidationBonus); - - _pool.setConfiguration(asset, currentConfig); - - emit CollateralConfigurationChanged(asset, ltv, liquidationThreshold, liquidationBonus); - } - - /// @inheritdoc IPoolConfigurator - function setReserveStableRateBorrowing(address asset, bool enabled) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - if (enabled) { - require(currentConfig.getBorrowingEnabled(), Errors.BORROWING_NOT_ENABLED); - } - currentConfig.setStableRateBorrowingEnabled(enabled); - _pool.setConfiguration(asset, currentConfig); - emit ReserveStableRateBorrowing(asset, enabled); - } - - /// @inheritdoc IPoolConfigurator - function setReserveActive(address asset, bool active) external override onlyPoolAdmin { - if (!active) _checkNoSuppliers(asset); - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setActive(active); - _pool.setConfiguration(asset, currentConfig); - emit ReserveActive(asset, active); - } - - /// @inheritdoc IPoolConfigurator - function setReserveFreeze(address asset, bool freeze) external override onlyRiskOrPoolAdmins { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setFrozen(freeze); - _pool.setConfiguration(asset, currentConfig); - emit ReserveFrozen(asset, freeze); - } - - /// @inheritdoc IPoolConfigurator - function setBorrowableInIsolation(address asset, bool borrowable) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setBorrowableInIsolation(borrowable); - _pool.setConfiguration(asset, currentConfig); - emit BorrowableInIsolationChanged(asset, borrowable); - } - - /// @inheritdoc IPoolConfigurator - function setReservePause(address asset, bool paused) public override onlyEmergencyOrPoolAdmin { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setPaused(paused); - _pool.setConfiguration(asset, currentConfig); - emit ReservePaused(asset, paused); - } - - /// @inheritdoc IPoolConfigurator - function setReserveFactor(address asset, uint256 newReserveFactor) - external - override - onlyRiskOrPoolAdmins - { - require(newReserveFactor <= PercentageMath.PERCENTAGE_FACTOR, Errors.INVALID_RESERVE_FACTOR); - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - uint256 oldReserveFactor = currentConfig.getReserveFactor(); - currentConfig.setReserveFactor(newReserveFactor); - _pool.setConfiguration(asset, currentConfig); - emit ReserveFactorChanged(asset, oldReserveFactor, newReserveFactor); - } - - /// @inheritdoc IPoolConfigurator - function setDebtCeiling(address asset, uint256 newDebtCeiling) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - uint256 oldDebtCeiling = currentConfig.getDebtCeiling(); - if (oldDebtCeiling == 0) { - _checkNoSuppliers(asset); - } - currentConfig.setDebtCeiling(newDebtCeiling); - _pool.setConfiguration(asset, currentConfig); - - if (newDebtCeiling == 0) { - _pool.resetIsolationModeTotalDebt(asset); - } - - emit DebtCeilingChanged(asset, oldDebtCeiling, newDebtCeiling); - } - - /// @inheritdoc IPoolConfigurator - function setSiloedBorrowing(address asset, bool newSiloed) - external - override - onlyRiskOrPoolAdmins - { - if (newSiloed) { - _checkNoBorrowers(asset); - } - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - bool oldSiloed = currentConfig.getSiloedBorrowing(); - - currentConfig.setSiloedBorrowing(newSiloed); - - _pool.setConfiguration(asset, currentConfig); - - emit SiloedBorrowingChanged(asset, oldSiloed, newSiloed); - } - - /// @inheritdoc IPoolConfigurator - function setBorrowCap(address asset, uint256 newBorrowCap) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - uint256 oldBorrowCap = currentConfig.getBorrowCap(); - currentConfig.setBorrowCap(newBorrowCap); - _pool.setConfiguration(asset, currentConfig); - emit BorrowCapChanged(asset, oldBorrowCap, newBorrowCap); - } - - /// @inheritdoc IPoolConfigurator - function setSupplyCap(address asset, uint256 newSupplyCap) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - uint256 oldSupplyCap = currentConfig.getSupplyCap(); - currentConfig.setSupplyCap(newSupplyCap); - _pool.setConfiguration(asset, currentConfig); - emit SupplyCapChanged(asset, oldSupplyCap, newSupplyCap); - } - - /// @inheritdoc IPoolConfigurator - function setLiquidationProtocolFee(address asset, uint256 newFee) - external - override - onlyRiskOrPoolAdmins - { - require(newFee <= PercentageMath.PERCENTAGE_FACTOR, Errors.INVALID_LIQUIDATION_PROTOCOL_FEE); - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - uint256 oldFee = currentConfig.getLiquidationProtocolFee(); - currentConfig.setLiquidationProtocolFee(newFee); - _pool.setConfiguration(asset, currentConfig); - emit LiquidationProtocolFeeChanged(asset, oldFee, newFee); - } - - /// @inheritdoc IPoolConfigurator - function setEModeCategory( - uint8 categoryId, - uint16 ltv, - uint16 liquidationThreshold, - uint16 liquidationBonus, - address oracle, - string calldata label - ) external override onlyRiskOrPoolAdmins { - require(ltv != 0, Errors.INVALID_EMODE_CATEGORY_PARAMS); - require(liquidationThreshold != 0, Errors.INVALID_EMODE_CATEGORY_PARAMS); - - // validation of the parameters: the LTV can - // only be lower or equal than the liquidation threshold - // (otherwise a loan against the asset would cause instantaneous liquidation) - require(ltv <= liquidationThreshold, Errors.INVALID_EMODE_CATEGORY_PARAMS); - require( - liquidationBonus > PercentageMath.PERCENTAGE_FACTOR, - Errors.INVALID_EMODE_CATEGORY_PARAMS - ); - - // if threshold * bonus is less than PERCENTAGE_FACTOR, it's guaranteed that at the moment - // a loan is taken there is enough collateral available to cover the liquidation bonus - require( - uint256(liquidationThreshold).percentMul(liquidationBonus) <= - PercentageMath.PERCENTAGE_FACTOR, - Errors.INVALID_EMODE_CATEGORY_PARAMS - ); - - address[] memory reserves = _pool.getReservesList(); - for (uint256 i = 0; i < reserves.length; i++) { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(reserves[i]); - if (categoryId == currentConfig.getEModeCategory()) { - require(ltv > currentConfig.getLtv(), Errors.INVALID_EMODE_CATEGORY_PARAMS); - require( - liquidationThreshold > currentConfig.getLiquidationThreshold(), - Errors.INVALID_EMODE_CATEGORY_PARAMS - ); - } - } - - _pool.configureEModeCategory( - categoryId, - DataTypes.EModeCategory({ - ltv: ltv, - liquidationThreshold: liquidationThreshold, - liquidationBonus: liquidationBonus, - priceSource: oracle, - label: label - }) - ); - emit EModeCategoryAdded(categoryId, ltv, liquidationThreshold, liquidationBonus, oracle, label); - } - - /// @inheritdoc IPoolConfigurator - function setAssetEModeCategory(address asset, uint8 newCategoryId) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - if (newCategoryId != 0) { - DataTypes.EModeCategory memory categoryData = _pool.getEModeCategoryData(newCategoryId); - require( - categoryData.liquidationThreshold > currentConfig.getLiquidationThreshold(), - Errors.INVALID_EMODE_CATEGORY_ASSIGNMENT - ); - } - uint256 oldCategoryId = currentConfig.getEModeCategory(); - currentConfig.setEModeCategory(newCategoryId); - _pool.setConfiguration(asset, currentConfig); - emit EModeAssetCategoryChanged(asset, uint8(oldCategoryId), newCategoryId); - } - - /// @inheritdoc IPoolConfigurator - function setUnbackedMintCap(address asset, uint256 newUnbackedMintCap) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - uint256 oldUnbackedMintCap = currentConfig.getUnbackedMintCap(); - currentConfig.setUnbackedMintCap(newUnbackedMintCap); - _pool.setConfiguration(asset, currentConfig); - emit UnbackedMintCapChanged(asset, oldUnbackedMintCap, newUnbackedMintCap); - } - - /// @inheritdoc IPoolConfigurator - function setReserveInterestRateStrategyAddress(address asset, address newRateStrategyAddress) - external - override - onlyRiskOrPoolAdmins - { - DataTypes.ReserveData memory reserve = _pool.getReserveData(asset); - address oldRateStrategyAddress = reserve.interestRateStrategyAddress; - _pool.setReserveInterestRateStrategyAddress(asset, newRateStrategyAddress); - emit ReserveInterestRateStrategyChanged(asset, oldRateStrategyAddress, newRateStrategyAddress); - } - - /// @inheritdoc IPoolConfigurator - function setPoolPause(bool paused) external override onlyEmergencyAdmin { - address[] memory reserves = _pool.getReservesList(); - - for (uint256 i = 0; i < reserves.length; i++) { - if (reserves[i] != address(0)) { - setReservePause(reserves[i], paused); - } - } - } - - /// @inheritdoc IPoolConfigurator - function updateBridgeProtocolFee(uint256 newBridgeProtocolFee) external override onlyPoolAdmin { - require( - newBridgeProtocolFee <= PercentageMath.PERCENTAGE_FACTOR, - Errors.BRIDGE_PROTOCOL_FEE_INVALID - ); - uint256 oldBridgeProtocolFee = _pool.BRIDGE_PROTOCOL_FEE(); - _pool.updateBridgeProtocolFee(newBridgeProtocolFee); - emit BridgeProtocolFeeUpdated(oldBridgeProtocolFee, newBridgeProtocolFee); - } - - /// @inheritdoc IPoolConfigurator - function updateFlashloanPremiumTotal(uint128 newFlashloanPremiumTotal) - external - override - onlyPoolAdmin - { - require( - newFlashloanPremiumTotal <= PercentageMath.PERCENTAGE_FACTOR, - Errors.FLASHLOAN_PREMIUM_INVALID - ); - uint128 oldFlashloanPremiumTotal = _pool.FLASHLOAN_PREMIUM_TOTAL(); - _pool.updateFlashloanPremiums(newFlashloanPremiumTotal, _pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()); - emit FlashloanPremiumTotalUpdated(oldFlashloanPremiumTotal, newFlashloanPremiumTotal); - } - - /// @inheritdoc IPoolConfigurator - function updateFlashloanPremiumToProtocol(uint128 newFlashloanPremiumToProtocol) - external - override - onlyPoolAdmin - { - require( - newFlashloanPremiumToProtocol <= PercentageMath.PERCENTAGE_FACTOR, - Errors.FLASHLOAN_PREMIUM_INVALID - ); - uint128 oldFlashloanPremiumToProtocol = _pool.FLASHLOAN_PREMIUM_TO_PROTOCOL(); - _pool.updateFlashloanPremiums(_pool.FLASHLOAN_PREMIUM_TOTAL(), newFlashloanPremiumToProtocol); - emit FlashloanPremiumToProtocolUpdated( - oldFlashloanPremiumToProtocol, - newFlashloanPremiumToProtocol - ); - } - - function _checkNoSuppliers(address asset) internal view { - uint256 totalATokens = IPoolDataProvider(_addressesProvider.getPoolDataProvider()) - .getATokenTotalSupply(asset); - require(totalATokens == 0, Errors.RESERVE_LIQUIDITY_NOT_ZERO); - } - - function _checkNoBorrowers(address asset) internal view { - uint256 totalDebt = IPoolDataProvider(_addressesProvider.getPoolDataProvider()).getTotalDebt( - asset - ); - require(totalDebt == 0, Errors.RESERVE_DEBT_NOT_ZERO); - } - - function _onlyPoolAdmin() internal view { - IACLManager aclManager = IACLManager(_addressesProvider.getACLManager()); - require(aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_POOL_ADMIN); - } - - function _onlyEmergencyAdmin() internal view { - IACLManager aclManager = IACLManager(_addressesProvider.getACLManager()); - require(aclManager.isEmergencyAdmin(msg.sender), Errors.CALLER_NOT_EMERGENCY_ADMIN); - } - - function _onlyPoolOrEmergencyAdmin() internal view { - IACLManager aclManager = IACLManager(_addressesProvider.getACLManager()); - require( - aclManager.isPoolAdmin(msg.sender) || aclManager.isEmergencyAdmin(msg.sender), - Errors.CALLER_NOT_POOL_OR_EMERGENCY_ADMIN - ); - } - - function _onlyAssetListingOrPoolAdmins() internal view { - IACLManager aclManager = IACLManager(_addressesProvider.getACLManager()); - require( - aclManager.isAssetListingAdmin(msg.sender) || aclManager.isPoolAdmin(msg.sender), - Errors.CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN - ); - } - - function _onlyRiskOrPoolAdmins() internal view { - IACLManager aclManager = IACLManager(_addressesProvider.getACLManager()); - require( - aclManager.isRiskAdmin(msg.sender) || aclManager.isPoolAdmin(msg.sender), - Errors.CALLER_NOT_RISK_OR_POOL_ADMIN - ); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/PoolStorage.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/PoolStorage.sol deleted file mode 100644 index 9fac0d9..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/pool/PoolStorage.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; -import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; -import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; -import {DataTypes} from '../libraries/types/DataTypes.sol'; - -/** - * @title PoolStorage - * @author Aave - * @notice Contract used as storage of the Pool contract. - * @dev It defines the storage layout of the Pool contract. - */ -contract PoolStorage { - using ReserveLogic for DataTypes.ReserveData; - using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using UserConfiguration for DataTypes.UserConfigurationMap; - - // Map of reserves and their data (underlyingAssetOfReserve => reserveData) - mapping(address => DataTypes.ReserveData) internal _reserves; - - // Map of users address and their configuration data (userAddress => userConfiguration) - mapping(address => DataTypes.UserConfigurationMap) internal _usersConfig; - - // List of reserves as a map (reserveId => reserve). - // It is structured as a mapping for gas savings reasons, using the reserve id as index - mapping(uint256 => address) internal _reservesList; - - // List of eMode categories as a map (eModeCategoryId => eModeCategory). - // It is structured as a mapping for gas savings reasons, using the eModeCategoryId as index - mapping(uint8 => DataTypes.EModeCategory) internal _eModeCategories; - - // Map of users address and their eMode category (userAddress => eModeCategoryId) - mapping(address => uint8) internal _usersEModeCategory; - - // Fee of the protocol bridge, expressed in bps - uint256 internal _bridgeProtocolFee; - - // Total FlashLoan Premium, expressed in bps - uint128 internal _flashLoanPremiumTotal; - - // FlashLoan premium paid to protocol treasury, expressed in bps - uint128 internal _flashLoanPremiumToProtocol; - - // Available liquidity that can be borrowed at once at stable rate, expressed in bps - uint64 internal _maxStableRateBorrowSizePercent; - - // Maximum number of active reserves there have been in the protocol. It is the upper bound of the reserves list - uint16 internal _reservesCount; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/AToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/AToken.sol deleted file mode 100644 index 2bd122e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/AToken.sol +++ /dev/null @@ -1,272 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {GPv2SafeERC20} from '../../dependencies/gnosis/contracts/GPv2SafeERC20.sol'; -import {SafeCast} from '../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; -import {WadRayMath} from '../libraries/math/WadRayMath.sol'; -import {IPool} from '../../interfaces/IPool.sol'; -import {IAToken} from '../../interfaces/IAToken.sol'; -import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; -import {IInitializableAToken} from '../../interfaces/IInitializableAToken.sol'; -import {ScaledBalanceTokenBase} from './base/ScaledBalanceTokenBase.sol'; -import {IncentivizedERC20} from './base/IncentivizedERC20.sol'; -import {EIP712Base} from './base/EIP712Base.sol'; - -/** - * @title Aave ERC20 AToken - * @author Aave - * @notice Implementation of the interest bearing token for the Aave protocol - */ -contract AToken is VersionedInitializable, ScaledBalanceTokenBase, EIP712Base, IAToken { - using WadRayMath for uint256; - using SafeCast for uint256; - using GPv2SafeERC20 for IERC20; - - bytes32 public constant PERMIT_TYPEHASH = - keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'); - - uint256 public constant ATOKEN_REVISION = 0x1; - - address internal _treasury; - address internal _underlyingAsset; - - /// @inheritdoc VersionedInitializable - function getRevision() internal pure virtual override returns (uint256) { - return ATOKEN_REVISION; - } - - /** - * @dev Constructor. - * @param pool The address of the Pool contract - */ - constructor(IPool pool) - ScaledBalanceTokenBase(pool, 'ATOKEN_IMPL', 'ATOKEN_IMPL', 0) - EIP712Base() - { - // Intentionally left blank - } - - /// @inheritdoc IInitializableAToken - function initialize( - IPool initializingPool, - address treasury, - address underlyingAsset, - IAaveIncentivesController incentivesController, - uint8 aTokenDecimals, - string calldata aTokenName, - string calldata aTokenSymbol, - bytes calldata params - ) external override initializer { - require(initializingPool == POOL, Errors.POOL_ADDRESSES_DO_NOT_MATCH); - _setName(aTokenName); - _setSymbol(aTokenSymbol); - _setDecimals(aTokenDecimals); - - _treasury = treasury; - _underlyingAsset = underlyingAsset; - _incentivesController = incentivesController; - - _domainSeparator = _calculateDomainSeparator(); - - emit Initialized( - underlyingAsset, - address(POOL), - treasury, - address(incentivesController), - aTokenDecimals, - aTokenName, - aTokenSymbol, - params - ); - } - - /// @inheritdoc IAToken - function mint( - address caller, - address onBehalfOf, - uint256 amount, - uint256 index - ) external virtual override onlyPool returns (bool) { - return _mintScaled(caller, onBehalfOf, amount, index); - } - - /// @inheritdoc IAToken - function burn( - address from, - address receiverOfUnderlying, - uint256 amount, - uint256 index - ) external virtual override onlyPool { - _burnScaled(from, receiverOfUnderlying, amount, index); - if (receiverOfUnderlying != address(this)) { - IERC20(_underlyingAsset).safeTransfer(receiverOfUnderlying, amount); - } - } - - /// @inheritdoc IAToken - function mintToTreasury(uint256 amount, uint256 index) external override onlyPool { - if (amount == 0) { - return; - } - _mintScaled(address(POOL), _treasury, amount, index); - } - - /// @inheritdoc IAToken - function transferOnLiquidation( - address from, - address to, - uint256 value - ) external override onlyPool { - // Being a normal transfer, the Transfer() and BalanceTransfer() are emitted - // so no need to emit a specific event here - _transfer(from, to, value, false); - - emit Transfer(from, to, value); - } - - /// @inheritdoc IERC20 - function balanceOf(address user) - public - view - virtual - override(IncentivizedERC20, IERC20) - returns (uint256) - { - return super.balanceOf(user).rayMul(POOL.getReserveNormalizedIncome(_underlyingAsset)); - } - - /// @inheritdoc IERC20 - function totalSupply() public view virtual override(IncentivizedERC20, IERC20) returns (uint256) { - uint256 currentSupplyScaled = super.totalSupply(); - - if (currentSupplyScaled == 0) { - return 0; - } - - return currentSupplyScaled.rayMul(POOL.getReserveNormalizedIncome(_underlyingAsset)); - } - - /// @inheritdoc IAToken - function RESERVE_TREASURY_ADDRESS() external view override returns (address) { - return _treasury; - } - - /// @inheritdoc IAToken - function UNDERLYING_ASSET_ADDRESS() external view override returns (address) { - return _underlyingAsset; - } - - /// @inheritdoc IAToken - function transferUnderlyingTo(address target, uint256 amount) external virtual override onlyPool { - IERC20(_underlyingAsset).safeTransfer(target, amount); - } - - /// @inheritdoc IAToken - function handleRepayment(address user, uint256 amount) external virtual override onlyPool { - // Intentionally left blank - } - - /// @inheritdoc IAToken - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external override { - require(owner != address(0), Errors.ZERO_ADDRESS_NOT_VALID); - //solium-disable-next-line - require(block.timestamp <= deadline, Errors.INVALID_EXPIRATION); - uint256 currentValidNonce = _nonces[owner]; - bytes32 digest = keccak256( - abi.encodePacked( - '\x19\x01', - DOMAIN_SEPARATOR(), - keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline)) - ) - ); - require(owner == ecrecover(digest, v, r, s), Errors.INVALID_SIGNATURE); - _nonces[owner] = currentValidNonce + 1; - _approve(owner, spender, value); - } - - /** - * @notice Transfers the aTokens between two users. Validates the transfer - * (ie checks for valid HF after the transfer) if required - * @param from The source address - * @param to The destination address - * @param amount The amount getting transferred - * @param validate True if the transfer needs to be validated, false otherwise - **/ - function _transfer( - address from, - address to, - uint256 amount, - bool validate - ) internal { - address underlyingAsset = _underlyingAsset; - - uint256 index = POOL.getReserveNormalizedIncome(underlyingAsset); - - uint256 fromBalanceBefore = super.balanceOf(from).rayMul(index); - uint256 toBalanceBefore = super.balanceOf(to).rayMul(index); - - super._transfer(from, to, amount.rayDiv(index).toUint128()); - - if (validate) { - POOL.finalizeTransfer(underlyingAsset, from, to, amount, fromBalanceBefore, toBalanceBefore); - } - - emit BalanceTransfer(from, to, amount, index); - } - - /** - * @notice Overrides the parent _transfer to force validated transfer() and transferFrom() - * @param from The source address - * @param to The destination address - * @param amount The amount getting transferred - **/ - function _transfer( - address from, - address to, - uint128 amount - ) internal override { - _transfer(from, to, amount, true); - } - - /** - * @dev Overrides the base function to fully implement IAToken - * @dev see `IncentivizedERC20.DOMAIN_SEPARATOR()` for more detailed documentation - */ - function DOMAIN_SEPARATOR() public view override(IAToken, EIP712Base) returns (bytes32) { - return super.DOMAIN_SEPARATOR(); - } - - /** - * @dev Overrides the base function to fully implement IAToken - * @dev see `IncentivizedERC20.nonces()` for more detailed documentation - */ - function nonces(address owner) public view override(IAToken, EIP712Base) returns (uint256) { - return super.nonces(owner); - } - - /// @inheritdoc EIP712Base - function _EIP712BaseId() internal view override returns (string memory) { - return name(); - } - - /// @inheritdoc IAToken - function rescueTokens( - address token, - address to, - uint256 amount - ) external override onlyPoolAdmin { - require(token != _underlyingAsset, Errors.UNDERLYING_CANNOT_BE_RESCUED); - IERC20(token).safeTransfer(to, amount); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/DelegationAwareAToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/DelegationAwareAToken.sol deleted file mode 100644 index 51a5f20..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/DelegationAwareAToken.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IPool} from '../../interfaces/IPool.sol'; -import {IDelegationToken} from '../../interfaces/IDelegationToken.sol'; -import {AToken} from './AToken.sol'; - -/** - * @title DelegationAwareAToken - * @author Aave - * @notice AToken enabled to delegate voting power of the underlying asset to a different address - * @dev The underlying asset needs to be compatible with the COMP delegation interface - */ -contract DelegationAwareAToken is AToken { - /** - * @dev Emitted when underlying voting power is delegated - * @param delegatee The address of the delegatee - */ - event DelegateUnderlyingTo(address indexed delegatee); - - /** - * @dev Constructor. - * @param pool The address of the Pool contract - */ - constructor(IPool pool) AToken(pool) { - // Intentionally left blank - } - - /** - * @notice Delegates voting power of the underlying asset to a `delegatee` address - * @param delegatee The address that will receive the delegation - **/ - function delegateUnderlyingTo(address delegatee) external onlyPoolAdmin { - IDelegationToken(_underlyingAsset).delegate(delegatee); - emit DelegateUnderlyingTo(delegatee); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/StableDebtToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/StableDebtToken.sol deleted file mode 100644 index c37358b..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/StableDebtToken.sol +++ /dev/null @@ -1,430 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; -import {MathUtils} from '../libraries/math/MathUtils.sol'; -import {WadRayMath} from '../libraries/math/WadRayMath.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; -import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; -import {IInitializableDebtToken} from '../../interfaces/IInitializableDebtToken.sol'; -import {IStableDebtToken} from '../../interfaces/IStableDebtToken.sol'; -import {IPool} from '../../interfaces/IPool.sol'; -import {EIP712Base} from './base/EIP712Base.sol'; -import {DebtTokenBase} from './base/DebtTokenBase.sol'; -import {IncentivizedERC20} from './base/IncentivizedERC20.sol'; -import {SafeCast} from '../../dependencies/openzeppelin/contracts/SafeCast.sol'; - -/** - * @title StableDebtToken - * @author Aave - * @notice Implements a stable debt token to track the borrowing positions of users - * at stable rate mode - * @dev Transfer and approve functionalities are disabled since its a non-transferable token - **/ -contract StableDebtToken is DebtTokenBase, IncentivizedERC20, IStableDebtToken { - using WadRayMath for uint256; - using SafeCast for uint256; - - uint256 public constant DEBT_TOKEN_REVISION = 0x1; - - // Map of users address and the timestamp of their last update (userAddress => lastUpdateTimestamp) - mapping(address => uint40) internal _timestamps; - - uint128 internal _avgStableRate; - - // Timestamp of the last update of the total supply - uint40 internal _totalSupplyTimestamp; - - /** - * @dev Constructor. - * @param pool The address of the Pool contract - */ - constructor(IPool pool) - DebtTokenBase() - IncentivizedERC20(pool, 'STABLE_DEBT_TOKEN_IMPL', 'STABLE_DEBT_TOKEN_IMPL', 0) - { - // Intentionally left blank - } - - /// @inheritdoc IInitializableDebtToken - function initialize( - IPool initializingPool, - address underlyingAsset, - IAaveIncentivesController incentivesController, - uint8 debtTokenDecimals, - string memory debtTokenName, - string memory debtTokenSymbol, - bytes calldata params - ) external override initializer { - require(initializingPool == POOL, Errors.POOL_ADDRESSES_DO_NOT_MATCH); - _setName(debtTokenName); - _setSymbol(debtTokenSymbol); - _setDecimals(debtTokenDecimals); - - _underlyingAsset = underlyingAsset; - _incentivesController = incentivesController; - - _domainSeparator = _calculateDomainSeparator(); - - emit Initialized( - underlyingAsset, - address(POOL), - address(incentivesController), - debtTokenDecimals, - debtTokenName, - debtTokenSymbol, - params - ); - } - - /// @inheritdoc VersionedInitializable - function getRevision() internal pure virtual override returns (uint256) { - return DEBT_TOKEN_REVISION; - } - - /// @inheritdoc IStableDebtToken - function getAverageStableRate() external view virtual override returns (uint256) { - return _avgStableRate; - } - - /// @inheritdoc IStableDebtToken - function getUserLastUpdated(address user) external view virtual override returns (uint40) { - return _timestamps[user]; - } - - /// @inheritdoc IStableDebtToken - function getUserStableRate(address user) external view virtual override returns (uint256) { - return _userState[user].additionalData; - } - - /// @inheritdoc IERC20 - function balanceOf(address account) public view virtual override returns (uint256) { - uint256 accountBalance = super.balanceOf(account); - uint256 stableRate = _userState[account].additionalData; - if (accountBalance == 0) { - return 0; - } - uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest( - stableRate, - _timestamps[account] - ); - return accountBalance.rayMul(cumulatedInterest); - } - - struct MintLocalVars { - uint256 previousSupply; - uint256 nextSupply; - uint256 amountInRay; - uint256 currentStableRate; - uint256 nextStableRate; - uint256 currentAvgStableRate; - } - - /// @inheritdoc IStableDebtToken - function mint( - address user, - address onBehalfOf, - uint256 amount, - uint256 rate - ) - external - virtual - override - onlyPool - returns ( - bool, - uint256, - uint256 - ) - { - MintLocalVars memory vars; - - if (user != onBehalfOf) { - _decreaseBorrowAllowance(onBehalfOf, user, amount); - } - - (, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(onBehalfOf); - - vars.previousSupply = totalSupply(); - vars.currentAvgStableRate = _avgStableRate; - vars.nextSupply = _totalSupply = vars.previousSupply + amount; - - vars.amountInRay = amount.wadToRay(); - - vars.currentStableRate = _userState[onBehalfOf].additionalData; - vars.nextStableRate = (vars.currentStableRate.rayMul(currentBalance.wadToRay()) + - vars.amountInRay.rayMul(rate)).rayDiv((currentBalance + amount).wadToRay()); - - _userState[onBehalfOf].additionalData = vars.nextStableRate.toUint128(); - - //solium-disable-next-line - _totalSupplyTimestamp = _timestamps[onBehalfOf] = uint40(block.timestamp); - - // Calculates the updated average stable rate - vars.currentAvgStableRate = _avgStableRate = ( - (vars.currentAvgStableRate.rayMul(vars.previousSupply.wadToRay()) + - rate.rayMul(vars.amountInRay)).rayDiv(vars.nextSupply.wadToRay()) - ).toUint128(); - - uint256 amountToMint = amount + balanceIncrease; - _mint(onBehalfOf, amountToMint, vars.previousSupply); - - emit Transfer(address(0), onBehalfOf, amountToMint); - emit Mint( - user, - onBehalfOf, - amountToMint, - currentBalance, - balanceIncrease, - vars.nextStableRate, - vars.currentAvgStableRate, - vars.nextSupply - ); - - return (currentBalance == 0, vars.nextSupply, vars.currentAvgStableRate); - } - - /// @inheritdoc IStableDebtToken - function burn(address from, uint256 amount) - external - virtual - override - onlyPool - returns (uint256, uint256) - { - (, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(from); - - uint256 previousSupply = totalSupply(); - uint256 nextAvgStableRate = 0; - uint256 nextSupply = 0; - uint256 userStableRate = _userState[from].additionalData; - - // Since the total supply and each single user debt accrue separately, - // there might be accumulation errors so that the last borrower repaying - // might actually try to repay more than the available debt supply. - // In this case we simply set the total supply and the avg stable rate to 0 - if (previousSupply <= amount) { - _avgStableRate = 0; - _totalSupply = 0; - } else { - nextSupply = _totalSupply = previousSupply - amount; - uint256 firstTerm = uint256(_avgStableRate).rayMul(previousSupply.wadToRay()); - uint256 secondTerm = userStableRate.rayMul(amount.wadToRay()); - - // For the same reason described above, when the last user is repaying it might - // happen that user rate * user balance > avg rate * total supply. In that case, - // we simply set the avg rate to 0 - if (secondTerm >= firstTerm) { - nextAvgStableRate = _totalSupply = _avgStableRate = 0; - } else { - nextAvgStableRate = _avgStableRate = ( - (firstTerm - secondTerm).rayDiv(nextSupply.wadToRay()) - ).toUint128(); - } - } - - if (amount == currentBalance) { - _userState[from].additionalData = 0; - _timestamps[from] = 0; - } else { - //solium-disable-next-line - _timestamps[from] = uint40(block.timestamp); - } - //solium-disable-next-line - _totalSupplyTimestamp = uint40(block.timestamp); - - if (balanceIncrease > amount) { - uint256 amountToMint = balanceIncrease - amount; - _mint(from, amountToMint, previousSupply); - emit Transfer(address(0), from, amountToMint); - emit Mint( - from, - from, - amountToMint, - currentBalance, - balanceIncrease, - userStableRate, - nextAvgStableRate, - nextSupply - ); - } else { - uint256 amountToBurn = amount - balanceIncrease; - _burn(from, amountToBurn, previousSupply); - emit Transfer(from, address(0), amountToBurn); - emit Burn(from, amountToBurn, currentBalance, balanceIncrease, nextAvgStableRate, nextSupply); - } - - return (nextSupply, nextAvgStableRate); - } - - /** - * @notice Calculates the increase in balance since the last user interaction - * @param user The address of the user for which the interest is being accumulated - * @return The previous principal balance - * @return The new principal balance - * @return The balance increase - **/ - function _calculateBalanceIncrease(address user) - internal - view - returns ( - uint256, - uint256, - uint256 - ) - { - uint256 previousPrincipalBalance = super.balanceOf(user); - - if (previousPrincipalBalance == 0) { - return (0, 0, 0); - } - - uint256 newPrincipalBalance = balanceOf(user); - - return ( - previousPrincipalBalance, - newPrincipalBalance, - newPrincipalBalance - previousPrincipalBalance - ); - } - - /// @inheritdoc IStableDebtToken - function getSupplyData() - external - view - override - returns ( - uint256, - uint256, - uint256, - uint40 - ) - { - uint256 avgRate = _avgStableRate; - return (super.totalSupply(), _calcTotalSupply(avgRate), avgRate, _totalSupplyTimestamp); - } - - /// @inheritdoc IStableDebtToken - function getTotalSupplyAndAvgRate() external view override returns (uint256, uint256) { - uint256 avgRate = _avgStableRate; - return (_calcTotalSupply(avgRate), avgRate); - } - - /// @inheritdoc IERC20 - function totalSupply() public view virtual override returns (uint256) { - return _calcTotalSupply(_avgStableRate); - } - - /// @inheritdoc IStableDebtToken - function getTotalSupplyLastUpdated() external view override returns (uint40) { - return _totalSupplyTimestamp; - } - - /// @inheritdoc IStableDebtToken - function principalBalanceOf(address user) external view virtual override returns (uint256) { - return super.balanceOf(user); - } - - /// @inheritdoc IStableDebtToken - function UNDERLYING_ASSET_ADDRESS() external view override returns (address) { - return _underlyingAsset; - } - - /** - * @notice Calculates the total supply - * @param avgRate The average rate at which the total supply increases - * @return The debt balance of the user since the last burn/mint action - **/ - function _calcTotalSupply(uint256 avgRate) internal view returns (uint256) { - uint256 principalSupply = super.totalSupply(); - - if (principalSupply == 0) { - return 0; - } - - uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest( - avgRate, - _totalSupplyTimestamp - ); - - return principalSupply.rayMul(cumulatedInterest); - } - - /** - * @notice Mints stable debt tokens to a user - * @param account The account receiving the debt tokens - * @param amount The amount being minted - * @param oldTotalSupply The total supply before the minting event - **/ - function _mint( - address account, - uint256 amount, - uint256 oldTotalSupply - ) internal { - uint128 castAmount = amount.toUint128(); - uint128 oldAccountBalance = _userState[account].balance; - _userState[account].balance = oldAccountBalance + castAmount; - - if (address(_incentivesController) != address(0)) { - _incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance); - } - } - - /** - * @notice Burns stable debt tokens of a user - * @param account The user getting his debt burned - * @param amount The amount being burned - * @param oldTotalSupply The total supply before the burning event - **/ - function _burn( - address account, - uint256 amount, - uint256 oldTotalSupply - ) internal { - uint128 castAmount = amount.toUint128(); - uint128 oldAccountBalance = _userState[account].balance; - _userState[account].balance = oldAccountBalance - castAmount; - - if (address(_incentivesController) != address(0)) { - _incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance); - } - } - - /// @inheritdoc EIP712Base - function _EIP712BaseId() internal view override returns (string memory) { - return name(); - } - - /** - * @dev Being non transferrable, the debt token does not implement any of the - * standard ERC20 functions for transfer and allowance. - **/ - function transfer(address, uint256) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function allowance(address, address) external view virtual override returns (uint256) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function approve(address, uint256) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function transferFrom( - address, - address, - uint256 - ) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function increaseAllowance(address, uint256) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function decreaseAllowance(address, uint256) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/VariableDebtToken.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/VariableDebtToken.sol deleted file mode 100644 index 6b73f4b..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/VariableDebtToken.sol +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {SafeCast} from '../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol'; -import {WadRayMath} from '../libraries/math/WadRayMath.sol'; -import {Errors} from '../libraries/helpers/Errors.sol'; -import {IPool} from '../../interfaces/IPool.sol'; -import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; -import {IInitializableDebtToken} from '../../interfaces/IInitializableDebtToken.sol'; -import {IVariableDebtToken} from '../../interfaces/IVariableDebtToken.sol'; -import {EIP712Base} from './base/EIP712Base.sol'; -import {DebtTokenBase} from './base/DebtTokenBase.sol'; -import {ScaledBalanceTokenBase} from './base/ScaledBalanceTokenBase.sol'; - -/** - * @title VariableDebtToken - * @author Aave - * @notice Implements a variable debt token to track the borrowing positions of users - * at variable rate mode - * @dev Transfer and approve functionalities are disabled since its a non-transferable token - **/ -contract VariableDebtToken is DebtTokenBase, ScaledBalanceTokenBase, IVariableDebtToken { - using WadRayMath for uint256; - using SafeCast for uint256; - - uint256 public constant DEBT_TOKEN_REVISION = 0x1; - - /** - * @dev Constructor. - * @param pool The address of the Pool contract - */ - constructor(IPool pool) - DebtTokenBase() - ScaledBalanceTokenBase(pool, 'VARIABLE_DEBT_TOKEN_IMPL', 'VARIABLE_DEBT_TOKEN_IMPL', 0) - { - // Intentionally left blank - } - - /// @inheritdoc IInitializableDebtToken - function initialize( - IPool initializingPool, - address underlyingAsset, - IAaveIncentivesController incentivesController, - uint8 debtTokenDecimals, - string memory debtTokenName, - string memory debtTokenSymbol, - bytes calldata params - ) external override initializer { - require(initializingPool == POOL, Errors.POOL_ADDRESSES_DO_NOT_MATCH); - _setName(debtTokenName); - _setSymbol(debtTokenSymbol); - _setDecimals(debtTokenDecimals); - - _underlyingAsset = underlyingAsset; - _incentivesController = incentivesController; - - _domainSeparator = _calculateDomainSeparator(); - - emit Initialized( - underlyingAsset, - address(POOL), - address(incentivesController), - debtTokenDecimals, - debtTokenName, - debtTokenSymbol, - params - ); - } - - /// @inheritdoc VersionedInitializable - function getRevision() internal pure virtual override returns (uint256) { - return DEBT_TOKEN_REVISION; - } - - /// @inheritdoc IERC20 - function balanceOf(address user) public view virtual override returns (uint256) { - uint256 scaledBalance = super.balanceOf(user); - - if (scaledBalance == 0) { - return 0; - } - - return scaledBalance.rayMul(POOL.getReserveNormalizedVariableDebt(_underlyingAsset)); - } - - /// @inheritdoc IVariableDebtToken - function mint( - address user, - address onBehalfOf, - uint256 amount, - uint256 index - ) external virtual override onlyPool returns (bool, uint256) { - if (user != onBehalfOf) { - _decreaseBorrowAllowance(onBehalfOf, user, amount); - } - return (_mintScaled(user, onBehalfOf, amount, index), scaledTotalSupply()); - } - - /// @inheritdoc IVariableDebtToken - function burn( - address from, - uint256 amount, - uint256 index - ) external virtual override onlyPool returns (uint256) { - _burnScaled(from, address(0), amount, index); - return scaledTotalSupply(); - } - - /// @inheritdoc IERC20 - function totalSupply() public view virtual override returns (uint256) { - return super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(_underlyingAsset)); - } - - /// @inheritdoc EIP712Base - function _EIP712BaseId() internal view override returns (string memory) { - return name(); - } - - /** - * @dev Being non transferrable, the debt token does not implement any of the - * standard ERC20 functions for transfer and allowance. - **/ - function transfer(address, uint256) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function allowance(address, address) external view virtual override returns (uint256) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function approve(address, uint256) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function transferFrom( - address, - address, - uint256 - ) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function increaseAllowance(address, uint256) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - function decreaseAllowance(address, uint256) external virtual override returns (bool) { - revert(Errors.OPERATION_NOT_SUPPORTED); - } - - /// @inheritdoc IVariableDebtToken - function UNDERLYING_ASSET_ADDRESS() external view override returns (address) { - return _underlyingAsset; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/DebtTokenBase.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/DebtTokenBase.sol deleted file mode 100644 index 3e5ac90..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/DebtTokenBase.sol +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {Context} from '../../../dependencies/openzeppelin/contracts/Context.sol'; -import {Errors} from '../../libraries/helpers/Errors.sol'; -import {VersionedInitializable} from '../../libraries/aave-upgradeability/VersionedInitializable.sol'; -import {ICreditDelegationToken} from '../../../interfaces/ICreditDelegationToken.sol'; -import {EIP712Base} from './EIP712Base.sol'; - -/** - * @title DebtTokenBase - * @author Aave - * @notice Base contract for different types of debt tokens, like StableDebtToken or VariableDebtToken - */ -abstract contract DebtTokenBase is - VersionedInitializable, - EIP712Base, - Context, - ICreditDelegationToken -{ - // Map of borrow allowances (delegator => delegatee => borrowAllowanceAmount) - mapping(address => mapping(address => uint256)) internal _borrowAllowances; - - // Credit Delegation Typehash - bytes32 public constant DELEGATION_WITH_SIG_TYPEHASH = - keccak256('DelegationWithSig(address delegatee,uint256 value,uint256 nonce,uint256 deadline)'); - - address internal _underlyingAsset; - - /** - * @dev Constructor. - */ - constructor() EIP712Base() { - // Intentionally left blank - } - - /// @inheritdoc ICreditDelegationToken - function approveDelegation(address delegatee, uint256 amount) external override { - _approveDelegation(_msgSender(), delegatee, amount); - } - - /// @inheritdoc ICreditDelegationToken - function delegationWithSig( - address delegator, - address delegatee, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external { - require(delegator != address(0), Errors.ZERO_ADDRESS_NOT_VALID); - //solium-disable-next-line - require(block.timestamp <= deadline, Errors.INVALID_EXPIRATION); - uint256 currentValidNonce = _nonces[delegator]; - bytes32 digest = keccak256( - abi.encodePacked( - '\x19\x01', - DOMAIN_SEPARATOR(), - keccak256( - abi.encode(DELEGATION_WITH_SIG_TYPEHASH, delegatee, value, currentValidNonce, deadline) - ) - ) - ); - require(delegator == ecrecover(digest, v, r, s), Errors.INVALID_SIGNATURE); - _nonces[delegator] = currentValidNonce + 1; - _approveDelegation(delegator, delegatee, value); - } - - /// @inheritdoc ICreditDelegationToken - function borrowAllowance(address fromUser, address toUser) - external - view - override - returns (uint256) - { - return _borrowAllowances[fromUser][toUser]; - } - - /** - * @notice Updates the borrow allowance of a user on the specific debt token. - * @param delegator The address delegating the borrowing power - * @param delegatee The address receiving the delegated borrowing power - * @param amount The allowance amount being delegated. - **/ - function _approveDelegation( - address delegator, - address delegatee, - uint256 amount - ) internal { - _borrowAllowances[delegator][delegatee] = amount; - emit BorrowAllowanceDelegated(delegator, delegatee, _underlyingAsset, amount); - } - - /** - * @notice Decreases the borrow allowance of a user on the specific debt token. - * @param delegator The address delegating the borrowing power - * @param delegatee The address receiving the delegated borrowing power - * @param amount The amount to subtract from the current allowance - **/ - function _decreaseBorrowAllowance( - address delegator, - address delegatee, - uint256 amount - ) internal { - uint256 newAllowance = _borrowAllowances[delegator][delegatee] - amount; - - _borrowAllowances[delegator][delegatee] = newAllowance; - - emit BorrowAllowanceDelegated(delegator, delegatee, _underlyingAsset, newAllowance); - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/EIP712Base.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/EIP712Base.sol deleted file mode 100644 index bb16119..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/EIP712Base.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -/** - * @title EIP712Base - * @author Aave - * @notice Base contract implementation of EIP712. - */ -abstract contract EIP712Base { - bytes public constant EIP712_REVISION = bytes('1'); - bytes32 internal constant EIP712_DOMAIN = - keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'); - - // Map of address nonces (address => nonce) - mapping(address => uint256) internal _nonces; - - bytes32 internal _domainSeparator; - uint256 internal immutable _chainId; - - /** - * @dev Constructor. - */ - constructor() { - _chainId = block.chainid; - } - - /** - * @notice Get the domain separator for the token - * @dev Return cached value if chainId matches cache, otherwise recomputes separator - * @return The domain separator of the token at current chain - */ - function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { - if (block.chainid == _chainId) { - return _domainSeparator; - } - return _calculateDomainSeparator(); - } - - /** - * @notice Returns the nonce value for address specified as parameter - * @param owner The address for which the nonce is being returned - * @return The nonce value for the input address` - */ - function nonces(address owner) public view virtual returns (uint256) { - return _nonces[owner]; - } - - /** - * @notice Compute the current domain separator - * @return The domain separator for the token - */ - function _calculateDomainSeparator() internal view returns (bytes32) { - return - keccak256( - abi.encode( - EIP712_DOMAIN, - keccak256(bytes(_EIP712BaseId())), - keccak256(EIP712_REVISION), - block.chainid, - address(this) - ) - ); - } - - /** - * @notice Returns the user readable name of signing domain (e.g. token name) - * @return The name of the signing domain - */ - function _EIP712BaseId() internal view virtual returns (string memory); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/IncentivizedERC20.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/IncentivizedERC20.sol deleted file mode 100644 index 4c0d83c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/IncentivizedERC20.sol +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.10; - -import {Context} from '../../../dependencies/openzeppelin/contracts/Context.sol'; -import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; -import {IERC20Detailed} from '../../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; -import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {WadRayMath} from '../../libraries/math/WadRayMath.sol'; -import {Errors} from '../../libraries/helpers/Errors.sol'; -import {IAaveIncentivesController} from '../../../interfaces/IAaveIncentivesController.sol'; -import {IPoolAddressesProvider} from '../../../interfaces/IPoolAddressesProvider.sol'; -import {IPool} from '../../../interfaces/IPool.sol'; -import {IACLManager} from '../../../interfaces/IACLManager.sol'; - -/** - * @title IncentivizedERC20 - * @author Aave, inspired by the Openzeppelin ERC20 implementation - * @notice Basic ERC20 implementation - **/ -abstract contract IncentivizedERC20 is Context, IERC20Detailed { - using WadRayMath for uint256; - using SafeCast for uint256; - - /** - * @dev Only pool admin can call functions marked by this modifier. - **/ - modifier onlyPoolAdmin() { - IACLManager aclManager = IACLManager(_addressesProvider.getACLManager()); - require(aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_POOL_ADMIN); - _; - } - - /** - * @dev Only pool can call functions marked by this modifier. - **/ - modifier onlyPool() { - require(_msgSender() == address(POOL), Errors.CALLER_MUST_BE_POOL); - _; - } - - /** - * @dev UserState - additionalData is a flexible field. - * ATokens and VariableDebtTokens use this field store the index of the - * user's last supply/withdrawal/borrow/repayment. StableDebtTokens use - * this field to store the user's stable rate. - */ - struct UserState { - uint128 balance; - uint128 additionalData; - } - // Map of users address and their state data (userAddress => userStateData) - mapping(address => UserState) internal _userState; - - // Map of allowances (delegator => delegatee => allowanceAmount) - mapping(address => mapping(address => uint256)) private _allowances; - - uint256 internal _totalSupply; - string private _name; - string private _symbol; - uint8 private _decimals; - IAaveIncentivesController internal _incentivesController; - IPoolAddressesProvider internal immutable _addressesProvider; - IPool public immutable POOL; - - /** - * @dev Constructor. - * @param pool The reference to the main Pool contract - * @param name The name of the token - * @param symbol The symbol of the token - * @param decimals The number of decimals of the token - */ - constructor( - IPool pool, - string memory name, - string memory symbol, - uint8 decimals - ) { - _addressesProvider = pool.ADDRESSES_PROVIDER(); - _name = name; - _symbol = symbol; - _decimals = decimals; - POOL = pool; - } - - /// @inheritdoc IERC20Detailed - function name() public view override returns (string memory) { - return _name; - } - - /// @inheritdoc IERC20Detailed - function symbol() external view override returns (string memory) { - return _symbol; - } - - /// @inheritdoc IERC20Detailed - function decimals() external view override returns (uint8) { - return _decimals; - } - - /// @inheritdoc IERC20 - function totalSupply() public view virtual override returns (uint256) { - return _totalSupply; - } - - /// @inheritdoc IERC20 - function balanceOf(address account) public view virtual override returns (uint256) { - return _userState[account].balance; - } - - /** - * @notice Returns the address of the Incentives Controller contract - * @return The address of the Incentives Controller - **/ - function getIncentivesController() external view virtual returns (IAaveIncentivesController) { - return _incentivesController; - } - - /** - * @notice Sets a new Incentives Controller - * @param controller the new Incentives controller - **/ - function setIncentivesController(IAaveIncentivesController controller) external onlyPoolAdmin { - _incentivesController = controller; - } - - /// @inheritdoc IERC20 - function transfer(address recipient, uint256 amount) external virtual override returns (bool) { - uint128 castAmount = amount.toUint128(); - _transfer(_msgSender(), recipient, castAmount); - return true; - } - - /// @inheritdoc IERC20 - function allowance(address owner, address spender) - external - view - virtual - override - returns (uint256) - { - return _allowances[owner][spender]; - } - - /// @inheritdoc IERC20 - function approve(address spender, uint256 amount) external virtual override returns (bool) { - _approve(_msgSender(), spender, amount); - return true; - } - - /// @inheritdoc IERC20 - function transferFrom( - address sender, - address recipient, - uint256 amount - ) external virtual override returns (bool) { - uint128 castAmount = amount.toUint128(); - _approve(sender, _msgSender(), _allowances[sender][_msgSender()] - castAmount); - _transfer(sender, recipient, castAmount); - return true; - } - - /** - * @notice Increases the allowance of spender to spend _msgSender() tokens - * @param spender The user allowed to spend on behalf of _msgSender() - * @param addedValue The amount being added to the allowance - * @return `true` - **/ - function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) { - _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); - return true; - } - - /** - * @notice Decreases the allowance of spender to spend _msgSender() tokens - * @param spender The user allowed to spend on behalf of _msgSender() - * @param subtractedValue The amount being subtracted to the allowance - * @return `true` - **/ - function decreaseAllowance(address spender, uint256 subtractedValue) - external - virtual - returns (bool) - { - _approve(_msgSender(), spender, _allowances[_msgSender()][spender] - subtractedValue); - return true; - } - - /** - * @notice Transfers tokens between two users and apply incentives if defined. - * @param sender The source address - * @param recipient The destination address - * @param amount The amount getting transferred - */ - function _transfer( - address sender, - address recipient, - uint128 amount - ) internal virtual { - uint128 oldSenderBalance = _userState[sender].balance; - _userState[sender].balance = oldSenderBalance - amount; - uint128 oldRecipientBalance = _userState[recipient].balance; - _userState[recipient].balance = oldRecipientBalance + amount; - - IAaveIncentivesController incentivesControllerLocal = _incentivesController; - if (address(incentivesControllerLocal) != address(0)) { - uint256 currentTotalSupply = _totalSupply; - incentivesControllerLocal.handleAction(sender, currentTotalSupply, oldSenderBalance); - if (sender != recipient) { - incentivesControllerLocal.handleAction(recipient, currentTotalSupply, oldRecipientBalance); - } - } - emit Transfer(sender, recipient, amount); - } - - /** - * @notice Approve `spender` to use `amount` of `owner`s balance - * @param owner The address owning the tokens - * @param spender The address approved for spending - * @param amount The amount of tokens to approve spending of - */ - function _approve( - address owner, - address spender, - uint256 amount - ) internal virtual { - _allowances[owner][spender] = amount; - emit Approval(owner, spender, amount); - } - - /** - * @notice Update the name of the token - * @param newName The new name for the token - */ - function _setName(string memory newName) internal { - _name = newName; - } - - /** - * @notice Update the symbol for the token - * @param newSymbol The new symbol for the token - */ - function _setSymbol(string memory newSymbol) internal { - _symbol = newSymbol; - } - - /** - * @notice Update the number of decimals for the token - * @param newDecimals The new number of decimals for the token - */ - function _setDecimals(uint8 newDecimals) internal { - _decimals = newDecimals; - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol deleted file mode 100644 index 51eba34..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/MintableIncentivizedERC20.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import {IAaveIncentivesController} from '../../../interfaces/IAaveIncentivesController.sol'; -import {IPool} from '../../../interfaces/IPool.sol'; -import {IncentivizedERC20} from './IncentivizedERC20.sol'; - -/** - * @title MintableIncentivizedERC20 - * @author Aave - * @notice Implements mint and burn functions for IncentivizedERC20 - **/ -abstract contract MintableIncentivizedERC20 is IncentivizedERC20 { - /** - * @dev Constructor. - * @param pool The reference to the main Pool contract - * @param name The name of the token - * @param symbol The symbol of the token - * @param decimals The number of decimals of the token - */ - constructor( - IPool pool, - string memory name, - string memory symbol, - uint8 decimals - ) IncentivizedERC20(pool, name, symbol, decimals) { - // Intentionally left blank - } - - /** - * @notice Mints tokens to an account and apply incentives if defined - * @param account The address receiving tokens - * @param amount The amount of tokens to mint - */ - function _mint(address account, uint128 amount) internal virtual { - uint256 oldTotalSupply = _totalSupply; - _totalSupply = oldTotalSupply + amount; - - uint128 oldAccountBalance = _userState[account].balance; - _userState[account].balance = oldAccountBalance + amount; - - IAaveIncentivesController incentivesControllerLocal = _incentivesController; - if (address(incentivesControllerLocal) != address(0)) { - incentivesControllerLocal.handleAction(account, oldTotalSupply, oldAccountBalance); - } - } - - /** - * @notice Burns tokens from an account and apply incentives if defined - * @param account The account whose tokens are burnt - * @param amount The amount of tokens to burn - */ - function _burn(address account, uint128 amount) internal virtual { - uint256 oldTotalSupply = _totalSupply; - _totalSupply = oldTotalSupply - amount; - - uint128 oldAccountBalance = _userState[account].balance; - _userState[account].balance = oldAccountBalance - amount; - - IAaveIncentivesController incentivesControllerLocal = _incentivesController; - - if (address(incentivesControllerLocal) != address(0)) { - incentivesControllerLocal.handleAction(account, oldTotalSupply, oldAccountBalance); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol b/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol deleted file mode 100644 index 119ee2a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/contracts/protocol/tokenization/base/ScaledBalanceTokenBase.sol +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: agpl-3.0 -pragma solidity 0.8.10; - -import {SafeCast} from '../../../dependencies/openzeppelin/contracts/SafeCast.sol'; -import {Errors} from '../../libraries/helpers/Errors.sol'; -import {WadRayMath} from '../../libraries/math/WadRayMath.sol'; -import {IPool} from '../../../interfaces/IPool.sol'; -import {IScaledBalanceToken} from '../../../interfaces/IScaledBalanceToken.sol'; -import {MintableIncentivizedERC20} from './MintableIncentivizedERC20.sol'; - -/** - * @title ScaledBalanceTokenBase - * @author Aave - * @notice Basic ERC20 implementation of scaled balance token - **/ -abstract contract ScaledBalanceTokenBase is MintableIncentivizedERC20, IScaledBalanceToken { - using WadRayMath for uint256; - using SafeCast for uint256; - - /** - * @dev Constructor. - * @param pool The reference to the main Pool contract - * @param name The name of the token - * @param symbol The symbol of the token - * @param decimals The number of decimals of the token - */ - constructor( - IPool pool, - string memory name, - string memory symbol, - uint8 decimals - ) MintableIncentivizedERC20(pool, name, symbol, decimals) { - // Intentionally left blank - } - - /// @inheritdoc IScaledBalanceToken - function scaledBalanceOf(address user) external view override returns (uint256) { - return super.balanceOf(user); - } - - /// @inheritdoc IScaledBalanceToken - function getScaledUserBalanceAndSupply(address user) - external - view - override - returns (uint256, uint256) - { - return (super.balanceOf(user), super.totalSupply()); - } - - /// @inheritdoc IScaledBalanceToken - function scaledTotalSupply() public view virtual override returns (uint256) { - return super.totalSupply(); - } - - /// @inheritdoc IScaledBalanceToken - function getPreviousIndex(address user) external view virtual override returns (uint256) { - return _userState[user].additionalData; - } - - /** - * @notice Implements the basic logic to mint a scaled balance token. - * @param caller The address performing the mint - * @param onBehalfOf The address of the user that will receive the scaled tokens - * @param amount The amount of tokens getting minted - * @param index The next liquidity index of the reserve - * @return `true` if the the previous balance of the user was 0 - **/ - function _mintScaled( - address caller, - address onBehalfOf, - uint256 amount, - uint256 index - ) internal returns (bool) { - uint256 amountScaled = amount.rayDiv(index); - require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT); - - uint256 scaledBalance = super.balanceOf(onBehalfOf); - uint256 balanceIncrease = scaledBalance.rayMul(index) - - scaledBalance.rayMul(_userState[onBehalfOf].additionalData); - - _userState[onBehalfOf].additionalData = index.toUint128(); - - _mint(onBehalfOf, amountScaled.toUint128()); - - uint256 amountToMint = amount + balanceIncrease; - emit Transfer(address(0), onBehalfOf, amountToMint); - emit Mint(caller, onBehalfOf, amountToMint, balanceIncrease, index); - - return (scaledBalance == 0); - } - - /** - * @notice Implements the basic logic to burn a scaled balance token. - * @dev In some instances, a burn transaction will emit a mint event - * if the amount to burn is less than the interest that the user accrued - * @param user The user which debt is burnt - * @param target The address that will receive the underlying, if any - * @param amount The amount getting burned - * @param index The variable debt index of the reserve - **/ - function _burnScaled( - address user, - address target, - uint256 amount, - uint256 index - ) internal { - uint256 amountScaled = amount.rayDiv(index); - require(amountScaled != 0, Errors.INVALID_BURN_AMOUNT); - - uint256 scaledBalance = super.balanceOf(user); - uint256 balanceIncrease = scaledBalance.rayMul(index) - - scaledBalance.rayMul(_userState[user].additionalData); - - _userState[user].additionalData = index.toUint128(); - - _burn(user, amountScaled.toUint128()); - - if (balanceIncrease > amount) { - uint256 amountToMint = balanceIncrease - amount; - emit Transfer(address(0), user, amountToMint); - emit Mint(user, user, amountToMint, balanceIncrease, index); - } else { - uint256 amountToBurn = amount - balanceIncrease; - emit Transfer(user, address(0), amountToBurn); - emit Burn(user, target, amountToBurn, balanceIncrease, index); - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/docker-compose.yml b/lib/morpho-utils/lib/aave-v3-core/docker-compose.yml deleted file mode 100644 index c54b792..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/docker-compose.yml +++ /dev/null @@ -1,26 +0,0 @@ -version: '3.5' - -services: - contracts-env: - env_file: - - .env - build: - context: ./ - working_dir: /src - command: npm run run-env - volumes: - - ./:/src - - $HOME/.tenderly/config.yaml:/root/.tenderly/config.yaml - environment: - MNEMONIC: ${MNEMONIC} - ETHERSCAN_KEY: ${ETHERSCAN_KEY} - INFURA_KEY: ${INFURA_KEY} - ETHERSCAN_NETWORK: ${ETHERSCAN_NETWORK} - TENDERLY_PROJECT: ${TENDERLY_PROJECT} - TENDERLY_USERNAME: ${TENDERLY_USERNAME} - ALCHEMY_KEY: ${ALCHEMY_KEY} - TENDERLY_FORK_ID: ${TENDERLY_FORK_ID} - TENDERLY_HEAD_ID: ${TENDERLY_HEAD_ID} - DEFENDER_API_KEY: ${DEFENDER_API_KEY} - DEFENDER_SECRET_KEY: ${DEFENDER_SECRET_KEY} - NODE_AUTH_TOKEN: ${NODE_AUTH_TOKEN} diff --git a/lib/morpho-utils/lib/aave-v3-core/hardhat.config.ts b/lib/morpho-utils/lib/aave-v3-core/hardhat.config.ts deleted file mode 100644 index 9c56114..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/hardhat.config.ts +++ /dev/null @@ -1,103 +0,0 @@ -import path from 'path'; -import { HardhatUserConfig } from 'hardhat/types'; -// @ts-ignore -import { accounts } from './test-wallets.js'; -import { COVERAGE_CHAINID, HARDHAT_CHAINID } from './helpers/constants'; -import { buildForkConfig } from './helper-hardhat-config'; - -require('dotenv').config(); - -import '@nomiclabs/hardhat-ethers'; -import '@nomiclabs/hardhat-etherscan'; -import 'hardhat-gas-reporter'; -import '@typechain/hardhat'; -import '@typechain/ethers-v5'; -import 'hardhat-deploy'; -import '@tenderly/hardhat-tenderly'; -import 'solidity-coverage'; -import 'hardhat-contract-sizer'; -import 'hardhat-dependency-compiler'; -import { DEFAULT_NAMED_ACCOUNTS } from '@aave/deploy-v3'; - -const DEFAULT_BLOCK_GAS_LIMIT = 12450000; -const HARDFORK = 'london'; - -const hardhatConfig: HardhatUserConfig = { - gasReporter: { - enabled: true, - }, - contractSizer: { - alphaSort: true, - runOnCompile: false, - disambiguatePaths: false, - }, - solidity: { - // Docs for the compiler https://docs.soliditylang.org/en/v0.8.10/using-the-compiler.html - version: '0.8.10', - settings: { - optimizer: { - enabled: true, - runs: 100000, - }, - evmVersion: 'london', - }, - }, - typechain: { - outDir: 'types', - target: 'ethers-v5', - }, - mocha: { - timeout: 0, - bail: false, - }, - tenderly: { - project: process.env.TENDERLY_PROJECT || '', - username: process.env.TENDERLY_USERNAME || '', - forkNetwork: '1', //Network id of the network we want to fork - }, - networks: { - coverage: { - url: 'http://localhost:8555', - chainId: COVERAGE_CHAINID, - throwOnTransactionFailures: true, - throwOnCallFailures: true, - }, - hardhat: { - hardfork: HARDFORK, - blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT, - gas: DEFAULT_BLOCK_GAS_LIMIT, - gasPrice: 8000000000, - chainId: HARDHAT_CHAINID, - throwOnTransactionFailures: true, - throwOnCallFailures: true, - forking: buildForkConfig(), - allowUnlimitedContractSize: true, - accounts: accounts.map(({ secretKey, balance }: { secretKey: string; balance: string }) => ({ - privateKey: secretKey, - balance, - })), - }, - ganache: { - url: 'http://ganache:8545', - accounts: { - mnemonic: 'fox sight canyon orphan hotel grow hedgehog build bless august weather swarm', - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - }, - }, - }, - namedAccounts: { - ...DEFAULT_NAMED_ACCOUNTS, - }, - external: { - contracts: [ - { - artifacts: './temp-artifacts', - deploy: 'node_modules/@aave/deploy-v3/dist/deploy', - }, - ], - }, -}; - -export default hardhatConfig; diff --git a/lib/morpho-utils/lib/aave-v3-core/helper-hardhat-config.ts b/lib/morpho-utils/lib/aave-v3-core/helper-hardhat-config.ts deleted file mode 100644 index 5226545..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/helper-hardhat-config.ts +++ /dev/null @@ -1,52 +0,0 @@ -// @ts-ignore -import { HardhatNetworkForkingUserConfig, HardhatUserConfig } from 'hardhat/types'; -import { eEthereumNetwork, iParamsPerNetwork } from './helpers/types'; - -require('dotenv').config(); - -const INFURA_KEY = process.env.INFURA_KEY || ''; -const ALCHEMY_KEY = process.env.ALCHEMY_KEY || ''; -const TENDERLY_FORK_ID = process.env.TENDERLY_FORK_ID || ''; -const FORK = process.env.FORK || ''; -const FORK_BLOCK_NUMBER = process.env.FORK_BLOCK_NUMBER - ? parseInt(process.env.FORK_BLOCK_NUMBER) - : 0; - -const GWEI = 1000 * 1000 * 1000; - -export const buildForkConfig = (): HardhatNetworkForkingUserConfig | undefined => { - let forkMode: HardhatNetworkForkingUserConfig | undefined; - if (FORK) { - forkMode = { - url: NETWORKS_RPC_URL[FORK], - }; - if (FORK_BLOCK_NUMBER || BLOCK_TO_FORK[FORK]) { - forkMode.blockNumber = FORK_BLOCK_NUMBER || BLOCK_TO_FORK[FORK]; - } - } - return forkMode; -}; - -export const NETWORKS_RPC_URL: iParamsPerNetwork = { - [eEthereumNetwork.kovan]: ALCHEMY_KEY - ? `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_KEY}` - : `https://kovan.infura.io/v3/${INFURA_KEY}`, - [eEthereumNetwork.ropsten]: ALCHEMY_KEY - ? `https://eth-ropsten.alchemyapi.io/v2/${ALCHEMY_KEY}` - : `https://ropsten.infura.io/v3/${INFURA_KEY}`, - [eEthereumNetwork.main]: ALCHEMY_KEY - ? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}` - : `https://mainnet.infura.io/v3/${INFURA_KEY}`, - [eEthereumNetwork.coverage]: 'http://localhost:8555', - [eEthereumNetwork.hardhat]: 'http://localhost:8545', - [eEthereumNetwork.tenderlyMain]: `https://rpc.tenderly.co/fork/${TENDERLY_FORK_ID}`, -}; - -export const BLOCK_TO_FORK: iParamsPerNetwork = { - [eEthereumNetwork.main]: 12406069, - [eEthereumNetwork.kovan]: undefined, - [eEthereumNetwork.ropsten]: undefined, - [eEthereumNetwork.coverage]: undefined, - [eEthereumNetwork.hardhat]: undefined, - [eEthereumNetwork.tenderlyMain]: 12406069, -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/helpers/constants.ts b/lib/morpho-utils/lib/aave-v3-core/helpers/constants.ts deleted file mode 100644 index 2b44397..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/helpers/constants.ts +++ /dev/null @@ -1,34 +0,0 @@ -// ---------------- -// MATH -// ---------------- - -import { BigNumber } from 'ethers'; -import { parseEther, parseUnits } from 'ethers/lib/utils'; - -export const PERCENTAGE_FACTOR = '10000'; -export const HALF_PERCENTAGE = BigNumber.from(PERCENTAGE_FACTOR).div(2).toString(); -export const WAD = BigNumber.from(10).pow(18).toString(); -export const HALF_WAD = BigNumber.from(WAD).div(2).toString(); -export const RAY = BigNumber.from(10).pow(27).toString(); -export const HALF_RAY = BigNumber.from(RAY).div(2).toString(); -export const WAD_RAY_RATIO = parseUnits('1', 9).toString(); -export const oneEther = parseUnits('1', 18); -export const oneRay = parseUnits('1', 27); -export const MAX_UINT_AMOUNT = - '115792089237316195423570985008687907853269984665640564039457584007913129639935'; -export const MAX_BORROW_CAP = '68719476735'; -export const MAX_SUPPLY_CAP = '68719476735'; -export const MAX_UNBACKED_MINT_CAP = '68719476735'; -export const ONE_YEAR = '31536000'; -export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; -export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001'; -// ---------------- -// PROTOCOL GLOBAL PARAMS -// ---------------- -export const MOCK_USD_PRICE_IN_WEI = '5848466240000000'; -export const USD_ADDRESS = '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96'; -export const AAVE_REFERRAL = '0'; - -export const TEST_SNAPSHOT_ID = '0x1'; -export const HARDHAT_CHAINID = 31337; -export const COVERAGE_CHAINID = 1337; diff --git a/lib/morpho-utils/lib/aave-v3-core/helpers/contracts-helpers.ts b/lib/morpho-utils/lib/aave-v3-core/helpers/contracts-helpers.ts deleted file mode 100644 index b7b0344..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/helpers/contracts-helpers.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { ethers } from 'ethers'; -import { signTypedData_v4 } from 'eth-sig-util'; -import { fromRpcSig, ECDSASignature } from 'ethereumjs-util'; -import { tEthereumAddress, tStringTokenSmallUnits } from './types'; -import { MintableERC20 } from '../types/MintableERC20'; -import { getContract } from '@aave/deploy-v3'; -import { impersonateAccountsHardhat } from './misc-utils'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { InitializableImmutableAdminUpgradeabilityProxy } from '../types'; - -declare var hre: HardhatRuntimeEnvironment; - -export type MockTokenMap = { [symbol: string]: MintableERC20 }; - -export const convertToCurrencyDecimals = async (tokenAddress: tEthereumAddress, amount: string) => { - const token = await getContract('IERC20Detailed', tokenAddress); - let decimals = (await token.decimals()).toString(); - - return ethers.utils.parseUnits(amount, decimals); -}; - -export const buildPermitParams = ( - chainId: number, - token: tEthereumAddress, - revision: string, - tokenName: string, - owner: tEthereumAddress, - spender: tEthereumAddress, - nonce: number, - deadline: string, - value: tStringTokenSmallUnits -) => ({ - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - Permit: [ - { name: 'owner', type: 'address' }, - { name: 'spender', type: 'address' }, - { name: 'value', type: 'uint256' }, - { name: 'nonce', type: 'uint256' }, - { name: 'deadline', type: 'uint256' }, - ], - }, - primaryType: 'Permit' as const, - domain: { - name: tokenName, - version: revision, - chainId: chainId, - verifyingContract: token, - }, - message: { - owner, - spender, - value, - nonce, - deadline, - }, -}); - -export const getSignatureFromTypedData = ( - privateKey: string, - typedData: any // TODO: should be TypedData, from eth-sig-utils, but TS doesn't accept it -): ECDSASignature => { - const signature = signTypedData_v4(Buffer.from(privateKey.substring(2, 66), 'hex'), { - data: typedData, - }); - return fromRpcSig(signature); -}; - -export const buildDelegationWithSigParams = ( - chainId: number, - token: tEthereumAddress, - revision: string, - tokenName: string, - delegatee: tEthereumAddress, - nonce: number, - deadline: string, - value: tStringTokenSmallUnits -) => ({ - types: { - EIP712Domain: [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, - ], - DelegationWithSig: [ - { name: 'delegatee', type: 'address' }, - { name: 'value', type: 'uint256' }, - { name: 'nonce', type: 'uint256' }, - { name: 'deadline', type: 'uint256' }, - ], - }, - primaryType: 'DelegationWithSig' as const, - domain: { - name: tokenName, - version: revision, - chainId: chainId, - verifyingContract: token, - }, - message: { - delegatee, - value, - nonce, - deadline, - }, -}); - -export const getProxyImplementation = async (proxyAdminAddress: string, proxyAddress: string) => { - // Impersonate proxy admin - await impersonateAccountsHardhat([proxyAdminAddress]); - const proxyAdminSigner = await hre.ethers.getSigner(proxyAdminAddress); - - const proxy = (await hre.ethers.getContractAt( - 'InitializableImmutableAdminUpgradeabilityProxy', - proxyAddress, - proxyAdminSigner - )) as InitializableImmutableAdminUpgradeabilityProxy; - - const implementationAddress = await proxy.callStatic.implementation(); - return implementationAddress; -}; - -export const getProxyAdmin = async (proxyAddress: string) => { - const EIP1967_ADMIN_SLOT = '0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103'; - const adminStorageSlot = await hre.ethers.provider.getStorageAt( - proxyAddress, - EIP1967_ADMIN_SLOT, - 'latest' - ); - const adminAddress = ethers.utils.defaultAbiCoder - .decode(['address'], adminStorageSlot) - .toString(); - return ethers.utils.getAddress(adminAddress); -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/helpers/misc-utils.ts b/lib/morpho-utils/lib/aave-v3-core/helpers/misc-utils.ts deleted file mode 100644 index cafdfff..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/helpers/misc-utils.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Wallet, BigNumber } from 'ethers'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; - -declare var hre: HardhatRuntimeEnvironment; - -export const createRandomAddress = () => Wallet.createRandom().address; - -export const timeLatest = async () => { - const block = await hre.ethers.provider.getBlock('latest'); - return BigNumber.from(block.timestamp); -}; - -export const setBlocktime = async (time: number) => { - await hre.ethers.provider.send('evm_setNextBlockTimestamp', [time]); -}; - -export const setAutomine = async (activate: boolean) => { - await hre.network.provider.send('evm_setAutomine', [activate]); - if (activate) await hre.network.provider.send('evm_mine', []); -}; - -export const setAutomineEvm = async (activate: boolean) => { - await hre.network.provider.send('evm_setAutomine', [activate]); -}; - -export const impersonateAccountsHardhat = async (accounts: string[]) => { - if (process.env.TENDERLY === 'true') { - return; - } - // eslint-disable-next-line no-restricted-syntax - for (const account of accounts) { - // eslint-disable-next-line no-await-in-loop - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [account], - }); - } -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/helpers/tenderly-utils.ts b/lib/morpho-utils/lib/aave-v3-core/helpers/tenderly-utils.ts deleted file mode 100644 index 27cf57a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/helpers/tenderly-utils.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { HardhatRuntimeEnvironment } from 'hardhat/types'; - -declare var hre: HardhatRuntimeEnvironment; - -export const usingTenderly = () => - hre && - ((hre as HardhatRuntimeEnvironment).network.name.includes('tenderly') || - process.env.TENDERLY === 'true'); diff --git a/lib/morpho-utils/lib/aave-v3-core/helpers/types.ts b/lib/morpho-utils/lib/aave-v3-core/helpers/types.ts deleted file mode 100644 index 79cd5f3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/helpers/types.ts +++ /dev/null @@ -1,414 +0,0 @@ -import { BigNumber } from 'ethers'; - -export interface SymbolMap { - [symbol: string]: T; -} - -export type eNetwork = eEthereumNetwork; - -export enum eEthereumNetwork { - kovan = 'kovan', - ropsten = 'ropsten', - main = 'main', - coverage = 'coverage', - hardhat = 'hardhat', - tenderlyMain = 'tenderlyMain', -} - -export enum eContractid { - Example = 'Example', - PoolAddressesProvider = 'PoolAddressesProvider', - MintableERC20 = 'MintableERC20', - MintableDelegationERC20 = 'MintableDelegationERC20', - PoolAddressesProviderRegistry = 'PoolAddressesProviderRegistry', - ACLManager = 'ACLManager', - PoolParametersProvider = 'PoolParametersProvider', - PoolConfigurator = 'PoolConfigurator', - ValidationLogic = 'ValidationLogic', - ReserveLogic = 'ReserveLogic', - GenericLogic = 'GenericLogic', - SupplyLogic = 'SupplyLogic', - BorrowLogic = 'BorrowLogic', - FlashLoanLogic = 'FlashLoanLogic', - LiquidationLogic = 'LiquidationLogic', - BridgeLogic = 'BridgeLogic', - EModeLogic = 'EModeLogic', - ConfiguratorLogic = 'ConfiguratorLogic', - Pool = 'Pool', - PriceOracle = 'PriceOracle', - Proxy = 'Proxy', - MockAggregator = 'MockAggregator', - AaveOracle = 'AaveOracle', - DefaultReserveInterestRateStrategy = 'DefaultReserveInterestRateStrategy', - InitializableImmutableAdminUpgradeabilityProxy = 'InitializableImmutableAdminUpgradeabilityProxy', - MockFlashLoanReceiver = 'MockFlashLoanReceiver', - AToken = 'AToken', - MockAToken = 'MockAToken', - DelegationAwareAToken = 'DelegationAwareAToken', - MockStableDebtToken = 'MockStableDebtToken', - MockVariableDebtToken = 'MockVariableDebtToken', - AaveProtocolDataProvider = 'AaveProtocolDataProvider', - IERC20Detailed = 'IERC20Detailed', - StableDebtToken = 'StableDebtToken', - VariableDebtToken = 'VariableDebtToken', - FeeProvider = 'FeeProvider', - TokenDistributor = 'TokenDistributor', - ReservesSetupHelper = 'ReservesSetupHelper', - WETH = 'WETH', - WETHMocked = 'WETHMocked', - PoolImpl = 'PoolImpl', - PoolConfiguratorImpl = 'PoolConfiguratorImpl', - MockIncentivesController = 'MockIncentivesController', - MockReserveConfiguration = 'MockReserveConfiguration', - MockPool = 'MockPool', - MockInitializableImple = 'MockInitializableImple', - MockInitializableImpleV2 = 'MockInitializableImpleV2', - MockInitializableFromConstructorImple = 'MockInitializableFromConstructorImple', - MockReentrantInitializableImple = 'MockReentrantInitializableImple', -} - -/* - * Error messages - */ -export enum ProtocolErrors { - CALLER_NOT_POOL_ADMIN = '1', // 'The caller of the function is not a pool admin' - CALLER_NOT_EMERGENCY_ADMIN = '2', // 'The caller of the function is not an emergency admin' - CALLER_NOT_POOL_OR_EMERGENCY_ADMIN = '3', // 'The caller of the function is not a pool or emergency admin' - CALLER_NOT_RISK_OR_POOL_ADMIN = '4', // 'The caller of the function is not a risk or pool admin' - CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN = '5', // 'The caller of the function is not an asset listing or pool admin' - CALLER_NOT_BRIDGE = '6', // 'The caller of the function is not a bridge' - ADDRESSES_PROVIDER_NOT_REGISTERED = '7', // 'Pool addresses provider is not registered' - INVALID_ADDRESSES_PROVIDER_ID = '8', // 'Invalid id for the pool addresses provider' - NOT_CONTRACT = '9', // 'Address is not a contract' - CALLER_NOT_POOL_CONFIGURATOR = '10', // 'The caller of the function is not the pool configurator' - CALLER_NOT_ATOKEN = '11', // 'The caller of the function is not an AToken' - INVALID_ADDRESSES_PROVIDER = '12', // 'The address of the pool addresses provider is invalid' - INVALID_FLASHLOAN_EXECUTOR_RETURN = '13', // 'Invalid return value of the flashloan executor function' - RESERVE_ALREADY_ADDED = '14', // 'Reserve has already been added to reserve list' - NO_MORE_RESERVES_ALLOWED = '15', // 'Maximum amount of reserves in the pool reached' - EMODE_CATEGORY_RESERVED = '16', // 'Zero eMode category is reserved for volatile heterogeneous assets' - INVALID_EMODE_CATEGORY_ASSIGNMENT = '17', // 'Invalid eMode category assignment to asset' - RESERVE_LIQUIDITY_NOT_ZERO = '18', // 'The liquidity of the reserve needs to be 0' - FLASHLOAN_PREMIUM_INVALID = '19', // 'Invalid flashloan premium' - INVALID_RESERVE_PARAMS = '20', // 'Invalid risk parameters for the reserve' - INVALID_EMODE_CATEGORY_PARAMS = '21', // 'Invalid risk parameters for the eMode category' - BRIDGE_PROTOCOL_FEE_INVALID = '22', // 'Invalid bridge protocol fee' - CALLER_MUST_BE_POOL = '23', // 'The caller of this function must be a pool' - INVALID_MINT_AMOUNT = '24', // 'Invalid amount to mint' - INVALID_BURN_AMOUNT = '25', // 'Invalid amount to burn' - INVALID_AMOUNT = '26', // 'Amount must be greater than 0' - RESERVE_INACTIVE = '27', // 'Action requires an active reserve' - RESERVE_FROZEN = '28', // 'Action cannot be performed because the reserve is frozen' - RESERVE_PAUSED = '29', // 'Action cannot be performed because the reserve is paused' - BORROWING_NOT_ENABLED = '30', // 'Borrowing is not enabled' - STABLE_BORROWING_NOT_ENABLED = '31', // 'Stable borrowing is not enabled' - NOT_ENOUGH_AVAILABLE_USER_BALANCE = '32', // 'User cannot withdraw more than the available balance' - INVALID_INTEREST_RATE_MODE_SELECTED = '33', // 'Invalid interest rate mode selected' - COLLATERAL_BALANCE_IS_ZERO = '34', // 'The collateral balance is 0' - HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '35', // 'Health factor is lesser than the liquidation threshold' - COLLATERAL_CANNOT_COVER_NEW_BORROW = '36', // 'There is not enough collateral to cover a new borrow' - COLLATERAL_SAME_AS_BORROWING_CURRENCY = '37', // 'Collateral is (mostly) the same currency that is being borrowed' - AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '38', // 'The requested amount is greater than the max loan size in stable rate mode' - NO_DEBT_OF_SELECTED_TYPE = '39', // 'For repayment of a specific type of debt, the user needs to have debt that type' - NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '40', // 'To repay on behalf of a user an explicit amount to repay is needed' - NO_OUTSTANDING_STABLE_DEBT = '41', // 'User does not have outstanding stable rate debt on this reserve' - NO_OUTSTANDING_VARIABLE_DEBT = '42', // 'User does not have outstanding variable rate debt on this reserve' - UNDERLYING_BALANCE_ZERO = '43', // 'The underlying balance needs to be greater than 0' - INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '44', // 'Interest rate rebalance conditions were not met' - HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '45', // 'Health factor is not below the threshold' - COLLATERAL_CANNOT_BE_LIQUIDATED = '46', // 'The collateral chosen cannot be liquidated' - SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '47', // 'User did not borrow the specified currency' - SAME_BLOCK_BORROW_REPAY = '48', // 'Borrow and repay in same block is not allowed' - INCONSISTENT_FLASHLOAN_PARAMS = '49', // 'Inconsistent flashloan parameters' - BORROW_CAP_EXCEEDED = '50', // 'Borrow cap is exceeded' - SUPPLY_CAP_EXCEEDED = '51', // 'Supply cap is exceeded' - UNBACKED_MINT_CAP_EXCEEDED = '52', // 'Unbacked mint cap is exceeded' - DEBT_CEILING_EXCEEDED = '53', // 'Debt ceiling is exceeded' - ATOKEN_SUPPLY_NOT_ZERO = '54', // 'AToken supply is not zero' - STABLE_DEBT_NOT_ZERO = '55', // 'Stable debt supply is not zero' - VARIABLE_DEBT_SUPPLY_NOT_ZERO = '56', // 'Variable debt supply is not zero' - LTV_VALIDATION_FAILED = '57', // 'Ltv validation failed' - INCONSISTENT_EMODE_CATEGORY = '58', // 'Inconsistent eMode category' - PRICE_ORACLE_SENTINEL_CHECK_FAILED = '59', // 'Price oracle sentinel validation failed' - ASSET_NOT_BORROWABLE_IN_ISOLATION = '60', // 'Asset is not borrowable in isolation mode' - RESERVE_ALREADY_INITIALIZED = '61', // 'Reserve has already been initialized' - USER_IN_ISOLATION_MODE = '62', // 'User is in isolation mode' - INVALID_LTV = '63', // 'Invalid ltv parameter for the reserve' - INVALID_LIQ_THRESHOLD = '64', // 'Invalid liquidity threshold parameter for the reserve' - INVALID_LIQ_BONUS = '65', // 'Invalid liquidity bonus parameter for the reserve' - INVALID_DECIMALS = '66', // 'Invalid decimals parameter of the underlying asset of the reserve' - INVALID_RESERVE_FACTOR = '67', // 'Invalid reserve factor parameter for the reserve' - INVALID_BORROW_CAP = '68', // 'Invalid borrow cap for the reserve' - INVALID_SUPPLY_CAP = '69', // 'Invalid supply cap for the reserve' - INVALID_LIQUIDATION_PROTOCOL_FEE = '70', // 'Invalid liquidation protocol fee for the reserve' - INVALID_EMODE_CATEGORY = '71', // 'Invalid eMode category for the reserve' - INVALID_UNBACKED_MINT_CAP = '72', // 'Invalid unbacked mint cap for the reserve' - INVALID_DEBT_CEILING = '73', // 'Invalid debt ceiling for the reserve - INVALID_RESERVE_INDEX = '74', // 'Invalid reserve index' - ACL_ADMIN_CANNOT_BE_ZERO = '75', // 'ACL admin cannot be set to the zero address' - INCONSISTENT_PARAMS_LENGTH = '76', // 'Array parameters that should be equal length are not' - ZERO_ADDRESS_NOT_VALID = '77', // 'Zero address not valid' - INVALID_EXPIRATION = '78', // 'Invalid expiration' - INVALID_SIGNATURE = '79', // 'Invalid signature' - OPERATION_NOT_SUPPORTED = '80', // 'Operation not supported' - DEBT_CEILING_NOT_ZERO = '81', // 'Debt ceiling is not zero' - ASSET_NOT_LISTED = '82', // 'Asset is not listed' - INVALID_OPTIMAL_USAGE_RATIO = '83', // 'Invalid optimal usage ratio' - INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = '84', // 'Invalid optimal stable to total debt ratio' - UNDERLYING_CANNOT_BE_RESCUED = '85', // 'The underlying asset cannot be rescued' - ADDRESSES_PROVIDER_ALREADY_ADDED = '86', // 'Reserve has already been added to reserve list' - POOL_ADDRESSES_DO_NOT_MATCH = '87', // 'The token implementation pool address and the pool address provided by the initializing pool do not match' - STABLE_BORROWING_ENABLED = '88', // 'Stable borrowing is enabled' - SILOED_BORROWING_VIOLATION = '89', // user is trying to violate the siloed borrowing rule - RESERVE_DEBT_NOT_ZERO = '90', // the total debt of the reserve needs to be 0 - // SafeCast - SAFECAST_UINT128_OVERFLOW = "SafeCast: value doesn't fit in 128 bits", - - // Ownable - OWNABLE_ONLY_OWNER = 'Ownable: caller is not the owner', - - // ERC20 - ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE = 'ERC20: transfer amount exceeds balance', - - // old - - INVALID_FROM_BALANCE_AFTER_TRANSFER = 'Invalid from balance after transfer', - INVALID_TO_BALANCE_AFTER_TRANSFER = 'Invalid from balance after transfer', - INVALID_HF = 'Invalid health factor', -} - -export type tEthereumAddress = string; -export type tStringTokenBigUnits = string; // 1 ETH, or 10e6 USDC or 10e18 DAI -export type tBigNumberTokenBigUnits = BigNumber; -export type tStringTokenSmallUnits = string; // 1 wei, or 1 basic unit of USDC, or 1 basic unit of DAI -export type tBigNumberTokenSmallUnits = BigNumber; - -export interface iAssetCommon { - [key: string]: T; -} -export interface iAssetBase { - WETH: T; - DAI: T; - TUSD: T; - USDC: T; - USDT: T; - SUSD: T; - AAVE: T; - BAT: T; - MKR: T; - LINK: T; - KNC: T; - WBTC: T; - MANA: T; - ZRX: T; - SNX: T; - BUSD: T; - YFI: T; - UNI: T; - USD: T; - REN: T; - ENJ: T; - UniDAIWETH: T; - UniWBTCWETH: T; - UniAAVEWETH: T; - UniBATWETH: T; - UniDAIUSDC: T; - UniCRVWETH: T; - UniLINKWETH: T; - UniMKRWETH: T; - UniRENWETH: T; - UniSNXWETH: T; - UniUNIWETH: T; - UniUSDCWETH: T; - UniWBTCUSDC: T; - UniYFIWETH: T; - BptWBTCWETH: T; - BptBALWETH: T; - WMATIC: T; - STAKE: T; - xSUSHI: T; -} - -export type iAssetsWithoutETH = Omit, 'ETH'>; - -export type iAssetsWithoutUSD = Omit, 'USD'>; - -export type iAavePoolAssets = Pick< - iAssetsWithoutUSD, - | 'DAI' - | 'TUSD' - | 'USDC' - | 'USDT' - | 'SUSD' - | 'AAVE' - | 'BAT' - | 'MKR' - | 'LINK' - | 'KNC' - | 'WBTC' - | 'MANA' - | 'ZRX' - | 'SNX' - | 'BUSD' - | 'WETH' - | 'YFI' - | 'UNI' - | 'REN' - | 'ENJ' - | 'xSUSHI' ->; - -export type iMultiPoolsAssets = iAssetCommon | iAavePoolAssets; - -export type iAssetAggregatorBase = iAssetsWithoutETH; - -export enum TokenContractId { - DAI = 'DAI', - AAVE = 'AAVE', - TUSD = 'TUSD', - BAT = 'BAT', - WETH = 'WETH', - USDC = 'USDC', - USDT = 'USDT', - SUSD = 'SUSD', - ZRX = 'ZRX', - MKR = 'MKR', - WBTC = 'WBTC', - LINK = 'LINK', - KNC = 'KNC', - MANA = 'MANA', - REN = 'REN', - SNX = 'SNX', - BUSD = 'BUSD', - USD = 'USD', - YFI = 'YFI', - UNI = 'UNI', - ENJ = 'ENJ', - UniDAIWETH = 'UniDAIWETH', - UniWBTCWETH = 'UniWBTCWETH', - UniAAVEWETH = 'UniAAVEWETH', - UniBATWETH = 'UniBATWETH', - UniDAIUSDC = 'UniDAIUSDC', - UniCRVWETH = 'UniCRVWETH', - UniLINKWETH = 'UniLINKWETH', - UniMKRWETH = 'UniMKRWETH', - UniRENWETH = 'UniRENWETH', - UniSNXWETH = 'UniSNXWETH', - UniUNIWETH = 'UniUNIWETH', - UniUSDCWETH = 'UniUSDCWETH', - UniWBTCUSDC = 'UniWBTCUSDC', - UniYFIWETH = 'UniYFIWETH', - BptWBTCWETH = 'BptWBTCWETH', - BptBALWETH = 'BptBALWETH', - WMATIC = 'WMATIC', - STAKE = 'STAKE', - xSUSHI = 'xSUSHI', -} - -export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams { - aTokenImpl: eContractid; - reserveFactor: string; - supplyCap: string; - strategy: IInterestRateStrategyParams; -} - -export interface IInterestRateStrategyParams { - name: string; - optimalUsageRatio: string; - baseVariableBorrowRate: string; - variableRateSlope1: string; - variableRateSlope2: string; - stableRateSlope1: string; - stableRateSlope2: string; - baseStableRateOffset: string; - stableRateExcessOffset: string; - optimalStableToTotalDebtRatio: string; -} - -export interface IReserveBorrowParams { - borrowingEnabled: boolean; - stableBorrowRateEnabled: boolean; - reserveDecimals: string; - borrowCap: string; -} - -export interface IReserveCollateralParams { - baseLTVAsCollateral: string; - liquidationThreshold: string; - liquidationBonus: string; -} -export interface IMarketRates { - borrowRate: string; -} - -export type iParamsPerNetwork = iEthereumParamsPerNetwork; - -export interface iParamsPerNetworkAll extends iEthereumParamsPerNetwork {} - -export interface iEthereumParamsPerNetwork { - [eEthereumNetwork.coverage]: T; - [eEthereumNetwork.kovan]: T; - [eEthereumNetwork.ropsten]: T; - [eEthereumNetwork.main]: T; - [eEthereumNetwork.hardhat]: T; - [eEthereumNetwork.tenderlyMain]: T; -} - -export enum RateMode { - None = '0', - Stable = '1', - Variable = '2', -} - -export interface IProtocolGlobalConfig { - TokenDistributorPercentageBase: string; - MockUsdPriceInWei: string; - UsdAddress: tEthereumAddress; - NilAddress: tEthereumAddress; - OneAddress: tEthereumAddress; - AaveReferral: string; -} - -export interface IMocksConfig { - AllAssetsInitialPrices: iAssetBase; -} - -export interface IRate { - borrowRate: string; -} - -export interface ICommonConfiguration { - MarketId: string; - ATokenNamePrefix: string; - StableDebtTokenNamePrefix: string; - VariableDebtTokenNamePrefix: string; - SymbolPrefix: string; - ProviderId: number; - ProtocolGlobalParams: IProtocolGlobalConfig; - Mocks: IMocksConfig; - ProviderRegistry: tEthereumAddress | undefined; - ProviderRegistryOwner: tEthereumAddress | undefined; - PoolConfigurator: tEthereumAddress | undefined; - Pool: tEthereumAddress | undefined; - TokenDistributor: tEthereumAddress | undefined; - AaveOracle: tEthereumAddress | undefined; - FallbackOracle: tEthereumAddress | undefined; - ChainlinkAggregator: tEthereumAddress | undefined; - PoolAdmin: tEthereumAddress | undefined; - PoolAdminIndex: number; - EmergencyAdmin: tEthereumAddress | undefined; - EmergencyAdminIndex: number; - ReserveAssets: SymbolMap | SymbolMap; - ReservesConfig: iMultiPoolsAssets; - ATokenDomainSeparator: string; - WETH: tEthereumAddress | undefined; - WrappedNativeToken: tEthereumAddress | undefined; - ReserveFactorTreasuryAddress: tEthereumAddress; - IncentivesController: tEthereumAddress | undefined; -} - -export interface IAaveConfiguration extends ICommonConfiguration { - ReservesConfig: iMultiPoolsAssets; -} - -export type PoolConfiguration = ICommonConfiguration | IAaveConfiguration; diff --git a/lib/morpho-utils/lib/aave-v3-core/package-lock.json b/lib/morpho-utils/lib/aave-v3-core/package-lock.json deleted file mode 100644 index d424992..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/package-lock.json +++ /dev/null @@ -1,43504 +0,0 @@ -{ - "name": "@aave/core-v3", - "version": "1.16.1", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "@aave/core-v3", - "version": "1.16.1", - "license": "BUSL-1.1", - "dependencies": { - "@nomiclabs/hardhat-etherscan": "^2.1.7", - "axios-curlirize": "^1.3.7", - "tmp-promise": "^3.0.2" - }, - "devDependencies": { - "@aave/deploy-v3": "^1.21.1-beta.4", - "@aave/periphery-v3": "^1.13.1-beta.1", - "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", - "@tenderly/hardhat-tenderly": "^1.1.0-beta.5", - "@typechain/ethers-v5": "^7.2.0", - "@typechain/hardhat": "^2.3.1", - "@types/chai": "^4.2.11", - "@types/lowdb": "1.0.9", - "@types/mocha": "7.0.2", - "@types/node": "14.0.5", - "chai": "^4.3.4", - "chai-bignumber": "3.0.0", - "defender-relay-client": "^1.7.0", - "dotenv": "^8.2.0", - "eth-sig-util": "2.5.3", - "ethereum-waffle": "3.0.2", - "ethereumjs-util": "7.0.2", - "ethers": "^5.4.7", - "globby": "^11.0.1", - "hardhat": "^2.6.8", - "hardhat-contract-sizer": "^2.0.3", - "hardhat-dependency-compiler": "^1.1.2", - "hardhat-deploy": "^0.9.4", - "hardhat-gas-reporter": "^1.0.0", - "husky": "^4.2.5", - "lowdb": "1.0.0", - "prettier": "^2.4.1", - "prettier-plugin-solidity": "^1.0.0-alpha.53", - "pretty-quick": "^3.1.1", - "solidity-coverage": "^0.7.17", - "ts-generator": "^0.1.1", - "ts-node": "^8.10.2", - "tslint": "^6.1.2", - "tslint-config-prettier": "^1.18.0", - "tslint-plugin-prettier": "^2.3.0", - "typechain": "^5.2.0", - "typescript": "^4.4.4" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aave/core-v3": { - "version": "1.14.2", - "resolved": "https://npm.pkg.github.com/download/@aave/core-v3/1.14.2/4f9d7f392d3801f1e30a8336d2eaba73a38c43f60f096871880683abccbbeac2", - "integrity": "sha512-3nq/WHuKpVU15yT3vemSx2gr8wzQuuzBjSailnnXbA4fMzHavZQLBTE0eLIbNFPkGAwx+jnECYZ2TuSnEqzMHQ==", - "dev": true, - "license": "BUSL-1.1", - "dependencies": { - "@nomiclabs/hardhat-etherscan": "^2.1.7", - "axios-curlirize": "^1.3.7", - "tmp-promise": "^3.0.2" - } - }, - "node_modules/@aave/deploy-v3": { - "version": "1.21.1-beta.4", - "resolved": "https://npm.pkg.github.com/download/@aave/deploy-v3/1.21.1-beta.4/379cc7907d7c26584ae52205062b10390b12562c1f20ee40cb476b3f8b36f6d7", - "integrity": "sha512-DCTxOk7nLhIasL14xSPUb+MqCH6NroX0JkcngrCyOj975s9ggrKcfqkVcew/zpHXPyJHRoBIb0fWjBg1vXBfjQ==", - "dev": true, - "license": "AGPLv3", - "dependencies": { - "defender-relay-client": "^1.11.1" - }, - "peerDependencies": { - "@aave/core-v3": "1.x", - "@aave/periphery-v3": "1.x", - "hardhat": "^2.6.1" - } - }, - "node_modules/@aave/periphery-v3": { - "version": "1.13.1-beta.1", - "resolved": "https://npm.pkg.github.com/download/@aave/periphery-v3/1.13.1-beta.1/68696c89f12caec5d977ae3b8f8a67313899079c7ca918b397d1f2d9d2455c69", - "integrity": "sha512-ErBWUBKkZMtop1EjsL/TgwB3Lxj++sHZd6UFiG4andKy0/AfaZjteHs2JZQHl1F+cRjz89spwsOJ9CKXkejUnA==", - "dev": true, - "license": "AGPLv3", - "dependencies": { - "@aave/core-v3": "^1.14.2" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", - "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "deprecated": "Please use @ensdomains/ens-contracts", - "dev": true, - "dependencies": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - } - }, - "node_modules/@ensdomains/ens/node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/@ensdomains/ens/node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/@ensdomains/ens/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@ensdomains/ens/node_modules/require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "node_modules/@ensdomains/ens/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@ensdomains/ens/node_modules/solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "dependencies": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - }, - "bin": { - "solcjs": "solcjs" - } - }, - "node_modules/@ensdomains/ens/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "node_modules/@ensdomains/ens/node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ensdomains/ens/node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "node_modules/@ensdomains/ens/node_modules/yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", - "dev": true, - "dependencies": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "node_modules/@ensdomains/ens/node_modules/yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - }, - "node_modules/@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "deprecated": "Please use @ensdomains/ens-contracts", - "dev": true - }, - "node_modules/@ethereum-waffle/chai": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.1.tgz", - "integrity": "sha512-8mjgjWCe8XSCWuyJgVtJY8sm00VTczGBTDxBejgEBWN/J9x7QD8jdmWW8bfxdnqZbxiDCTvRFL58Wmd254BEqQ==", - "dev": true, - "dependencies": { - "@ethereum-waffle/provider": "^3.4.0", - "ethers": "^5.4.7" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereum-waffle/compiler": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.0.tgz", - "integrity": "sha512-a2wxGOoB9F1QFRE+Om7Cz2wn+pxM/o7a0a6cbwhaS2lECJgFzeN9xEkVrKahRkF4gEfXGcuORg4msP0Asxezlw==", - "dev": true, - "dependencies": { - "@resolver-engine/imports": "^0.3.3", - "@resolver-engine/imports-fs": "^0.3.3", - "@typechain/ethers-v5": "^2.0.0", - "@types/mkdirp": "^0.5.2", - "@types/node-fetch": "^2.5.5", - "ethers": "^5.0.1", - "mkdirp": "^0.5.1", - "node-fetch": "^2.6.1", - "solc": "^0.6.3", - "ts-generator": "^0.1.1", - "typechain": "^3.0.0" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereum-waffle/compiler/node_modules/@typechain/ethers-v5": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", - "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==", - "dev": true, - "dependencies": { - "ethers": "^5.0.2" - }, - "peerDependencies": { - "ethers": "^5.0.0", - "typechain": "^3.0.0" - } - }, - "node_modules/@ethereum-waffle/compiler/node_modules/ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", - "dev": true, - "peerDependencies": { - "typescript": ">=3.7.0" - } - }, - "node_modules/@ethereum-waffle/compiler/node_modules/typechain": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", - "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==", - "dev": true, - "dependencies": { - "command-line-args": "^4.0.7", - "debug": "^4.1.1", - "fs-extra": "^7.0.0", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "ts-essentials": "^6.0.3", - "ts-generator": "^0.1.1" - }, - "bin": { - "typechain": "dist/cli/cli.js" - } - }, - "node_modules/@ethereum-waffle/ens": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.3.1.tgz", - "integrity": "sha512-xSjNWnT2Iwii3J3XGqD+F5yLEOzQzLHNLGfI5KIXdtQ4FHgReW/AMGRgPPLi+n+SP08oEQWJ3sEKrvbFlwJuaA==", - "dev": true, - "dependencies": { - "@ensdomains/ens": "^0.4.4", - "@ensdomains/resolver": "^0.2.4", - "ethers": "^5.5.2" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereum-waffle/mock-contract": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.3.1.tgz", - "integrity": "sha512-h9yChF7IkpJLODg/o9/jlwKwTcXJLSEIq3gewgwUJuBHnhPkJGekcZvsTbximYc+e42QUZrDUATSuTCIryeCEA==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.5.0", - "ethers": "^5.5.2" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereum-waffle/provider": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.1.tgz", - "integrity": "sha512-5iDte7c9g9N1rTRE/P4npwk1Hus/wA2yH850X6sP30mr1IrwSG9NKn6/2SOQkAVJnh9jqyLVg2X9xCODWL8G4A==", - "dev": true, - "dependencies": { - "@ethereum-waffle/ens": "^3.3.1", - "ethers": "^5.5.2", - "ganache-core": "^2.13.2", - "patch-package": "^6.2.2", - "postinstall-postinstall": "^2.1.0" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/@ethereumjs/block": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz", - "integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==", - "dependencies": { - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "ethereumjs-util": "^7.1.3", - "merkle-patricia-tree": "^4.2.2" - } - }, - "node_modules/@ethereumjs/block/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ethereumjs/block/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/@ethereumjs/block/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@ethereumjs/blockchain": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz", - "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==", - "dependencies": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/ethash": "^1.1.0", - "debug": "^2.2.0", - "ethereumjs-util": "^7.1.3", - "level-mem": "^5.0.1", - "lru-cache": "^5.1.1", - "semaphore-async-await": "^1.5.1" - } - }, - "node_modules/@ethereumjs/blockchain/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ethereumjs/blockchain/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/@ethereumjs/blockchain/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@ethereumjs/blockchain/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@ethereumjs/blockchain/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/@ethereumjs/common": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz", - "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==", - "dependencies": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.3" - } - }, - "node_modules/@ethereumjs/common/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ethereumjs/common/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/@ethereumjs/common/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@ethereumjs/ethash": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", - "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", - "dependencies": { - "@ethereumjs/block": "^3.5.0", - "@types/levelup": "^4.3.0", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.1.1", - "miller-rabin": "^4.0.0" - } - }, - "node_modules/@ethereumjs/ethash/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ethereumjs/ethash/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/@ethereumjs/ethash/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@ethereumjs/tx": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz", - "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==", - "dependencies": { - "@ethereumjs/common": "^2.6.0", - "ethereumjs-util": "^7.1.3" - } - }, - "node_modules/@ethereumjs/tx/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ethereumjs/tx/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/@ethereumjs/tx/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@ethereumjs/vm": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz", - "integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==", - "dependencies": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "async-eventemitter": "^0.2.4", - "core-js-pure": "^3.0.1", - "debug": "^2.2.0", - "ethereumjs-util": "^7.1.3", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.2", - "rustbn.js": "~0.2.0" - } - }, - "node_modules/@ethereumjs/vm/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ethereumjs/vm/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/@ethereumjs/vm/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@ethereumjs/vm/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@ethereumjs/vm/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/@ethersproject/abi": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz", - "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz", - "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz", - "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz", - "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/rlp": "^5.5.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz", - "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", - "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", - "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "bn.js": "^4.11.9" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz", - "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", - "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.5.0", - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0" - } - }, - "node_modules/@ethersproject/hardware-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.5.0.tgz", - "integrity": "sha512-oZh/Ps/ohxFQdKVeMw8wpw0xZpL+ndsRlQwNE3Eki2vLeH2to14de6fNrgETZtAbAhzglH6ES9Nlx1+UuqvvYg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "peer": true, - "dependencies": { - "@ledgerhq/hw-app-eth": "5.27.2", - "@ledgerhq/hw-transport": "5.26.0", - "@ledgerhq/hw-transport-u2f": "5.26.0", - "ethers": "^5.5.0" - }, - "optionalDependencies": { - "@ledgerhq/hw-transport-node-hid": "5.26.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", - "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", - "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", - "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", - "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.2.tgz", - "integrity": "sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", - "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/sha2": "^5.5.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", - "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.2.tgz", - "integrity": "sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/random": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz", - "integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", - "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", - "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/solidity": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", - "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", - "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz", - "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", - "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", - "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/json-wallets": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz", - "integrity": "sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", - "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ledgerhq/cryptoassets": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-5.53.0.tgz", - "integrity": "sha512-M3ibc3LRuHid5UtL7FI3IC6nMEppvly98QHFoSa7lJU0HDzQxY6zHec/SPM4uuJUC8sXoGVAiRJDkgny54damw==", - "dev": true, - "peer": true, - "dependencies": { - "invariant": "2" - } - }, - "node_modules/@ledgerhq/devices": { - "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.51.1.tgz", - "integrity": "sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA==", - "dev": true, - "peer": true, - "dependencies": { - "@ledgerhq/errors": "^5.50.0", - "@ledgerhq/logs": "^5.50.0", - "rxjs": "6", - "semver": "^7.3.5" - } - }, - "node_modules/@ledgerhq/errors": { - "version": "5.50.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-5.50.0.tgz", - "integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==", - "dev": true, - "peer": true - }, - "node_modules/@ledgerhq/hw-app-eth": { - "version": "5.27.2", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-5.27.2.tgz", - "integrity": "sha512-llNdrE894cCN8j6yxJEUniciyLVcLmu5N0UmIJLOObztG+5rOF4bX54h4SreTWK+E10Z0CzHSeyE5Lz/tVcqqQ==", - "dev": true, - "peer": true, - "dependencies": { - "@ledgerhq/cryptoassets": "^5.27.2", - "@ledgerhq/errors": "^5.26.0", - "@ledgerhq/hw-transport": "^5.26.0", - "bignumber.js": "^9.0.1", - "rlp": "^2.2.6" - } - }, - "node_modules/@ledgerhq/hw-transport": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.26.0.tgz", - "integrity": "sha512-NFeJOJmyEfAX8uuIBTpocWHcz630sqPcXbu864Q+OCBm4EK5UOKV1h/pX7e0xgNIKY8zhJ/O4p4cIZp9tnXLHQ==", - "dev": true, - "peer": true, - "dependencies": { - "@ledgerhq/devices": "^5.26.0", - "@ledgerhq/errors": "^5.26.0", - "events": "^3.2.0" - } - }, - "node_modules/@ledgerhq/hw-transport-node-hid": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.26.0.tgz", - "integrity": "sha512-qhaefZVZatJ6UuK8Wb6WSFNOLWc2mxcv/xgsfKi5HJCIr4bPF/ecIeN+7fRcEaycxj4XykY6Z4A7zDVulfFH4w==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@ledgerhq/devices": "^5.26.0", - "@ledgerhq/errors": "^5.26.0", - "@ledgerhq/hw-transport": "^5.26.0", - "@ledgerhq/hw-transport-node-hid-noevents": "^5.26.0", - "@ledgerhq/logs": "^5.26.0", - "lodash": "^4.17.20", - "node-hid": "1.3.0", - "usb": "^1.6.3" - } - }, - "node_modules/@ledgerhq/hw-transport-node-hid-noevents": { - "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz", - "integrity": "sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@ledgerhq/devices": "^5.51.1", - "@ledgerhq/errors": "^5.50.0", - "@ledgerhq/hw-transport": "^5.51.1", - "@ledgerhq/logs": "^5.50.0", - "node-hid": "2.1.1" - } - }, - "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/@ledgerhq/hw-transport": { - "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz", - "integrity": "sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@ledgerhq/devices": "^5.51.1", - "@ledgerhq/errors": "^5.50.0", - "events": "^3.3.0" - } - }, - "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/node-hid": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.1.tgz", - "integrity": "sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "peer": true, - "dependencies": { - "bindings": "^1.5.0", - "node-addon-api": "^3.0.2", - "prebuild-install": "^6.0.0" - }, - "bin": { - "hid-showdevices": "src/show-devices.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@ledgerhq/hw-transport-node-hid-noevents/node_modules/prebuild-install": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", - "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.21.0", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@ledgerhq/hw-transport-u2f": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.26.0.tgz", - "integrity": "sha512-QTxP1Rsh+WZ184LUOelYVLeaQl3++V3I2jFik+l9JZtakwEHjD0XqOT750xpYNL/vfHsy31Wlz+oicdxGzFk+w==", - "deprecated": "@ledgerhq/hw-transport-u2f is deprecated. Please use @ledgerhq/hw-transport-webusb or @ledgerhq/hw-transport-webhid. https://github.com/LedgerHQ/ledgerjs/blob/master/docs/migrate_webusb.md", - "dev": true, - "peer": true, - "dependencies": { - "@ledgerhq/errors": "^5.26.0", - "@ledgerhq/hw-transport": "^5.26.0", - "@ledgerhq/logs": "^5.26.0", - "u2f-api": "0.2.7" - } - }, - "node_modules/@ledgerhq/logs": { - "version": "5.50.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.50.0.tgz", - "integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==", - "dev": true, - "peer": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nomiclabs/hardhat-ethers": { - "name": "hardhat-deploy-ethers", - "version": "0.3.0-beta.13", - "resolved": "https://registry.npmjs.org/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.3.0-beta.13.tgz", - "integrity": "sha512-PdWVcKB9coqWV1L7JTpfXRCI91Cgwsm7KLmBcwZ8f0COSm1xtABHZTyz3fvF6p42cTnz1VM0QnfDvMFlIRkSNw==", - "dev": true, - "peerDependencies": { - "ethers": "^5.0.0", - "hardhat": "^2.0.0" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz", - "integrity": "sha512-0+rj0SsZotVOcTLyDOxnOc3Gulo8upo0rsw/h+gBPcmtj91YqYJNhdARHoBxOhhE8z+5IUQPx+Dii04lXT14PA==", - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^5.0.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "node-fetch": "^2.6.0", - "semver": "^6.3.0" - }, - "peerDependencies": { - "hardhat": "^2.0.4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@resolver-engine/core": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", - "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", - "dev": true, - "dependencies": { - "debug": "^3.1.0", - "is-url": "^1.2.4", - "request": "^2.85.0" - } - }, - "node_modules/@resolver-engine/core/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@resolver-engine/fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", - "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", - "dev": true, - "dependencies": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0" - } - }, - "node_modules/@resolver-engine/fs/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@resolver-engine/imports": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", - "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", - "dev": true, - "dependencies": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0", - "hosted-git-info": "^2.6.0", - "path-browserify": "^1.0.0", - "url": "^0.11.0" - } - }, - "node_modules/@resolver-engine/imports-fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", - "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", - "dev": true, - "dependencies": { - "@resolver-engine/fs": "^0.3.3", - "@resolver-engine/imports": "^0.3.3", - "debug": "^3.1.0" - } - }, - "node_modules/@resolver-engine/imports-fs/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@resolver-engine/imports/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dependencies": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/minimal": { - "version": "5.30.0", - "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", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dependencies": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/utils": { - "version": "5.30.0", - "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", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@solidity-parser/parser": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.0.tgz", - "integrity": "sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ==", - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@tenderly/hardhat-tenderly": { - "version": "1.1.0-beta.8", - "resolved": "https://registry.npmjs.org/@tenderly/hardhat-tenderly/-/hardhat-tenderly-1.1.0-beta.8.tgz", - "integrity": "sha512-ppXvp2/CGI/1iAGZvCpHk7vBmlvUJerMcVtiXtCRZtXFO1vDs2SJ+RKaW5bI+eFFkLWx75aZVc/lxTx2vIzPsg==", - "dev": true, - "dependencies": { - "@nomiclabs/hardhat-ethers": "^2.0.1", - "axios": "^0.21.1", - "ethers": "^5.0.24", - "fs-extra": "^9.0.1", - "js-yaml": "^3.14.0" - }, - "peerDependencies": { - "hardhat": "^2.0.3" - } - }, - "node_modules/@tenderly/hardhat-tenderly/node_modules/@nomiclabs/hardhat-ethers": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.4.tgz", - "integrity": "sha512-7LMR344TkdCYkMVF9LuC9VU2NBIi84akQiwqm7OufpWaDgHbWhuanY53rk3SVAW0E4HBk5xn5wl5+bN5f+Mq5w==", - "dev": true, - "peerDependencies": { - "ethers": "^5.0.0", - "hardhat": "^2.0.0" - } - }, - "node_modules/@tenderly/hardhat-tenderly/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@tenderly/hardhat-tenderly/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@truffle/error": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz", - "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.8.tgz", - "integrity": "sha512-vvy3xpq36oLgjjy8KE9l2Jabg3WcGPOt18tIyMfTQX9MFnbHoQA2Ne2i8xsd4p6KfxIqSjAB53Q9/nScAqY0UQ==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.5.3" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "dependencies": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/ethers/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true - }, - "node_modules/@truffle/provider": { - "version": "0.2.42", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.42.tgz", - "integrity": "sha512-ZNoglPho4alYIjJR+sLTgX0x6ho7m4OAUWuJ50RAWmoEqYc4AM6htdrI+lTSoRrOHHbmgasv22a7rFPMnmDrTg==", - "dev": true, - "dependencies": { - "@truffle/error": "^0.0.14", - "@truffle/interface-adapter": "^0.5.8", - "web3": "1.5.3" - } - }, - "node_modules/@typechain/ethers-v5": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz", - "integrity": "sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15", - "ts-essentials": "^7.0.1" - }, - "peerDependencies": { - "@ethersproject/abi": "^5.0.0", - "@ethersproject/bytes": "^5.0.0", - "@ethersproject/providers": "^5.0.0", - "ethers": "^5.1.3", - "typechain": "^5.0.0", - "typescript": ">=4.0.0" - } - }, - "node_modules/@typechain/hardhat": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-2.3.1.tgz", - "integrity": "sha512-BQV8OKQi0KAzLXCdsPO0pZBNQQ6ra8A2ucC26uFX/kquRBtJu1yEyWnVSmtr07b5hyRoJRpzUeINLnyqz4/MAw==", - "dev": true, - "dependencies": { - "fs-extra": "^9.1.0" - }, - "peerDependencies": { - "hardhat": "^2.0.10", - "lodash": "^4.17.15", - "typechain": "^5.1.2" - } - }, - "node_modules/@typechain/hardhat/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typechain/hardhat/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@typechain/hardhat/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@types/abstract-leveldown": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", - "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==" - }, - "node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", - "dev": true - }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/level-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", - "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==" - }, - "node_modules/@types/levelup": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", - "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", - "dependencies": { - "@types/abstract-leveldown": "*", - "@types/level-errors": "*", - "@types/node": "*" - } - }, - "node_modules/@types/lodash": { - "version": "4.14.178", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", - "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==", - "dev": true - }, - "node_modules/@types/lowdb": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/lowdb/-/lowdb-1.0.9.tgz", - "integrity": "sha512-LBRG5EPXFOJDoJc9jACstMhtMP+u+UkPYllBeGQXXKiaHc+uzJs9+/Aynb/5KkX33DtrIiKyzNVTPQc/4RcD6A==", - "dev": true, - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" - }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "node_modules/@types/mkdirp": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "node_modules/@types/node": { - "version": "14.0.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz", - "integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==" - }, - "node_modules/@types/node-fetch": { - "version": "2.5.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", - "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", - "dev": true - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "node_modules/@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/abstract-leveldown": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", - "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", - "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/abstract-leveldown/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", - "dev": true, - "engines": { - "node": ">= 0.12.0" - } - }, - "node_modules/adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "engines": { - "node": ">=0.3.0" - } - }, - "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=", - "dev": true - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/amazon-cognito-identity-js": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-4.6.3.tgz", - "integrity": "sha512-MPVJfirbdmSGo7l4h7Kbn3ms1eJXT5Xq8ly+mCPPi8yAxaxdg7ouMUUNTqtDykoZxIdDLF/P6F3Zbg3dlGKOWg==", - "dev": true, - "dependencies": { - "buffer": "4.9.2", - "crypto-js": "^4.0.0", - "fast-base64-decode": "^1.0.0", - "isomorphic-unfetch": "^3.0.0", - "js-cookie": "^2.2.1" - } - }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.4.2" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "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" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "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" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==" - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/are-we-there-yet/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "dependencies": { - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "dependencies": { - "async": "^2.4.0" - } - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/axios-curlirize": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/axios-curlirize/-/axios-curlirize-1.3.7.tgz", - "integrity": "sha512-csSsuMyZj1dv1fL0zRPnDAHWrmlISMvK+wx9WJI/igRVDT4VMgbf2AVenaHghFLfI1nQijXUevYEguYV6u5hjA==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true, - "peer": true, - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/blakejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", - "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", - "dev": true, - "dependencies": { - "bytes": "3.1.1", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", - "dev": true, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-aes/node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-rsa/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", - "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", - "dependencies": { - "safe-buffer": "^5.1.1" - } - }, - "node_modules/bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "node_modules/cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dependencies": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-bignumber": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chai-bignumber/-/chai-bignumber-3.0.0.tgz", - "integrity": "sha512-SubOtaSI2AILWTWe2j0c6i2yFT/f9J6UBjeVGDuwDiPLkF/U5+/eTWUE3sbCZ1KgcPF6UJsDVYbIxaYA097MQA==", - "dev": true - }, - "node_modules/chalk": { - "version": "2.4.2", - "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", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "node_modules/cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" - } - }, - "node_modules/cids/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true - }, - "node_modules/cli-table3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", - "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "colors": "^1.1.2" - } - }, - "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/clone-response/node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "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" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" - }, - "node_modules/command-line-args": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", - "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", - "dev": true, - "dependencies": { - "array-back": "^2.0.0", - "find-replace": "^1.0.3", - "typical": "^2.6.1" - }, - "bin": { - "command-line-args": "bin/cli.js" - } - }, - "node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" - }, - "node_modules/compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, - "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "node_modules/cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", - "dev": true - }, - "node_modules/core-js-pure": { - "version": "3.20.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.2.tgz", - "integrity": "sha512-CmWHvSKn2vNL6p6StNp1EmMIfVY/pqn3JLAjfZQ8WZGPOlGoO92EkX9/Mk81i6GxvoPXjUqEQnpM3rJ5QxxIOg==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "dependencies": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - }, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "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", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "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", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", - "dev": true - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "mimic-response": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/defender-base-client": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/defender-base-client/-/defender-base-client-1.12.1.tgz", - "integrity": "sha512-DMLSCMz6LsCb8jWHhsULEPMLKSc48nYCtdAEa5dXj5YWzPTn9YprcXKbf5NwHqY0uy85j3AAis5ZG7L7+RqBYw==", - "dev": true, - "dependencies": { - "amazon-cognito-identity-js": "^4.3.3", - "axios": "^0.19.2", - "lodash": "^4.17.19", - "node-fetch": "^2.6.0" - } - }, - "node_modules/defender-base-client/node_modules/axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", - "dev": true, - "dependencies": { - "follow-redirects": "1.5.10" - } - }, - "node_modules/defender-base-client/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/defender-base-client/node_modules/follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "dependencies": { - "debug": "=3.1.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/defender-base-client/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/defender-relay-client": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/defender-relay-client/-/defender-relay-client-1.12.1.tgz", - "integrity": "sha512-zOml68K5uZNhikFcXrL2tNWHbgC0++yw9487XKt4iZXpMxKHZNHEyG1D7lFpC9+Ic6bXHLr10fES+AeYjZCHuQ==", - "dev": true, - "dependencies": { - "amazon-cognito-identity-js": "^4.3.3", - "axios": "^0.19.2", - "defender-base-client": "^1.12.1", - "lodash": "^4.17.19", - "node-fetch": "^2.6.0" - }, - "peerDependencies": { - "@ethersproject/abstract-provider": "^5.0.2", - "@ethersproject/abstract-signer": "^5.0.2", - "@ethersproject/providers": "^5.0.5", - "web3-core": "^1.3.4", - "web3-core-helpers": "^1.3.4" - } - }, - "node_modules/defender-relay-client/node_modules/axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", - "dev": true, - "dependencies": { - "follow-redirects": "1.5.10" - } - }, - "node_modules/defender-relay-client/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/defender-relay-client/node_modules/follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "dependencies": { - "debug": "=3.1.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/defender-relay-client/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "dependencies": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deferred-leveldown/node_modules/abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deferred-leveldown/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/emoji-regex": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.0.0.tgz", - "integrity": "sha512-KmJa8l6uHi1HrBI34udwlzZY1jOEuID/ft4d8BSSEdRyap7PwBEt910453PJa5MuGvxkLqlt4Uvhu7tttFHViw==", - "dev": true - }, - "node_modules/encode-utf8": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "dependencies": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-abstract/node_modules/object.assign": { - "version": "4.1.2", - "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", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "dependencies": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=0.12.0" - }, - "optionalDependencies": { - "source-map": "~0.2.0" - } - }, - "node_modules/escodegen/node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", - "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.1", - "jest-docblock": "^21.0.0" - }, - "engines": { - "node": ">=4.0.0" - }, - "peerDependencies": { - "prettier": ">= 0.11.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", - "dev": true, - "dependencies": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "node_modules/eth-ens-namehash/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", - "dev": true - }, - "node_modules/eth-gas-reporter": { - "version": "0.2.23", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.23.tgz", - "integrity": "sha512-T8KsVakDEupvQxW3MfFfHDfJ7y8zl2+XhyEQk4hZ3qQsAh/FE27BfFHM9UhqNQvrJLz8zVWnPZWNcARwLT/lsA==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "^1.1.2", - "ethereumjs-util": "6.2.0", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "peerDependencies": { - "@codechecks/client": "^0.1.0" - }, - "peerDependenciesMeta": { - "@codechecks/client": { - "optional": true - } - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - }, - "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "colors": "^1.1.2" - } - }, - "node_modules/eth-gas-reporter/node_modules/ethereumjs-util": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz", - "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "0.1.6", - "keccak": "^2.0.0", - "rlp": "^2.2.3", - "secp256k1": "^3.0.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "dependencies": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/keccak": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz", - "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.5.0", - "inherits": "^2.0.4", - "nan": "^2.14.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=5.12.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/secp256k1": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", - "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.5.2", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true - }, - "node_modules/eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/eth-lib/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/eth-lib/node_modules/ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "node_modules/eth-sig-util": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.3.tgz", - "integrity": "sha512-KpXbCKmmBUNUTGh9MRKmNkIPietfhzBqqYqysDavLseIiMUGl95k6UcPEkALAZlj41e9E6yioYXc1PC333RKqw==", - "deprecated": "Deprecated in favor of '@metamask/eth-sig-util'", - "dependencies": { - "buffer": "^5.2.1", - "elliptic": "^6.4.0", - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - } - }, - "node_modules/eth-sig-util/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/eth-sig-util/node_modules/ethereumjs-util": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", - "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dev": true, - "dependencies": { - "js-sha3": "^0.8.0" - } - }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "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", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethereum-waffle": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.0.2.tgz", - "integrity": "sha512-VJQTL9oBbHIQRxQFuh1NBXoFXSlTIY6DrkPpO7CvevXRI9ixxq01nSc6hPYUIVy7s+U03sp4ply497O6mD3gsQ==", - "dev": true, - "dependencies": { - "@ethereum-waffle/chai": "^3.0.2", - "@ethereum-waffle/compiler": "^3.0.2", - "@ethereum-waffle/mock-contract": "^3.0.2", - "@ethereum-waffle/provider": "^3.0.2", - "ethers": "^5.0.1" - }, - "bin": { - "waffle": "bin/waffle" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/ethereumjs-abi": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz", - "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", - "dependencies": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - } - }, - "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz", - "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==", - "dependencies": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.0.0" - } - }, - "node_modules/ethereumjs-util": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.2.tgz", - "integrity": "sha512-ATAP02eJLpAlWGfiKQddNrRfZpwXiTFhRN2EM/yLXMCdBW/xjKYblNKcx8GLzzrjXg0ymotck+lam1nuV90arQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethjs-util": "0.1.6", - "keccak": "^3.0.0", - "rlp": "^2.2.4", - "secp256k1": "^4.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "node_modules/ethers": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.3.tgz", - "integrity": "sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.5.0", - "@ethersproject/abstract-provider": "5.5.1", - "@ethersproject/abstract-signer": "5.5.0", - "@ethersproject/address": "5.5.0", - "@ethersproject/base64": "5.5.0", - "@ethersproject/basex": "5.5.0", - "@ethersproject/bignumber": "5.5.0", - "@ethersproject/bytes": "5.5.0", - "@ethersproject/constants": "5.5.0", - "@ethersproject/contracts": "5.5.0", - "@ethersproject/hash": "5.5.0", - "@ethersproject/hdnode": "5.5.0", - "@ethersproject/json-wallets": "5.5.0", - "@ethersproject/keccak256": "5.5.0", - "@ethersproject/logger": "5.5.0", - "@ethersproject/networks": "5.5.2", - "@ethersproject/pbkdf2": "5.5.0", - "@ethersproject/properties": "5.5.0", - "@ethersproject/providers": "5.5.2", - "@ethersproject/random": "5.5.1", - "@ethersproject/rlp": "5.5.0", - "@ethersproject/sha2": "5.5.0", - "@ethersproject/signing-key": "5.5.0", - "@ethersproject/solidity": "5.5.0", - "@ethersproject/strings": "5.5.0", - "@ethersproject/transactions": "5.5.0", - "@ethersproject/units": "5.5.0", - "@ethersproject/wallet": "5.5.0", - "@ethersproject/web": "5.5.1", - "@ethersproject/wordlists": "5.5.0" - } - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "dev": true, - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", - "dev": true - }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "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", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "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", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/execa/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/execa/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/execa/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", - "dev": true, - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.6", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/express/node_modules/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", - "dev": true, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "dev": true, - "dependencies": { - "type": "^2.5.0" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-base64-decode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", - "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", - "dev": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.8.tgz", - "integrity": "sha512-UsiHHXoDbC3iS7vBOFvld7Q9XqBu318xztdHiL10Fjov3AK5GI5bek2ZJkxZcjPguOYH39UL1W4A6w+l7tpNtw==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, - "node_modules/fill-range": { - "version": "7.0.1", - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/find-replace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", - "dev": true, - "dependencies": { - "array-back": "^1.0.4", - "test-value": "^2.1.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/find-replace/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "dev": true, - "dependencies": { - "semver-regex": "^3.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "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==", - "dev": true, - "dependencies": { - "micromatch": "^4.0.2" - } - }, - "node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/fmix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", - "integrity": "sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw=", - "dev": true, - "dependencies": { - "imul": "^1.0.0" - } - }, - "node_modules/follow-redirects": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", - "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "node_modules/ganache-cli": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.12.2.tgz", - "integrity": "sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw==", - "bundleDependencies": [ - "source-map-support", - "yargs", - "ethereumjs-util" - ], - "dev": true, - "dependencies": { - "ethereumjs-util": "6.2.1", - "source-map-support": "0.5.12", - "yargs": "13.2.4" - }, - "bin": { - "ganache-cli": "cli.js" - } - }, - "node_modules/ganache-cli/node_modules/@types/bn.js": { - "version": "4.11.6", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ganache-cli/node_modules/@types/node": { - "version": "14.11.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/@types/pbkdf2": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ganache-cli/node_modules/@types/secp256k1": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ganache-cli/node_modules/ansi-regex": { - "version": "4.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/base-x": { - "version": "3.0.8", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ganache-cli/node_modules/blakejs": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "CC0-1.0" - }, - "node_modules/ganache-cli/node_modules/bn.js": { - "version": "4.11.9", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/brorand": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/browserify-aes": { - "version": "1.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ganache-cli/node_modules/bs58": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/ganache-cli/node_modules/bs58check": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/ganache-cli/node_modules/buffer-from": { - "version": "1.1.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/buffer-xor": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/camelcase": { - "version": "5.3.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/cipher-base": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ganache-cli/node_modules/cliui": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/ganache-cli/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ganache-cli/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/create-hash": { - "version": "1.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/ganache-cli/node_modules/create-hmac": { - "version": "1.1.7", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/ganache-cli/node_modules/cross-spawn": { - "version": "6.0.5", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/ganache-cli/node_modules/decamelize": { - "version": "1.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-cli/node_modules/elliptic": { - "version": "6.5.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "node_modules/ganache-cli/node_modules/emoji-regex": { - "version": "7.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/end-of-stream": { - "version": "1.4.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/ganache-cli/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ganache-cli/node_modules/ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "MPL-2.0", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ganache-cli/node_modules/ethjs-util": { - "version": "0.1.6", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-cli/node_modules/evp_bytestokey": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-cli/node_modules/execa": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/find-up": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/get-caller-file": { - "version": "2.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/ganache-cli/node_modules/get-stream": { - "version": "4.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/hash-base": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/hash.js": { - "version": "1.1.7", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/ganache-cli/node_modules/hmac-drbg": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/ganache-cli/node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/invert-kv": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/is-hex-prefixed": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-cli/node_modules/is-stream": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-cli/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/keccak": { - "version": "3.0.1", - "dev": true, - "hasInstallScript": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ganache-cli/node_modules/lcid": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "invert-kv": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/locate-path": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/map-age-cleaner": { - "version": "0.1.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/md5.js": { - "version": "1.3.5", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/ganache-cli/node_modules/mem": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/minimalistic-assert": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/nice-try": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/node-addon-api": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/node-gyp-build": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/ganache-cli/node_modules/npm-run-path": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/once": { - "version": "1.4.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/ganache-cli/node_modules/os-locale": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/p-defer": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/p-finally": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/p-is-promise": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ganache-cli/node_modules/p-locate": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/path-exists": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/path-key": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-cli/node_modules/pbkdf2": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/ganache-cli/node_modules/pump": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/ganache-cli/node_modules/randombytes": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/ganache-cli/node_modules/readable-stream": { - "version": "3.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ganache-cli/node_modules/require-directory": { - "version": "2.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-cli/node_modules/require-main-filename": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/ripemd160": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/ganache-cli/node_modules/rlp": { - "version": "2.2.6", - "dev": true, - "inBundle": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.1" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/ganache-cli/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/scrypt-js": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/secp256k1": { - "version": "4.0.2", - "dev": true, - "hasInstallScript": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ganache-cli/node_modules/semver": { - "version": "5.7.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-cli/node_modules/set-blocking": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/setimmediate": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/sha.js": { - "version": "2.4.11", - "dev": true, - "inBundle": true, - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/ganache-cli/node_modules/shebang-command": { - "version": "1.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-cli/node_modules/shebang-regex": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-cli/node_modules/signal-exit": { - "version": "3.0.3", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-cli/node_modules/source-map-support": { - "version": "0.5.12", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/ganache-cli/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/ganache-cli/node_modules/string-width": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/strip-ansi": { - "version": "5.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/strip-eof": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-cli/node_modules/strip-hex-prefix": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-cli/node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-cli/node_modules/which": { - "version": "1.3.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/ganache-cli/node_modules/which-module": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/wrap-ansi": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-cli/node_modules/wrappy": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/y18n": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/ganache-cli/node_modules/yargs": { - "version": "13.2.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" - } - }, - "node_modules/ganache-cli/node_modules/yargs-parser": { - "version": "13.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/ganache-core": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", - "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", - "bundleDependencies": [ - "keccak" - ], - "dev": true, - "hasShrinkwrap": true, - "dependencies": { - "abstract-leveldown": "3.0.0", - "async": "2.6.2", - "bip39": "2.5.0", - "cachedown": "1.0.0", - "clone": "2.1.2", - "debug": "3.2.6", - "encoding-down": "5.0.4", - "eth-sig-util": "3.0.0", - "ethereumjs-abi": "0.6.8", - "ethereumjs-account": "3.0.0", - "ethereumjs-block": "2.2.2", - "ethereumjs-common": "1.5.0", - "ethereumjs-tx": "2.1.2", - "ethereumjs-util": "6.2.1", - "ethereumjs-vm": "4.2.0", - "heap": "0.2.6", - "keccak": "3.0.1", - "level-sublevel": "6.6.4", - "levelup": "3.1.1", - "lodash": "4.17.20", - "lru-cache": "5.1.1", - "merkle-patricia-tree": "3.0.0", - "patch-package": "6.2.2", - "seedrandom": "3.0.1", - "source-map-support": "0.5.12", - "tmp": "0.1.0", - "web3-provider-engine": "14.2.1", - "websocket": "1.0.32" - }, - "engines": { - "node": ">=8.9.0" - }, - "optionalDependencies": { - "ethereumjs-wallet": "0.6.5", - "web3": "1.2.11" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/abi": { - "version": "5.0.0-beta.153", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/address": ">=5.0.0-beta.128", - "@ethersproject/bignumber": ">=5.0.0-beta.130", - "@ethersproject/bytes": ">=5.0.0-beta.129", - "@ethersproject/constants": ">=5.0.0-beta.128", - "@ethersproject/hash": ">=5.0.0-beta.128", - "@ethersproject/keccak256": ">=5.0.0-beta.127", - "@ethersproject/logger": ">=5.0.0-beta.129", - "@ethersproject/properties": ">=5.0.0-beta.131", - "@ethersproject/strings": ">=5.0.0-beta.130" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/abstract-provider": { - "version": "5.0.8", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/networks": "^5.0.7", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/transactions": "^5.0.9", - "@ethersproject/web": "^5.0.12" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/abstract-signer": { - "version": "5.0.10", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.0.8", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/address": { - "version": "5.0.9", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/rlp": "^5.0.7" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/base64": { - "version": "5.0.7", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/bignumber": { - "version": "5.0.13", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "bn.js": "^4.4.0" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/bytes": { - "version": "5.0.9", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/logger": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/constants": { - "version": "5.0.8", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bignumber": "^5.0.13" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/hash": { - "version": "5.0.10", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abstract-signer": "^5.0.10", - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/keccak256": { - "version": "5.0.7", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "js-sha3": "0.5.7" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/logger": { - "version": "5.0.8", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/@ethersproject/networks": { - "version": "5.0.7", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/logger": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/properties": { - "version": "5.0.7", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/logger": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/rlp": { - "version": "5.0.7", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/signing-key": { - "version": "5.0.8", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "elliptic": "6.5.3" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/strings": { - "version": "5.0.8", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/logger": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/transactions": { - "version": "5.0.9", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/rlp": "^5.0.7", - "@ethersproject/signing-key": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@ethersproject/web": { - "version": "5.0.12", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/base64": "^5.0.7", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "node_modules/ganache-core/node_modules/@sindresorhus/is": { - "version": "0.14.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/@types/bn.js": { - "version": "4.11.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ganache-core/node_modules/@types/node": { - "version": "14.14.20", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/@types/pbkdf2": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ganache-core/node_modules/@types/secp256k1": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ganache-core/node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/ganache-core/node_modules/abstract-leveldown": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/accepts": { - "version": "1.3.7", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/aes-js": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ganache-core/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/arr-diff": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/arr-flatten": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/arr-union": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/array-flatten": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/array-unique": { - "version": "0.3.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/asn1": { - "version": "0.2.4", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/ganache-core/node_modules/asn1.js": { - "version": "5.4.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ganache-core/node_modules/assert-plus": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/ganache-core/node_modules/assign-symbols": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/async": { - "version": "2.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.11" - } - }, - "node_modules/ganache-core/node_modules/async-eventemitter": { - "version": "0.2.4", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^2.4.0" - } - }, - "node_modules/ganache-core/node_modules/async-limiter": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/asynckit": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/atob": { - "version": "2.1.2", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/ganache-core/node_modules/aws-sign2": { - "version": "0.7.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/aws4": { - "version": "1.11.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-code-frame": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-regex": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/ansi-styles": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/chalk": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/js-tokens": { - "version": "3.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/strip-ansi": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/babel-code-frame/node_modules/supports-color": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ganache-core/node_modules/babel-core": { - "version": "6.26.3", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - } - }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/json5": { - "version": "0.5.1", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-core/node_modules/slash": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/babel-generator": { - "version": "6.26.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/babel-generator/node_modules/jsesc": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-call-delegate": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-define-map": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-function-name": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-get-function-arity": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-hoist-variables": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-optimise-call-expression": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-regex": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helper-replace-supers": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-helpers": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-messages": { - "version": "6.23.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-regenerator": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerator-transform": "^0.10.0" - } - }, - "node_modules/ganache-core/node_modules/babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "node_modules/ganache-core/node_modules/babel-preset-env": { - "version": "1.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "node_modules/ganache-core/node_modules/babel-preset-env/node_modules/semver": { - "version": "5.7.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/babel-register": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "node_modules/ganache-core/node_modules/babel-register/node_modules/source-map-support": { - "version": "0.4.18", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "^0.5.6" - } - }, - "node_modules/ganache-core/node_modules/babel-runtime": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "node_modules/ganache-core/node_modules/babel-template": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "node_modules/ganache-core/node_modules/babel-traverse": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/globals": { - "version": "9.18.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/babel-traverse/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/babel-types": { - "version": "6.26.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "node_modules/ganache-core/node_modules/babel-types/node_modules/to-fast-properties": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/babelify": { - "version": "7.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/babylon": { - "version": "6.18.0", - "dev": true, - "license": "MIT", - "bin": { - "babylon": "bin/babylon.js" - } - }, - "node_modules/ganache-core/node_modules/backoff": { - "version": "2.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "precond": "0.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/balanced-match": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/base": { - "version": "0.11.2", - "dev": true, - "license": "MIT", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/base-x": { - "version": "3.0.8", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ganache-core/node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/base64-js": { - "version": "1.5.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/ganache-core/node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "dev": true, - "license": "Unlicense" - }, - "node_modules/ganache-core/node_modules/bignumber.js": { - "version": "9.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/bip39": { - "version": "2.5.0", - "dev": true, - "license": "ISC", - "dependencies": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, - "node_modules/ganache-core/node_modules/blakejs": { - "version": "1.1.0", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/ganache-core/node_modules/bluebird": { - "version": "3.7.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/bn.js": { - "version": "4.11.9", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/body-parser": { - "version": "1.19.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/body-parser/node_modules/qs": { - "version": "6.7.0", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ganache-core/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/ganache-core/node_modules/brorand": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/browserify-aes": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ganache-core/node_modules/browserify-cipher": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/browserify-des": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/ganache-core/node_modules/browserify-rsa": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/ganache-core/node_modules/browserify-rsa/node_modules/bn.js": { - "version": "5.1.3", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/browserify-sign": { - "version": "4.2.1", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/ganache-core/node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.1.3", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ganache-core/node_modules/browserslist": { - "version": "3.2.8", - "dev": true, - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - }, - "bin": { - "browserslist": "cli.js" - } - }, - "node_modules/ganache-core/node_modules/bs58": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/ganache-core/node_modules/bs58check": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/ganache-core/node_modules/buffer": { - "version": "5.7.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/ganache-core/node_modules/buffer-from": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/buffer-xor": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/bufferutil": { - "version": "4.0.3", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-gyp-build": "^4.2.0" - } - }, - "node_modules/ganache-core/node_modules/bytes": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/bytewise": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" - } - }, - "node_modules/ganache-core/node_modules/bytewise-core": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "typewise-core": "^1.2" - } - }, - "node_modules/ganache-core/node_modules/cache-base": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/cacheable-request": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ganache-core/node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ganache-core/node_modules/cachedown": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "^2.4.1", - "lru-cache": "^3.2.0" - } - }, - "node_modules/ganache-core/node_modules/cachedown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/cachedown/node_modules/lru-cache": { - "version": "3.2.0", - "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/call-bind": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/caniuse-lite": { - "version": "1.0.30001174", - "dev": true, - "license": "CC-BY-4.0" - }, - "node_modules/ganache-core/node_modules/caseless": { - "version": "0.12.0", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/ganache-core/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/checkpoint-store": { - "version": "1.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "functional-red-black-tree": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/ganache-core/node_modules/ci-info": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/cids": { - "version": "0.7.5", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" - } - }, - "node_modules/ganache-core/node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/cipher-base": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ganache-core/node_modules/class-is": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/class-utils": { - "version": "0.3.6", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/clone": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/ganache-core/node_modules/clone-response": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/collection-visit": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ganache-core/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/combined-stream": { - "version": "1.0.8", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/component-emitter": { - "version": "1.3.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/concat-stream": { - "version": "1.6.2", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/ganache-core/node_modules/content-disposition": { - "version": "0.5.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/content-hash": { - "version": "2.5.2", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "node_modules/ganache-core/node_modules/content-type": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/convert-source-map": { - "version": "1.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/ganache-core/node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/cookie": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/cookie-signature": { - "version": "1.0.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/cookiejar": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/copy-descriptor": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/core-js": { - "version": "2.6.12", - "dev": true, - "hasInstallScript": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/core-js-pure": { - "version": "3.8.2", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/ganache-core/node_modules/core-util-is": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/cors": { - "version": "2.8.5", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/ganache-core/node_modules/create-ecdh": { - "version": "4.0.4", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/ganache-core/node_modules/create-hash": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/ganache-core/node_modules/create-hmac": { - "version": "1.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/ganache-core/node_modules/cross-fetch": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" - } - }, - "node_modules/ganache-core/node_modules/crypto-browserify": { - "version": "3.12.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/d": { - "version": "1.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/dashdash": { - "version": "1.14.1", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/ganache-core/node_modules/debug": { - "version": "3.2.6", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/ganache-core/node_modules/decode-uri-component": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/ganache-core/node_modules/decompress-response": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/deep-equal": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/defer-to-connect": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/deferred-leveldown": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/deferred-leveldown/node_modules/abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/define-properties": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ganache-core/node_modules/define-property": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/defined": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/delayed-stream": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ganache-core/node_modules/depd": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/des.js": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/destroy": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/detect-indent": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "repeating": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/diffie-hellman": { - "version": "5.0.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/ganache-core/node_modules/dom-walk": { - "version": "0.1.2", - "dev": true - }, - "node_modules/ganache-core/node_modules/dotignore": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.4" - }, - "bin": { - "ignored": "bin/ignored" - } - }, - "node_modules/ganache-core/node_modules/duplexer3": { - "version": "0.1.4", - "dev": true, - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/ganache-core/node_modules/ecc-jsbn": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ganache-core/node_modules/ee-first": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/electron-to-chromium": { - "version": "1.3.636", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/elliptic": { - "version": "6.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/encodeurl": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/ganache-core/node_modules/encoding-down": { - "version": "5.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "^5.0.0", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/encoding-down/node_modules/abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/end-of-stream": { - "version": "1.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/ganache-core/node_modules/errno": { - "version": "0.1.8", - "dev": true, - "license": "MIT", - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/ganache-core/node_modules/es-abstract": { - "version": "1.18.0-next.1", - "dev": true, - "license": "MIT", - "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/es-to-primitive": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/es5-ext": { - "version": "0.10.53", - "dev": true, - "license": "ISC", - "dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "node_modules/ganache-core/node_modules/es6-iterator": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/ganache-core/node_modules/es6-symbol": { - "version": "3.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/ganache-core/node_modules/escape-html": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ganache-core/node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/etag": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/eth-block-tracker": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - } - }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-block-tracker/node_modules/pify": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/eth-ens-namehash": { - "version": "2.0.8", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-infura": { - "version": "3.2.1", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-fetch": "^2.1.1", - "eth-json-rpc-middleware": "^1.5.0", - "json-rpc-engine": "^3.4.0", - "json-rpc-error": "^2.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware": { - "version": "1.6.0", - "dev": true, - "license": "ISC", - "dependencies": { - "async": "^2.5.0", - "eth-query": "^2.1.2", - "eth-tx-summary": "^3.1.2", - "ethereumjs-block": "^1.6.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", - "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "tape": "^4.6.3" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-block/node_modules/ethereum-common": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-codec": { - "version": "7.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-errors": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws": { - "version": "0.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", - "dev": true, - "dependencies": { - "object-keys": "~0.4.0" - }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/levelup": { - "version": "1.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/semver": { - "version": "5.4.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/eth-json-rpc-middleware/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-lib": { - "version": "0.1.29", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/ganache-core/node_modules/eth-query": { - "version": "2.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "node_modules/ganache-core/node_modules/eth-sig-util": { - "version": "3.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "buffer": "^5.2.1", - "elliptic": "^6.4.0", - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - } - }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi": { - "version": "0.6.5", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - } - }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "4.5.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-sig-util/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary": { - "version": "3.2.4", - "dev": true, - "license": "ISC", - "dependencies": { - "async": "^2.1.2", - "clone": "^2.0.0", - "concat-stream": "^1.5.1", - "end-of-stream": "^1.1.0", - "eth-query": "^2.0.2", - "ethereumjs-block": "^1.4.1", - "ethereumjs-tx": "^1.1.1", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "^2.6.0", - "through2": "^2.0.3" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-block/node_modules/ethereum-common": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-codec": { - "version": "7.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-errors": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws": { - "version": "0.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", - "dev": true, - "dependencies": { - "object-keys": "~0.4.0" - }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/levelup": { - "version": "1.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/semver": { - "version": "5.4.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/eth-tx-summary/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethashjs": { - "version": "0.0.8", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.0.2", - "miller-rabin": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/bn.js": { - "version": "5.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/buffer-xor": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethashjs/node_modules/ethereumjs-util": { - "version": "7.0.7", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereum-bloom-filters": { - "version": "1.0.7", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "js-sha3": "^0.8.0" - } - }, - "node_modules/ganache-core/node_modules/ethereum-bloom-filters/node_modules/js-sha3": { - "version": "0.8.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ethereum-common": { - "version": "0.0.18", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-abi": { - "version": "0.6.8", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-account": { - "version": "3.0.0", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-util": "^6.0.0", - "rlp": "^2.2.1", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-codec": { - "version": "7.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-errors": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws": { - "version": "0.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", - "dev": true, - "dependencies": { - "object-keys": "~0.4.0" - }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/levelup": { - "version": "1.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/semver": { - "version": "5.4.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-block/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-blockchain": { - "version": "4.0.4", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.6.1", - "ethashjs": "~0.0.7", - "ethereumjs-block": "~2.2.2", - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.1.0", - "flow-stoplight": "^1.0.0", - "level-mem": "^3.0.1", - "lru-cache": "^5.1.1", - "rlp": "^2.2.2", - "semaphore": "^1.1.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-common": { - "version": "1.5.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm": { - "version": "4.2.0", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "core-js-pure": "^3.0.1", - "ethereumjs-account": "^3.0.0", - "ethereumjs-block": "^2.2.2", - "ethereumjs-blockchain": "^4.0.3", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.2", - "ethereumjs-util": "^6.2.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1", - "util.promisify": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-codec": { - "version": "7.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-errors": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws": { - "version": "0.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", - "dev": true, - "dependencies": { - "object-keys": "~0.4.0" - }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/levelup": { - "version": "1.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/semver": { - "version": "5.4.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/ethereumjs-vm/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ethereumjs-wallet": { - "version": "0.6.5", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "aes-js": "^3.1.1", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^6.0.0", - "randombytes": "^2.0.6", - "safe-buffer": "^5.1.2", - "scryptsy": "^1.2.1", - "utf8": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "node_modules/ganache-core/node_modules/ethjs-unit": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-core/node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ethjs-util": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-core/node_modules/eventemitter3": { - "version": "4.0.4", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/events": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/ganache-core/node_modules/evp_bytestokey": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/express": { - "version": "4.17.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/ganache-core/node_modules/express/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/express/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/express/node_modules/qs": { - "version": "6.7.0", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ganache-core/node_modules/express/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ext": { - "version": "1.4.0", - "dev": true, - "license": "ISC", - "dependencies": { - "type": "^2.0.0" - } - }, - "node_modules/ganache-core/node_modules/ext/node_modules/type": { - "version": "2.1.0", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/extend": { - "version": "3.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/extend-shallow": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/extglob": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/extsprintf": { - "version": "1.3.0", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/fake-merkle-patricia-tree": { - "version": "1.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "checkpoint-store": "^1.1.0" - } - }, - "node_modules/ganache-core/node_modules/fast-deep-equal": { - "version": "3.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/fetch-ponyfill": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "node-fetch": "~1.7.1" - } - }, - "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": { - "version": "1.7.3", - "dev": true, - "license": "MIT", - "dependencies": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/finalhandler": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root": { - "version": "1.2.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "fs-extra": "^4.0.3", - "micromatch": "^3.1.4" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces": { - "version": "2.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/fs-extra": { - "version": "4.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/micromatch": { - "version": "3.1.10", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/find-yarn-workspace-root/node_modules/to-regex-range": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/flow-stoplight": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/for-each": { - "version": "0.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/ganache-core/node_modules/for-in": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/forever-agent": { - "version": "0.6.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/form-data": { - "version": "2.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/ganache-core/node_modules/forwarded": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/fragment-cache": { - "version": "0.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/fresh": { - "version": "0.5.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/fs-extra": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/ganache-core/node_modules/fs.realpath": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/function-bind": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/functional-red-black-tree": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/get-intrinsic": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/get-stream": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ganache-core/node_modules/get-value": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/getpass": { - "version": "0.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/glob": { - "version": "7.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/global": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/ganache-core/node_modules/got": { - "version": "9.6.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/ganache-core/node_modules/got/node_modules/get-stream": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/graceful-fs": { - "version": "4.2.4", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/har-schema": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/har-validator": { - "version": "5.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/has": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/ganache-core/node_modules/has-ansi": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/has-symbol-support-x": { - "version": "1.4.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/has-symbols": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/has-to-string-tag-x": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "has-symbol-support-x": "^1.4.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/has-value": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/has-values": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/has-values/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/hash-base": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ganache-core/node_modules/hash.js": { - "version": "1.1.7", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/heap": { - "version": "0.2.6", - "dev": true - }, - "node_modules/ganache-core/node_modules/hmac-drbg": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/home-or-tmp": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/http-cache-semantics": { - "version": "4.1.0", - "dev": true, - "license": "BSD-2-Clause", - "optional": true - }, - "node_modules/ganache-core/node_modules/http-errors": { - "version": "1.7.2", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/ganache-core/node_modules/http-https": { - "version": "1.0.0", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/ganache-core/node_modules/http-signature": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/ganache-core/node_modules/iconv-lite": { - "version": "0.4.24", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/idna-uts46-hx": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "punycode": "2.1.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/ganache-core/node_modules/idna-uts46-hx/node_modules/punycode": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/ieee754": { - "version": "1.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ganache-core/node_modules/immediate": { - "version": "3.2.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/inflight": { - "version": "1.0.6", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/ganache-core/node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/invariant": { - "version": "2.2.4", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/ipaddr.js": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/ganache-core/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-arguments": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/is-callable": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/is-ci": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/ganache-core/node_modules/is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-date-object": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/is-descriptor": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-extendable": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-finite": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ganache-core/node_modules/is-fn": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-function": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/is-hex-prefixed": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-core/node_modules/is-negative-zero": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/is-object": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "optional": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/is-plain-obj": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-plain-object": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-regex": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/is-retry-allowed": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/is-symbol": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/is-typedarray": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/is-windows": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/isarray": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/isobject": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/isstream": { - "version": "0.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/isurl": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ganache-core/node_modules/js-sha3": { - "version": "0.5.7", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/jsbn": { - "version": "0.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/json-buffer": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/json-rpc-engine": { - "version": "3.8.0", - "dev": true, - "license": "ISC", - "dependencies": { - "async": "^2.0.1", - "babel-preset-env": "^1.7.0", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/json-rpc-error": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1" - } - }, - "node_modules/ganache-core/node_modules/json-rpc-random-id": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/json-schema": { - "version": "0.2.3", - "dev": true - }, - "node_modules/ganache-core/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/json-stable-stringify": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "jsonify": "~0.0.0" - } - }, - "node_modules/ganache-core/node_modules/json-stringify-safe": { - "version": "5.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/jsonfile": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/ganache-core/node_modules/jsonify": { - "version": "0.0.0", - "dev": true, - "license": "Public Domain" - }, - "node_modules/ganache-core/node_modules/jsprim": { - "version": "1.4.1", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/ganache-core/node_modules/keccak": { - "version": "3.0.1", - "dev": true, - "hasInstallScript": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ganache-core/node_modules/keyv": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/ganache-core/node_modules/kind-of": { - "version": "6.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/klaw-sync": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, - "node_modules/ganache-core/node_modules/level-codec": { - "version": "9.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/level-errors": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/level-iterator-stream": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.5", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/level-mem": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "level-packager": "~4.0.0", - "memdown": "~3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/level-mem/node_modules/abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/level-mem/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/level-mem/node_modules/memdown": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~5.0.0", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/level-mem/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/level-packager": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "encoding-down": "~5.0.0", - "levelup": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/level-post": { - "version": "1.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "ltgt": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/level-sublevel": { - "version": "6.6.4", - "dev": true, - "license": "MIT", - "dependencies": { - "bytewise": "~1.1.0", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "level-iterator-stream": "^2.0.3", - "ltgt": "~2.1.1", - "pull-defer": "^0.2.2", - "pull-level": "^2.0.3", - "pull-stream": "^3.6.8", - "typewiselite": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/level-ws": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.8", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/levelup": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~4.0.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~3.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/levelup/node_modules/level-iterator-stream": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/lodash": { - "version": "4.17.20", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/looper": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/loose-envify": { - "version": "1.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/ganache-core/node_modules/lowercase-keys": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/lru-cache": { - "version": "5.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/ganache-core/node_modules/ltgt": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/map-cache": { - "version": "0.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/map-visit": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/md5.js": { - "version": "1.3.5", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/ganache-core/node_modules/media-typer": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/merge-descriptors": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/merkle-patricia-tree": { - "version": "3.0.0", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.6.1", - "ethereumjs-util": "^5.2.0", - "level-mem": "^3.0.1", - "level-ws": "^1.0.0", - "readable-stream": "^3.0.6", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - } - }, - "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/merkle-patricia-tree/node_modules/readable-stream": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ganache-core/node_modules/methods": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/miller-rabin": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/ganache-core/node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/mime-db": { - "version": "1.45.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/mime-types": { - "version": "2.1.28", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.45.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/mimic-response": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/min-document": { - "version": "2.19.0", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/ganache-core/node_modules/minimalistic-assert": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/minimatch": { - "version": "3.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/minimist": { - "version": "1.2.5", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/minizlib": { - "version": "1.3.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/ganache-core/node_modules/minizlib/node_modules/minipass": { - "version": "2.9.0", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/ganache-core/node_modules/mixin-deep": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/mkdirp": { - "version": "0.5.5", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/ganache-core/node_modules/mkdirp-promise": { - "version": "5.0.1", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "mkdirp": "*" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/mock-fs": { - "version": "4.13.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/multibase": { - "version": "0.6.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/ganache-core/node_modules/multicodec": { - "version": "0.5.7", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "varint": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/multihashes": { - "version": "0.4.21", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/multihashes/node_modules/multibase": { - "version": "0.7.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/ganache-core/node_modules/nano-json-stream-parser": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/nanomatch": { - "version": "1.2.13", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/negotiator": { - "version": "0.6.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/next-tick": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/nice-try": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/node-addon-api": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/node-fetch": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/ganache-core/node_modules/node-gyp-build": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/ganache-core/node_modules/normalize-url": { - "version": "4.5.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ganache-core/node_modules/number-to-bn": { - "version": "1.7.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-core/node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/oauth-sign": { - "version": "0.9.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object-copy": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object-inspect": { - "version": "1.9.0", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/object-is": { - "version": "1.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/object-keys": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ganache-core/node_modules/object-visit": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/object.assign": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/object.getownpropertydescriptors": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/object.pick": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/oboe": { - "version": "2.1.4", - "dev": true, - "license": "BSD", - "optional": true, - "dependencies": { - "http-https": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/on-finished": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/once": { - "version": "1.4.0", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/ganache-core/node_modules/os-homedir": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/os-tmpdir": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/p-cancelable": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/p-timeout": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/p-timeout/node_modules/p-finally": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/parse-asn1": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/parse-headers": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/parseurl": { - "version": "1.3.3", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/pascalcase": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/patch-package": { - "version": "6.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^1.2.1", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "npm": ">5" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/cross-spawn": { - "version": "6.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/path-key": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/semver": { - "version": "5.7.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-command": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/shebang-regex": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/tmp": { - "version": "0.0.33", - "dev": true, - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/ganache-core/node_modules/patch-package/node_modules/which": { - "version": "1.3.1", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/ganache-core/node_modules/path-is-absolute": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/path-parse": { - "version": "1.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/path-to-regexp": { - "version": "0.1.7", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/pbkdf2": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/ganache-core/node_modules/performance-now": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/posix-character-classes": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/precond": { - "version": "0.2.3", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/prepend-http": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/private": { - "version": "0.1.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/process": { - "version": "0.11.10", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/ganache-core/node_modules/process-nextick-args": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/promise-to-callback": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/proxy-addr": { - "version": "2.0.6", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/ganache-core/node_modules/prr": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/pseudomap": { - "version": "1.0.2", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/psl": { - "version": "1.8.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/public-encrypt": { - "version": "4.0.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/ganache-core/node_modules/pull-cat": { - "version": "1.1.11", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/pull-defer": { - "version": "0.2.3", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/pull-level": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "level-post": "^1.0.7", - "pull-cat": "^1.1.9", - "pull-live": "^1.0.1", - "pull-pushable": "^2.0.0", - "pull-stream": "^3.4.0", - "pull-window": "^2.1.4", - "stream-to-pull-stream": "^1.7.1" - } - }, - "node_modules/ganache-core/node_modules/pull-live": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "pull-cat": "^1.1.9", - "pull-stream": "^3.4.0" - } - }, - "node_modules/ganache-core/node_modules/pull-pushable": { - "version": "2.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/pull-stream": { - "version": "3.6.14", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/pull-window": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "looper": "^2.0.0" - } - }, - "node_modules/ganache-core/node_modules/pump": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/ganache-core/node_modules/punycode": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/qs": { - "version": "6.5.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ganache-core/node_modules/query-string": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/randombytes": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/ganache-core/node_modules/randomfill": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/ganache-core/node_modules/range-parser": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/raw-body": { - "version": "2.4.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/readable-stream": { - "version": "2.3.7", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/ganache-core/node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/regenerate": { - "version": "1.4.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/regenerator-runtime": { - "version": "0.11.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/regenerator-transform": { - "version": "0.10.1", - "dev": true, - "license": "BSD", - "dependencies": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "node_modules/ganache-core/node_modules/regex-not": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/regexp.prototype.flags": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/regexp.prototype.flags/node_modules/es-abstract": { - "version": "1.17.7", - "dev": true, - "license": "MIT", - "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/regexpu-core": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "node_modules/ganache-core/node_modules/regjsgen": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/regjsparser": { - "version": "0.1.5", - "dev": true, - "license": "BSD", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/ganache-core/node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/ganache-core/node_modules/repeat-element": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/repeat-string": { - "version": "1.6.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/ganache-core/node_modules/repeating": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-finite": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/request": { - "version": "2.88.2", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ganache-core/node_modules/resolve-url": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/responselike": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/resumer": { - "version": "0.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "through": "~2.3.4" - } - }, - "node_modules/ganache-core/node_modules/ret": { - "version": "0.1.15", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/ganache-core/node_modules/rimraf": { - "version": "2.6.3", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ganache-core/node_modules/ripemd160": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/ganache-core/node_modules/rlp": { - "version": "2.2.6", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.1" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/ganache-core/node_modules/rustbn.js": { - "version": "0.2.0", - "dev": true, - "license": "(MIT OR Apache-2.0)" - }, - "node_modules/ganache-core/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/safe-event-emitter": { - "version": "1.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "events": "^3.0.0" - } - }, - "node_modules/ganache-core/node_modules/safe-regex": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/ganache-core/node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/scrypt-js": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/scryptsy": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "pbkdf2": "^3.0.3" - } - }, - "node_modules/ganache-core/node_modules/secp256k1": { - "version": "4.0.2", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ganache-core/node_modules/seedrandom": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/semaphore": { - "version": "1.1.0", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ganache-core/node_modules/send": { - "version": "0.17.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ganache-core/node_modules/send/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/send/node_modules/ms": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/serve-static": { - "version": "1.14.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ganache-core/node_modules/servify": { - "version": "0.1.12", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/set-immediate-shim": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/set-value": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/setimmediate": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/setprototypeof": { - "version": "1.1.1", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/ganache-core/node_modules/sha.js": { - "version": "2.4.11", - "dev": true, - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/ganache-core/node_modules/simple-concat": { - "version": "1.0.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/simple-get": { - "version": "2.8.1", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon": { - "version": "0.8.2", - "dev": true, - "license": "MIT", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon-node": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon-util": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/source-map": { - "version": "0.5.7", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/source-map-resolve": { - "version": "0.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/ganache-core/node_modules/source-map-support": { - "version": "0.5.12", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/ganache-core/node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/source-map-url": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/split-string": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/sshpk": { - "version": "1.16.1", - "dev": true, - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "dev": true, - "license": "Unlicense" - }, - "node_modules/ganache-core/node_modules/static-extend": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/statuses": { - "version": "1.5.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/stream-to-pull-stream": { - "version": "1.7.3", - "dev": true, - "license": "MIT", - "dependencies": { - "looper": "^3.0.0", - "pull-stream": "^3.2.3" - } - }, - "node_modules/ganache-core/node_modules/stream-to-pull-stream/node_modules/looper": { - "version": "3.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/strict-uri-encode": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/string_decoder": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/ganache-core/node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/string.prototype.trim": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/string.prototype.trimend": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/string.prototype.trimstart": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/strip-hex-prefix": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ganache-core/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/swarm-js": { - "version": "0.1.40", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - } - }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/fs-extra": { - "version": "4.0.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/get-stream": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/got": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/is-stream": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/p-cancelable": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/prepend-http": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/swarm-js/node_modules/url-parse-lax": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "prepend-http": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/tape": { - "version": "4.13.3", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-equal": "~1.1.1", - "defined": "~1.0.0", - "dotignore": "~0.1.2", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.6", - "has": "~1.0.3", - "inherits": "~2.0.4", - "is-regex": "~1.0.5", - "minimist": "~1.2.5", - "object-inspect": "~1.7.0", - "resolve": "~1.17.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.2.1", - "through": "~2.3.8" - }, - "bin": { - "tape": "bin/tape" - } - }, - "node_modules/ganache-core/node_modules/tape/node_modules/glob": { - "version": "7.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ganache-core/node_modules/tape/node_modules/is-regex": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/tape/node_modules/object-inspect": { - "version": "1.7.0", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/tape/node_modules/resolve": { - "version": "1.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/tar": { - "version": "4.4.13", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/ganache-core/node_modules/tar/node_modules/fs-minipass": { - "version": "1.2.7", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/ganache-core/node_modules/tar/node_modules/minipass": { - "version": "2.9.0", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/ganache-core/node_modules/through": { - "version": "2.3.8", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/through2": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/ganache-core/node_modules/timed-out": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/tmp": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "rimraf": "^2.6.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/to-object-path": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/to-object-path/node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/to-readable-stream": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ganache-core/node_modules/to-regex": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/toidentifier": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ganache-core/node_modules/tough-cookie": { - "version": "2.5.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/ganache-core/node_modules/trim-right": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/tunnel-agent": { - "version": "0.6.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ganache-core/node_modules/tweetnacl": { - "version": "1.0.3", - "dev": true, - "license": "Unlicense" - }, - "node_modules/ganache-core/node_modules/tweetnacl-util": { - "version": "0.15.1", - "dev": true, - "license": "Unlicense" - }, - "node_modules/ganache-core/node_modules/type": { - "version": "1.2.0", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/type-is": { - "version": "1.6.18", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ganache-core/node_modules/typedarray": { - "version": "0.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/ganache-core/node_modules/typewise": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "typewise-core": "^1.2.0" - } - }, - "node_modules/ganache-core/node_modules/typewise-core": { - "version": "1.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/typewiselite": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/ultron": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/underscore": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/union-value": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/universalify": { - "version": "0.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/ganache-core/node_modules/unorm": { - "version": "1.6.0", - "dev": true, - "license": "MIT or GPL-2.0", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/ganache-core/node_modules/unpipe": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/unset-value": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/uri-js": { - "version": "4.4.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/ganache-core/node_modules/urix": { - "version": "0.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/url-parse-lax": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ganache-core/node_modules/url-set-query": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/url-to-options": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ganache-core/node_modules/use": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ganache-core/node_modules/utf-8-validate": { - "version": "5.0.4", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-gyp-build": "^4.2.0" - } - }, - "node_modules/ganache-core/node_modules/utf8": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/util.promisify": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "for-each": "^0.3.3", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ganache-core/node_modules/utils-merge": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/ganache-core/node_modules/uuid": { - "version": "3.4.0", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/ganache-core/node_modules/varint": { - "version": "5.0.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/vary": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ganache-core/node_modules/verror": { - "version": "1.10.0", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/ganache-core/node_modules/web3": { - "version": "1.2.11", - "dev": true, - "hasInstallScript": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "web3-bzz": "1.2.11", - "web3-core": "1.2.11", - "web3-eth": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-shh": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-bzz": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40", - "underscore": "1.9.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.19.12", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/web3-core": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-requestmanager": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-core-helpers": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "underscore": "1.9.1", - "web3-eth-iban": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-core-method": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-core-promievent": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-core-requestmanager": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-providers-http": "1.2.11", - "web3-providers-ipc": "1.2.11", - "web3-providers-ws": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-core-subscriptions": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-core/node_modules/@types/node": { - "version": "12.19.12", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/web3-eth": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-accounts": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-eth-ens": "1.2.11", - "web3-eth-iban": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-abi": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@ethersproject/abi": "5.0.0-beta.153", - "underscore": "1.9.1", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-accounts": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-common": "^1.3.2", - "ethereumjs-tx": "^2.1.1", - "scrypt-js": "^3.0.1", - "underscore": "1.9.1", - "uuid": "3.3.2", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "3.3.2", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-contract": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-ens": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-iban": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-personal": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.19.12", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/web3-net": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine": { - "version": "14.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^2.5.0", - "backoff": "^2.5.0", - "clone": "^2.0.0", - "cross-fetch": "^2.1.0", - "eth-block-tracker": "^3.0.0", - "eth-json-rpc-infura": "^3.1.0", - "eth-sig-util": "3.0.0", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.5", - "ethereumjs-vm": "^2.3.4", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.85.0", - "semaphore": "^1.0.3", - "ws": "^5.1.1", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.6.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/eth-sig-util": { - "version": "1.4.2", - "dev": true, - "license": "ISC", - "dependencies": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "ethereumjs-util": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-block/node_modules/ethereum-common": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-block/node_modules/ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ethereumjs-vm/node_modules/ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-codec": { - "version": "7.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-errors": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "errno": "~0.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-iterator-stream/node_modules/readable-stream": { - "version": "1.1.14", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws": { - "version": "0.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/readable-stream": { - "version": "1.0.34", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/level-ws/node_modules/xtend": { - "version": "2.1.2", - "dev": true, - "dependencies": { - "object-keys": "~0.4.0" - }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/levelup": { - "version": "1.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ltgt": { - "version": "2.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/memdown/node_modules/abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "xtend": "~4.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/merkle-patricia-tree/node_modules/async": { - "version": "1.5.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/object-keys": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/semver": { - "version": "5.4.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/string_decoder": { - "version": "0.10.31", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/web3-provider-engine/node_modules/ws": { - "version": "5.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "async-limiter": "~1.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-providers-http": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "web3-core-helpers": "1.2.11", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-providers-ipc": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "oboe": "2.1.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-providers-ws": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "websocket": "^1.0.31" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-shh": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-net": "1.2.11" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-utils": { - "version": "1.2.11", - "dev": true, - "license": "LGPL-3.0", - "optional": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "underscore": "1.9.1", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ganache-core/node_modules/web3-utils/node_modules/eth-lib": { - "version": "0.2.8", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/ganache-core/node_modules/websocket": { - "version": "1.0.32", - "dev": true, - "license": "Apache-2.0", - "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" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/ganache-core/node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/ganache-core/node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/whatwg-fetch": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, - "node_modules/ganache-core/node_modules/wrappy": { - "version": "1.0.2", - "dev": true, - "license": "ISC" - }, - "node_modules/ganache-core/node_modules/ws": { - "version": "3.3.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "node_modules/ganache-core/node_modules/ws/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ganache-core/node_modules/xhr": { - "version": "2.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/ganache-core/node_modules/xhr-request": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/ganache-core/node_modules/xhr-request-promise": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/ganache-core/node_modules/xhr2-cookies": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "cookiejar": "^2.1.1" - } - }, - "node_modules/ganache-core/node_modules/xtend": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/ganache-core/node_modules/yaeti": { - "version": "0.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.32" - } - }, - "node_modules/ganache-core/node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "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", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "bin": { - "testrpc-sc": "index.js" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/got/node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/got/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/got/node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "engines": { - "node": ">=4.x" - } - }, - "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.8.2.tgz", - "integrity": "sha512-cBUqzZGOi+lwKHArWl5Be7zeFIwlu1IUXOna6k5XhORZ8hAWDVbAJBVfxgmjkcX5GffIf0C5g841zRxo36sQ5g==", - "dependencies": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "@ethereumjs/vm": "^5.6.0", - "@ethersproject/abi": "^5.1.2", - "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.14.0", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "eth-sig-util": "^2.5.2", - "ethereum-cryptography": "^0.1.2", - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.3", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "^7.1.3", - "https-proxy-agent": "^5.0.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.2", - "mnemonist": "^0.38.0", - "mocha": "^7.2.0", - "node-fetch": "^2.6.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "slash": "^3.0.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "true-case-path": "^2.2.1", - "tsort": "0.0.1", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "bin": { - "hardhat": "internal/cli/cli.js" - }, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/hardhat-contract-sizer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.3.0.tgz", - "integrity": "sha512-hRUwn5PhNWPO1t0ehtlDhEtP8YzzwCB+NNEdt6p+ZQ2bnq9rSgAjMsybSeOYt/ohen3kH31Pqm0hK0ies5/1tA==", - "dev": true, - "dependencies": { - "cli-table3": "^0.6.0", - "colors": "^1.4.0" - }, - "peerDependencies": { - "hardhat": "^2.0.0" - } - }, - "node_modules/hardhat-dependency-compiler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.2.tgz", - "integrity": "sha512-LVnsPSZnGvzWVvlpewlkPKlPtFP/S9V41RC1fd/ygZc4jkG8ubNlfE82nwiGw5oPueHSmFi6TACgmyrEOokK8w==", - "dev": true, - "engines": { - "node": ">=14.14.0" - }, - "peerDependencies": { - "hardhat": "^2.0.0" - } - }, - "node_modules/hardhat-deploy": { - "version": "0.9.24", - "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.9.24.tgz", - "integrity": "sha512-fIIg6Wt7lV8h+6c6dFnINUKcJ/5Wfe5GYDaDsGGPqaK2b71DaeFHjsWRL+2ozaHkMZjdyYBOweY09wRu/KM1Qw==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.1", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.1", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/contracts": "^5.4.1", - "@ethersproject/providers": "^5.4.4", - "@ethersproject/solidity": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/wallet": "^5.4.0", - "@types/qs": "^6.9.7", - "axios": "^0.21.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.2", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "form-data": "^4.0.0", - "fs-extra": "^10.0.0", - "match-all": "^1.2.6", - "murmur-128": "^0.2.1", - "qs": "^6.9.4" - }, - "peerDependencies": { - "@ethersproject/hardware-wallets": "^5.0.14", - "hardhat": "^2.6.8" - } - }, - "node_modules/hardhat-deploy/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/hardhat-deploy/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/hardhat-deploy/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/hardhat-deploy/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/hardhat-deploy/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/hardhat-deploy/node_modules/fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/hardhat-deploy/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hardhat-deploy/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/hardhat-deploy/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/hardhat-deploy/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/hardhat-gas-reporter": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.6.tgz", - "integrity": "sha512-LlCEmSx1dZpnxKmODb2hmP5eJ1IAM5It3NnBNTUpBTxn9g9qPPI3JQTxj8AbGEiNc3r6V+w/mXYCmiC8pWvnoQ==", - "dev": true, - "dependencies": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.23", - "sha1": "^1.1.1" - }, - "peerDependencies": { - "hardhat": "^2.0.2" - } - }, - "node_modules/hardhat/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/hardhat/node_modules/ethereumjs-abi": { - "version": "0.6.8", - "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", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/hardhat/node_modules/ethereumjs-abi/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/hardhat/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "6.2.1", - "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", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/hardhat/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/hardhat/node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/hardhat/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/hardhat/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/hardhat/node_modules/solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/hardhat/node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-to-string-tag-x": { - "version": "1.4.1", - "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==", - "dev": true, - "dependencies": { - "has-symbol-support-x": "^1.4.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", - "dev": true - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "bin": { - "husky-run": "bin/run.js", - "husky-upgrade": "lib/upgrader/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/husky" - } - }, - "node_modules/husky/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/husky/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/husky/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/husky/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/husky/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/husky/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "dev": true, - "dependencies": { - "punycode": "2.1.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" - }, - "node_modules/immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==" - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imul": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", - "integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "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" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "peer": true, - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/io-ts": { - "version": "1.10.4", - "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" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "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", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "node_modules/is-regex": { - "version": "1.1.4", - "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", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", - "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/isomorphic-unfetch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", - "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", - "dev": true, - "dependencies": { - "node-fetch": "^2.6.1", - "unfetch": "^4.2.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "node_modules/isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "dependencies": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/jest-docblock": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", - "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", - "dev": true - }, - "node_modules/js-cookie": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", - "dev": true - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "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==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonschema": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz", - "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/level-codec": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", - "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-codec/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "dependencies": { - "errno": "~0.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-mem": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", - "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", - "dependencies": { - "level-packager": "^5.0.3", - "memdown": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-packager": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", - "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", - "dependencies": { - "encoding-down": "^6.3.0", - "levelup": "^4.3.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-supports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "dependencies": { - "xtend": "^4.0.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-ws": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", - "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^3.1.0", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", - "dependencies": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true - }, - "node_modules/log-symbols": { - "version": "3.0.0", - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "peer": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lowdb": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", - "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.3", - "is-promise": "^2.1.0", - "lodash": "4", - "pify": "^3.0.0", - "steno": "^0.4.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "node_modules/match-all": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/match-all/-/match-all-1.2.6.tgz", - "integrity": "sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ==", - "dev": true - }, - "node_modules/mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "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", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memdown": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", - "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", - "dependencies": { - "abstract-leveldown": "~6.2.1", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/memdown/node_modules/abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/memdown/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/memdown/node_modules/immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/merkle-patricia-tree": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.2.tgz", - "integrity": "sha512-eqZYNTshcYx9aESkSPr71EqwsR/QmpnObDEV4iLxkt/x/IoLYZYjJvKY72voP/27Vy61iMOrfOG6jrn7ttXD+Q==", - "dependencies": { - "@types/levelup": "^4.3.0", - "ethereumjs-util": "^7.1.2", - "level-mem": "^5.0.1", - "level-ws": "^2.0.0", - "readable-stream": "^3.6.0", - "rlp": "^2.2.4", - "semaphore-async-await": "^1.5.1" - } - }, - "node_modules/merkle-patricia-tree/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/merkle-patricia-tree/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/merkle-patricia-tree/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "dependencies": { - "mime-db": "1.51.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", - "dev": true, - "dependencies": { - "mkdirp": "*" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dependencies": { - "obliterator": "^2.0.0" - } - }, - "node_modules/mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/mocha/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "6.0.0", - "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" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", - "dev": true - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/multibase/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "varint": "^5.0.0" - } - }, - "node_modules/multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - } - }, - "node_modules/multihashes/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/multihashes/node_modules/multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", - "dev": true, - "dependencies": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/murmur-128": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz", - "integrity": "sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg==", - "dev": true, - "dependencies": { - "encode-utf8": "^1.0.2", - "fmix": "^0.1.0", - "imul": "^1.0.0" - } - }, - "node_modules/nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true - }, - "node_modules/nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", - "dev": true - }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-abi": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "semver": "^5.4.1" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/node-environment-flags": { - "version": "1.0.6", - "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", - "semver": "^5.7.0" - } - }, - "node_modules/node-environment-flags/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-hid": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-1.3.0.tgz", - "integrity": "sha512-BA6G4V84kiNd1uAChub/Z/5s/xS3EHBCxotQ0nyYrUG65mXewUDHE1tWOSqA2dp3N+mV0Ffq9wo2AW9t4p/G7g==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "peer": true, - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.14.0", - "node-abi": "^2.18.0", - "prebuild-install": "^5.3.4" - }, - "bin": { - "hid-showdevices": "src/show-devices.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "dev": true, - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", - "dev": true - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.3", - "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" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obliterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz", - "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w==" - }, - "node_modules/oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", - "dev": true, - "dependencies": { - "http-https": "^1.0.0" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", - "dev": true, - "bin": { - "opencollective-postinstall": "index.js" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "engines": { - "node": ">=4" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", - "dev": true - }, - "node_modules/parse-headers": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz", - "integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw==", - "dev": true - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/patch-package": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", - "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", - "dev": true, - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "npm": ">5" - } - }, - "node_modules/patch-package/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "dependencies": { - "semver-compare": "^1.0.0" - } - }, - "node_modules/postinstall-postinstall": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", - "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==", - "dev": true, - "hasInstallScript": true - }, - "node_modules/prebuild-install": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", - "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/prettier-plugin-solidity": { - "version": "1.0.0-beta.19", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz", - "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.14.0", - "emoji-regex": "^10.0.0", - "escape-string-regexp": "^4.0.0", - "semver": "^7.3.5", - "solidity-comments-extractor": "^0.0.7", - "string-width": "^4.2.3" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "prettier": "^2.3.0" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-quick": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.3.tgz", - "integrity": "sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "execa": "^4.0.0", - "find-up": "^4.1.0", - "ignore": "^5.1.4", - "mri": "^1.1.5", - "multimatch": "^4.0.0" - }, - "bin": { - "pretty-quick": "bin/pretty-quick.js" - }, - "engines": { - "node": ">=10.13" - }, - "peerDependencies": { - "prettier": ">=2.0.0" - } - }, - "node_modules/pretty-quick/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/pretty-quick/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/pretty-quick/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/pretty-quick/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-quick/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pretty-quick/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", - "bin": { - "printj": "bin/printj.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", - "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", - "dependencies": { - "bytes": "3.1.1", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "dev": true, - "dependencies": { - "minimatch": "3.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", - "dev": true, - "dependencies": { - "req-from": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", - "dev": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/rlp/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==" - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "peer": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "dependencies": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "istanbul": "lib/cli.js" - } - }, - "node_modules/sc-istanbul/node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "node_modules/sc-istanbul/node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sc-istanbul/node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "node_modules/sc-istanbul/node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "node_modules/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/semaphore-async-await": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", - "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=", - "engines": { - "node": ">=4.1" - } - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "node_modules/semver-regex": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.3.tgz", - "integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dev": true, - "dependencies": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", - "dev": true, - "dependencies": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", - "dev": true, - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/solc/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "node_modules/solidity-coverage": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.17.tgz", - "integrity": "sha512-Erw2hd2xdACAvDX8jUdYkmgJlIIazGznwDJA5dhRaw4def2SisXN9jUjneeyOZnl/E7j6D3XJYug4Zg9iwodsg==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.13.2", - "@truffle/provider": "^0.2.24", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "fs-extra": "^8.1.0", - "ganache-cli": "^6.12.2", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.0" - }, - "bin": { - "solidity-coverage": "plugins/bin.js" - } - }, - "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.13.2.tgz", - "integrity": "sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==", - "dev": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/solidity-coverage/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/solidity-coverage/node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/solidity-coverage/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "node_modules/stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stacktrace-parser/node_modules/type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/steno": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", - "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.3" - } - }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "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" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - } - }, - "node_modules/swarm-js/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/swarm-js/node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/swarm-js/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/swarm-js/node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/swarm-js/node_modules/url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "dependencies": { - "prepend-http": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "dependencies": { - "get-port": "^3.1.0" - } - }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/test-value": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", - "dev": true, - "dependencies": { - "array-back": "^1.0.3", - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/test-value/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", - "dev": true - }, - "node_modules/then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "dependencies": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, - "node_modules/then-request/node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tmp-promise": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", - "dependencies": { - "tmp": "^0.2.0" - } - }, - "node_modules/tmp-promise/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tmp-promise/node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "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" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "node_modules/true-case-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", - "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" - }, - "node_modules/ts-essentials": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", - "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "peerDependencies": { - "typescript": ">=3.7.0" - } - }, - "node_modules/ts-generator": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", - "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", - "dev": true, - "dependencies": { - "@types/mkdirp": "^0.5.2", - "@types/prettier": "^2.1.1", - "@types/resolve": "^0.0.8", - "chalk": "^2.4.1", - "glob": "^7.1.2", - "mkdirp": "^0.5.1", - "prettier": "^2.1.2", - "resolve": "^1.8.1", - "ts-essentials": "^1.0.0" - }, - "bin": { - "ts-generator": "dist/cli/run.js" - } - }, - "node_modules/ts-generator/node_modules/ts-essentials": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", - "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", - "dev": true - }, - "node_modules/ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "dev": true, - "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "typescript": ">=2.7" - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.8.0" - }, - "peerDependencies": { - "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" - } - }, - "node_modules/tslint-config-prettier": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", - "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", - "dev": true, - "bin": { - "tslint-config-prettier-check": "bin/check.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/tslint-plugin-prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz", - "integrity": "sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA==", - "dev": true, - "dependencies": { - "eslint-plugin-prettier": "^2.2.0", - "lines-and-columns": "^1.1.6", - "tslib": "^1.7.1" - }, - "engines": { - "node": ">= 4" - }, - "peerDependencies": { - "prettier": "^1.9.0 || ^2.0.0", - "tslint": "^5.0.0 || ^6.0.0" - } - }, - "node_modules/tslint/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/tslint/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslint/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=" - }, - "node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typechain": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-5.2.0.tgz", - "integrity": "sha512-0INirvQ+P+MwJOeMct+WLkUE4zov06QxC96D+i3uGFEHoiSkZN70MKDQsaj8zkL86wQwByJReI2e7fOUwECFuw==", - "dev": true, - "dependencies": { - "@types/prettier": "^2.1.1", - "command-line-args": "^4.0.7", - "debug": "^4.1.1", - "fs-extra": "^7.0.0", - "glob": "^7.1.6", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.1.2", - "ts-essentials": "^7.0.1" - }, - "bin": { - "typechain": "dist/cli/cli.js" - }, - "peerDependencies": { - "typescript": ">=4.1.0" - } - }, - "node_modules/typechain/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", - "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", - "dev": true - }, - "node_modules/u2f-api": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/u2f-api/-/u2f-api-0.2.7.tgz", - "integrity": "sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg==", - "dev": true, - "peer": true - }, - "node_modules/uglify-js": { - "version": "3.14.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.5.tgz", - "integrity": "sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unfetch": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", - "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", - "dev": true - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", - "dev": true - }, - "node_modules/url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - }, - "node_modules/usb": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/usb/-/usb-1.9.2.tgz", - "integrity": "sha512-dryNz030LWBPAf6gj8vyq0Iev3vPbCLHCT8dBw3gQRXRzVNsIdeuU+VjPp3ksmSPkeMAl1k+kQ14Ij0QHyeiAg==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "peer": true, - "dependencies": { - "node-addon-api": "^4.2.0", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/usb/node_modules/node-addon-api": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.2.0.tgz", - "integrity": "sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/utf-8-validate": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", - "integrity": "sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true - }, - "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3-core": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.6.1.tgz", - "integrity": "sha512-m+b7UfYvU5cQUAh6NRfxRzH/5B3to1AdEQi1HIQt570cDWlObOOmoO9tY6iJnI5w4acxIO19LqjDMqEJGBYyRQ==", - "dev": true, - "peer": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.6.1", - "web3-core-method": "1.6.1", - "web3-core-requestmanager": "1.6.1", - "web3-utils": "1.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-helpers": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.6.1.tgz", - "integrity": "sha512-om2PZvK1uoWcgMq6JfcSx3241LEIVF6qi2JuHz2SLKiKEW5UsBUaVx0mNCmcZaiuYQCyOsLS3r33q5AdM+v8ng==", - "dev": true, - "peer": true, - "dependencies": { - "web3-eth-iban": "1.6.1", - "web3-utils": "1.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-method": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.6.1.tgz", - "integrity": "sha512-szH5KyIWIaULQDBdDvevQUCHV9lsExJ/oV0ePqK+w015D2SdMPMuhii0WB+HCePaksWO+rr/GAypvV9g2T3N+w==", - "dev": true, - "peer": true, - "dependencies": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.6.1", - "web3-core-promievent": "1.6.1", - "web3-core-subscriptions": "1.6.1", - "web3-utils": "1.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-promievent": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.6.1.tgz", - "integrity": "sha512-byJ5s2MQxrWdXd27pWFmujfzsTZK4ik8rDgIV1RFDFc+rHZ2nZhq+VWk7t/Nkrj7EaVXncEgTdPEHc18nx+ocQ==", - "dev": true, - "peer": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-requestmanager": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.6.1.tgz", - "integrity": "sha512-4y7etYEUtkfflyYVBfN1oJtCbVFNhNX1omlEYzezhTnPj3/dT7n+dhUXcqvIhx9iKA13unGfpFge80XNFfcB8A==", - "dev": true, - "peer": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.6.1", - "web3-providers-http": "1.6.1", - "web3-providers-ipc": "1.6.1", - "web3-providers-ws": "1.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-subscriptions": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.6.1.tgz", - "integrity": "sha512-WZwxsYttIojyGQ5RqxuQcKg0IJdDCFpUe4EncS3QKZwxPqWzGmgyLwE0rm7tP+Ux1waJn5CUaaoSCBxWGSun1g==", - "dev": true, - "peer": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true, - "peer": true - }, - "node_modules/web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "node_modules/web3-eth-abi/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth-abi/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth-accounts/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/ethereumjs-util/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/web3-eth-accounts/node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3-eth-contract/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-contract/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3-eth-ens/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-iban": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.6.1.tgz", - "integrity": "sha512-91H0jXZnWlOoXmc13O9NuQzcjThnWyAHyDn5Yf7u6mmKOhpJSGF/OHlkbpXt1Y4v2eJdEPaVFa+6i8aRyagE7Q==", - "dev": true, - "peer": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3-eth-personal/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3-eth/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3-net/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-net/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-net/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-http": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.6.1.tgz", - "integrity": "sha512-xBoKOJxu10+kO3ikamXmBfrWZ/xpQOGy0ocdp7Y81B17En5TXELwlmMXt1UlIgWiyYDhjq4OwlH/VODYqHXy3A==", - "dev": true, - "peer": true, - "dependencies": { - "web3-core-helpers": "1.6.1", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ipc": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.6.1.tgz", - "integrity": "sha512-anyoIZlpMzwEQI4lwylTzDrHsVp20v0QUtSTp2B5jInBinmQtyCE7vnbX20jEQ4j5uPwfJabKNtoJsk6a3O4WQ==", - "dev": true, - "peer": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ws": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.6.1.tgz", - "integrity": "sha512-FWMEFYb4rYFYRgSFBf/O1Ex4p/YKSlN+JydCtdlJwRimd89qm95CTfs4xGjCskwvXMjV2sarH+f1NPwJXicYpg==", - "dev": true, - "peer": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.6.1", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3-shh/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-shh/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", - "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/web3-utils/node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/web3-utils/node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "node_modules/web3/node_modules/@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "node_modules/web3/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "node_modules/which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, - "node_modules/which-typed-array": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", - "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.3", - "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" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", - "dev": true, - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dev": true, - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xhr-request/node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/xhr-request/node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/xhr-request/node_modules/simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "dev": true, - "dependencies": { - "cookiejar": "^2.1.1" - } - }, - "node_modules/xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", - "dev": true, - "engines": { - "node": ">=0.10.32" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@aave/core-v3": { - "version": "1.14.2", - "resolved": "https://npm.pkg.github.com/download/@aave/core-v3/1.14.2/4f9d7f392d3801f1e30a8336d2eaba73a38c43f60f096871880683abccbbeac2", - "integrity": "sha512-3nq/WHuKpVU15yT3vemSx2gr8wzQuuzBjSailnnXbA4fMzHavZQLBTE0eLIbNFPkGAwx+jnECYZ2TuSnEqzMHQ==", - "dev": true, - "requires": { - "@nomiclabs/hardhat-etherscan": "^2.1.7", - "axios-curlirize": "^1.3.7", - "tmp-promise": "^3.0.2" - } - }, - "@aave/deploy-v3": { - "version": "1.21.1-beta.4", - "resolved": "https://npm.pkg.github.com/download/@aave/deploy-v3/1.21.1-beta.4/379cc7907d7c26584ae52205062b10390b12562c1f20ee40cb476b3f8b36f6d7", - "integrity": "sha512-DCTxOk7nLhIasL14xSPUb+MqCH6NroX0JkcngrCyOj975s9ggrKcfqkVcew/zpHXPyJHRoBIb0fWjBg1vXBfjQ==", - "dev": true, - "requires": { - "defender-relay-client": "^1.11.1" - } - }, - "@aave/periphery-v3": { - "version": "1.13.1-beta.1", - "resolved": "https://npm.pkg.github.com/download/@aave/periphery-v3/1.13.1-beta.1/68696c89f12caec5d977ae3b8f8a67313899079c7ca918b397d1f2d9d2455c69", - "integrity": "sha512-ErBWUBKkZMtop1EjsL/TgwB3Lxj++sHZd6UFiG4andKy0/AfaZjteHs2JZQHl1F+cRjz89spwsOJ9CKXkejUnA==", - "dev": true, - "requires": { - "@aave/core-v3": "^1.14.2" - } - }, - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.7" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", - "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "dev": true, - "requires": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", - "dev": true, - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - } - } - }, - "@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "dev": true - }, - "@ethereum-waffle/chai": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.1.tgz", - "integrity": "sha512-8mjgjWCe8XSCWuyJgVtJY8sm00VTczGBTDxBejgEBWN/J9x7QD8jdmWW8bfxdnqZbxiDCTvRFL58Wmd254BEqQ==", - "dev": true, - "requires": { - "@ethereum-waffle/provider": "^3.4.0", - "ethers": "^5.4.7" - } - }, - "@ethereum-waffle/compiler": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-3.4.0.tgz", - "integrity": "sha512-a2wxGOoB9F1QFRE+Om7Cz2wn+pxM/o7a0a6cbwhaS2lECJgFzeN9xEkVrKahRkF4gEfXGcuORg4msP0Asxezlw==", - "dev": true, - "requires": { - "@resolver-engine/imports": "^0.3.3", - "@resolver-engine/imports-fs": "^0.3.3", - "@typechain/ethers-v5": "^2.0.0", - "@types/mkdirp": "^0.5.2", - "@types/node-fetch": "^2.5.5", - "ethers": "^5.0.1", - "mkdirp": "^0.5.1", - "node-fetch": "^2.6.1", - "solc": "^0.6.3", - "ts-generator": "^0.1.1", - "typechain": "^3.0.0" - }, - "dependencies": { - "@typechain/ethers-v5": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-2.0.0.tgz", - "integrity": "sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==", - "dev": true, - "requires": { - "ethers": "^5.0.2" - } - }, - "ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==", - "dev": true, - "requires": {} - }, - "typechain": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-3.0.0.tgz", - "integrity": "sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==", - "dev": true, - "requires": { - "command-line-args": "^4.0.7", - "debug": "^4.1.1", - "fs-extra": "^7.0.0", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "ts-essentials": "^6.0.3", - "ts-generator": "^0.1.1" - } - } - } - }, - "@ethereum-waffle/ens": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-3.3.1.tgz", - "integrity": "sha512-xSjNWnT2Iwii3J3XGqD+F5yLEOzQzLHNLGfI5KIXdtQ4FHgReW/AMGRgPPLi+n+SP08oEQWJ3sEKrvbFlwJuaA==", - "dev": true, - "requires": { - "@ensdomains/ens": "^0.4.4", - "@ensdomains/resolver": "^0.2.4", - "ethers": "^5.5.2" - } - }, - "@ethereum-waffle/mock-contract": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-3.3.1.tgz", - "integrity": "sha512-h9yChF7IkpJLODg/o9/jlwKwTcXJLSEIq3gewgwUJuBHnhPkJGekcZvsTbximYc+e42QUZrDUATSuTCIryeCEA==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.5.0", - "ethers": "^5.5.2" - } - }, - "@ethereum-waffle/provider": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-3.4.1.tgz", - "integrity": "sha512-5iDte7c9g9N1rTRE/P4npwk1Hus/wA2yH850X6sP30mr1IrwSG9NKn6/2SOQkAVJnh9jqyLVg2X9xCODWL8G4A==", - "dev": true, - "requires": { - "@ethereum-waffle/ens": "^3.3.1", - "ethers": "^5.5.2", - "ganache-core": "^2.13.2", - "patch-package": "^6.2.2", - "postinstall-postinstall": "^2.1.0" - } - }, - "@ethereumjs/block": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.0.tgz", - "integrity": "sha512-dqLo1LtsLG+Oelu5S5tWUDG0pah3QUwV5TJZy2cm19BXDr4ka/S9XBSgao0i09gTcuPlovlHgcs6d7EZ37urjQ==", - "requires": { - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "ethereumjs-util": "^7.1.3", - "merkle-patricia-tree": "^4.2.2" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "@ethereumjs/blockchain": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.1.tgz", - "integrity": "sha512-JS2jeKxl3tlaa5oXrZ8mGoVBCz6YqsGG350XVNtHAtNZXKk7pU3rH4xzF2ru42fksMMqzFLzKh9l4EQzmNWDqA==", - "requires": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/ethash": "^1.1.0", - "debug": "^2.2.0", - "ethereumjs-util": "^7.1.3", - "level-mem": "^5.0.1", - "lru-cache": "^5.1.1", - "semaphore-async-await": "^1.5.1" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "@ethereumjs/common": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz", - "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==", - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.3" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "@ethereumjs/ethash": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", - "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", - "requires": { - "@ethereumjs/block": "^3.5.0", - "@types/levelup": "^4.3.0", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.1.1", - "miller-rabin": "^4.0.0" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "@ethereumjs/tx": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz", - "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==", - "requires": { - "@ethereumjs/common": "^2.6.0", - "ethereumjs-util": "^7.1.3" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "@ethereumjs/vm": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz", - "integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==", - "requires": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "async-eventemitter": "^0.2.4", - "core-js-pure": "^3.0.1", - "debug": "^2.2.0", - "ethereumjs-util": "^7.1.3", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.2", - "rustbn.js": "~0.2.0" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "@ethersproject/abi": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz", - "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==", - "requires": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz", - "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz", - "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "@ethersproject/address": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz", - "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/rlp": "^5.5.0" - } - }, - "@ethersproject/base64": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz", - "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==", - "requires": { - "@ethersproject/bytes": "^5.5.0" - } - }, - "@ethersproject/basex": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", - "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", - "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "bn.js": "^4.11.9" - } - }, - "@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/constants": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz", - "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==", - "requires": { - "@ethersproject/bignumber": "^5.5.0" - } - }, - "@ethersproject/contracts": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", - "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.5.0", - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0" - } - }, - "@ethersproject/hardware-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hardware-wallets/-/hardware-wallets-5.5.0.tgz", - "integrity": "sha512-oZh/Ps/ohxFQdKVeMw8wpw0xZpL+ndsRlQwNE3Eki2vLeH2to14de6fNrgETZtAbAhzglH6ES9Nlx1+UuqvvYg==", - "dev": true, - "peer": true, - "requires": { - "@ledgerhq/hw-app-eth": "5.27.2", - "@ledgerhq/hw-transport": "5.26.0", - "@ledgerhq/hw-transport-node-hid": "5.26.0", - "@ledgerhq/hw-transport-u2f": "5.26.0", - "ethers": "^5.5.0" - } - }, - "@ethersproject/hash": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", - "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", - "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", - "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "@ethersproject/keccak256": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", - "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" - }, - "@ethersproject/networks": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.2.tgz", - "integrity": "sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", - "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/sha2": "^5.5.0" - } - }, - "@ethersproject/properties": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", - "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/providers": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.2.tgz", - "integrity": "sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "@ethersproject/random": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz", - "integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/rlp": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", - "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", - "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "@ethersproject/solidity": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", - "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/strings": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", - "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/transactions": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz", - "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==", - "requires": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0" - } - }, - "@ethersproject/units": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", - "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/wallet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", - "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/json-wallets": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "@ethersproject/web": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz", - "integrity": "sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg==", - "requires": { - "@ethersproject/base64": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", - "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ledgerhq/cryptoassets": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-5.53.0.tgz", - "integrity": "sha512-M3ibc3LRuHid5UtL7FI3IC6nMEppvly98QHFoSa7lJU0HDzQxY6zHec/SPM4uuJUC8sXoGVAiRJDkgny54damw==", - "dev": true, - "peer": true, - "requires": { - "invariant": "2" - } - }, - "@ledgerhq/devices": { - "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.51.1.tgz", - "integrity": "sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA==", - "dev": true, - "peer": true, - "requires": { - "@ledgerhq/errors": "^5.50.0", - "@ledgerhq/logs": "^5.50.0", - "rxjs": "6", - "semver": "^7.3.5" - } - }, - "@ledgerhq/errors": { - "version": "5.50.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-5.50.0.tgz", - "integrity": "sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==", - "dev": true, - "peer": true - }, - "@ledgerhq/hw-app-eth": { - "version": "5.27.2", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-5.27.2.tgz", - "integrity": "sha512-llNdrE894cCN8j6yxJEUniciyLVcLmu5N0UmIJLOObztG+5rOF4bX54h4SreTWK+E10Z0CzHSeyE5Lz/tVcqqQ==", - "dev": true, - "peer": true, - "requires": { - "@ledgerhq/cryptoassets": "^5.27.2", - "@ledgerhq/errors": "^5.26.0", - "@ledgerhq/hw-transport": "^5.26.0", - "bignumber.js": "^9.0.1", - "rlp": "^2.2.6" - } - }, - "@ledgerhq/hw-transport": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.26.0.tgz", - "integrity": "sha512-NFeJOJmyEfAX8uuIBTpocWHcz630sqPcXbu864Q+OCBm4EK5UOKV1h/pX7e0xgNIKY8zhJ/O4p4cIZp9tnXLHQ==", - "dev": true, - "peer": true, - "requires": { - "@ledgerhq/devices": "^5.26.0", - "@ledgerhq/errors": "^5.26.0", - "events": "^3.2.0" - } - }, - "@ledgerhq/hw-transport-node-hid": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.26.0.tgz", - "integrity": "sha512-qhaefZVZatJ6UuK8Wb6WSFNOLWc2mxcv/xgsfKi5HJCIr4bPF/ecIeN+7fRcEaycxj4XykY6Z4A7zDVulfFH4w==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@ledgerhq/devices": "^5.26.0", - "@ledgerhq/errors": "^5.26.0", - "@ledgerhq/hw-transport": "^5.26.0", - "@ledgerhq/hw-transport-node-hid-noevents": "^5.26.0", - "@ledgerhq/logs": "^5.26.0", - "lodash": "^4.17.20", - "node-hid": "1.3.0", - "usb": "^1.6.3" - } - }, - "@ledgerhq/hw-transport-node-hid-noevents": { - "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz", - "integrity": "sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@ledgerhq/devices": "^5.51.1", - "@ledgerhq/errors": "^5.50.0", - "@ledgerhq/hw-transport": "^5.51.1", - "@ledgerhq/logs": "^5.50.0", - "node-hid": "2.1.1" - }, - "dependencies": { - "@ledgerhq/hw-transport": { - "version": "5.51.1", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz", - "integrity": "sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@ledgerhq/devices": "^5.51.1", - "@ledgerhq/errors": "^5.50.0", - "events": "^3.3.0" - } - }, - "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true, - "optional": true, - "peer": true - }, - "node-hid": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.1.tgz", - "integrity": "sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "bindings": "^1.5.0", - "node-addon-api": "^3.0.2", - "prebuild-install": "^6.0.0" - } - }, - "prebuild-install": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", - "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.21.0", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - } - } - } - }, - "@ledgerhq/hw-transport-u2f": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.26.0.tgz", - "integrity": "sha512-QTxP1Rsh+WZ184LUOelYVLeaQl3++V3I2jFik+l9JZtakwEHjD0XqOT750xpYNL/vfHsy31Wlz+oicdxGzFk+w==", - "dev": true, - "peer": true, - "requires": { - "@ledgerhq/errors": "^5.26.0", - "@ledgerhq/hw-transport": "^5.26.0", - "@ledgerhq/logs": "^5.26.0", - "u2f-api": "0.2.7" - } - }, - "@ledgerhq/logs": { - "version": "5.50.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.50.0.tgz", - "integrity": "sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==", - "dev": true, - "peer": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@nomiclabs/hardhat-ethers": { - "version": "npm:hardhat-deploy-ethers@0.3.0-beta.13", - "resolved": "https://registry.npmjs.org/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.3.0-beta.13.tgz", - "integrity": "sha512-PdWVcKB9coqWV1L7JTpfXRCI91Cgwsm7KLmBcwZ8f0COSm1xtABHZTyz3fvF6p42cTnz1VM0QnfDvMFlIRkSNw==", - "dev": true, - "requires": {} - }, - "@nomiclabs/hardhat-etherscan": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz", - "integrity": "sha512-0+rj0SsZotVOcTLyDOxnOc3Gulo8upo0rsw/h+gBPcmtj91YqYJNhdARHoBxOhhE8z+5IUQPx+Dii04lXT14PA==", - "requires": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^5.0.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "node-fetch": "^2.6.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@resolver-engine/core": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", - "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "is-url": "^1.2.4", - "request": "^2.85.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", - "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", - "dev": true, - "requires": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/imports": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", - "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", - "dev": true, - "requires": { - "@resolver-engine/core": "^0.3.3", - "debug": "^3.1.0", - "hosted-git-info": "^2.6.0", - "path-browserify": "^1.0.0", - "url": "^0.11.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@resolver-engine/imports-fs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", - "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", - "dev": true, - "requires": { - "@resolver-engine/fs": "^0.3.3", - "@resolver-engine/imports": "^0.3.3", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "requires": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "requires": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - } - }, - "@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==" - }, - "@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "requires": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@solidity-parser/parser": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.0.tgz", - "integrity": "sha512-cX0JJRcmPtNUJpzD2K7FdA7qQsTOk1UZnFx2k7qAg9ZRvuaH5NBe5IEdBMXGlmf2+FmjhqbygJ26H8l2SV7aKQ==", - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@tenderly/hardhat-tenderly": { - "version": "1.1.0-beta.8", - "resolved": "https://registry.npmjs.org/@tenderly/hardhat-tenderly/-/hardhat-tenderly-1.1.0-beta.8.tgz", - "integrity": "sha512-ppXvp2/CGI/1iAGZvCpHk7vBmlvUJerMcVtiXtCRZtXFO1vDs2SJ+RKaW5bI+eFFkLWx75aZVc/lxTx2vIzPsg==", - "dev": true, - "requires": { - "@nomiclabs/hardhat-ethers": "^2.0.1", - "axios": "^0.21.1", - "ethers": "^5.0.24", - "fs-extra": "^9.0.1", - "js-yaml": "^3.14.0" - }, - "dependencies": { - "@nomiclabs/hardhat-ethers": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.4.tgz", - "integrity": "sha512-7LMR344TkdCYkMVF9LuC9VU2NBIi84akQiwqm7OufpWaDgHbWhuanY53rk3SVAW0E4HBk5xn5wl5+bN5f+Mq5w==", - "dev": true, - "requires": {} - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@truffle/error": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.14.tgz", - "integrity": "sha512-utJx+SZYoMqk8wldQG4gCVKhV8GwMJbWY7sLXFT/D8wWZTnE2peX7URFJh/cxkjTRCO328z1s2qewkhyVsu2HA==", - "dev": true - }, - "@truffle/interface-adapter": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.8.tgz", - "integrity": "sha512-vvy3xpq36oLgjjy8KE9l2Jabg3WcGPOt18tIyMfTQX9MFnbHoQA2Ne2i8xsd4p6KfxIqSjAB53Q9/nScAqY0UQ==", - "dev": true, - "requires": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.5.3" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", - "dev": true - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", - "dev": true - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "dev": true - } - } - }, - "@truffle/provider": { - "version": "0.2.42", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.42.tgz", - "integrity": "sha512-ZNoglPho4alYIjJR+sLTgX0x6ho7m4OAUWuJ50RAWmoEqYc4AM6htdrI+lTSoRrOHHbmgasv22a7rFPMnmDrTg==", - "dev": true, - "requires": { - "@truffle/error": "^0.0.14", - "@truffle/interface-adapter": "^0.5.8", - "web3": "1.5.3" - } - }, - "@typechain/ethers-v5": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-7.2.0.tgz", - "integrity": "sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw==", - "dev": true, - "requires": { - "lodash": "^4.17.15", - "ts-essentials": "^7.0.1" - } - }, - "@typechain/hardhat": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-2.3.1.tgz", - "integrity": "sha512-BQV8OKQi0KAzLXCdsPO0pZBNQQ6ra8A2ucC26uFX/kquRBtJu1yEyWnVSmtr07b5hyRoJRpzUeINLnyqz4/MAw==", - "dev": true, - "requires": { - "fs-extra": "^9.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@types/abstract-leveldown": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", - "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==" - }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", - "dev": true - }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/level-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", - "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==" - }, - "@types/levelup": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", - "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", - "requires": { - "@types/abstract-leveldown": "*", - "@types/level-errors": "*", - "@types/node": "*" - } - }, - "@types/lodash": { - "version": "4.14.178", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", - "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==", - "dev": true - }, - "@types/lowdb": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/lowdb/-/lowdb-1.0.9.tgz", - "integrity": "sha512-LBRG5EPXFOJDoJc9jACstMhtMP+u+UkPYllBeGQXXKiaHc+uzJs9+/Aynb/5KkX33DtrIiKyzNVTPQc/4RcD6A==", - "dev": true, - "requires": { - "@types/lodash": "*" - } - }, - "@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" - }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "@types/mkdirp": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true - }, - "@types/node": { - "version": "14.0.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.5.tgz", - "integrity": "sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==" - }, - "@types/node-fetch": { - "version": "2.5.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", - "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", - "dev": true, - "requires": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", - "dev": true - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "requires": { - "@types/node": "*" - } - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "abstract-leveldown": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", - "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", - "dev": true - }, - "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" - }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "amazon-cognito-identity-js": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-4.6.3.tgz", - "integrity": "sha512-MPVJfirbdmSGo7l4h7Kbn3ms1eJXT5Xq8ly+mCPPi8yAxaxdg7ouMUUNTqtDykoZxIdDLF/P6F3Zbg3dlGKOWg==", - "dev": true, - "requires": { - "buffer": "4.9.2", - "crypto-js": "^4.0.0", - "fast-base64-decode": "^1.0.0", - "isomorphic-unfetch": "^3.0.0", - "js-cookie": "^2.2.1" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true, - "optional": true - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==" - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true, - "peer": true - }, - "are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true, - "peer": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "requires": { - "typical": "^2.6.1" - } - }, - "array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, - "async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "requires": { - "async": "^2.4.0" - } - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.0" - } - }, - "axios-curlirize": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/axios-curlirize/-/axios-curlirize-1.3.7.tgz", - "integrity": "sha512-csSsuMyZj1dv1fL0zRPnDAHWrmlISMvK+wx9WJI/igRVDT4VMgbf2AVenaHghFLfI1nQijXUevYEguYV6u5hjA==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - } - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "blakejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", - "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", - "dev": true, - "requires": { - "bytes": "3.1.1", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "dependencies": { - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - } - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=", - "dev": true - }, - "buffer-xor": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", - "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", - "requires": { - "safe-buffer": "^5.1.1" - } - }, - "bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "devOptional": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==" - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "requires": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - } - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chai-bignumber": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chai-bignumber/-/chai-bignumber-3.0.0.tgz", - "integrity": "sha512-SubOtaSI2AILWTWe2j0c6i2yFT/f9J6UBjeVGDuwDiPLkF/U5+/eTWUE3sbCZ1KgcPF6UJsDVYbIxaYA097MQA==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "dev": true, - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true - }, - "cli-table3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", - "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", - "dev": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^4.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - }, - "dependencies": { - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" - }, - "command-line-args": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-4.0.7.tgz", - "integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==", - "dev": true, - "requires": { - "array-back": "^2.0.0", - "find-replace": "^1.0.3", - "typical": "^2.6.1" - } - }, - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" - }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true, - "peer": true - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", - "dev": true - }, - "core-js-pure": { - "version": "3.20.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.2.tgz", - "integrity": "sha512-CmWHvSKn2vNL6p6StNp1EmMIfVY/pqn3JLAjfZQ8WZGPOlGoO92EkX9/Mk81i6GxvoPXjUqEQnpM3rJ5QxxIOg==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", - "dev": true - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", - "dev": true - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "mimic-response": "^2.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "optional": true, - "peer": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "defender-base-client": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/defender-base-client/-/defender-base-client-1.12.1.tgz", - "integrity": "sha512-DMLSCMz6LsCb8jWHhsULEPMLKSc48nYCtdAEa5dXj5YWzPTn9YprcXKbf5NwHqY0uy85j3AAis5ZG7L7+RqBYw==", - "dev": true, - "requires": { - "amazon-cognito-identity-js": "^4.3.3", - "axios": "^0.19.2", - "lodash": "^4.17.19", - "node-fetch": "^2.6.0" - }, - "dependencies": { - "axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "dev": true, - "requires": { - "follow-redirects": "1.5.10" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "defender-relay-client": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/defender-relay-client/-/defender-relay-client-1.12.1.tgz", - "integrity": "sha512-zOml68K5uZNhikFcXrL2tNWHbgC0++yw9487XKt4iZXpMxKHZNHEyG1D7lFpC9+Ic6bXHLr10fES+AeYjZCHuQ==", - "dev": true, - "requires": { - "amazon-cognito-identity-js": "^4.3.3", - "axios": "^0.19.2", - "defender-base-client": "^1.12.1", - "lodash": "^4.17.19", - "node-fetch": "^2.6.0" - }, - "dependencies": { - "axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "dev": true, - "requires": { - "follow-redirects": "1.5.10" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "requires": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true, - "peer": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true, - "peer": true - }, - "detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "dev": true - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "emoji-regex": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.0.0.tgz", - "integrity": "sha512-KmJa8l6uHi1HrBI34udwlzZY1jOEuID/ft4d8BSSEdRyap7PwBEt910453PJa5MuGvxkLqlt4Uvhu7tttFHViw==", - "dev": true - }, - "encode-utf8": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "requires": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "dependencies": { - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - } - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - } - } - }, - "eslint-plugin-prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", - "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", - "dev": true, - "requires": { - "fast-diff": "^1.1.1", - "jest-docblock": "^21.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", - "dev": true, - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - }, - "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", - "dev": true - } - } - }, - "eth-gas-reporter": { - "version": "0.2.23", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.23.tgz", - "integrity": "sha512-T8KsVakDEupvQxW3MfFfHDfJ7y8zl2+XhyEQk4hZ3qQsAh/FE27BfFHM9UhqNQvrJLz8zVWnPZWNcARwLT/lsA==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "^1.1.2", - "ethereumjs-util": "6.2.0", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - } - }, - "ethereumjs-util": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz", - "integrity": "sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "0.1.6", - "keccak": "^2.0.0", - "rlp": "^2.2.3", - "secp256k1": "^3.0.1" - } - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=", - "dev": true - }, - "keccak": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-2.1.0.tgz", - "integrity": "sha512-m1wbJRTo+gWbctZWay9i26v5fFnYkOn7D5PCxJ3fZUGUEb49dE1Pm4BREUYCt/aoO6di7jeoGmhvqN9Nzylm3Q==", - "dev": true, - "requires": { - "bindings": "^1.5.0", - "inherits": "^2.0.4", - "nan": "^2.14.0", - "safe-buffer": "^5.2.0" - } - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "secp256k1": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", - "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", - "dev": true, - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.5.2", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "dev": true - } - } - }, - "eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "eth-sig-util": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.3.tgz", - "integrity": "sha512-KpXbCKmmBUNUTGh9MRKmNkIPietfhzBqqYqysDavLseIiMUGl95k6UcPEkALAZlj41e9E6yioYXc1PC333RKqw==", - "requires": { - "buffer": "^5.2.1", - "elliptic": "^6.4.0", - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", - "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dev": true, - "requires": { - "js-sha3": "^0.8.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereum-waffle": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-3.0.2.tgz", - "integrity": "sha512-VJQTL9oBbHIQRxQFuh1NBXoFXSlTIY6DrkPpO7CvevXRI9ixxq01nSc6hPYUIVy7s+U03sp4ply497O6mD3gsQ==", - "dev": true, - "requires": { - "@ethereum-waffle/chai": "^3.0.2", - "@ethereum-waffle/compiler": "^3.0.2", - "@ethereum-waffle/mock-contract": "^3.0.2", - "@ethereum-waffle/provider": "^3.0.2", - "ethers": "^5.0.1" - } - }, - "ethereumjs-abi": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz", - "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz", - "integrity": "sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==", - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.0.0" - } - } - } - }, - "ethereumjs-util": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.2.tgz", - "integrity": "sha512-ATAP02eJLpAlWGfiKQddNrRfZpwXiTFhRN2EM/yLXMCdBW/xjKYblNKcx8GLzzrjXg0ymotck+lam1nuV90arQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethjs-util": "0.1.6", - "keccak": "^3.0.0", - "rlp": "^2.2.4", - "secp256k1": "^4.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } - } - }, - "ethers": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.3.tgz", - "integrity": "sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.5.0", - "@ethersproject/abstract-provider": "5.5.1", - "@ethersproject/abstract-signer": "5.5.0", - "@ethersproject/address": "5.5.0", - "@ethersproject/base64": "5.5.0", - "@ethersproject/basex": "5.5.0", - "@ethersproject/bignumber": "5.5.0", - "@ethersproject/bytes": "5.5.0", - "@ethersproject/constants": "5.5.0", - "@ethersproject/contracts": "5.5.0", - "@ethersproject/hash": "5.5.0", - "@ethersproject/hdnode": "5.5.0", - "@ethersproject/json-wallets": "5.5.0", - "@ethersproject/keccak256": "5.5.0", - "@ethersproject/logger": "5.5.0", - "@ethersproject/networks": "5.5.2", - "@ethersproject/pbkdf2": "5.5.0", - "@ethersproject/properties": "5.5.0", - "@ethersproject/providers": "5.5.2", - "@ethersproject/random": "5.5.1", - "@ethersproject/rlp": "5.5.0", - "@ethersproject/sha2": "5.5.0", - "@ethersproject/signing-key": "5.5.0", - "@ethersproject/solidity": "5.5.0", - "@ethersproject/strings": "5.5.0", - "@ethersproject/transactions": "5.5.0", - "@ethersproject/units": "5.5.0", - "@ethersproject/wallet": "5.5.0", - "@ethersproject/web": "5.5.1", - "@ethersproject/wordlists": "5.5.0" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "dev": true, - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", - "dev": true - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "peer": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" - }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "optional": true, - "peer": true - }, - "express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.6", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", - "dev": true - } - } - }, - "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "dev": true, - "requires": { - "type": "^2.5.0" - }, - "dependencies": { - "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-base64-decode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", - "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.8.tgz", - "integrity": "sha512-UsiHHXoDbC3iS7vBOFvld7Q9XqBu318xztdHiL10Fjov3AK5GI5bek2ZJkxZcjPguOYH39UL1W4A6w+l7tpNtw==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "find-replace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-1.0.3.tgz", - "integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=", - "dev": true, - "requires": { - "array-back": "^1.0.4", - "test-value": "^2.1.0" - }, - "dependencies": { - "array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", - "dev": true, - "requires": { - "typical": "^2.6.0" - } - } - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "dev": true, - "requires": { - "semver-regex": "^3.1.2" - } - }, - "find-yarn-workspace-root": { - "version": "2.0.0", - "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==", - "dev": true, - "requires": { - "micromatch": "^4.0.2" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fmix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", - "integrity": "sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw=", - "dev": true, - "requires": { - "imul": "^1.0.0" - } - }, - "follow-redirects": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", - "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==" - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "optional": true, - "peer": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "ganache-cli": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.12.2.tgz", - "integrity": "sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw==", - "dev": true, - "requires": { - "ethereumjs-util": "6.2.1", - "source-map-support": "0.5.12", - "yargs": "13.2.4" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "bundled": true, - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "14.11.2", - "bundled": true, - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "base-x": { - "version": "3.0.8", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "bn.js": { - "version": "4.11.9", - "bundled": true, - "dev": true - }, - "brorand": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "bs58": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer-from": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "bundled": true, - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "bundled": true, - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "create-hash": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "bundled": true, - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "bundled": true, - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "bundled": true, - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "bundled": true, - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "ethjs-util": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "hash-base": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "invert-kv": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-hex-prefixed": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "keccak": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "lcid": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mem": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "node-addon-api": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "node-gyp-build": { - "version": "4.2.3", - "bundled": true, - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-locale": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-defer": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "pbkdf2": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pump": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "randombytes": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "ripemd160": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.6", - "bundled": true, - "dev": true, - "requires": { - "bn.js": "^4.11.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "bundled": true, - "dev": true - }, - "scrypt-js": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "secp256k1": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "bundled": true, - "dev": true - }, - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - }, - "source-map-support": { - "version": "0.5.12", - "bundled": true, - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "string_decoder": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "strip-hex-prefix": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "which": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "y18n": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "yargs": { - "version": "13.2.4", - "bundled": true, - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" - } - }, - "yargs-parser": { - "version": "13.1.2", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "ganache-core": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.13.2.tgz", - "integrity": "sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==", - "dev": true, - "requires": { - "abstract-leveldown": "3.0.0", - "async": "2.6.2", - "bip39": "2.5.0", - "cachedown": "1.0.0", - "clone": "2.1.2", - "debug": "3.2.6", - "encoding-down": "5.0.4", - "eth-sig-util": "3.0.0", - "ethereumjs-abi": "0.6.8", - "ethereumjs-account": "3.0.0", - "ethereumjs-block": "2.2.2", - "ethereumjs-common": "1.5.0", - "ethereumjs-tx": "2.1.2", - "ethereumjs-util": "6.2.1", - "ethereumjs-vm": "4.2.0", - "ethereumjs-wallet": "0.6.5", - "heap": "0.2.6", - "keccak": "3.0.1", - "level-sublevel": "6.6.4", - "levelup": "3.1.1", - "lodash": "4.17.20", - "lru-cache": "5.1.1", - "merkle-patricia-tree": "3.0.0", - "patch-package": "6.2.2", - "seedrandom": "3.0.1", - "source-map-support": "0.5.12", - "tmp": "0.1.0", - "web3": "1.2.11", - "web3-provider-engine": "14.2.1", - "websocket": "1.0.32" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.0-beta.153", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/address": ">=5.0.0-beta.128", - "@ethersproject/bignumber": ">=5.0.0-beta.130", - "@ethersproject/bytes": ">=5.0.0-beta.129", - "@ethersproject/constants": ">=5.0.0-beta.128", - "@ethersproject/hash": ">=5.0.0-beta.128", - "@ethersproject/keccak256": ">=5.0.0-beta.127", - "@ethersproject/logger": ">=5.0.0-beta.129", - "@ethersproject/properties": ">=5.0.0-beta.131", - "@ethersproject/strings": ">=5.0.0-beta.130" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/networks": "^5.0.7", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/transactions": "^5.0.9", - "@ethersproject/web": "^5.0.12" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.0.10", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abstract-provider": "^5.0.8", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7" - } - }, - "@ethersproject/address": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/rlp": "^5.0.7" - } - }, - "@ethersproject/base64": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9" - } - }, - "@ethersproject/bignumber": { - "version": "5.0.13", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/constants": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13" - } - }, - "@ethersproject/hash": { - "version": "5.0.10", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abstract-signer": "^5.0.10", - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "@ethersproject/keccak256": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "js-sha3": "0.5.7" - } - }, - "@ethersproject/logger": { - "version": "5.0.8", - "dev": true, - "optional": true - }, - "@ethersproject/networks": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/properties": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/rlp": { - "version": "5.0.7", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/signing-key": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "elliptic": "6.5.3" - } - }, - "@ethersproject/strings": { - "version": "5.0.8", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/logger": "^5.0.8" - } - }, - "@ethersproject/transactions": { - "version": "5.0.9", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/address": "^5.0.9", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/constants": "^5.0.8", - "@ethersproject/keccak256": "^5.0.7", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/rlp": "^5.0.7", - "@ethersproject/signing-key": "^5.0.8" - } - }, - "@ethersproject/web": { - "version": "5.0.12", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/base64": "^5.0.7", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "dev": true, - "optional": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "dev": true, - "optional": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "14.14.20", - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.1", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "dev": true - }, - "abstract-leveldown": { - "version": "3.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "accepts": { - "version": "1.3.7", - "dev": true, - "optional": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "aes-js": { - "version": "3.1.2", - "dev": true, - "optional": true - }, - "ajv": { - "version": "6.12.6", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-styles": { - "version": "3.2.1", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "arr-diff": { - "version": "4.0.0", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "array-unique": { - "version": "0.3.2", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "dev": true - }, - "async": { - "version": "2.6.2", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "async-eventemitter": { - "version": "0.2.4", - "dev": true, - "requires": { - "async": "^2.4.0" - } - }, - "async-limiter": { - "version": "1.0.1", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "dev": true - }, - "atob": { - "version": "2.1.2", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "json5": { - "version": "0.5.1", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - }, - "slash": { - "version": "1.0.0", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "dev": true - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-env": { - "version": "1.7.0", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "dev": true - } - } - }, - "babel-register": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "source-map-support": { - "version": "0.4.18", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "dev": true - } - } - }, - "babelify": { - "version": "7.3.0", - "dev": true, - "requires": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" - } - }, - "babylon": { - "version": "6.18.0", - "dev": true - }, - "backoff": { - "version": "2.5.0", - "dev": true, - "requires": { - "precond": "0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "dev": true - }, - "base": { - "version": "0.11.2", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "base-x": { - "version": "3.0.8", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "dev": true - } - } - }, - "bignumber.js": { - "version": "9.0.1", - "dev": true, - "optional": true - }, - "bip39": { - "version": "2.5.0", - "dev": true, - "requires": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, - "blakejs": { - "version": "1.1.0", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "dev": true, - "optional": true - }, - "bn.js": { - "version": "4.11.9", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "dev": true, - "optional": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.7.0", - "dev": true, - "optional": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "dev": true, - "optional": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "dev": true, - "optional": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true, - "optional": true - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "3.6.0", - "dev": true, - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserslist": { - "version": "3.2.8", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "bs58": { - "version": "4.0.1", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "5.7.1", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-from": { - "version": "1.1.1", - "dev": true - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "dev": true, - "optional": true - }, - "buffer-xor": { - "version": "1.0.3", - "dev": true - }, - "bufferutil": { - "version": "4.0.3", - "dev": true, - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "bytes": { - "version": "3.1.0", - "dev": true, - "optional": true - }, - "bytewise": { - "version": "1.1.0", - "dev": true, - "requires": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" - } - }, - "bytewise-core": { - "version": "1.2.3", - "dev": true, - "requires": { - "typewise-core": "^1.2" - } - }, - "cache-base": { - "version": "1.0.1", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cacheable-request": { - "version": "6.1.0", - "dev": true, - "optional": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "lowercase-keys": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "cachedown": { - "version": "1.0.0", - "dev": true, - "requires": { - "abstract-leveldown": "^2.4.1", - "lru-cache": "^3.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "lru-cache": { - "version": "3.2.0", - "dev": true, - "requires": { - "pseudomap": "^1.0.1" - } - } - } - }, - "call-bind": { - "version": "1.0.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caniuse-lite": { - "version": "1.0.30001174", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "checkpoint-store": { - "version": "1.1.0", - "dev": true, - "requires": { - "functional-red-black-tree": "^1.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "dev": true, - "optional": true - }, - "ci-info": { - "version": "2.0.0", - "dev": true - }, - "cids": { - "version": "0.7.5", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "multicodec": { - "version": "1.0.4", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "class-utils": { - "version": "0.3.6", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "clone": { - "version": "2.1.2", - "dev": true - }, - "clone-response": { - "version": "1.0.2", - "dev": true, - "optional": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "component-emitter": { - "version": "1.3.0", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "content-disposition": { - "version": "0.5.3", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } - } - }, - "content-hash": { - "version": "2.5.2", - "dev": true, - "optional": true, - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "content-type": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "convert-source-map": { - "version": "1.7.0", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "cookie": { - "version": "0.4.0", - "dev": true, - "optional": true - }, - "cookie-signature": { - "version": "1.0.6", - "dev": true, - "optional": true - }, - "cookiejar": { - "version": "2.1.2", - "dev": true, - "optional": true - }, - "copy-descriptor": { - "version": "0.1.1", - "dev": true - }, - "core-js": { - "version": "2.6.12", - "dev": true - }, - "core-js-pure": { - "version": "3.8.2", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "dev": true - }, - "cors": { - "version": "2.8.5", - "dev": true, - "optional": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-ecdh": { - "version": "4.0.4", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-fetch": { - "version": "2.2.3", - "dev": true, - "requires": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "dev": true, - "optional": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "d": { - "version": "1.0.1", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "3.2.6", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "dev": true, - "optional": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "dev": true, - "optional": true - }, - "deferred-leveldown": { - "version": "4.0.2", - "dev": true, - "requires": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "define-properties": { - "version": "1.1.3", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "defined": { - "version": "1.0.0", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "dev": true - }, - "depd": { - "version": "1.1.2", - "dev": true, - "optional": true - }, - "des.js": { - "version": "1.0.1", - "dev": true, - "optional": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "detect-indent": { - "version": "4.0.0", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "diffie-hellman": { - "version": "5.0.3", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dom-walk": { - "version": "0.1.2", - "dev": true - }, - "dotignore": { - "version": "0.1.2", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "electron-to-chromium": { - "version": "1.3.636", - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "encodeurl": { - "version": "1.0.2", - "dev": true, - "optional": true - }, - "encoding": { - "version": "0.1.13", - "dev": true, - "requires": { - "iconv-lite": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.2", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "encoding-down": { - "version": "5.0.4", - "dev": true, - "requires": { - "abstract-leveldown": "^5.0.0", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "end-of-stream": { - "version": "1.4.4", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "errno": { - "version": "0.1.8", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.18.0-next.1", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escape-html": { - "version": "1.0.3", - "dev": true, - "optional": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "dev": true - }, - "etag": { - "version": "1.8.1", - "dev": true, - "optional": true - }, - "eth-block-tracker": { - "version": "3.0.1", - "dev": true, - "requires": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - }, - "dependencies": { - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "pify": { - "version": "2.3.0", - "dev": true - } - } - }, - "eth-ens-namehash": { - "version": "2.0.8", - "dev": true, - "optional": true, - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "eth-json-rpc-infura": { - "version": "3.2.1", - "dev": true, - "requires": { - "cross-fetch": "^2.1.1", - "eth-json-rpc-middleware": "^1.5.0", - "json-rpc-engine": "^3.4.0", - "json-rpc-error": "^2.0.0" - } - }, - "eth-json-rpc-middleware": { - "version": "1.6.0", - "dev": true, - "requires": { - "async": "^2.5.0", - "eth-query": "^2.1.2", - "eth-tx-summary": "^3.1.2", - "ethereumjs-block": "^1.6.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", - "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "tape": "^4.6.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "eth-lib": { - "version": "0.1.29", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "eth-query": { - "version": "2.1.2", - "dev": true, - "requires": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "eth-sig-util": { - "version": "3.0.0", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "elliptic": "^6.4.0", - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - }, - "dependencies": { - "ethereumjs-abi": { - "version": "0.6.5", - "dev": true, - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "4.5.1", - "dev": true, - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.0.0" - } - } - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "eth-tx-summary": { - "version": "3.2.4", - "dev": true, - "requires": { - "async": "^2.1.2", - "clone": "^2.0.0", - "concat-stream": "^1.5.1", - "end-of-stream": "^1.1.0", - "eth-query": "^2.0.2", - "ethereumjs-block": "^1.4.1", - "ethereumjs-tx": "^1.1.1", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "^2.6.0", - "through2": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethashjs": { - "version": "0.0.8", - "dev": true, - "requires": { - "async": "^2.1.2", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.0.2", - "miller-rabin": "^4.0.0" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "dev": true - }, - "buffer-xor": { - "version": "2.0.2", - "dev": true, - "requires": { - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-util": { - "version": "7.0.7", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.4" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.7", - "dev": true, - "optional": true, - "requires": { - "js-sha3": "^0.8.0" - }, - "dependencies": { - "js-sha3": { - "version": "0.8.0", - "dev": true, - "optional": true - } - } - }, - "ethereum-common": { - "version": "0.0.18", - "dev": true - }, - "ethereum-cryptography": { - "version": "0.1.3", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-account": { - "version": "3.0.0", - "dev": true, - "requires": { - "ethereumjs-util": "^6.0.0", - "rlp": "^2.2.1", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethereumjs-blockchain": { - "version": "4.0.4", - "dev": true, - "requires": { - "async": "^2.6.1", - "ethashjs": "~0.0.7", - "ethereumjs-block": "~2.2.2", - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.1.0", - "flow-stoplight": "^1.0.0", - "level-mem": "^3.0.1", - "lru-cache": "^5.1.1", - "rlp": "^2.2.2", - "semaphore": "^1.1.0" - } - }, - "ethereumjs-common": { - "version": "1.5.0", - "dev": true - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "ethereumjs-vm": { - "version": "4.2.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "core-js-pure": "^3.0.1", - "ethereumjs-account": "^3.0.0", - "ethereumjs-block": "^2.2.2", - "ethereumjs-blockchain": "^4.0.3", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.2", - "ethereumjs-util": "^6.2.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1", - "util.promisify": "^1.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - } - } - }, - "ethereumjs-wallet": { - "version": "0.6.5", - "dev": true, - "optional": true, - "requires": { - "aes-js": "^3.1.1", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^6.0.0", - "randombytes": "^2.0.6", - "safe-buffer": "^5.1.2", - "scryptsy": "^1.2.1", - "utf8": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "dev": true, - "optional": true, - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "dev": true, - "optional": true - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "eventemitter3": { - "version": "4.0.4", - "dev": true, - "optional": true - }, - "events": { - "version": "3.2.0", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "2.1.4", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "express": { - "version": "4.17.1", - "dev": true, - "optional": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.7.0", - "dev": true, - "optional": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } - } - }, - "ext": { - "version": "1.4.0", - "dev": true, - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.1.0", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "extglob": { - "version": "2.0.4", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "dev": true - }, - "fake-merkle-patricia-tree": { - "version": "1.0.1", - "dev": true, - "requires": { - "checkpoint-store": "^1.1.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true - }, - "fetch-ponyfill": { - "version": "4.1.0", - "dev": true, - "requires": { - "node-fetch": "~1.7.1" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "dev": true - }, - "node-fetch": { - "version": "1.7.3", - "dev": true, - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "find-yarn-workspace-root": { - "version": "1.2.1", - "dev": true, - "requires": { - "fs-extra": "^4.0.3", - "micromatch": "^3.1.4" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fs-extra": { - "version": "4.0.3", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "flow-stoplight": { - "version": "1.0.0", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "dev": true, - "optional": true - }, - "fragment-cache": { - "version": "0.2.1", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "dev": true, - "optional": true - }, - "fs-extra": { - "version": "7.0.1", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "dev": true - }, - "get-intrinsic": { - "version": "1.0.2", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "5.2.0", - "dev": true, - "optional": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global": { - "version": "4.4.0", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "got": { - "version": "9.6.0", - "dev": true, - "optional": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "dependencies": { - "get-stream": { - "version": "4.1.0", - "dev": true, - "optional": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, - "graceful-fs": { - "version": "4.2.4", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "dev": true - } - } - }, - "has-flag": { - "version": "3.0.0", - "dev": true - }, - "has-symbol-support-x": { - "version": "1.4.2", - "dev": true, - "optional": true - }, - "has-symbols": { - "version": "1.0.1", - "dev": true - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "dev": true, - "optional": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "has-value": { - "version": "1.0.0", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "heap": { - "version": "0.2.6", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "dev": true, - "optional": true - }, - "http-errors": { - "version": "1.7.2", - "dev": true, - "optional": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "dev": true, - "optional": true - } - } - }, - "http-https": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "http-signature": { - "version": "1.2.0", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "dev": true, - "optional": true, - "requires": { - "punycode": "2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.0", - "dev": true, - "optional": true - } - } - }, - "ieee754": { - "version": "1.2.1", - "dev": true - }, - "immediate": { - "version": "3.2.3", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "dev": true, - "optional": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-arguments": { - "version": "1.1.0", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.2", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-date-object": { - "version": "1.0.2", - "dev": true - }, - "is-descriptor": { - "version": "1.0.2", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-finite": { - "version": "1.1.0", - "dev": true - }, - "is-fn": { - "version": "1.0.0", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "dev": true - }, - "is-hex-prefixed": { - "version": "1.0.0", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.1", - "dev": true - }, - "is-object": { - "version": "1.0.2", - "dev": true, - "optional": true - }, - "is-plain-obj": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "is-plain-object": { - "version": "2.0.4", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.1", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-retry-allowed": { - "version": "1.2.0", - "dev": true, - "optional": true - }, - "is-symbol": { - "version": "1.0.3", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "dev": true - }, - "isurl": { - "version": "1.0.0", - "dev": true, - "optional": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "js-sha3": { - "version": "0.5.7", - "dev": true, - "optional": true - }, - "js-tokens": { - "version": "4.0.0", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "json-rpc-engine": { - "version": "3.8.0", - "dev": true, - "requires": { - "async": "^2.0.1", - "babel-preset-env": "^1.7.0", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1" - } - }, - "json-rpc-error": { - "version": "2.0.0", - "dev": true, - "requires": { - "inherits": "^2.0.1" - } - }, - "json-rpc-random-id": { - "version": "1.0.1", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "keyv": { - "version": "3.1.0", - "dev": true, - "optional": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "dev": true - }, - "klaw-sync": { - "version": "6.0.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11" - } - }, - "level-codec": { - "version": "9.0.2", - "dev": true, - "requires": { - "buffer": "^5.6.0" - } - }, - "level-errors": { - "version": "2.0.1", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "2.0.3", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.5", - "xtend": "^4.0.0" - } - }, - "level-mem": { - "version": "3.0.1", - "dev": true, - "requires": { - "level-packager": "~4.0.0", - "memdown": "~3.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "3.0.0", - "dev": true, - "requires": { - "abstract-leveldown": "~5.0.0", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "level-packager": { - "version": "4.0.1", - "dev": true, - "requires": { - "encoding-down": "~5.0.0", - "levelup": "^3.0.0" - } - }, - "level-post": { - "version": "1.0.7", - "dev": true, - "requires": { - "ltgt": "^2.1.2" - } - }, - "level-sublevel": { - "version": "6.6.4", - "dev": true, - "requires": { - "bytewise": "~1.1.0", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "level-iterator-stream": "^2.0.3", - "ltgt": "~2.1.1", - "pull-defer": "^0.2.2", - "pull-level": "^2.0.3", - "pull-stream": "^3.6.8", - "typewiselite": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "level-ws": { - "version": "1.0.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.8", - "xtend": "^4.0.1" - } - }, - "levelup": { - "version": "3.1.1", - "dev": true, - "requires": { - "deferred-leveldown": "~4.0.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~3.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "level-iterator-stream": { - "version": "3.0.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "xtend": "^4.0.0" - } - } - } - }, - "lodash": { - "version": "4.17.20", - "dev": true - }, - "looper": { - "version": "2.0.0", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "lru-cache": { - "version": "5.1.1", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "ltgt": { - "version": "2.1.3", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "dev": true, - "optional": true - }, - "merge-descriptors": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "merkle-patricia-tree": { - "version": "3.0.0", - "dev": true, - "requires": { - "async": "^2.6.1", - "ethereumjs-util": "^5.2.0", - "level-mem": "^3.0.1", - "level-ws": "^1.0.0", - "readable-stream": "^3.0.6", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "readable-stream": { - "version": "3.6.0", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "methods": { - "version": "1.1.2", - "dev": true, - "optional": true - }, - "miller-rabin": { - "version": "4.0.1", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "dev": true, - "optional": true - }, - "mime-db": { - "version": "1.45.0", - "dev": true - }, - "mime-types": { - "version": "2.1.28", - "dev": true, - "requires": { - "mime-db": "1.45.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "min-document": { - "version": "2.19.0", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "dev": true - }, - "minizlib": { - "version": "1.3.3", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "mixin-deep": { - "version": "1.3.2", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } - }, - "mkdirp": { - "version": "0.5.5", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "dev": true, - "optional": true, - "requires": { - "mkdirp": "*" - } - }, - "mock-fs": { - "version": "4.13.0", - "dev": true, - "optional": true - }, - "ms": { - "version": "2.1.3", - "dev": true - }, - "multibase": { - "version": "0.6.1", - "dev": true, - "optional": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "multicodec": { - "version": "0.5.7", - "dev": true, - "optional": true, - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "multibase": { - "version": "0.7.0", - "dev": true, - "optional": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "dev": true, - "optional": true - }, - "next-tick": { - "version": "1.0.0", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "dev": true - }, - "node-addon-api": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "node-fetch": { - "version": "2.1.2", - "dev": true - }, - "node-gyp-build": { - "version": "4.2.3", - "bundled": true, - "dev": true - }, - "normalize-url": { - "version": "4.5.0", - "dev": true, - "optional": true - }, - "number-to-bn": { - "version": "1.7.0", - "dev": true, - "optional": true, - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "dev": true, - "optional": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.9.0", - "dev": true - }, - "object-is": { - "version": "1.1.4", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.2", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.1", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "object.pick": { - "version": "1.3.0", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "oboe": { - "version": "2.1.4", - "dev": true, - "optional": true, - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "dev": true, - "optional": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "p-timeout": { - "version": "1.2.1", - "dev": true, - "optional": true, - "requires": { - "p-finally": "^1.0.0" - }, - "dependencies": { - "p-finally": { - "version": "1.0.0", - "dev": true, - "optional": true - } - } - }, - "parse-asn1": { - "version": "5.1.6", - "dev": true, - "optional": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-headers": { - "version": "2.0.3", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "dev": true, - "optional": true - }, - "pascalcase": { - "version": "0.1.1", - "dev": true - }, - "patch-package": { - "version": "6.2.2", - "dev": true, - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^1.2.1", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "dev": true - }, - "semver": { - "version": "5.7.1", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "dev": true - }, - "slash": { - "version": "2.0.0", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "which": { - "version": "1.3.1", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "path-is-absolute": { - "version": "1.0.1", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "dev": true, - "optional": true - }, - "pbkdf2": { - "version": "3.1.1", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "dev": true - }, - "precond": { - "version": "0.2.3", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "dev": true, - "optional": true - }, - "private": { - "version": "0.1.8", - "dev": true - }, - "process": { - "version": "0.11.10", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "dev": true - }, - "promise-to-callback": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" - } - }, - "proxy-addr": { - "version": "2.0.6", - "dev": true, - "optional": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "dev": true - }, - "psl": { - "version": "1.8.0", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pull-cat": { - "version": "1.1.11", - "dev": true - }, - "pull-defer": { - "version": "0.2.3", - "dev": true - }, - "pull-level": { - "version": "2.0.4", - "dev": true, - "requires": { - "level-post": "^1.0.7", - "pull-cat": "^1.1.9", - "pull-live": "^1.0.1", - "pull-pushable": "^2.0.0", - "pull-stream": "^3.4.0", - "pull-window": "^2.1.4", - "stream-to-pull-stream": "^1.7.1" - } - }, - "pull-live": { - "version": "1.0.1", - "dev": true, - "requires": { - "pull-cat": "^1.1.9", - "pull-stream": "^3.4.0" - } - }, - "pull-pushable": { - "version": "2.2.0", - "dev": true - }, - "pull-stream": { - "version": "3.6.14", - "dev": true - }, - "pull-window": { - "version": "2.1.4", - "dev": true, - "requires": { - "looper": "^2.0.0" - } - }, - "pump": { - "version": "3.0.0", - "dev": true, - "optional": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "dev": true - }, - "qs": { - "version": "6.5.2", - "dev": true - }, - "query-string": { - "version": "5.1.1", - "dev": true, - "optional": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "randombytes": { - "version": "2.1.0", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "dev": true, - "optional": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "dev": true, - "optional": true - }, - "raw-body": { - "version": "2.4.0", - "dev": true, - "optional": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "regenerate": { - "version": "1.4.2", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "dev": true - }, - "regenerator-transform": { - "version": "0.10.1", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, - "regexpu-core": { - "version": "2.0.0", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "dev": true - } - } - }, - "repeat-element": { - "version": "1.1.3", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.2", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "resolve-url": { - "version": "0.2.1", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "dev": true, - "optional": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "resumer": { - "version": "0.0.0", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "ret": { - "version": "0.1.15", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.6", - "dev": true, - "requires": { - "bn.js": "^4.11.1" - } - }, - "rustbn.js": { - "version": "0.2.0", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "dev": true - }, - "safe-event-emitter": { - "version": "1.0.1", - "dev": true, - "requires": { - "events": "^3.0.0" - } - }, - "safe-regex": { - "version": "1.1.0", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "dev": true - }, - "scrypt-js": { - "version": "3.0.1", - "dev": true - }, - "scryptsy": { - "version": "1.2.1", - "dev": true, - "optional": true, - "requires": { - "pbkdf2": "^3.0.3" - } - }, - "secp256k1": { - "version": "4.0.2", - "dev": true, - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "seedrandom": { - "version": "3.0.1", - "dev": true - }, - "semaphore": { - "version": "1.1.0", - "dev": true - }, - "send": { - "version": "0.17.1", - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "dev": true, - "optional": true - } - } - }, - "ms": { - "version": "2.1.1", - "dev": true, - "optional": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "dev": true, - "optional": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "servify": { - "version": "0.1.12", - "dev": true, - "optional": true, - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "set-immediate-shim": { - "version": "1.0.1", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - } - } - }, - "setimmediate": { - "version": "1.0.5", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "sha.js": { - "version": "2.4.11", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "simple-concat": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "simple-get": { - "version": "2.8.1", - "dev": true, - "optional": true, - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "dev": true - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.5.7", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.12", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.0", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "dev": true - } - } - }, - "static-extend": { - "version": "0.1.2", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "dev": true - } - } - }, - "statuses": { - "version": "1.5.0", - "dev": true, - "optional": true - }, - "stream-to-pull-stream": { - "version": "1.7.3", - "dev": true, - "requires": { - "looper": "^3.0.0", - "pull-stream": "^3.2.3" - }, - "dependencies": { - "looper": { - "version": "3.0.0", - "dev": true - } - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "string_decoder": { - "version": "1.1.1", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true - } - } - }, - "string.prototype.trim": { - "version": "1.2.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.3", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "strip-hex-prefix": { - "version": "1.0.0", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "swarm-js": { - "version": "0.1.40", - "dev": true, - "optional": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, - "dependencies": { - "fs-extra": { - "version": "4.0.3", - "dev": true, - "optional": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-stream": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "got": { - "version": "7.1.0", - "dev": true, - "optional": true, - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "dev": true, - "optional": true - }, - "p-cancelable": { - "version": "0.3.0", - "dev": true, - "optional": true - }, - "prepend-http": { - "version": "1.0.4", - "dev": true, - "optional": true - }, - "url-parse-lax": { - "version": "1.0.0", - "dev": true, - "optional": true, - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "tape": { - "version": "4.13.3", - "dev": true, - "requires": { - "deep-equal": "~1.1.1", - "defined": "~1.0.0", - "dotignore": "~0.1.2", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.6", - "has": "~1.0.3", - "inherits": "~2.0.4", - "is-regex": "~1.0.5", - "minimist": "~1.2.5", - "object-inspect": "~1.7.0", - "resolve": "~1.17.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.2.1", - "through": "~2.3.8" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "is-regex": { - "version": "1.0.5", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "object-inspect": { - "version": "1.7.0", - "dev": true - }, - "resolve": { - "version": "1.17.0", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, - "tar": { - "version": "4.4.13", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - }, - "dependencies": { - "fs-minipass": { - "version": "1.2.7", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "minipass": { - "version": "2.9.0", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "through": { - "version": "2.3.8", - "dev": true - }, - "through2": { - "version": "2.0.5", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timed-out": { - "version": "4.0.1", - "dev": true, - "optional": true - }, - "tmp": { - "version": "0.1.0", - "dev": true, - "requires": { - "rimraf": "^2.6.3" - } - }, - "to-object-path": { - "version": "0.3.0", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-readable-stream": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "to-regex": { - "version": "3.0.2", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "toidentifier": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "tough-cookie": { - "version": "2.5.0", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "trim-right": { - "version": "1.0.1", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.3", - "dev": true - }, - "tweetnacl-util": { - "version": "0.15.1", - "dev": true - }, - "type": { - "version": "1.2.0", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "dev": true, - "optional": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typewise": { - "version": "1.0.3", - "dev": true, - "requires": { - "typewise-core": "^1.2.0" - } - }, - "typewise-core": { - "version": "1.2.0", - "dev": true - }, - "typewiselite": { - "version": "1.0.0", - "dev": true - }, - "ultron": { - "version": "1.1.1", - "dev": true, - "optional": true - }, - "underscore": { - "version": "1.9.1", - "dev": true, - "optional": true - }, - "union-value": { - "version": "1.0.1", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "0.1.1", - "dev": true - } - } - }, - "universalify": { - "version": "0.1.2", - "dev": true - }, - "unorm": { - "version": "1.6.0", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "unset-value": { - "version": "1.0.0", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "dev": true - } - } - }, - "uri-js": { - "version": "4.4.1", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "dev": true - }, - "url-parse-lax": { - "version": "3.0.0", - "dev": true, - "optional": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "dev": true, - "optional": true - }, - "url-to-options": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "use": { - "version": "3.1.1", - "dev": true - }, - "utf-8-validate": { - "version": "5.0.4", - "dev": true, - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "utf8": { - "version": "3.0.0", - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "dev": true - }, - "util.promisify": { - "version": "1.1.1", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "for-each": "^0.3.3", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.1" - } - }, - "utils-merge": { - "version": "1.0.1", - "dev": true, - "optional": true - }, - "uuid": { - "version": "3.4.0", - "dev": true - }, - "varint": { - "version": "5.0.2", - "dev": true, - "optional": true - }, - "vary": { - "version": "1.1.2", - "dev": true, - "optional": true - }, - "verror": { - "version": "1.10.0", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "web3-bzz": "1.2.11", - "web3-core": "1.2.11", - "web3-eth": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-shh": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-bzz": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40", - "underscore": "1.9.1" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } - } - }, - "web3-core": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-requestmanager": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } - } - }, - "web3-core-helpers": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "underscore": "1.9.1", - "web3-eth-iban": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-core-method": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-core-promievent": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "web3-providers-http": "1.2.11", - "web3-providers-ipc": "1.2.11", - "web3-providers-ws": "1.2.11" - } - }, - "web3-core-subscriptions": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" - } - }, - "web3-eth": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-accounts": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-eth-ens": "1.2.11", - "web3-eth-iban": "1.2.11", - "web3-eth-personal": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-eth-abi": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abi": "5.0.0-beta.153", - "underscore": "1.9.1", - "web3-utils": "1.2.11" - } - }, - "web3-eth-accounts": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-common": "^1.3.2", - "ethereumjs-tx": "^2.1.1", - "scrypt-js": "^3.0.1", - "underscore": "1.9.1", - "uuid": "3.3.2", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "dev": true, - "optional": true - } - } - }, - "web3-eth-contract": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@types/bn.js": "^4.11.5", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-eth-ens": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "underscore": "1.9.1", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-promievent": "1.2.11", - "web3-eth-abi": "1.2.11", - "web3-eth-contract": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-eth-iban": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.2.11" - } - }, - "web3-eth-personal": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.2.11", - "web3-core-helpers": "1.2.11", - "web3-core-method": "1.2.11", - "web3-net": "1.2.11", - "web3-utils": "1.2.11" - }, - "dependencies": { - "@types/node": { - "version": "12.19.12", - "dev": true, - "optional": true - } - } - }, - "web3-net": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-utils": "1.2.11" - } - }, - "web3-provider-engine": { - "version": "14.2.1", - "dev": true, - "requires": { - "async": "^2.5.0", - "backoff": "^2.5.0", - "clone": "^2.0.0", - "cross-fetch": "^2.1.0", - "eth-block-tracker": "^3.0.0", - "eth-json-rpc-infura": "^3.1.0", - "eth-sig-util": "3.0.0", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.5", - "ethereumjs-vm": "^2.3.4", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.85.0", - "semaphore": "^1.0.3", - "ws": "^5.1.1", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "1.2.2", - "dev": true, - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "eth-sig-util": { - "version": "1.4.2", - "dev": true, - "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "ethereumjs-util": "^5.1.1" - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "dev": true, - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "dev": true - } - } - }, - "ethereumjs-tx": { - "version": "1.3.7", - "dev": true, - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-vm": { - "version": "2.6.0", - "dev": true, - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.2.0", - "ethereumjs-common": "^1.1.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.3.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.2.2", - "dev": true, - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^1.5.0", - "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereumjs-tx": { - "version": "2.1.2", - "dev": true, - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "dev": true - }, - "level-codec": { - "version": "7.0.1", - "dev": true - }, - "level-errors": { - "version": "1.0.5", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-ws": { - "version": "0.0.0", - "dev": true, - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "dev": true, - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "dev": true - }, - "memdown": { - "version": "1.4.1", - "dev": true, - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "dev": true, - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "dev": true - } - } - }, - "object-keys": { - "version": "0.4.0", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "dev": true - }, - "semver": { - "version": "5.4.1", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "dev": true - }, - "ws": { - "version": "5.2.2", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, - "web3-providers-http": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "web3-core-helpers": "1.2.11", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "oboe": "2.1.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11" - } - }, - "web3-providers-ws": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.9.1", - "web3-core-helpers": "1.2.11", - "websocket": "^1.0.31" - } - }, - "web3-shh": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "web3-core": "1.2.11", - "web3-core-method": "1.2.11", - "web3-core-subscriptions": "1.2.11", - "web3-net": "1.2.11" - } - }, - "web3-utils": { - "version": "1.2.11", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "underscore": "1.9.1", - "utf8": "3.0.0" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "dev": true, - "optional": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - } - } - }, - "websocket": { - "version": "1.0.32", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "dev": true - } - } - }, - "whatwg-fetch": { - "version": "2.0.4", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "dev": true - }, - "ws": { - "version": "3.3.3", - "dev": true, - "optional": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "dev": true, - "optional": true - } - } - }, - "xhr": { - "version": "2.6.0", - "dev": true, - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "dev": true, - "optional": true, - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "xhr-request-promise": { - "version": "0.1.3", - "dev": true, - "optional": true, - "requires": { - "xhr-request": "^1.1.0" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "dev": true, - "optional": true, - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xtend": { - "version": "4.0.2", - "dev": true - }, - "yaeti": { - "version": "0.0.6", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "dev": true - } - } - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", - "dev": true - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - } - }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "dev": true, - "optional": true, - "peer": true - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "dependencies": { - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "hardhat": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.8.2.tgz", - "integrity": "sha512-cBUqzZGOi+lwKHArWl5Be7zeFIwlu1IUXOna6k5XhORZ8hAWDVbAJBVfxgmjkcX5GffIf0C5g841zRxo36sQ5g==", - "requires": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "@ethereumjs/vm": "^5.6.0", - "@ethersproject/abi": "^5.1.2", - "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.14.0", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "eth-sig-util": "^2.5.2", - "ethereum-cryptography": "^0.1.2", - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.3", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "^7.1.3", - "https-proxy-agent": "^5.0.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.2", - "mnemonist": "^0.38.0", - "mocha": "^7.2.0", - "node-fetch": "^2.6.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "slash": "^3.0.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "true-case-path": "^2.2.1", - "tsort": "0.0.1", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "requires": { - "@types/node": "*" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - } - } - }, - "hardhat-contract-sizer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.3.0.tgz", - "integrity": "sha512-hRUwn5PhNWPO1t0ehtlDhEtP8YzzwCB+NNEdt6p+ZQ2bnq9rSgAjMsybSeOYt/ohen3kH31Pqm0hK0ies5/1tA==", - "dev": true, - "requires": { - "cli-table3": "^0.6.0", - "colors": "^1.4.0" - } - }, - "hardhat-dependency-compiler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.2.tgz", - "integrity": "sha512-LVnsPSZnGvzWVvlpewlkPKlPtFP/S9V41RC1fd/ygZc4jkG8ubNlfE82nwiGw5oPueHSmFi6TACgmyrEOokK8w==", - "dev": true, - "requires": {} - }, - "hardhat-deploy": { - "version": "0.9.24", - "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.9.24.tgz", - "integrity": "sha512-fIIg6Wt7lV8h+6c6dFnINUKcJ/5Wfe5GYDaDsGGPqaK2b71DaeFHjsWRL+2ozaHkMZjdyYBOweY09wRu/KM1Qw==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.1", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.1", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/contracts": "^5.4.1", - "@ethersproject/providers": "^5.4.4", - "@ethersproject/solidity": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/wallet": "^5.4.0", - "@types/qs": "^6.9.7", - "axios": "^0.21.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.2", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "form-data": "^4.0.0", - "fs-extra": "^10.0.0", - "match-all": "^1.2.6", - "murmur-128": "^0.2.1", - "qs": "^6.9.4" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "hardhat-gas-reporter": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.6.tgz", - "integrity": "sha512-LlCEmSx1dZpnxKmODb2hmP5eJ1IAM5It3NnBNTUpBTxn9g9qPPI3JQTxj8AbGEiNc3r6V+w/mXYCmiC8pWvnoQ==", - "dev": true, - "requires": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.23", - "sha1": "^1.1.1" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "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==", - "dev": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true, - "peer": true - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "requires": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=", - "dev": true - }, - "http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "requires": { - "@types/node": "^10.0.3" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true - }, - "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "dev": true, - "requires": { - "punycode": "2.1.0" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" - }, - "immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imul": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", - "integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "peer": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "requires": { - "fp-ts": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "dev": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", - "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isomorphic-unfetch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", - "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", - "dev": true, - "requires": { - "node-fetch": "^2.6.1", - "unfetch": "^4.2.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "jest-docblock": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", - "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", - "dev": true - }, - "js-cookie": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", - "dev": true - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "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==", - "dev": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonschema": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz", - "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==", - "dev": true - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "level-codec": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", - "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", - "requires": { - "buffer": "^5.6.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" - }, - "level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - } - }, - "level-mem": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", - "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", - "requires": { - "level-packager": "^5.0.3", - "memdown": "^5.0.0" - } - }, - "level-packager": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", - "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", - "requires": { - "encoding-down": "^6.3.0", - "levelup": "^4.3.2" - } - }, - "level-supports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "requires": { - "xtend": "^4.0.2" - } - }, - "level-ws": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", - "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^3.1.0", - "xtend": "^4.0.1" - } - }, - "levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", - "requires": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "requires": { - "chalk": "^2.4.2" - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "peer": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lowdb": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", - "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.3", - "is-promise": "^2.1.0", - "lodash": "4", - "pify": "^3.0.0", - "steno": "^0.4.1" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "match-all": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/match-all/-/match-all-1.2.6.tgz", - "integrity": "sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ==", - "dev": true - }, - "mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "memdown": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", - "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", - "requires": { - "abstract-leveldown": "~6.2.1", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" - } - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "merkle-patricia-tree": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.2.tgz", - "integrity": "sha512-eqZYNTshcYx9aESkSPr71EqwsR/QmpnObDEV4iLxkt/x/IoLYZYjJvKY72voP/27Vy61iMOrfOG6jrn7ttXD+Q==", - "requires": { - "@types/levelup": "^4.3.0", - "ethereumjs-util": "^7.1.2", - "level-mem": "^5.0.1", - "level-ws": "^2.0.0", - "readable-stream": "^3.6.0", - "rlp": "^2.2.4", - "semaphore-async-await": "^1.5.1" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "requires": { - "mime-db": "1.51.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "dev": true, - "optional": true, - "peer": true - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, - "optional": true, - "peer": true - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "dev": true, - "requires": { - "mkdirp": "*" - } - }, - "mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "requires": { - "obliterator": "^2.0.0" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "requires": { - "picomatch": "^2.0.4" - } - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", - "dev": true - }, - "mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "dev": true, - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", - "dev": true, - "requires": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - } - }, - "murmur-128": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz", - "integrity": "sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg==", - "dev": true, - "requires": { - "encode-utf8": "^1.0.2", - "fmix": "^0.1.0", - "imul": "^1.0.0" - } - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=", - "dev": true - }, - "napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true, - "optional": true, - "peer": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-abi": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "optional": true, - "peer": true - } - } - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" - }, - "node-hid": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-1.3.0.tgz", - "integrity": "sha512-BA6G4V84kiNd1uAChub/Z/5s/xS3EHBCxotQ0nyYrUG65mXewUDHE1tWOSqA2dp3N+mV0Ffq9wo2AW9t4p/G7g==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.14.0", - "node-abi": "^2.18.0", - "prebuild-install": "^5.3.4" - } - }, - "nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==" - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", - "dev": true, - "optional": true, - "peer": true - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - }, - "dependencies": { - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - } - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "dev": true, - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", - "dev": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "obliterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.1.tgz", - "integrity": "sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w==" - }, - "oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", - "dev": true, - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - } - }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", - "dev": true - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=", - "dev": true - }, - "parse-headers": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz", - "integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw==", - "dev": true - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "patch-package": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", - "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", - "dev": true, - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - } - } - }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - }, - "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" - } - }, - "postinstall-postinstall": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz", - "integrity": "sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==", - "dev": true - }, - "prebuild-install": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", - "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", - "dev": true - }, - "prettier-plugin-solidity": { - "version": "1.0.0-beta.19", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz", - "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.14.0", - "emoji-regex": "^10.0.0", - "escape-string-regexp": "^4.0.0", - "semver": "^7.3.5", - "solidity-comments-extractor": "^0.0.7", - "string-width": "^4.2.3" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - } - } - }, - "pretty-quick": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.3.tgz", - "integrity": "sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "execa": "^4.0.0", - "find-up": "^4.1.0", - "ignore": "^5.1.4", - "mri": "^1.1.5", - "multimatch": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "requires": { - "asap": "~2.0.6" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", - "dev": true - }, - "qs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", - "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", - "requires": { - "bytes": "3.1.1", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "dev": true, - "requires": { - "minimatch": "3.0.4" - } - }, - "req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha1-1AgrTURZgDZkD7c93qAe1T20nrw=", - "dev": true, - "requires": { - "req-from": "^2.0.0" - } - }, - "req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha1-10GI5H+TeW9Kpx327jWuaJ8+DnA=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "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": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "requires": { - "bn.js": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==" - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "peer": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semaphore-async-await": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", - "integrity": "sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=" - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "semver-regex": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.3.tgz", - "integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==", - "dev": true - }, - "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - } - }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dev": true, - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=", - "dev": true, - "requires": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", - "dev": true - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true - }, - "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", - "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "solidity-coverage": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.17.tgz", - "integrity": "sha512-Erw2hd2xdACAvDX8jUdYkmgJlIIazGznwDJA5dhRaw4def2SisXN9jUjneeyOZnl/E7j6D3XJYug4Zg9iwodsg==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.13.2", - "@truffle/provider": "^0.2.24", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "fs-extra": "^8.1.0", - "ganache-cli": "^6.12.2", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.0" - }, - "dependencies": { - "@solidity-parser/parser": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.13.2.tgz", - "integrity": "sha512-RwHnpRnfrnD2MSPveYoPh8nhofEvX7fgjHk1Oq+NNvCcLx4r1js91CO9o+F/F3fBzOCyvm8kKRTriFICX/odWw==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - } - } - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - } - } - }, - "stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "requires": { - "type-fest": "^0.7.1" - }, - "dependencies": { - "type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==" - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, - "steno": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", - "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.3" - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "requires": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - } - }, - "sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "requires": { - "get-port": "^3.1.0" - } - }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - } - }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "test-value": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", - "dev": true, - "requires": { - "array-back": "^1.0.3", - "typical": "^2.6.0" - }, - "dependencies": { - "array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", - "dev": true, - "requires": { - "typical": "^2.6.0" - } - } - } - }, - "testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "dev": true - }, - "then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - } - } - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tmp-promise": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", - "requires": { - "tmp": "^0.2.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "requires": { - "rimraf": "^3.0.0" - } - } - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "true-case-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", - "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" - }, - "ts-essentials": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", - "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, - "requires": {} - }, - "ts-generator": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ts-generator/-/ts-generator-0.1.1.tgz", - "integrity": "sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==", - "dev": true, - "requires": { - "@types/mkdirp": "^0.5.2", - "@types/prettier": "^2.1.1", - "@types/resolve": "^0.0.8", - "chalk": "^2.4.1", - "glob": "^7.1.2", - "mkdirp": "^0.5.1", - "prettier": "^2.1.2", - "resolve": "^1.8.1", - "ts-essentials": "^1.0.0" - }, - "dependencies": { - "ts-essentials": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-1.0.4.tgz", - "integrity": "sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==", - "dev": true - } - } - }, - "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tslint": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", - "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "tslint-config-prettier": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", - "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", - "dev": true - }, - "tslint-plugin-prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz", - "integrity": "sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA==", - "dev": true, - "requires": { - "eslint-plugin-prettier": "^2.2.0", - "lines-and-columns": "^1.1.6", - "tslib": "^1.7.1" - } - }, - "tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=" - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typechain": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-5.2.0.tgz", - "integrity": "sha512-0INirvQ+P+MwJOeMct+WLkUE4zov06QxC96D+i3uGFEHoiSkZN70MKDQsaj8zkL86wQwByJReI2e7fOUwECFuw==", - "dev": true, - "requires": { - "@types/prettier": "^2.1.1", - "command-line-args": "^4.0.7", - "debug": "^4.1.1", - "fs-extra": "^7.0.0", - "glob": "^7.1.6", - "js-sha3": "^0.8.0", - "lodash": "^4.17.15", - "mkdirp": "^1.0.4", - "prettier": "^2.1.2", - "ts-essentials": "^7.0.1" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", - "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", - "dev": true - }, - "typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", - "dev": true - }, - "u2f-api": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/u2f-api/-/u2f-api-0.2.7.tgz", - "integrity": "sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg==", - "dev": true, - "peer": true - }, - "uglify-js": { - "version": "3.14.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.5.tgz", - "integrity": "sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ==", - "dev": true, - "optional": true - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "unfetch": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", - "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", - "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=", - "dev": true - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true - }, - "usb": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/usb/-/usb-1.9.2.tgz", - "integrity": "sha512-dryNz030LWBPAf6gj8vyq0Iev3vPbCLHCT8dBw3gQRXRzVNsIdeuU+VjPp3ksmSPkeMAl1k+kQ14Ij0QHyeiAg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "node-addon-api": "^4.2.0", - "node-gyp-build": "^4.3.0" - }, - "dependencies": { - "node-addon-api": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.2.0.tgz", - "integrity": "sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q==", - "dev": true, - "optional": true, - "peer": true - } - } - }, - "utf-8-validate": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", - "integrity": "sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA==", - "devOptional": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true - }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "requires": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - } - } - }, - "web3-core": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.6.1.tgz", - "integrity": "sha512-m+b7UfYvU5cQUAh6NRfxRzH/5B3to1AdEQi1HIQt570cDWlObOOmoO9tY6iJnI5w4acxIO19LqjDMqEJGBYyRQ==", - "dev": true, - "peer": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.6.1", - "web3-core-method": "1.6.1", - "web3-core-requestmanager": "1.6.1", - "web3-utils": "1.6.1" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true, - "peer": true - } - } - }, - "web3-core-helpers": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.6.1.tgz", - "integrity": "sha512-om2PZvK1uoWcgMq6JfcSx3241LEIVF6qi2JuHz2SLKiKEW5UsBUaVx0mNCmcZaiuYQCyOsLS3r33q5AdM+v8ng==", - "dev": true, - "peer": true, - "requires": { - "web3-eth-iban": "1.6.1", - "web3-utils": "1.6.1" - } - }, - "web3-core-method": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.6.1.tgz", - "integrity": "sha512-szH5KyIWIaULQDBdDvevQUCHV9lsExJ/oV0ePqK+w015D2SdMPMuhii0WB+HCePaksWO+rr/GAypvV9g2T3N+w==", - "dev": true, - "peer": true, - "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.6.1", - "web3-core-promievent": "1.6.1", - "web3-core-subscriptions": "1.6.1", - "web3-utils": "1.6.1" - } - }, - "web3-core-promievent": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.6.1.tgz", - "integrity": "sha512-byJ5s2MQxrWdXd27pWFmujfzsTZK4ik8rDgIV1RFDFc+rHZ2nZhq+VWk7t/Nkrj7EaVXncEgTdPEHc18nx+ocQ==", - "dev": true, - "peer": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.6.1.tgz", - "integrity": "sha512-4y7etYEUtkfflyYVBfN1oJtCbVFNhNX1omlEYzezhTnPj3/dT7n+dhUXcqvIhx9iKA13unGfpFge80XNFfcB8A==", - "dev": true, - "peer": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.6.1", - "web3-providers-http": "1.6.1", - "web3-providers-ipc": "1.6.1", - "web3-providers-ws": "1.6.1" - } - }, - "web3-core-subscriptions": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.6.1.tgz", - "integrity": "sha512-WZwxsYttIojyGQ5RqxuQcKg0IJdDCFpUe4EncS3QKZwxPqWzGmgyLwE0rm7tP+Ux1waJn5CUaaoSCBxWGSun1g==", - "dev": true, - "peer": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.6.1" - } - }, - "web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-eth-iban": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.6.1.tgz", - "integrity": "sha512-91H0jXZnWlOoXmc13O9NuQzcjThnWyAHyDn5Yf7u6mmKOhpJSGF/OHlkbpXt1Y4v2eJdEPaVFa+6i8aRyagE7Q==", - "dev": true, - "peer": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.6.1" - } - }, - "web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-providers-http": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.6.1.tgz", - "integrity": "sha512-xBoKOJxu10+kO3ikamXmBfrWZ/xpQOGy0ocdp7Y81B17En5TXELwlmMXt1UlIgWiyYDhjq4OwlH/VODYqHXy3A==", - "dev": true, - "peer": true, - "requires": { - "web3-core-helpers": "1.6.1", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.6.1.tgz", - "integrity": "sha512-anyoIZlpMzwEQI4lwylTzDrHsVp20v0QUtSTp2B5jInBinmQtyCE7vnbX20jEQ4j5uPwfJabKNtoJsk6a3O4WQ==", - "dev": true, - "peer": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.6.1" - } - }, - "web3-providers-ws": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.6.1.tgz", - "integrity": "sha512-FWMEFYb4rYFYRgSFBf/O1Ex4p/YKSlN+JydCtdlJwRimd89qm95CTfs4xGjCskwvXMjV2sarH+f1NPwJXicYpg==", - "dev": true, - "peer": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.6.1", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - }, - "dependencies": { - "@types/node": { - "version": "12.20.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", - "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "web3-utils": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", - "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "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" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - } - } - } - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, - "which-typed-array": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", - "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.7" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "requires": {} - }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - }, - "dependencies": { - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "dev": true, - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - } - } - }, - "xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dev": true, - "requires": { - "xhr-request": "^1.1.0" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "dev": true, - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/package.json b/lib/morpho-utils/lib/aave-v3-core/package.json deleted file mode 100644 index b1c9937..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/package.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "name": "@aave/core-v3", - "version": "1.16.1", - "description": "Aave Protocol V3 core smart contracts", - "files": [ - "contracts", - "artifacts", - "types" - ], - "engines": { - "node": ">=16.0.0" - }, - "scripts": { - "size": "npm run compile && npm run hardhat size-contracts", - "auth-registry": "npx dotenv-cli -- bash -c 'npm config set //npm.pkg.github.com/:_authToken \"$NODE_AUTH_TOKEN\"'", - "run-env": "npm run auth-registry && npm i && tail -f /dev/null", - "hardhat": "hardhat", - "compile": "SKIP_LOAD=true hardhat compile", - "compile:clean": "npm run ci:clean && npm run compile", - "console:fork": "FORK=main hardhat console", - "prettier:check": "npx prettier -c 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts' 'test-suites/**/*.ts' 'market-config/**/*.ts'", - "prettier:write": "prettier --write 'tasks/**/*.ts' 'contracts/**/*.sol' 'helpers/**/*.ts' 'test-suites/**/*.ts' 'market-config/**/*.ts'", - "coverage": ". ./setup-test-env.sh && COVERAGE=true npx hardhat coverage --temp temp-artifacts --testfiles test-suites/emptyrun.coverage.ts && rm -rf coverage.json coverage/ && COVERAGE=true npx hardhat coverage --temp temp-artifacts --testfiles 'test-suites/*.spec.ts'", - "test": ". ./setup-test-env.sh && TS_NODE_TRANSPILE_ONLY=1 hardhat test test-suites/*.spec.ts", - "test-scenarios": ". ./setup-test-env.sh && npx hardhat test test-suites/__setup.spec.ts test-suites/scenario.spec.ts", - "test-l2pool": ". ./setup-test-env.sh && npx hardhat test test-suites/__setup.spec.ts test-suites/pool-l2.spec.ts", - "test-subgraph:scenarios": ". ./setup-test-env.sh && hardhat --network hardhatevm_docker test test-suites/__setup.spec.ts test-suites/subgraph-scenarios.spec.ts", - "ci:test": ". ./setup-test-env.sh && npm run test", - "ci:clean": "rm -rf ./artifacts ./cache ./types ./temp-artifacts", - "prepublish": "npm run compile" - }, - "devDependencies": { - "@aave/deploy-v3": "^1.21.1-beta.4", - "@aave/periphery-v3": "^1.13.1-beta.1", - "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", - "@tenderly/hardhat-tenderly": "^1.1.0-beta.5", - "@typechain/ethers-v5": "^7.2.0", - "@typechain/hardhat": "^2.3.1", - "@types/chai": "^4.2.11", - "@types/lowdb": "1.0.9", - "@types/mocha": "7.0.2", - "@types/node": "14.0.5", - "chai": "^4.3.4", - "chai-bignumber": "3.0.0", - "defender-relay-client": "^1.7.0", - "dotenv": "^8.2.0", - "eth-sig-util": "2.5.3", - "ethereum-waffle": "3.0.2", - "ethereumjs-util": "7.0.2", - "ethers": "^5.4.7", - "globby": "^11.0.1", - "hardhat": "^2.6.8", - "hardhat-contract-sizer": "^2.0.3", - "hardhat-dependency-compiler": "^1.1.2", - "hardhat-deploy": "^0.9.4", - "hardhat-gas-reporter": "^1.0.0", - "husky": "^4.2.5", - "lowdb": "1.0.0", - "prettier": "^2.4.1", - "prettier-plugin-solidity": "^1.0.0-alpha.53", - "pretty-quick": "^3.1.1", - "solidity-coverage": "^0.7.17", - "ts-generator": "^0.1.1", - "ts-node": "^8.10.2", - "tslint": "^6.1.2", - "tslint-config-prettier": "^1.18.0", - "tslint-plugin-prettier": "^2.3.0", - "typechain": "^5.2.0", - "typescript": "^4.4.4" - }, - "husky": { - "hooks": { - "pre-commit": "pretty-quick --staged --pattern 'contracts/**/*.sol' --pattern 'helpers/**/*.ts' --pattern 'test-suites**/*.ts' --pattern 'tasks/**/*.ts' --pattern 'markets/**/*.ts'" - } - }, - "author": "Aave", - "contributors": [ - "Emilio Frangella ", - "Miguel Martinez ", - "Steven Valeri ", - "David Racero ", - "Lasse Herskind ", - "Mark Hinschberger ", - "Peter Michael ", - "Pol Sendra " - ], - "license": "BUSL-1.1", - "dependencies": { - "@nomiclabs/hardhat-etherscan": "^2.1.7", - "axios-curlirize": "^1.3.7", - "tmp-promise": "^3.0.2" - }, - "keywords": [ - "aave", - "protocol", - "protocol-v3", - "core-v3", - "ethereum", - "solidity" - ], - "publishConfig": { - "registry": "https://npm.pkg.github.com" - }, - "repository": { - "type": "git", - "url": "git://github.com/aave/aave-v3-core" - } -} diff --git a/lib/morpho-utils/lib/aave-v3-core/setup-test-env.sh b/lib/morpho-utils/lib/aave-v3-core/setup-test-env.sh deleted file mode 100644 index 45962e4..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/setup-test-env.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# @dev -# This bash script setups the needed artifacts to use -# the @aave/deploy-v3 package as source of deployment -# scripts for testing or coverage purposes. -# -# A separate artifacts directory was created -# due at running tests all external artifacts -# located at /artifacts are deleted, causing -# the deploy library to not find the external -# artifacts. - -echo "[BASH] Setting up testnet enviroment" - -if [ ! "$COVERAGE" = true ]; then - # remove hardhat and artifacts cache - npm run ci:clean - - # compile @aave/core-v3 contracts - npm run compile -else - echo "[BASH] Skipping compilation to keep coverage artifacts" -fi - -# Copy artifacts into separate directory to allow -# the hardhat-deploy library load all artifacts without duplicates -mkdir -p temp-artifacts -cp -r artifacts/* temp-artifacts - -# Import external @aave/periphery artifacts -mkdir -p temp-artifacts/periphery -cp -r node_modules/@aave/periphery-v3/artifacts/contracts/* temp-artifacts/periphery - -# Import external @aave/deploy artifacts -mkdir -p temp-artifacts/deploy -cp -r node_modules/@aave/deploy-v3/artifacts/contracts/* temp-artifacts/deploy - -# Export MARKET_NAME variable to use Aave market as testnet deployment setup -export MARKET_NAME="Test" -export ENABLE_REWARDS="false" -echo "[BASH] Testnet enviroment ready" \ No newline at end of file diff --git a/lib/morpho-utils/lib/aave-v3-core/techpaper/Aave_V3_Technical_Paper.pdf b/lib/morpho-utils/lib/aave-v3-core/techpaper/Aave_V3_Technical_Paper.pdf deleted file mode 100644 index 21a2e578341d6c6ce53e8d89169da8217df7eba1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 780635 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

    ?2 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

    S4&GzuNpShB!5HumqU9E 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%0DVk1CZ~C!uYd~%+*h8N^QOO5r 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%0DVPQDjoU+85|)>>olEAj@06i@OtDcG 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%0A!yBTBN%USp$K$G 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%0D1zTPL+BgAStpxO^jN1V5!s~&C)Po1HEShX~ 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

    }BaTY0M( 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 diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/__setup.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/__setup.spec.ts deleted file mode 100644 index dd75c64..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/__setup.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import rawBRE from 'hardhat'; -import { initializeMakeSuite } from './helpers/make-suite'; - -before(async () => { - await rawBRE.deployments.fixture(['market']); - - console.log('-> Deployed market'); - - console.log('-> Initializing test enviroment'); - await initializeMakeSuite(); - console.log('\n***************'); - console.log('Setup and snapshot finished'); - console.log('***************\n'); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/aave-oracle.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/aave-oracle.spec.ts deleted file mode 100644 index 42649f5..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/aave-oracle.spec.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { MOCK_CHAINLINK_AGGREGATORS_PRICES } from '@aave/deploy-v3/dist/helpers/constants'; -import { expect } from 'chai'; -import { oneEther, ONE_ADDRESS, ZERO_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { - deployMintableERC20, - deployMockAggregator, - evmRevert, - evmSnapshot, - MintableERC20, - MockAggregator, -} from '@aave/deploy-v3'; - -makeSuite('AaveOracle', (testEnv: TestEnv) => { - let snap: string; - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - afterEach(async () => { - await evmRevert(snap); - }); - - let mockToken: MintableERC20; - let mockAggregator: MockAggregator; - let assetPrice: string; - - before(async () => { - mockToken = await deployMintableERC20(['MOCK', 'MOCK', '18']); - assetPrice = MOCK_CHAINLINK_AGGREGATORS_PRICES.ETH; - mockAggregator = await deployMockAggregator(assetPrice); - }); - - it('Owner set a new asset source', async () => { - const { poolAdmin, aaveOracle } = testEnv; - - // Asset has no source - expect(await aaveOracle.getSourceOfAsset(mockToken.address)).to.be.eq(ZERO_ADDRESS); - const priorSourcePrice = await aaveOracle.getAssetPrice(mockToken.address); - const priorSourcesPrices = (await aaveOracle.getAssetsPrices([mockToken.address])).map((x) => - x.toString() - ); - expect(priorSourcePrice).to.equal('0'); - expect(priorSourcesPrices).to.eql(['0']); - - // Add asset source - expect( - await aaveOracle - .connect(poolAdmin.signer) - .setAssetSources([mockToken.address], [mockAggregator.address]) - ) - .to.emit(aaveOracle, 'AssetSourceUpdated') - .withArgs(mockToken.address, mockAggregator.address); - - const sourcesPrices = await ( - await aaveOracle.getAssetsPrices([mockToken.address]) - ).map((x) => x.toString()); - expect(await aaveOracle.getSourceOfAsset(mockToken.address)).to.be.eq(mockAggregator.address); - expect(await aaveOracle.getAssetPrice(mockToken.address)).to.be.eq(assetPrice); - expect(sourcesPrices).to.eql([assetPrice]); - }); - - it('Owner update an existing asset source', async () => { - const { poolAdmin, aaveOracle, dai } = testEnv; - - // DAI token has already a source - const daiSource = await aaveOracle.getSourceOfAsset(dai.address); - expect(daiSource).to.be.not.eq(ZERO_ADDRESS); - - // Update DAI source - expect( - await aaveOracle - .connect(poolAdmin.signer) - .setAssetSources([dai.address], [mockAggregator.address]) - ) - .to.emit(aaveOracle, 'AssetSourceUpdated') - .withArgs(dai.address, mockAggregator.address); - - expect(await aaveOracle.getSourceOfAsset(dai.address)).to.be.eq(mockAggregator.address); - expect(await aaveOracle.getAssetPrice(dai.address)).to.be.eq(assetPrice); - }); - - it('Owner tries to set a new asset source with wrong input params (revert expected)', async () => { - const { poolAdmin, aaveOracle } = testEnv; - - await expect( - aaveOracle.connect(poolAdmin.signer).setAssetSources([mockToken.address], []) - ).to.be.revertedWith(ProtocolErrors.INCONSISTENT_PARAMS_LENGTH); - }); - - it('Get price of BASE_CURRENCY asset', async () => { - const { aaveOracle } = testEnv; - - // Check returns the fixed price BASE_CURRENCY_UNIT - expect(await aaveOracle.getAssetPrice(await aaveOracle.BASE_CURRENCY())).to.be.eq( - await aaveOracle.BASE_CURRENCY_UNIT() - ); - }); - - it('A non-owner user tries to set a new asset source (revert expected)', async () => { - const { users, aaveOracle } = testEnv; - const user = users[0]; - - const { CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN } = ProtocolErrors; - - await expect( - aaveOracle.connect(user.signer).setAssetSources([mockToken.address], [mockAggregator.address]) - ).to.be.revertedWith(CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN); - }); - - it('Get price of BASE_CURRENCY asset with registered asset source for its address', async () => { - const { poolAdmin, aaveOracle, weth } = testEnv; - - // Add asset source for BASE_CURRENCY address - expect( - await aaveOracle - .connect(poolAdmin.signer) - .setAssetSources([weth.address], [mockAggregator.address]) - ) - .to.emit(aaveOracle, 'AssetSourceUpdated') - .withArgs(weth.address, mockAggregator.address); - - // Check returns the fixed price BASE_CURRENCY_UNIT - expect(await aaveOracle.getAssetPrice(weth.address)).to.be.eq( - MOCK_CHAINLINK_AGGREGATORS_PRICES.WETH - ); - }); - - it('Get price of asset with no asset source', async () => { - const { aaveOracle, oracle } = testEnv; - const fallbackPrice = oneEther; - - // Register price on FallbackOracle - expect(await oracle.setAssetPrice(mockToken.address, fallbackPrice)); - - // Asset has no source - expect(await aaveOracle.getSourceOfAsset(mockToken.address)).to.be.eq(ZERO_ADDRESS); - - // Returns 0 price - expect(await aaveOracle.getAssetPrice(mockToken.address)).to.be.eq(fallbackPrice); - }); - - it('Get price of asset with 0 price and no fallback price', async () => { - const { poolAdmin, aaveOracle } = testEnv; - const zeroPriceMockAgg = await deployMockAggregator('0'); - - // Asset has no source - expect(await aaveOracle.getSourceOfAsset(mockToken.address)).to.be.eq(ZERO_ADDRESS); - - // Add asset source - expect( - await aaveOracle - .connect(poolAdmin.signer) - .setAssetSources([mockToken.address], [zeroPriceMockAgg.address]) - ) - .to.emit(aaveOracle, 'AssetSourceUpdated') - .withArgs(mockToken.address, zeroPriceMockAgg.address); - - expect(await aaveOracle.getSourceOfAsset(mockToken.address)).to.be.eq(zeroPriceMockAgg.address); - expect(await aaveOracle.getAssetPrice(mockToken.address)).to.be.eq(0); - }); - - it('Get price of asset with 0 price but non-zero fallback price', async () => { - const { poolAdmin, aaveOracle, oracle } = testEnv; - const zeroPriceMockAgg = await deployMockAggregator('0'); - const fallbackPrice = oneEther; - - // Register price on FallbackOracle - expect(await oracle.setAssetPrice(mockToken.address, fallbackPrice)); - - // Asset has no source - expect(await aaveOracle.getSourceOfAsset(mockToken.address)).to.be.eq(ZERO_ADDRESS); - - // Add asset source - expect( - await aaveOracle - .connect(poolAdmin.signer) - .setAssetSources([mockToken.address], [zeroPriceMockAgg.address]) - ) - .to.emit(aaveOracle, 'AssetSourceUpdated') - .withArgs(mockToken.address, zeroPriceMockAgg.address); - - expect(await aaveOracle.getSourceOfAsset(mockToken.address)).to.be.eq(zeroPriceMockAgg.address); - expect(await aaveOracle.getAssetPrice(mockToken.address)).to.be.eq(fallbackPrice); - }); - - it('Owner update the FallbackOracle', async () => { - const { poolAdmin, aaveOracle, oracle } = testEnv; - - expect(await aaveOracle.getFallbackOracle()).to.be.eq(oracle.address); - - // Update oracle source - expect(await aaveOracle.connect(poolAdmin.signer).setFallbackOracle(ONE_ADDRESS)) - .to.emit(aaveOracle, 'FallbackOracleUpdated') - .withArgs(ONE_ADDRESS); - - expect(await aaveOracle.getFallbackOracle()).to.be.eq(ONE_ADDRESS); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/aave-protocol-data-provider.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/aave-protocol-data-provider.spec.ts deleted file mode 100644 index c29ebc6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/aave-protocol-data-provider.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import hre from 'hardhat'; -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { getMockPool, ZERO_ADDRESS } from '@aave/deploy-v3'; -import { InitializableImmutableAdminUpgradeabilityProxy } from '../types'; -import { impersonateAccountsHardhat } from '../helpers/misc-utils'; -import { topUpNonPayableWithEther } from './helpers/utils/funds'; -import { getProxyImplementation } from '../helpers/contracts-helpers'; - -makeSuite('AaveProtocolDataProvider: Edge cases', (testEnv: TestEnv) => { - const MKR_ADDRESS = '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2'; - const ETH_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - - it('getAllReservesTokens() with MKR and ETH as symbols', async () => { - const { addressesProvider, poolAdmin, helpersContract } = testEnv; - const { deployer } = await hre.getNamedAccounts(); - - // Deploy a mock Pool - const mockPool = await hre.deployments.deploy('MockPool', { from: deployer }); - - const poolProxyAddress = await addressesProvider.getPool(); - const oldPoolImpl = await getProxyImplementation(addressesProvider.address, poolProxyAddress); - - // Update the addressesProvider with a mock pool - expect(await addressesProvider.connect(poolAdmin.signer).setPoolImpl(mockPool.address)) - .to.emit(addressesProvider, 'PoolUpdated') - .withArgs(oldPoolImpl, mockPool.address); - - // Add MKR and ETH addresses - const proxiedMockPoolAddress = await addressesProvider.getPool(); - const proxiedMockPool = await getMockPool(proxiedMockPoolAddress); - expect(await proxiedMockPool.addReserveToReservesList(MKR_ADDRESS)); - expect(await proxiedMockPool.addReserveToReservesList(ETH_ADDRESS)); - - expect(await helpersContract.getAllReservesTokens()).to.be.eql([ - ['MKR', MKR_ADDRESS], - ['ETH', ETH_ADDRESS], - ]); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/acl-manager.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/acl-manager.spec.ts deleted file mode 100644 index b8d1d94..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/acl-manager.spec.ts +++ /dev/null @@ -1,272 +0,0 @@ -import { expect } from 'chai'; -import { constants, utils } from 'ethers'; -import { ZERO_ADDRESS } from '../helpers/constants'; -import { ACLManager, ACLManager__factory } from '../types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { ProtocolErrors } from '../helpers/types'; - -makeSuite('Access Control List Manager', (testEnv: TestEnv) => { - let aclManager: ACLManager; - - const FLASH_BORROW_ADMIN_ROLE = utils.keccak256( - utils.formatBytes32String('FLASH_BORROWER_ADMIN') - ); - - before(async () => { - const { deployer, addressesProvider } = testEnv; - aclManager = await new ACLManager__factory(deployer.signer).deploy(addressesProvider.address); - }); - - it('Check DEFAULT_ADMIN_ROLE', async () => { - const { deployer, users } = testEnv; - - const DEFAULT_ADMIN_ROLE = await aclManager.DEFAULT_ADMIN_ROLE(); - expect(await aclManager.hasRole(DEFAULT_ADMIN_ROLE, deployer.address)).to.be.eq(true); - expect(await aclManager.hasRole(DEFAULT_ADMIN_ROLE, users[0].address)).to.be.eq(false); - }); - - it('Grant FLASH_BORROW_ADMIN role', async () => { - const { - deployer, - users: [flashBorrowAdmin], - } = testEnv; - - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - false - ); - await aclManager - .connect(deployer.signer) - .grantRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - }); - - it('FLASH_BORROW_ADMIN grant FLASH_BORROW_ROLE (revert expected)', async () => { - const { - users: [flashBorrowAdmin, flashBorrower], - } = testEnv; - - expect(await aclManager.isFlashBorrower(flashBorrower.address)).to.be.eq(false); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - - await expect( - aclManager.connect(flashBorrowAdmin.signer).addFlashBorrower(flashBorrower.address) - ).to.be.revertedWith( - `'AccessControl: account ${flashBorrowAdmin.address.toLowerCase()} is missing role ${ - constants.HashZero - }'` - ); - - expect(await aclManager.isFlashBorrower(flashBorrower.address)).to.be.eq(false); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - }); - - it('Make FLASH_BORROW_ADMIN_ROLE admin of FLASH_BORROWER_ROLE', async () => { - const { deployer } = testEnv; - const FLASH_BORROW_ROLE = await aclManager.FLASH_BORROWER_ROLE(); - expect(await aclManager.getRoleAdmin(FLASH_BORROW_ROLE)).to.not.be.eq(FLASH_BORROW_ADMIN_ROLE); - await aclManager - .connect(deployer.signer) - .setRoleAdmin(FLASH_BORROW_ROLE, FLASH_BORROW_ADMIN_ROLE); - expect(await aclManager.getRoleAdmin(FLASH_BORROW_ROLE)).to.be.eq(FLASH_BORROW_ADMIN_ROLE); - }); - - it('FLASH_BORROW_ADMIN grant FLASH_BORROW_ROLE', async () => { - const { - users: [flashBorrowAdmin, flashBorrower], - } = testEnv; - - expect(await aclManager.isFlashBorrower(flashBorrower.address)).to.be.eq(false); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - - await aclManager.connect(flashBorrowAdmin.signer).addFlashBorrower(flashBorrower.address); - - expect(await aclManager.isFlashBorrower(flashBorrower.address)).to.be.eq(true); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - }); - - it('DEFAULT_ADMIN tries to revoke FLASH_BORROW_ROLE (revert expected)', async () => { - const { - deployer, - users: [flashBorrowAdmin, flashBorrower], - } = testEnv; - - expect(await aclManager.isFlashBorrower(flashBorrower.address)).to.be.eq(true); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - - await expect( - aclManager.connect(deployer.signer).removeFlashBorrower(flashBorrower.address) - ).to.be.revertedWith( - `'AccessControl: account ${deployer.address.toLowerCase()} is missing role ${FLASH_BORROW_ADMIN_ROLE}'` - ); - - expect(await aclManager.isFlashBorrower(flashBorrower.address)).to.be.eq(true); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - }); - - it('Grant POOL_ADMIN role', async () => { - const { - deployer, - users: [, poolAdmin], - } = testEnv; - - expect(await aclManager.isPoolAdmin(poolAdmin.address)).to.be.eq(false); - await aclManager.connect(deployer.signer).addPoolAdmin(poolAdmin.address); - expect(await aclManager.isPoolAdmin(poolAdmin.address)).to.be.eq(true); - }); - - it('Grant EMERGENCY_ADMIN role', async () => { - const { - deployer, - users: [, , emergencyAdmin], - } = testEnv; - - expect(await aclManager.isEmergencyAdmin(emergencyAdmin.address)).to.be.eq(false); - await aclManager.connect(deployer.signer).addEmergencyAdmin(emergencyAdmin.address); - expect(await aclManager.isEmergencyAdmin(emergencyAdmin.address)).to.be.eq(true); - }); - - it('Grant BRIDGE role', async () => { - const { - deployer, - users: [, , , bridge], - } = testEnv; - - expect(await aclManager.isBridge(bridge.address)).to.be.eq(false); - await aclManager.connect(deployer.signer).addBridge(bridge.address); - expect(await aclManager.isBridge(bridge.address)).to.be.eq(true); - }); - - it('Grant RISK_ADMIN role', async () => { - const { - deployer, - users: [, , , , riskAdmin], - } = testEnv; - - expect(await aclManager.isRiskAdmin(riskAdmin.address)).to.be.eq(false); - await aclManager.connect(deployer.signer).addRiskAdmin(riskAdmin.address); - expect(await aclManager.isRiskAdmin(riskAdmin.address)).to.be.eq(true); - }); - - it('Grant ASSET_LISTING_ADMIN role', async () => { - const { - deployer, - users: [, , , , , assetListingAdmin], - } = testEnv; - - expect(await aclManager.isAssetListingAdmin(assetListingAdmin.address)).to.be.eq(false); - await aclManager.connect(deployer.signer).addAssetListingAdmin(assetListingAdmin.address); - expect(await aclManager.isAssetListingAdmin(assetListingAdmin.address)).to.be.eq(true); - }); - - it('Revoke FLASH_BORROWER', async () => { - const { - users: [flashBorrowAdmin, flashBorrower], - } = testEnv; - - expect(await aclManager.isFlashBorrower(flashBorrower.address)).to.be.eq(true); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - - await aclManager.connect(flashBorrowAdmin.signer).removeFlashBorrower(flashBorrower.address); - - expect(await aclManager.isFlashBorrower(flashBorrower.address)).to.be.eq(false); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - }); - - it('Revoke FLASH_BORROWER_ADMIN', async () => { - const { - deployer, - users: [flashBorrowAdmin], - } = testEnv; - - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - true - ); - await aclManager - .connect(deployer.signer) - .revokeRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address); - expect(await aclManager.hasRole(FLASH_BORROW_ADMIN_ROLE, flashBorrowAdmin.address)).to.be.eq( - false - ); - }); - - it('Revoke POOL_ADMIN', async () => { - const { - deployer, - users: [, poolAdmin], - } = testEnv; - - expect(await aclManager.isPoolAdmin(poolAdmin.address)).to.be.eq(true); - await aclManager.connect(deployer.signer).removePoolAdmin(poolAdmin.address); - expect(await aclManager.isPoolAdmin(poolAdmin.address)).to.be.eq(false); - }); - - it('Revoke EMERGENCY_ADMIN', async () => { - const { - deployer, - users: [, , emergencyAdmin], - } = testEnv; - - expect(await aclManager.isEmergencyAdmin(emergencyAdmin.address)).to.be.eq(true); - await aclManager.connect(deployer.signer).removeEmergencyAdmin(emergencyAdmin.address); - expect(await aclManager.isEmergencyAdmin(emergencyAdmin.address)).to.be.eq(false); - }); - - it('Revoke BRIDGE', async () => { - const { - deployer, - users: [, , , bridge], - } = testEnv; - - expect(await aclManager.isBridge(bridge.address)).to.be.eq(true); - await aclManager.connect(deployer.signer).removeBridge(bridge.address); - expect(await aclManager.isBridge(bridge.address)).to.be.eq(false); - }); - - it('Revoke RISK_ADMIN', async () => { - const { - deployer, - users: [, , , , riskAdmin], - } = testEnv; - - expect(await aclManager.isRiskAdmin(riskAdmin.address)).to.be.eq(true); - await aclManager.connect(deployer.signer).removeRiskAdmin(riskAdmin.address); - expect(await aclManager.isRiskAdmin(riskAdmin.address)).to.be.eq(false); - }); - - it('Revoke ASSET_LISTING_ADMIN', async () => { - const { - deployer, - users: [, , , , , assetListingAdmin], - } = testEnv; - - expect(await aclManager.isAssetListingAdmin(assetListingAdmin.address)).to.be.eq(true); - await aclManager.connect(deployer.signer).removeAssetListingAdmin(assetListingAdmin.address); - expect(await aclManager.isAssetListingAdmin(assetListingAdmin.address)).to.be.eq(false); - }); - - it('Tries to deploy ACLManager when ACLAdmin is ZERO_ADDRESS (revert expected)', async () => { - const { deployer, addressesProvider } = testEnv; - - expect(await addressesProvider.setACLAdmin(ZERO_ADDRESS)); - const deployTx = new ACLManager__factory(deployer.signer).deploy(addressesProvider.address); - await expect(deployTx).to.be.revertedWith(ProtocolErrors.ACL_ADMIN_CANNOT_BE_ZERO); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/addresses-provider-registry.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/addresses-provider-registry.spec.ts deleted file mode 100644 index 4f1ea47..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/addresses-provider-registry.spec.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { expect } from 'chai'; -import { ProtocolErrors } from '../helpers/types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import { ONE_ADDRESS } from '@aave/deploy-v3'; -import { ethers } from 'hardhat'; - -makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => { - const NEW_ADDRESSES_PROVIDER_ID_2 = 2; - const NEW_ADDRESSES_PROVIDER_ID_3 = 3; - const NEW_ADDRESSES_PROVIDER_ADDRESS = ONE_ADDRESS; - - const { - INVALID_ADDRESSES_PROVIDER_ID, - ADDRESSES_PROVIDER_NOT_REGISTERED, - ADDRESSES_PROVIDER_ALREADY_ADDED, - } = ProtocolErrors; - - it('Checks the addresses provider is added to the registry', async () => { - const { addressesProvider, registry } = testEnv; - - const providers = await registry.getAddressesProvidersList(); - - expect(providers.length).to.be.equal(1, 'Invalid length of the addresses providers list'); - expect(providers[0].toString()).to.be.equal( - addressesProvider.address, - 'Invalid addresses provider added to the list' - ); - }); - - it('Tries to register an addresses provider with id 0 (revert expected)', async () => { - const { registry } = testEnv; - - await expect( - registry.registerAddressesProvider(NEW_ADDRESSES_PROVIDER_ADDRESS, '0') - ).to.be.revertedWith(INVALID_ADDRESSES_PROVIDER_ID); - }); - - it('Registers a mock addresses provider', async () => { - const { registry } = testEnv; - - const providersBefore = await registry.getAddressesProvidersList(); - - expect( - await registry.registerAddressesProvider( - NEW_ADDRESSES_PROVIDER_ADDRESS, - NEW_ADDRESSES_PROVIDER_ID_2 - ) - ) - .to.emit(registry, 'AddressesProviderRegistered') - .withArgs(NEW_ADDRESSES_PROVIDER_ADDRESS, NEW_ADDRESSES_PROVIDER_ID_2); - - expect(await registry.getAddressesProviderIdByAddress(NEW_ADDRESSES_PROVIDER_ADDRESS)).to.be.eq( - NEW_ADDRESSES_PROVIDER_ID_2 - ); - - const providersAfter = await registry.getAddressesProvidersList(); - expect(providersAfter.length).to.be.equal( - providersBefore.length + 1, - 'Invalid length of the addresses providers list' - ); - expect(providersAfter[1].toString()).to.be.equal( - NEW_ADDRESSES_PROVIDER_ADDRESS, - 'Invalid addresses provider added to the list' - ); - expect(await registry.getAddressesProviderAddressById(NEW_ADDRESSES_PROVIDER_ID_2)).to.be.equal( - NEW_ADDRESSES_PROVIDER_ADDRESS, - 'Invalid update of id mapping' - ); - }); - - it('Registers users[2] as another addresses provider', async () => { - const { users, registry } = testEnv; - - // Simulating an addresses provider using the users[2] wallet address - expect(await registry.registerAddressesProvider(users[2].address, NEW_ADDRESSES_PROVIDER_ID_3)) - .to.emit(registry, 'AddressesProviderRegistered') - .withArgs(users[2].address, NEW_ADDRESSES_PROVIDER_ID_3); - - const providers = await registry.getAddressesProvidersList(); - - expect(providers.length).to.be.equal( - NEW_ADDRESSES_PROVIDER_ID_3, - 'Invalid length of the addresses providers list' - ); - expect(providers[2].toString()).to.be.equal( - users[2].address, - 'Invalid addresses provider added to the list' - ); - }); - - it('Removes the mock addresses provider', async () => { - const { users, registry, addressesProvider } = testEnv; - - const providersBefore = await registry.getAddressesProvidersList(); - - expect( - await registry.getAddressesProviderIdByAddress(NEW_ADDRESSES_PROVIDER_ADDRESS) - ).to.be.equal(NEW_ADDRESSES_PROVIDER_ID_2); - - expect(await registry.unregisterAddressesProvider(NEW_ADDRESSES_PROVIDER_ADDRESS)) - .to.emit(registry, 'AddressesProviderUnregistered') - .withArgs(NEW_ADDRESSES_PROVIDER_ADDRESS, NEW_ADDRESSES_PROVIDER_ID_2); - - const providersAfter = await registry.getAddressesProvidersList(); - - expect(providersAfter.length).to.be.equal( - providersBefore.length - 1, - 'Invalid length of the addresses providers list' - ); - expect(providersAfter[0].toString()).to.be.equal( - addressesProvider.address, - 'Invalid addresses provider added to the list' - ); - }); - - it('Tries to remove an already unregistered addressesProvider (revert expected)', async () => { - const { users, registry } = testEnv; - - await expect( - registry.unregisterAddressesProvider(NEW_ADDRESSES_PROVIDER_ADDRESS) - ).to.be.revertedWith(ADDRESSES_PROVIDER_NOT_REGISTERED); - }); - - it('Tries to add an already registered addressesProvider with a different id (revert expected)', async () => { - const { registry, addressesProvider } = testEnv; - - const id = await registry.getAddressesProviderIdByAddress(addressesProvider.address); - expect(id).not.to.be.eq(0); - - const providersBefore = await registry.getAddressesProvidersList(); - await expect( - registry.registerAddressesProvider(addressesProvider.address, NEW_ADDRESSES_PROVIDER_ID_2) - ).to.be.revertedWith(ADDRESSES_PROVIDER_ALREADY_ADDED); - - const providersAfter = await registry.getAddressesProvidersList(); - - expect(await registry.getAddressesProviderIdByAddress(addressesProvider.address)).to.be.eq(id); - - expect(providersAfter.length).to.be.equal( - providersBefore.length, - 'Invalid length of the addresses providers list' - ); - expect(providersAfter[0].toString()).to.be.equal( - addressesProvider.address, - 'Invalid addresses provider added to the list' - ); - }); - - it('Tries to add an addressesProvider with an already used id (revert expected)', async () => { - const { users, registry, addressesProvider } = testEnv; - - const id = await registry.getAddressesProviderIdByAddress(addressesProvider.address); - expect(id).not.to.be.eq(0); - - // Simulating an addresses provider using the users[5] wallet address - await expect(registry.registerAddressesProvider(users[5].address, id)).to.be.revertedWith( - ProtocolErrors.INVALID_ADDRESSES_PROVIDER_ID - ); - - const providers = await registry.getAddressesProvidersList(); - const idMap = {}; - - for (let i = 0; i < providers.length; i++) { - const id = (await registry.getAddressesProviderIdByAddress(providers[i])).toNumber(); - if (id > 0) { - if (idMap[id] == undefined) { - idMap[id] = true; - } else { - expect(false, 'Duplicate ids').to.be.true; - } - } - } - }); - - it('Reregisters the mock addresses provider after it being removed', async () => { - const { registry } = testEnv; - - const providersBefore = await registry.getAddressesProvidersList(); - - expect( - await registry.registerAddressesProvider( - NEW_ADDRESSES_PROVIDER_ADDRESS, - NEW_ADDRESSES_PROVIDER_ID_2 - ) - ) - .to.emit(registry, 'AddressesProviderRegistered') - .withArgs(NEW_ADDRESSES_PROVIDER_ADDRESS, NEW_ADDRESSES_PROVIDER_ID_2); - - expect(await registry.getAddressesProviderIdByAddress(NEW_ADDRESSES_PROVIDER_ADDRESS)).to.be.eq( - NEW_ADDRESSES_PROVIDER_ID_2 - ); - - const providersAfter = await registry.getAddressesProvidersList(); - expect(providersAfter.length).to.be.equal( - providersBefore.length + 1, - 'Invalid length of the addresses providers list' - ); - expect(providersAfter[providersAfter.length - 1].toString()).to.be.equal( - NEW_ADDRESSES_PROVIDER_ADDRESS, - 'Invalid addresses provider added to the list' - ); - expect(await registry.getAddressesProviderAddressById(NEW_ADDRESSES_PROVIDER_ID_2)).to.be.equal( - NEW_ADDRESSES_PROVIDER_ADDRESS, - 'Invalid update of id mapping' - ); - }); - - it('Removes the last addresses provider', async () => { - const { registry, addressesProvider } = testEnv; - - const providersBefore = await registry.getAddressesProvidersList(); - const providerToRemove = providersBefore[providersBefore.length - 1]; - const providerToRemoveId = await registry.getAddressesProviderIdByAddress(providerToRemove); - - expect(await registry.unregisterAddressesProvider(providerToRemove)) - .to.emit(registry, 'AddressesProviderUnregistered') - .withArgs(providerToRemove, providerToRemoveId); - - const providersAfter = await registry.getAddressesProvidersList(); - - expect(providersAfter.length).to.be.equal( - providersBefore.length - 1, - 'Invalid length of the addresses providers list' - ); - expect(providersAfter[0].toString()).to.be.equal( - addressesProvider.address, - 'Invalid addresses provider added to the list' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-delegation-aware.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-delegation-aware.spec.ts deleted file mode 100644 index d0ecfc6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-delegation-aware.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { DelegationAwareAToken, MintableDelegationERC20 } from '../types'; -import { expect } from 'chai'; -import { ZERO_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { - deployMintableDelegationERC20, - deployDelegationAwareAToken, -} from '@aave/deploy-v3/dist/helpers/contract-deployments'; - -makeSuite('AToken: DelegationAwareAToken', (testEnv: TestEnv) => { - let delegationAToken = {}; - let delegationERC20 = {}; - - it('Deploys a new MintableDelegationERC20 and a DelegationAwareAToken', async () => { - const { pool } = testEnv; - - delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']); - - delegationAToken = await deployDelegationAwareAToken([ - pool.address, - delegationERC20.address, - ZERO_ADDRESS, - ZERO_ADDRESS, - 'aDEL', - 'aDEL', - ]); - }); - - it('Tries to delegate with the caller not being the Aave admin (revert expected)', async () => { - const { users } = testEnv; - - await expect( - delegationAToken.connect(users[1].signer).delegateUnderlyingTo(users[2].address) - ).to.be.revertedWith(ProtocolErrors.CALLER_NOT_POOL_ADMIN); - }); - - it('Delegates to user 2', async () => { - const { users } = testEnv; - - expect(await delegationAToken.delegateUnderlyingTo(users[2].address)) - .to.emit(delegationAToken, 'DelegateUnderlyingTo') - .withArgs(users[2].address); - - const delegateeAddress = await delegationERC20.delegatee(); - - expect(delegateeAddress).to.be.equal(users[2].address); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-edge.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-edge.spec.ts deleted file mode 100644 index 9d76006..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-edge.spec.ts +++ /dev/null @@ -1,259 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { impersonateAccountsHardhat } from '../helpers/misc-utils'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { topUpNonPayableWithEther } from './helpers/utils/funds'; -import { evmRevert, evmSnapshot, waitForTx } from '@aave/deploy-v3'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('AToken: Edge cases', (testEnv: TestEnv) => { - const { - INVALID_MINT_AMOUNT, - INVALID_BURN_AMOUNT, - SAFECAST_UINT128_OVERFLOW, - CALLER_NOT_POOL_ADMIN, - } = ProtocolErrors; - - it('Check getters', async () => { - const { pool, users, dai, aDai } = testEnv; - - expect(await aDai.decimals()).to.be.eq(await dai.decimals()); - expect(await aDai.UNDERLYING_ASSET_ADDRESS()).to.be.eq(dai.address); - expect(await aDai.POOL()).to.be.eq(pool.address); - expect(await aDai.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - - const scaledUserBalanceAndSupplyBefore = await aDai.getScaledUserBalanceAndSupply( - users[0].address - ); - expect(scaledUserBalanceAndSupplyBefore[0]).to.be.eq(0); - expect(scaledUserBalanceAndSupplyBefore[1]).to.be.eq(0); - - await waitForTx( - await dai - .connect(users[0].signer) - ['mint(address,uint256)']( - users[0].address, - await convertToCurrencyDecimals(dai.address, '1000') - ) - ); - await waitForTx(await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT)); - await waitForTx( - await pool - .connect(users[0].signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, '1000'), - users[0].address, - 0 - ) - ); - const scaledUserBalanceAndSupplyAfter = await aDai.getScaledUserBalanceAndSupply( - users[0].address - ); - expect(scaledUserBalanceAndSupplyAfter[0]).to.be.eq( - await convertToCurrencyDecimals(aDai.address, '1000') - ); - expect(scaledUserBalanceAndSupplyAfter[1]).to.be.eq( - await convertToCurrencyDecimals(aDai.address, '1000') - ); - }); - - it('approve()', async () => { - const { users, aDai } = testEnv; - await aDai.connect(users[0].signer).approve(users[1].address, MAX_UINT_AMOUNT); - expect(await aDai.allowance(users[0].address, users[1].address)).to.be.eq(MAX_UINT_AMOUNT); - }); - - it('approve() with a ZERO_ADDRESS spender', async () => { - const { users, aDai } = testEnv; - expect(await aDai.connect(users[0].signer).approve(ZERO_ADDRESS, MAX_UINT_AMOUNT)) - .to.emit(aDai, 'Approval') - .withArgs(users[0].address, ZERO_ADDRESS, MAX_UINT_AMOUNT); - }); - - it('transferFrom()', async () => { - const { users, aDai } = testEnv; - await aDai.connect(users[1].signer).transferFrom(users[0].address, users[1].address, 0); - }); - - it('increaseAllowance()', async () => { - const { users, aDai } = testEnv; - expect(await aDai.allowance(users[1].address, users[0].address)).to.be.eq(0); - await aDai - .connect(users[1].signer) - .increaseAllowance(users[0].address, await convertToCurrencyDecimals(aDai.address, '1')); - expect(await aDai.allowance(users[1].address, users[0].address)).to.be.eq( - await convertToCurrencyDecimals(aDai.address, '1') - ); - }); - - it('decreaseAllowance()', async () => { - const { users, aDai } = testEnv; - expect(await aDai.allowance(users[1].address, users[0].address)).to.be.eq( - await convertToCurrencyDecimals(aDai.address, '1') - ); - await aDai - .connect(users[1].signer) - .decreaseAllowance(users[0].address, await convertToCurrencyDecimals(aDai.address, '1')); - expect(await aDai.allowance(users[1].address, users[0].address)).to.be.eq(0); - }); - - it('transfer() with a ZERO_ADDRESS recipient', async () => { - const { users, aDai } = testEnv; - expect(await aDai.connect(users[1].signer).transfer(ZERO_ADDRESS, 0)) - .to.emit(aDai, 'Transfer') - .withArgs(users[1].address, ZERO_ADDRESS, 0); - }); - - it('transfer() with a ZERO_ADDRESS origin', async () => { - const { users, aDai } = testEnv; - expect(await aDai.connect(users[1].signer).transferFrom(ZERO_ADDRESS, users[1].address, 0)) - .to.emit(aDai, 'Transfer') - .withArgs(ZERO_ADDRESS, users[1].address, 0); - }); - - it('mint() when amountScaled == 0 (revert expected)', async () => { - const { deployer, pool, aDai, users } = testEnv; - - // Impersonate Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - await expect( - aDai - .connect(poolSigner) - .mint(users[0].address, users[0].address, 0, utils.parseUnits('1', 27)) - ).to.be.revertedWith(INVALID_MINT_AMOUNT); - }); - - it('mint() to a ZERO_ADDRESS account', async () => { - const { deployer, pool, aDai } = testEnv; - - // Impersonate Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - const mintingAmount = await convertToCurrencyDecimals(aDai.address, '100'); - expect( - aDai - .connect(poolSigner) - .mint(ZERO_ADDRESS, ZERO_ADDRESS, mintingAmount, utils.parseUnits('1', 27)) - ) - .to.emit(aDai, 'Transfer') - .withArgs(ZERO_ADDRESS, ZERO_ADDRESS, mintingAmount); - }); - - it('burn() when amountScaled == 0 (revert expected)', async () => { - const { deployer, pool, aDai, users } = testEnv; - - // Impersonate Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - await expect( - aDai - .connect(poolSigner) - .burn(users[0].address, users[0].address, 0, utils.parseUnits('1', 27)) - ).to.be.revertedWith(INVALID_BURN_AMOUNT); - }); - - it('burn() of a ZERO_ADDRESS account (revert expected)', async () => { - const { deployer, pool, aDai, users } = testEnv; - - // Impersonate Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - const burnAmount = await convertToCurrencyDecimals(aDai.address, '100'); - expect( - await aDai - .connect(poolSigner) - .burn(ZERO_ADDRESS, users[0].address, burnAmount, utils.parseUnits('1', 27)) - ) - .to.emit(aDai, 'Transfer') - .withArgs(ZERO_ADDRESS, ZERO_ADDRESS, burnAmount); - }); - - it('mintToTreasury() with amount == 0', async () => { - const { deployer, pool, aDai } = testEnv; - - // Impersonate Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - expect(await aDai.connect(poolSigner).mintToTreasury(0, utils.parseUnits('1', 27))); - }); - - it('setIncentivesController() ', async () => { - const snapshot = await evmSnapshot(); - const { deployer, poolAdmin, aWETH, aclManager } = testEnv; - - expect(await aclManager.connect(deployer.signer).addPoolAdmin(poolAdmin.address)); - - expect(await aWETH.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - expect(await aWETH.connect(poolAdmin.signer).setIncentivesController(ZERO_ADDRESS)); - expect(await aWETH.getIncentivesController()).to.be.eq(ZERO_ADDRESS); - - await evmRevert(snapshot); - }); - - it('setIncentivesController() from not pool admin (revert expected)', async () => { - const { - users: [user], - aWETH, - } = testEnv; - - expect(await aWETH.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - - await expect( - aWETH.connect(user.signer).setIncentivesController(ZERO_ADDRESS) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); - - it('transfer() amount > MAX_UINT_128', async () => { - const { - aDai, - users: [depositor, borrower], - } = testEnv; - - expect(aDai.transfer(borrower.address, MAX_UINT_AMOUNT)).to.be.revertedWith( - SAFECAST_UINT128_OVERFLOW - ); - }); - - it('setIncentivesController() ', async () => { - const snapshot = await evmSnapshot(); - const { deployer, poolAdmin, aWETH, aclManager } = testEnv; - - expect(await aclManager.connect(deployer.signer).addPoolAdmin(poolAdmin.address)); - - expect(await aWETH.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - expect(await aWETH.connect(poolAdmin.signer).setIncentivesController(ZERO_ADDRESS)); - expect(await aWETH.getIncentivesController()).to.be.eq(ZERO_ADDRESS); - - await evmRevert(snapshot); - }); - - it('setIncentivesController() from not pool admin (revert expected)', async () => { - const { - users: [user], - aWETH, - } = testEnv; - - expect(await aWETH.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - - await expect( - aWETH.connect(user.signer).setIncentivesController(ZERO_ADDRESS) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-event-accounting.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-event-accounting.spec.ts deleted file mode 100644 index 67ded1a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-event-accounting.spec.ts +++ /dev/null @@ -1,570 +0,0 @@ -import { waitForTx, increaseTime, ZERO_ADDRESS } from '@aave/deploy-v3'; -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { RateMode } from '../helpers/types'; -import { makeSuite } from './helpers/make-suite'; - -makeSuite('AToken Mint and Burn Event Accounting', (testEnv) => { - let firstDaiDeposit; - let secondDaiDeposit; - let thirdDaiDeposit; - let accruedInterest1: BigNumber = BigNumber.from(0); - let accruedInterest2: BigNumber = BigNumber.from(0); - let accruedInterest3: BigNumber = BigNumber.from(0); - - let firstDaiBorrow; - let secondDaiBorrow; - let accruedDebt1: BigNumber = BigNumber.from(0); - let accruedDebt2: BigNumber = BigNumber.from(0); - let accruedDebt3: BigNumber = BigNumber.from(0); - - const transferEventSignature = utils.keccak256( - utils.toUtf8Bytes('Transfer(address,address,uint256)') - ); - - const aTokenMintEventSignature = utils.keccak256( - utils.toUtf8Bytes('Mint(address,address,uint256,uint256,uint256)') - ); - const aTokenBurnEventSignature = utils.keccak256( - utils.toUtf8Bytes('Burn(address,address,uint256,uint256,uint256)') - ); - const vDebtTokenMintEventSignature = utils.keccak256( - utils.toUtf8Bytes('Mint(address,address,uint256,uint256,uint256)') - ); - const vDebtTokenBurnEventSignature = utils.keccak256( - utils.toUtf8Bytes('Burn(address,address,uint256,uint256,uint256)') - ); - - before('User 0 deposits 100 DAI, user 1 deposits 1 WETH, borrows 50 DAI', async () => { - const { dai } = testEnv; - firstDaiDeposit = await convertToCurrencyDecimals(dai.address, '10000'); - secondDaiDeposit = await convertToCurrencyDecimals(dai.address, '20000'); - thirdDaiDeposit = await convertToCurrencyDecimals(dai.address, '50000'); - }); - - it('User 1 Deposit dai', async () => { - const { - dai, - aDai, - users: [depositor], - pool, - helpersContract, - } = testEnv; - - // mints DAI to depositor - await waitForTx( - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '10000')) - ); - - // approve protocol to access depositor wallet - await waitForTx(await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - const daiReserveData = await helpersContract.getReserveData(dai.address); - - const expectedBalanceIncrease = 0; - - await expect( - pool.connect(depositor.signer).deposit(dai.address, firstDaiDeposit, depositor.address, '0') - ) - .to.emit(aDai, 'Mint') - .withArgs( - depositor.address, - depositor.address, - firstDaiDeposit, - expectedBalanceIncrease, - daiReserveData.liquidityIndex - ); - - const aDaiBalance = await aDai.balanceOf(depositor.address); - expect(aDaiBalance).to.be.equal(firstDaiDeposit); - }); - - it('User 1 - Deposit dai on behalf of user 2', async () => { - const { - dai, - aDai, - users: [depositor, receiver], - pool, - helpersContract, - } = testEnv; - - // mints DAI to depositor - await waitForTx( - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '10000')) - ); - - // approve protocol to access depositor wallet - await waitForTx(await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - const daiReserveData = await helpersContract.getReserveData(dai.address); - - const expectedBalanceIncrease = 0; - - await expect( - pool.connect(depositor.signer).deposit(dai.address, firstDaiDeposit, receiver.address, '0') - ) - .to.emit(aDai, 'Mint') - .withArgs( - depositor.address, - receiver.address, - firstDaiDeposit, - expectedBalanceIncrease, - daiReserveData.liquidityIndex - ); - - const aDaiBalance = await aDai.balanceOf(receiver.address); - expect(aDaiBalance).to.be.equal(firstDaiDeposit); - }); - - it('User 2 - deposit ETH, borrow Dai', async () => { - const { - dai, - weth, - users: [, borrower], - pool, - helpersContract, - } = testEnv; - - //user 2 deposits 100 ETH - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '20000'); - - //mints WETH to borrower - await waitForTx( - await weth - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(weth.address, '20000')) - ); - - //approve protocol to access the borrower wallet - await waitForTx(await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - await waitForTx( - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0') - ); - - // Borrow dai - firstDaiBorrow = await convertToCurrencyDecimals(dai.address, '5000'); - - await waitForTx( - await pool - .connect(borrower.signer) - .borrow(dai.address, firstDaiBorrow, RateMode.Variable, '0', borrower.address) - ); - - const borrowerWethData = await helpersContract.getUserReserveData( - weth.address, - borrower.address - ); - const borrowerDaiData = await helpersContract.getUserReserveData(dai.address, borrower.address); - expect(borrowerWethData.currentATokenBalance).to.be.equal(amountETHtoDeposit); - expect(borrowerDaiData.currentVariableDebt).to.be.equal(firstDaiBorrow); - }); - - it('User 2 - borrow more Dai - confirm mint event includes accrued interest', async () => { - const { - dai, - variableDebtDai, - users: [, borrower], - pool, - helpersContract, - } = testEnv; - await increaseTime(86400); - - // execute borrow - secondDaiBorrow = await convertToCurrencyDecimals(dai.address, '2000'); - const borrowTx = await pool - .connect(borrower.signer) - .borrow(dai.address, secondDaiBorrow, RateMode.Variable, '0', borrower.address); - const borrowReceipt = await borrowTx.wait(); - - const borrowerDaiData = await helpersContract.getUserReserveData(dai.address, borrower.address); - accruedDebt1 = borrowerDaiData.currentVariableDebt.sub(firstDaiBorrow).sub(secondDaiBorrow); - const totalMinted = secondDaiBorrow.add(accruedDebt1); - - // get transfer event - const rawTransferEvents = borrowReceipt.logs.filter( - (log) => log.topics[0] === transferEventSignature - ); - expect(rawTransferEvents.length).to.equal(2, 'Incorrect number of Transfer Events'); - const parsedTransferEvent = variableDebtDai.interface.parseLog(rawTransferEvents[0]); - - // get mint event - const rawMintEvents = borrowReceipt.logs.filter( - (log) => log.topics[0] === vDebtTokenMintEventSignature - ); - expect(rawMintEvents.length).to.equal(1, 'Incorrect number of Mint Events'); - const parsedMintEvent = variableDebtDai.interface.parseLog(rawMintEvents[0]); - - // check transfer event parameters - expect(parsedTransferEvent.args.from).to.equal(ZERO_ADDRESS); - expect(parsedTransferEvent.args.to).to.equal(borrower.address); - expect(parsedTransferEvent.args.value).to.be.closeTo(totalMinted, 2); - - // check mint event parameters - expect(parsedMintEvent.args.caller).to.equal(borrower.address); - expect(parsedMintEvent.args.onBehalfOf).to.equal(borrower.address); - expect(parsedMintEvent.args.value).to.be.closeTo(totalMinted, 2); - expect(parsedMintEvent.args.balanceIncrease).to.be.closeTo(accruedDebt1, 2); - }); - - it('User 1 - deposit more Dai - confirm mint event includes accrued interest', async () => { - const { - dai, - aDai, - users: [depositor], - pool, - helpersContract, - } = testEnv; - - await increaseTime(86400); - - //mints DAI to depositor - await waitForTx( - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '20000')) - ); - - //user 1 deposits 2000 DAI - - const depositTx = await waitForTx( - await pool - .connect(depositor.signer) - .deposit(dai.address, secondDaiDeposit, depositor.address, '0') - ); - - const aDaiBalance = await aDai.balanceOf(depositor.address); - accruedInterest1 = aDaiBalance.sub(firstDaiDeposit).sub(secondDaiDeposit); - const totalMinted = secondDaiDeposit.add(accruedInterest1); - - // get transfer event - const rawTransferEvents = depositTx.logs.filter( - (log) => log.topics[0] === transferEventSignature - ); - expect(rawTransferEvents.length).to.equal(2, 'Incorrect number of Transfer Events'); - const parsedTransferEvent = aDai.interface.parseLog(rawTransferEvents[1]); - - // get mint event - const rawMintEvents = depositTx.logs.filter( - (log) => log.topics[0] === aTokenMintEventSignature - ); - expect(rawMintEvents.length).to.equal(1, 'Incorrect number of Mint Events'); - const parsedMintEvent = aDai.interface.parseLog(rawMintEvents[0]); - - // check transfer event parameters - expect(parsedTransferEvent.args.from).to.equal(ZERO_ADDRESS); - expect(parsedTransferEvent.args.to).to.equal(depositor.address); - expect(parsedTransferEvent.args.value).to.be.closeTo(totalMinted, 2); - - // check mint event parameters - expect(parsedMintEvent.args.caller).to.equal(depositor.address); - expect(parsedMintEvent.args.onBehalfOf).to.equal(depositor.address); - expect(parsedMintEvent.args.value).to.be.closeTo(totalMinted, 2); - expect(parsedMintEvent.args.balanceIncrease).to.be.closeTo(accruedInterest1, 2); - }); - - it('User 1 - deposit more Dai again - confirm mint event includes accrued interest', async () => { - const { - dai, - aDai, - users: [depositor], - pool, - helpersContract, - } = testEnv; - - await increaseTime(86400); - - //mints DAI to depositor - await waitForTx( - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '50000')) - ); - - //user 1 deposits 2000 DAI - const depositTx = await pool - .connect(depositor.signer) - .deposit(dai.address, thirdDaiDeposit, depositor.address, '0'); - const depositReceipt = await depositTx.wait(); - - const aDaiBalance = await aDai.balanceOf(depositor.address); - accruedInterest2 = aDaiBalance - .sub(firstDaiDeposit) - .sub(secondDaiDeposit) - .sub(thirdDaiDeposit) - .sub(accruedInterest1); - const daiReserveData = await helpersContract.getReserveData(dai.address); - const totalMinted = thirdDaiDeposit.add(accruedInterest2); - - // get transfer event - const rawTransferEvents = depositReceipt.logs.filter( - (log) => log.topics[0] === transferEventSignature - ); - expect(rawTransferEvents.length).to.equal(2, 'Incorrect number of Transfer Events'); - const parsedTransferEvent = aDai.interface.parseLog(rawTransferEvents[1]); - - // get mint event - const rawMintEvents = depositReceipt.logs.filter( - (log) => log.topics[0] === aTokenMintEventSignature - ); - expect(rawMintEvents.length).to.equal(1, 'Incorrect number of Mint Events'); - const parsedMintEvent = aDai.interface.parseLog(rawMintEvents[0]); - - // check transfer event - expect(parsedTransferEvent.args.from).to.equal(ZERO_ADDRESS); - expect(parsedTransferEvent.args.to).to.be.equal(depositor.address); - expect(parsedTransferEvent.args.value).to.be.closeTo(totalMinted, 2); - - // check mint event - expect(parsedMintEvent.args.caller).to.equal(depositor.address); - expect(parsedMintEvent.args.onBehalfOf).to.equal(depositor.address); - expect(parsedMintEvent.args.value).to.be.closeTo(totalMinted, 2); - expect(parsedMintEvent.args.balanceIncrease).to.be.closeTo(accruedInterest2, 2); - expect(parsedMintEvent.args.index).to.equal(daiReserveData.liquidityIndex); - }); - - it('User 2 - repay all remaining dai', async () => { - const { - dai, - variableDebtDai, - users: [, borrower], - pool, - helpersContract, - } = testEnv; - - await increaseTime(86400); - - //mints DAI to borrower - await waitForTx( - await dai - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '50000')) - ); - - // approve protocol to access depositor wallet - await waitForTx(await dai.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - const daiBalanceBefore = await dai.balanceOf(borrower.address); - - // repay dai loan - const repayTx = await pool - .connect(borrower.signer) - .repay(dai.address, MAX_UINT_AMOUNT, RateMode.Variable, borrower.address); - const repayReceipt = await repayTx.wait(); - - const daiBalanceAfter = await dai.balanceOf(borrower.address); - const daiRepaid = daiBalanceBefore.sub(daiBalanceAfter); - accruedDebt3 = daiRepaid - .sub(firstDaiBorrow) - .sub(accruedDebt1) - .sub(secondDaiBorrow) - .sub(accruedDebt2); - const borrowerDaiData = await helpersContract.getUserReserveData(dai.address, borrower.address); - const totalBurned = daiRepaid.sub(accruedDebt3); - - // get transfer event - const rawTransferEvents = repayReceipt.logs.filter( - (log) => log.topics[0] === transferEventSignature - ); - expect(rawTransferEvents.length).to.equal(2, 'Incorrect number of Transfer Events'); - const parsedTransferEvent = variableDebtDai.interface.parseLog(rawTransferEvents[0]); - - // get burn event - const rawBurnEvents = repayReceipt.logs.filter( - (log) => log.topics[0] === vDebtTokenBurnEventSignature - ); - expect(rawBurnEvents.length).to.equal(1, 'Incorrect number of Burn Events'); - const parsedBurnEvent = variableDebtDai.interface.parseLog(rawBurnEvents[0]); - - // check burn parameters - expect(parsedTransferEvent.args.from).to.equal(borrower.address); - expect(parsedTransferEvent.args.to).to.equal(ZERO_ADDRESS); - expect(parsedTransferEvent.args.value).to.be.closeTo(totalBurned, 2); - - // check burn parameters - expect(parsedBurnEvent.args.from).to.equal(borrower.address); - expect(parsedBurnEvent.args.value).to.be.closeTo(totalBurned, 2); - expect(parsedBurnEvent.args.balanceIncrease).to.be.closeTo(accruedDebt3, 2); - expect(borrowerDaiData.currentVariableDebt).to.be.equal(0); - }); - - it('User 1 - withdraws all deposited funds and interest', async () => { - const { - dai, - aDai, - users: [depositor], - pool, - helpersContract, - } = testEnv; - const daiBalanceBefore = await dai.balanceOf(depositor.address); - - const withdrawTx = await pool - .connect(depositor.signer) - .withdraw(dai.address, MAX_UINT_AMOUNT, depositor.address); - const withdrawReceipt = await withdrawTx.wait(); - - const aDaiBalance = await aDai.balanceOf(depositor.address); - expect(aDaiBalance).to.be.equal(0); - - const daiBalanceAfter = await dai.balanceOf(depositor.address); - const daiWithdrawn = daiBalanceAfter.sub(daiBalanceBefore); - accruedInterest3 = daiWithdrawn - .sub(firstDaiDeposit) - .sub(accruedInterest1) - .sub(secondDaiDeposit) - .sub(accruedInterest2) - .sub(thirdDaiDeposit); - const totalBurned = daiWithdrawn.sub(accruedInterest3); - const daiReserveData = await helpersContract.getReserveData(dai.address); - - // get transfer event - const rawTransferEvents = withdrawReceipt.logs.filter( - (log) => log.topics[0] === transferEventSignature - ); - expect(rawTransferEvents.length).to.equal(2, 'Incorrect number of Transfer Events'); - const parsedTransferEvent = aDai.interface.parseLog(rawTransferEvents[0]); - - // get burn event - const rawBurnEvents = withdrawReceipt.logs.filter( - (log) => log.topics[0] === aTokenBurnEventSignature - ); - expect(rawBurnEvents.length).to.equal(1, 'Incorrect number of Burn Events'); - const parsedBurnEvent = aDai.interface.parseLog(rawBurnEvents[0]); - - // check transfer parameters - expect(parsedTransferEvent.args.from).to.equal(depositor.address); - expect(parsedTransferEvent.args.to).to.equal(ZERO_ADDRESS); - expect(parsedTransferEvent.args.value).to.be.closeTo(totalBurned, 2); - - // check burn parameters - expect(parsedBurnEvent.args.from).to.equal(depositor.address); - expect(parsedBurnEvent.args.target).to.equal(depositor.address); - expect(parsedBurnEvent.args.value).to.be.closeTo(totalBurned, 2); - expect(parsedBurnEvent.args.balanceIncrease).to.be.closeTo(accruedInterest3, 2); - expect(parsedBurnEvent.args.index).to.equal(daiReserveData.liquidityIndex); - }); - - it('User 2 - borrow, pass time and repay dai less than accrued debt', async () => { - const { - dai, - variableDebtDai, - users: [depositor, borrower], - pool, - } = testEnv; - // User 1 - Deposit dai - await waitForTx( - await pool - .connect(depositor.signer) - .deposit(dai.address, firstDaiDeposit, depositor.address, '0') - ); - - // User 2 - Borrow dai - const borrowAmount = await convertToCurrencyDecimals(dai.address, '8000'); - - await waitForTx( - await pool - .connect(borrower.signer) - .borrow(dai.address, borrowAmount, RateMode.Variable, '0', borrower.address) - ); - - const debtBalanceBefore = await variableDebtDai.balanceOf(borrower.address); - - await increaseTime(86400); - - // repay a very small amount - less than accrued debt - const smallRepay = BigNumber.from('100000'); - - // approve protocol to access depositor wallet - await waitForTx(await dai.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - // repay dai loan - const repayTx = await pool - .connect(borrower.signer) - .repay(dai.address, smallRepay, RateMode.Variable, borrower.address); - const repayReceipt = await repayTx.wait(); - - const debtBalanceAfter = await variableDebtDai.balanceOf(borrower.address); - const totalMinted = debtBalanceAfter.sub(debtBalanceBefore); - - // get transfer event - const rawTransferEvents = repayReceipt.logs.filter( - (log) => log.topics[0] === transferEventSignature - ); - expect(rawTransferEvents.length).to.equal(2, 'Incorrect number of Transfer Events'); - const parsedTransferEvent = variableDebtDai.interface.parseLog(rawTransferEvents[0]); - - // get mint event - const rawMintEvents = repayReceipt.logs.filter( - (log) => log.topics[0] === vDebtTokenMintEventSignature - ); - expect(rawMintEvents.length).to.equal(1, 'Incorrect number of Mint Events'); - const parsedMintEvent = variableDebtDai.interface.parseLog(rawMintEvents[0]); - - // check transfer event - expect(parsedTransferEvent.args.from).to.equal(ZERO_ADDRESS); - expect(parsedTransferEvent.args.to).to.equal(borrower.address); - expect(parsedTransferEvent.args.value).to.be.closeTo(totalMinted, 2); - - // check mint event - expect(parsedMintEvent.args.caller).to.equal(borrower.address); - expect(parsedMintEvent.args.onBehalfOf).to.equal(borrower.address); - expect(parsedMintEvent.args.value).to.be.closeTo(totalMinted, 2); - expect(parsedMintEvent.args.balanceIncrease).to.be.closeTo(totalMinted.add(smallRepay), 2); - }); - - it('User 1 - withdraw amount less than accrued interest', async () => { - const { - dai, - aDai, - users: [depositor], - pool, - helpersContract, - } = testEnv; - - // repay a very small amount - less than accrued debt - const smallWithdrawal = BigNumber.from('100000'); - - const withdrawTx = await pool - .connect(depositor.signer) - .withdraw(dai.address, smallWithdrawal, depositor.address); - const withdrawReceipt = await withdrawTx.wait(); - - const aTokenSupplyAfter = await aDai.balanceOf(depositor.address); - const daiReserveData = await helpersContract.getReserveData(dai.address); - const totalMinted = aTokenSupplyAfter.sub(firstDaiDeposit); - - // get transfer event - const rawTransferEvents = withdrawReceipt.logs.filter( - (log) => log.topics[0] === transferEventSignature - ); - expect(rawTransferEvents.length).to.equal(2, 'Incorrect number of Transfer Events'); - const parsedTransferEvent = aDai.interface.parseLog(rawTransferEvents[0]); - - // get mint event - const rawMintEvents = withdrawReceipt.logs.filter( - (log) => log.topics[0] === aTokenMintEventSignature - ); - expect(rawMintEvents.length).to.equal(1, 'Incorrect number of Mint Events'); - const parsedMintEvent = aDai.interface.parseLog(rawMintEvents[0]); - - // check transfer event - expect(parsedTransferEvent.args.from).to.equal(ZERO_ADDRESS); - expect(parsedTransferEvent.args.to).to.equal(depositor.address); - expect(parsedTransferEvent.args.value).to.be.closeTo(totalMinted, 2); - - // check mint event - expect(parsedMintEvent.args.caller).to.equal(depositor.address); - expect(parsedMintEvent.args.onBehalfOf).to.equal(depositor.address); - expect(parsedMintEvent.args.value).to.be.closeTo(totalMinted, 2); - expect(parsedMintEvent.args.balanceIncrease).to.be.closeTo(totalMinted.add(smallWithdrawal), 2); - expect(parsedMintEvent.args.index).to.equal(daiReserveData.liquidityIndex); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-modifiers.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-modifiers.spec.ts deleted file mode 100644 index 68771e5..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-modifiers.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { expect } from 'chai'; -import { ProtocolErrors } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; - -makeSuite('AToken: Modifiers', (testEnv: TestEnv) => { - const { CALLER_MUST_BE_POOL } = ProtocolErrors; - - it('Tries to invoke mint not being the Pool (revert expected)', async () => { - const { deployer, aDai } = testEnv; - await expect(aDai.mint(deployer.address, deployer.address, '1', '1')).to.be.revertedWith( - CALLER_MUST_BE_POOL - ); - }); - - it('Tries to invoke burn not being the Pool (revert expected)', async () => { - const { deployer, aDai } = testEnv; - await expect(aDai.burn(deployer.address, deployer.address, '1', '1')).to.be.revertedWith( - CALLER_MUST_BE_POOL - ); - }); - - it('Tries to invoke transferOnLiquidation not being the Pool (revert expected)', async () => { - const { deployer, users, aDai } = testEnv; - await expect( - aDai.transferOnLiquidation(deployer.address, users[0].address, '1') - ).to.be.revertedWith(CALLER_MUST_BE_POOL); - }); - - it('Tries to invoke transferUnderlyingTo not being the Pool (revert expected)', async () => { - const { deployer, aDai } = testEnv; - await expect(aDai.transferUnderlyingTo(deployer.address, '1')).to.be.revertedWith( - CALLER_MUST_BE_POOL - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-permit.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-permit.spec.ts deleted file mode 100644 index 26d3459..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-permit.spec.ts +++ /dev/null @@ -1,300 +0,0 @@ -import { waitForTx } from '@aave/deploy-v3'; -import { expect } from 'chai'; -import { ethers, utils } from 'ethers'; -import { HARDHAT_CHAINID, MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { buildPermitParams, getSignatureFromTypedData } from '../helpers/contracts-helpers'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { getTestWallets } from './helpers/utils/wallets'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { ProtocolErrors } from '../helpers/types'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('AToken: Permit', (testEnv: TestEnv) => { - let testWallets; - - const EIP712_REVISION = '1'; - - before(async () => { - const { dai, pool, deployer } = testEnv; - - testWallets = getTestWallets(); - - // Mint DAI and deposit to Pool to for aDAI - await waitForTx(await dai['mint(uint256)'](utils.parseEther('20000'))); - await waitForTx(await dai.approve(pool.address, utils.parseEther('20000'))); - - await waitForTx( - await pool.deposit(dai.address, utils.parseEther('20000'), deployer.address, 0) - ); - }); - - it('Checks the domain separator', async () => { - const { aDai } = testEnv; - const separator = await aDai.DOMAIN_SEPARATOR(); - - const domain = { - name: await aDai.name(), - version: EIP712_REVISION, - chainId: hre.network.config.chainId, - verifyingContract: aDai.address, - }; - const domainSeparator = utils._TypedDataEncoder.hashDomain(domain); - - expect(separator).to.be.equal(domainSeparator, 'Invalid domain separator'); - }); - - it('Tries to submit a permit with 0 expiration (revert expected)', async () => { - const { aDai, deployer, users } = testEnv; - const owner = deployer; - const spender = users[1]; - - const tokenName = await aDai.name(); - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = 0; - const nonce = (await aDai.nonces(owner.address)).toNumber(); - const permitAmount = utils.parseEther('2').toString(); - const msgParams = buildPermitParams( - chainId, - aDai.address, - EIP712_REVISION, - tokenName, - owner.address, - spender.address, - nonce, - permitAmount, - expiration.toFixed() - ); - - const ownerPrivateKey = testWallets[0].secretKey; - - expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal( - '0', - 'INVALID_ALLOWANCE_BEFORE_PERMIT' - ); - - const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); - - await expect( - aDai - .connect(spender.signer) - .permit(owner.address, spender.address, permitAmount, expiration, v, r, s) - ).to.be.revertedWith(ProtocolErrors.INVALID_EXPIRATION); - - expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal( - '0', - 'INVALID_ALLOWANCE_AFTER_PERMIT' - ); - }); - - it('Submits a permit with maximum expiration length', async () => { - const { aDai, deployer, users } = testEnv; - const owner = deployer; - const spender = users[1]; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const deadline = MAX_UINT_AMOUNT; - const nonce = (await aDai.nonces(owner.address)).toNumber(); - const permitAmount = utils.parseEther('2').toString(); - const msgParams = buildPermitParams( - chainId, - aDai.address, - EIP712_REVISION, - await aDai.name(), - owner.address, - spender.address, - nonce, - deadline, - permitAmount - ); - - const ownerPrivateKey = testWallets[0].secretKey; - - expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal( - '0', - 'INVALID_ALLOWANCE_BEFORE_PERMIT' - ); - - const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); - - expect( - await aDai - .connect(spender.signer) - .permit(owner.address, spender.address, permitAmount, deadline, v, r, s) - ); - - expect((await aDai.nonces(owner.address)).toNumber()).to.be.equal(1); - }); - - it('Cancels the previous permit', async () => { - const { aDai, deployer, users } = testEnv; - const owner = deployer; - const spender = users[1]; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const deadline = MAX_UINT_AMOUNT; - const nonce = (await aDai.nonces(owner.address)).toNumber(); - const permitAmount = '0'; - const msgParams = buildPermitParams( - chainId, - aDai.address, - EIP712_REVISION, - await aDai.name(), - owner.address, - spender.address, - nonce, - deadline, - permitAmount - ); - - const ownerPrivateKey = testWallets[0].secretKey; - - const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); - - expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal( - ethers.utils.parseEther('2'), - 'INVALID_ALLOWANCE_BEFORE_PERMIT' - ); - - expect( - await aDai - .connect(spender.signer) - .permit(owner.address, spender.address, permitAmount, deadline, v, r, s) - ); - expect((await aDai.allowance(owner.address, spender.address)).toString()).to.be.equal( - permitAmount, - 'INVALID_ALLOWANCE_AFTER_PERMIT' - ); - - expect((await aDai.nonces(owner.address)).toNumber()).to.be.equal(2); - }); - - it('Tries to submit a permit with invalid nonce (revert expected)', async () => { - const { aDai, deployer, users } = testEnv; - const owner = deployer; - const spender = users[1]; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const deadline = MAX_UINT_AMOUNT; - const nonce = 1000; - const permitAmount = '0'; - const msgParams = buildPermitParams( - chainId, - aDai.address, - EIP712_REVISION, - await aDai.name(), - owner.address, - spender.address, - nonce, - deadline, - permitAmount - ); - - const ownerPrivateKey = testWallets[0].secretKey; - - const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); - - await expect( - aDai - .connect(spender.signer) - .permit(owner.address, spender.address, permitAmount, deadline, v, r, s) - ).to.be.revertedWith(ProtocolErrors.INVALID_SIGNATURE); - }); - - it('Tries to submit a permit with invalid expiration (previous to the current block) (revert expected)', async () => { - const { aDai, deployer, users } = testEnv; - const owner = deployer; - const spender = users[1]; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = '1'; - const nonce = (await aDai.nonces(owner.address)).toNumber(); - const permitAmount = '0'; - const msgParams = buildPermitParams( - chainId, - aDai.address, - EIP712_REVISION, - await aDai.name(), - owner.address, - spender.address, - nonce, - expiration, - permitAmount - ); - - const ownerPrivateKey = testWallets[0].secretKey; - - const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); - - await expect( - aDai - .connect(spender.signer) - .permit(owner.address, spender.address, expiration, permitAmount, v, r, s) - ).to.be.revertedWith(ProtocolErrors.INVALID_EXPIRATION); - }); - - it('Tries to submit a permit with invalid signature (revert expected)', async () => { - const { aDai, deployer, users } = testEnv; - const owner = deployer; - const spender = users[1]; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const deadline = MAX_UINT_AMOUNT; - const nonce = (await aDai.nonces(owner.address)).toNumber(); - const permitAmount = '0'; - const msgParams = buildPermitParams( - chainId, - aDai.address, - EIP712_REVISION, - await aDai.name(), - owner.address, - spender.address, - nonce, - deadline, - permitAmount - ); - - const ownerPrivateKey = testWallets[0].secretKey; - - const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); - - await expect( - aDai - .connect(spender.signer) - .permit(owner.address, ZERO_ADDRESS, permitAmount, deadline, v, r, s) - ).to.be.revertedWith(ProtocolErrors.INVALID_SIGNATURE); - }); - - it('Tries to submit a permit with invalid owner (revert expected)', async () => { - const { aDai, deployer, users } = testEnv; - const owner = deployer; - const spender = users[1]; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = MAX_UINT_AMOUNT; - const nonce = (await aDai.nonces(owner.address)).toNumber(); - const permitAmount = '0'; - const msgParams = buildPermitParams( - chainId, - aDai.address, - EIP712_REVISION, - await aDai.name(), - owner.address, - spender.address, - nonce, - expiration, - permitAmount - ); - - const ownerPrivateKey = testWallets[0].secretKey; - - const { v, r, s } = getSignatureFromTypedData(ownerPrivateKey, msgParams); - - await expect( - aDai - .connect(spender.signer) - .permit(ZERO_ADDRESS, spender.address, expiration, permitAmount, v, r, s) - ).to.be.revertedWith(ProtocolErrors.ZERO_ADDRESS_NOT_VALID); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-repay.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-repay.spec.ts deleted file mode 100644 index a09e51a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-repay.spec.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { - waitForTx, - evmSnapshot, - evmRevert, - DefaultReserveInterestRateStrategy__factory, - IStableDebtToken__factory, - IVariableDebtToken__factory, -} from '@aave/deploy-v3'; -import { parseUnits } from '@ethersproject/units'; -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { setBlocktime, timeLatest } from '../helpers/misc-utils'; -import { RateMode } from '../helpers/types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; - -makeSuite('AToken: Repay', (testEnv: TestEnv) => { - let snapShot: string; - - before('User 0 deposits 100 DAI, user 1 deposits 1 WETH, borrows 50 DAI', async () => { - const { - weth, - pool, - dai, - users: [user0, user1], - } = testEnv; - - const daiAmount = utils.parseEther('100'); - const wethAmount = utils.parseEther('1'); - await waitForTx(await dai.connect(user0.signer)['mint(uint256)'](daiAmount)); - await waitForTx(await weth.connect(user1.signer)['mint(uint256)'](wethAmount)); - - await waitForTx(await dai.connect(user0.signer).approve(pool.address, MAX_UINT_AMOUNT)); - await waitForTx(await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect(await pool.connect(user0.signer).deposit(dai.address, daiAmount, user0.address, 0)); - expect(await pool.connect(user1.signer).deposit(weth.address, wethAmount, user1.address, 0)); - - expect( - await pool.connect(user1.signer).borrow(dai.address, daiAmount.div(2), 2, 0, user1.address) - ); - }); - - beforeEach(async () => { - snapShot = await evmSnapshot(); - }); - - afterEach(async () => { - await evmRevert(snapShot); - }); - - it('User 1 tries to repay using aTokens without actually holding aDAI', async () => { - const { - pool, - dai, - users: [, user1], - } = testEnv; - const repayAmount = utils.parseEther('25'); - - await expect(pool.connect(user1.address).repayWithATokens(dai.address, repayAmount, 2)).to.be - .reverted; - }); - - it('User 1 receives 25 aDAI from user 0, repays half of the debt', async () => { - const { - pool, - dai, - aDai, - variableDebtDai, - users: [user0, user1], - } = testEnv; - - const repayAmount = utils.parseEther('25'); - - await expect(await aDai.connect(user0.signer).transfer(user1.address, repayAmount)); - - const time = await timeLatest(); - - await setBlocktime(time.add(1).toNumber()); - - const balanceBefore = await aDai.balanceOf(user1.address, { blockTag: 'pending' }); - const debtBefore = await variableDebtDai.balanceOf(user1.address, { blockTag: 'pending' }); - - await expect(pool.connect(user1.signer).repayWithATokens(dai.address, repayAmount, 2)) - .to.emit(pool, 'Repay') - .withArgs(dai.address, user1.address, user1.address, repayAmount, true); - const balanceAfter = await aDai.balanceOf(user1.address); - const debtAfter = await variableDebtDai.balanceOf(user1.address); - - expect(balanceAfter).to.be.closeTo(balanceBefore.sub(repayAmount), 2); - expect(debtAfter).to.be.closeTo(debtBefore.sub(repayAmount), 2); - }); - - it('User 1 receives 25 aDAI from user 0, use all aDai to repay debt', async () => { - const { - pool, - dai, - aDai, - variableDebtDai, - users: [user0, user1], - } = testEnv; - - const transferAmount = utils.parseEther('25'); - expect(await aDai.connect(user0.signer).transfer(user1.address, transferAmount)); - - const time = await timeLatest(); - await setBlocktime(time.add(1).toNumber()); - - const balanceBefore = await aDai.balanceOf(user1.address, { blockTag: 'pending' }); - expect(balanceBefore).to.be.gt(transferAmount); - - const debtBefore = await variableDebtDai.balanceOf(user1.address, { blockTag: 'pending' }); - - const tx = await waitForTx( - await pool.connect(user1.signer).repayWithATokens(dai.address, MAX_UINT_AMOUNT, 2) - ); - - const repayEventSignature = utils.keccak256( - utils.toUtf8Bytes('Repay(address,address,address,uint256,bool)') - ); - - const rawRepayEvents = tx.logs.filter((log) => log.topics[0] === repayEventSignature); - const parsedRepayEvent = pool.interface.parseLog(rawRepayEvents[0]); - - expect(parsedRepayEvent.args.useATokens).to.be.true; - expect(parsedRepayEvent.args.reserve).to.be.eq(dai.address); - expect(parsedRepayEvent.args.repayer).to.be.eq(user1.address); - expect(parsedRepayEvent.args.user).to.be.eq(user1.address); - - const repayAmount = parsedRepayEvent.args.amount; - const balanceAfter = await aDai.balanceOf(user1.address); - const debtAfter = await variableDebtDai.balanceOf(user1.address); - - expect(balanceAfter).to.be.eq(0); - expect(debtAfter).to.be.closeTo(debtBefore.sub(repayAmount), 2); - }); - - it('User 1 receives 55 aDAI from user 0, repay all debt', async () => { - const { - pool, - dai, - aDai, - variableDebtDai, - users: [user0, user1], - } = testEnv; - - const transferAmount = utils.parseEther('55'); - expect(await aDai.connect(user0.signer).transfer(user1.address, transferAmount)); - - const time = await timeLatest(); - await setBlocktime(time.add(1).toNumber()); - - const balanceBefore = await aDai.balanceOf(user1.address, { blockTag: 'pending' }); - const debtBefore = await variableDebtDai.balanceOf(user1.address, { blockTag: 'pending' }); - expect(debtBefore).to.be.gt(parseUnits('50', 18)); - - const tx = await waitForTx( - await pool.connect(user1.signer).repayWithATokens(dai.address, MAX_UINT_AMOUNT, 2) - ); - - const repayEventSignature = utils.keccak256( - utils.toUtf8Bytes('Repay(address,address,address,uint256,bool)') - ); - - const rawRepayEvents = tx.logs.filter((log) => log.topics[0] === repayEventSignature); - const parsedRepayEvent = pool.interface.parseLog(rawRepayEvents[0]); - - expect(parsedRepayEvent.args.useATokens).to.be.true; - expect(parsedRepayEvent.args.reserve).to.be.eq(dai.address); - expect(parsedRepayEvent.args.repayer).to.be.eq(user1.address); - expect(parsedRepayEvent.args.user).to.be.eq(user1.address); - - const repayAmount = parsedRepayEvent.args.amount; - const balanceAfter = await aDai.balanceOf(user1.address); - const debtAfter = await variableDebtDai.balanceOf(user1.address); - - expect(debtAfter).to.be.eq(0); - expect(balanceAfter).to.be.eq(balanceBefore.sub(repayAmount)); - }); - - it('Check interest rates after repaying with aTokens', async () => { - const { - weth, - dai, - aDai, - pool, - helpersContract, - users: [user], - } = testEnv; - - const depositAmount = parseUnits('1000', 18); - await dai.connect(user.signer)['mint(uint256)'](depositAmount); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).supply(dai.address, depositAmount, user.address, 0); - - const collateralAmount = parseUnits('100', 18); - await weth.connect(user.signer)['mint(uint256)'](collateralAmount); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).supply(weth.address, collateralAmount, user.address, 0); - - const borrowAmount = parseUnits('500', 18); - await pool - .connect(user.signer) - .borrow(dai.address, borrowAmount, RateMode.Variable, 0, user.address); - - // Now we repay 250 with aTokens - const repayAmount = parseUnits('250', 18); - await pool.connect(user.signer).repayWithATokens(dai.address, repayAmount, RateMode.Variable); - - const reserveData = await pool.getReserveData(dai.address); - const strategy = DefaultReserveInterestRateStrategy__factory.connect( - reserveData.interestRateStrategyAddress, - user.signer - ); - - const stableDebtToken = IStableDebtToken__factory.connect( - reserveData.stableDebtTokenAddress, - user.signer - ); - const stableDebtData = await stableDebtToken.getSupplyData(); - - const variableDebtToken = IVariableDebtToken__factory.connect( - reserveData.variableDebtTokenAddress, - user.signer - ); - const scaledTotalSupply = await variableDebtToken.scaledTotalSupply(); - const variableDebt = scaledTotalSupply.rayMul( - await pool.getReserveNormalizedVariableDebt(dai.address) - ); - - const expectedRates = await strategy.calculateInterestRates({ - unbacked: 0, - liquidityAdded: 0, - liquidityTaken: 0, - totalStableDebt: stableDebtData[1], - totalVariableDebt: variableDebt, - aToken: aDai.address, - reserve: dai.address, - reserveFactor: (await helpersContract.getReserveConfigurationData(dai.address)).reserveFactor, - averageStableBorrowRate: stableDebtData[2], - }); - - expect(reserveData.currentLiquidityRate).to.be.eq(expectedRates[0]); - expect(reserveData.currentStableBorrowRate).to.be.eq(expectedRates[1]); - expect(reserveData.currentVariableBorrowRate).to.be.eq(expectedRates[2]); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-transfer.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-transfer.spec.ts deleted file mode 100644 index 77f9b64..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/atoken-transfer.spec.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { evmSnapshot, evmRevert } from '@aave/deploy-v3'; -import { expect } from 'chai'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { RateMode, ProtocolErrors } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; - -makeSuite('AToken: Transfer', (testEnv: TestEnv) => { - const { - INVALID_FROM_BALANCE_AFTER_TRANSFER, - INVALID_TO_BALANCE_AFTER_TRANSFER, - HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD, - } = ProtocolErrors; - - const DAI_AMOUNT_TO_DEPOSIT = '1000'; - - it('User 0 deposits 1000 DAI, transfers 1000 to user 0', async () => { - const { users, pool, dai, aDai } = testEnv; - const snap = await evmSnapshot(); - - // User 1 deposits 1000 DAI - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, DAI_AMOUNT_TO_DEPOSIT); - - // Top up user - expect(await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit)); - - expect(await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect(await aDai.getPreviousIndex(users[0].address)).to.be.eq(0); - - expect( - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ); - - expect(await aDai.getPreviousIndex(users[0].address)).to.be.gt(0); - - expect(await aDai.connect(users[0].signer).transfer(users[0].address, amountDAItoDeposit)) - .to.emit(aDai, 'Transfer') - .withArgs(users[0].address, users[0].address, amountDAItoDeposit); - - const name = await aDai.name(); - - expect(name).to.be.equal('Aave Testnet interest bearing DAI'); - - const fromBalance = await aDai.balanceOf(users[0].address); - const toBalance = await aDai.balanceOf(users[0].address); - expect(fromBalance.toString()).to.be.eq(toBalance.toString()); - - await evmRevert(snap); - }); - - it('User 0 deposits 1000 DAI, disable as collateral, transfers 1000 to user 1', async () => { - const { users, pool, dai, aDai } = testEnv; - const snap = await evmSnapshot(); - - // User 1 deposits 1000 DAI - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, DAI_AMOUNT_TO_DEPOSIT); - - // Top up user - expect(await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit)); - - expect(await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect( - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ); - - expect(await pool.connect(users[0].signer).setUserUseReserveAsCollateral(dai.address, false)); - - expect(await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit)) - .to.emit(aDai, 'Transfer') - .withArgs(users[0].address, users[1].address, amountDAItoDeposit); - - const name = await aDai.name(); - - expect(name).to.be.equal('Aave Testnet interest bearing DAI'); - - const fromBalance = await aDai.balanceOf(users[0].address); - const toBalance = await aDai.balanceOf(users[1].address); - expect(fromBalance.toString()).to.be.equal('0', INVALID_FROM_BALANCE_AFTER_TRANSFER); - expect(toBalance.toString()).to.be.equal( - amountDAItoDeposit.toString(), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - - await evmRevert(snap); - }); - - it('User 0 deposits 1000 DAI, transfers 5 to user 1 twice, then transfer 0 to user 1', async () => { - const { users, pool, dai, aDai } = testEnv; - const snap = await evmSnapshot(); - - expect( - await dai - .connect(users[0].signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, DAI_AMOUNT_TO_DEPOSIT)) - ); - - expect(await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT)); - - // User 1 deposits 1000 DAI - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, DAI_AMOUNT_TO_DEPOSIT); - const amountDAItoTransfer = await convertToCurrencyDecimals(dai.address, '5'); - - expect( - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ); - - expect(await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoTransfer)) - .to.emit(aDai, 'Transfer') - .withArgs(users[0].address, users[1].address, amountDAItoTransfer); - expect(await aDai.balanceOf(users[0].address)).to.be.eq( - (await convertToCurrencyDecimals(dai.address, '995')).toString(), - INVALID_FROM_BALANCE_AFTER_TRANSFER - ); - expect(await aDai.balanceOf(users[1].address)).to.be.eq( - (await convertToCurrencyDecimals(dai.address, '5')).toString(), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - - expect(await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoTransfer)) - .to.emit(aDai, 'Transfer') - .withArgs(users[0].address, users[1].address, amountDAItoTransfer); - expect(await aDai.balanceOf(users[0].address)).to.be.eq( - (await convertToCurrencyDecimals(dai.address, '990')).toString(), - INVALID_FROM_BALANCE_AFTER_TRANSFER - ); - expect(await aDai.balanceOf(users[1].address)).to.be.eq( - (await convertToCurrencyDecimals(dai.address, '10')).toString(), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - - expect(await aDai.connect(users[0].signer).transfer(users[1].address, 0)) - .to.emit(aDai, 'Transfer') - .withArgs(users[0].address, users[1].address, 0); - expect(await aDai.balanceOf(users[0].address)).to.be.eq( - (await convertToCurrencyDecimals(dai.address, '990')).toString(), - INVALID_FROM_BALANCE_AFTER_TRANSFER - ); - expect(await aDai.balanceOf(users[1].address)).to.be.eq( - (await convertToCurrencyDecimals(dai.address, '10')).toString(), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - - await evmRevert(snap); - }); - - it('User 0 deposits 1000 DAI, transfers to user 1', async () => { - const { users, pool, dai, aDai } = testEnv; - - // User 1 deposits 1000 DAI - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, DAI_AMOUNT_TO_DEPOSIT); - - // Top up user - expect(await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit)); - - expect(await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect( - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ); - - expect(await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit)) - .to.emit(aDai, 'Transfer') - .withArgs(users[0].address, users[1].address, amountDAItoDeposit); - - const name = await aDai.name(); - - expect(name).to.be.equal('Aave Testnet interest bearing DAI'); - - const fromBalance = await aDai.balanceOf(users[0].address); - const toBalance = await aDai.balanceOf(users[1].address); - - expect(fromBalance.toString()).to.be.equal('0', INVALID_FROM_BALANCE_AFTER_TRANSFER); - expect(toBalance.toString()).to.be.equal( - amountDAItoDeposit.toString(), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - }); - - it('User 0 deposits 1 WETH and user 1 tries to borrow the WETH with the received DAI as collateral', async () => { - const { users, pool, weth, helpersContract } = testEnv; - const userAddress = await pool.signer.getAddress(); - - const amountWETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1'); - const amountWETHtoBorrow = await convertToCurrencyDecimals(weth.address, '0.1'); - - expect(await weth.connect(users[0].signer)['mint(uint256)'](amountWETHtoDeposit)); - - expect(await weth.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect( - await pool - .connect(users[0].signer) - .deposit(weth.address, amountWETHtoDeposit, userAddress, '0') - ); - expect( - await pool - .connect(users[1].signer) - .borrow(weth.address, amountWETHtoBorrow, RateMode.Stable, '0', users[1].address) - ); - - const userReserveData = await helpersContract.getUserReserveData( - weth.address, - users[1].address - ); - - expect(userReserveData.currentStableDebt.toString()).to.be.eq(amountWETHtoBorrow); - }); - - it('User 1 tries to transfer all the DAI used as collateral back to user 0 (revert expected)', async () => { - const { users, aDai, dai } = testEnv; - - const amountDAItoTransfer = await convertToCurrencyDecimals(dai.address, DAI_AMOUNT_TO_DEPOSIT); - - await expect( - aDai.connect(users[1].signer).transfer(users[0].address, amountDAItoTransfer), - HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD - ).to.be.revertedWith(HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD); - }); - - it('User 1 transfers a small amount of DAI used as collateral back to user 0', async () => { - const { users, aDai, dai } = testEnv; - - const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '100'); - - expect(await aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer)) - .to.emit(aDai, 'Transfer') - .withArgs(users[1].address, users[0].address, aDAItoTransfer); - - const user0Balance = await aDai.balanceOf(users[0].address); - - expect(user0Balance.toString()).to.be.eq(aDAItoTransfer.toString()); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/bridge-logic.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/bridge-logic.spec.ts deleted file mode 100644 index 511c4fb..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/bridge-logic.spec.ts +++ /dev/null @@ -1,344 +0,0 @@ -const { expect } = require('chai'); -import { BigNumber, Event, utils } from 'ethers'; -import AaveConfig from '@aave/deploy-v3/dist/markets/aave'; -import { waitForTx, advanceTimeAndBlock } from '@aave/deploy-v3'; -import { getACLManager } from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { ReserveData, UserReserveData } from './helpers/utils/interfaces'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { MAX_UINT_AMOUNT, MAX_UNBACKED_MINT_CAP } from '../helpers/constants'; -import { ACLManager } from '../types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import { getReserveData } from './helpers/utils/helpers'; -import { getTxCostAndTimestamp } from './helpers/actions'; -import { - calcExpectedReserveDataAfterMintUnbacked, - calcExpectedReserveDataAfterBackUnbacked, - configuration as calculationsConfiguration, -} from './helpers/utils/calculations'; -import './helpers/utils/wadraymath'; - -const expectEqual = ( - actual: UserReserveData | ReserveData, - expected: UserReserveData | ReserveData -) => { - expect(actual).to.be.almostEqualOrEqual(expected); -}; - -makeSuite('BridgeLogic: Testing with borrows', (testEnv: TestEnv) => { - const { INVALID_AMOUNT, CALLER_NOT_BRIDGE, UNBACKED_MINT_CAP_EXCEEDED } = ProtocolErrors; - - const depositAmount = utils.parseEther('1000'); - const borrowAmount = utils.parseEther('200'); - const withdrawAmount = utils.parseEther('100'); - const feeBps = BigNumber.from(30); - const denominatorBP = BigNumber.from(10000); - const bridgeProtocolFeeBps = BigNumber.from(2000); - - const mintAmount = withdrawAmount.mul(denominatorBP.sub(feeBps)).div(denominatorBP); - const feeAmount = withdrawAmount.mul(feeBps).div(denominatorBP); - - let aclManager: ACLManager; - - before(async () => { - calculationsConfiguration.reservesParams = AaveConfig.ReservesConfig; - - const { users, poolAdmin, configurator } = testEnv; - - aclManager = await getACLManager(); - - await waitForTx(await aclManager.addBridge(users[2].address)); - await waitForTx(await aclManager.addBridge(users[3].address)); - - await waitForTx( - await configurator.connect(poolAdmin.signer).updateBridgeProtocolFee(bridgeProtocolFeeBps) - ); - }); - - it('User 0 deposit 1000 dai.', async () => { - const { users, pool, dai } = testEnv; - await waitForTx(await dai.connect(users[0].signer)['mint(uint256)'](depositAmount)); - await waitForTx(await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT)); - await waitForTx( - await pool.connect(users[0].signer).deposit(dai.address, depositAmount, users[0].address, 0) - ); - }); - - it('User 1 deposit 2 eth', async () => { - const { users, pool, weth } = testEnv; - await waitForTx(await weth.connect(users[1].signer).deposit({ value: utils.parseEther('2') })); - await waitForTx(await weth.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT)); - await waitForTx( - await pool - .connect(users[1].signer) - .deposit(weth.address, utils.parseEther('2'), users[1].address, 0) - ); - }); - - it('User 1 borrows 200 dai with variable debt', async () => { - const { users, pool, dai } = testEnv; - await waitForTx( - await pool - .connect(users[1].signer) - .borrow(dai.address, borrowAmount, RateMode.Variable, 0, users[1].address) - ); - }); - - it('User 1 borrows 200 dai with stable debt', async () => { - const { users, pool, dai } = testEnv; - await waitForTx( - await pool - .connect(users[1].signer) - .borrow(dai.address, borrowAmount, RateMode.Stable, 0, users[1].address) - ); - }); - - it('User 1 tries to perform fast withdraw 100 aDai from L2 (revert expected)', async () => { - const { users, pool, dai } = testEnv; - await expect( - pool.connect(users[1].signer).mintUnbacked(dai.address, mintAmount, users[0].address, 0) - ).to.be.revertedWith(CALLER_NOT_BRIDGE); - }); - - it('User 2 tries to perform fast withdraw from L2 with no unbackedMintCap (revert expected)', async () => { - const { users, pool, dai } = testEnv; - // fast withdraw a100 DAI - await expect( - pool.connect(users[2].signer).mintUnbacked(dai.address, mintAmount, users[0].address, 0) - ).to.be.revertedWith(UNBACKED_MINT_CAP_EXCEEDED); - - // fast withdraw 0 aDAI - await expect( - pool.connect(users[2].signer).mintUnbacked(dai.address, 0, users[0].address, 0) - ).to.be.revertedWith(INVALID_AMOUNT); - }); - - it('RiskAdmin updates the unbackedMintCap to 10 aDai (10 left) and user 1 tries to perform fast withdraw 100 aDai from L2 (revert expected)', async () => { - const { users, riskAdmin, pool, configurator, dai } = testEnv; - expect(await configurator.connect(riskAdmin.signer).setUnbackedMintCap(dai.address, '10')); - await expect( - pool.connect(users[2].signer).mintUnbacked(dai.address, mintAmount, users[0].address, 0) - ).to.be.revertedWith(UNBACKED_MINT_CAP_EXCEEDED); - - expect( - await configurator - .connect(riskAdmin.signer) - .setUnbackedMintCap(dai.address, MAX_UNBACKED_MINT_CAP) - ); - }); - - it('User 2 perform fast withdraw 100 aDai from L2', async () => { - const { users, pool, dai, helpersContract } = testEnv; - const reserveDataBefore = await getReserveData(helpersContract, dai.address); - const tx = await waitForTx( - await pool.connect(users[2].signer).mintUnbacked(dai.address, mintAmount, users[2].address, 0) - ); - const { txTimestamp } = await getTxCostAndTimestamp(tx); - const expectedDataAfter = calcExpectedReserveDataAfterMintUnbacked( - mintAmount.toString(), - reserveDataBefore, - txTimestamp - ); - const reserveDataAfter = await getReserveData(helpersContract, dai.address); - expectEqual(reserveDataAfter, expectedDataAfter); - }); - - it('RiskAdmin updates the unbackedMintCap to 100 aDai (0 left) and user 1 tries to perform fast withdraw 1 aDai from L2 (revert expected)', async () => { - const { users, riskAdmin, pool, configurator, dai } = testEnv; - expect(await configurator.connect(riskAdmin.signer).setUnbackedMintCap(dai.address, '100')); - await expect( - pool.connect(users[2].signer).mintUnbacked(dai.address, mintAmount, users[0].address, 0) - ).to.be.revertedWith(UNBACKED_MINT_CAP_EXCEEDED); - - expect( - await configurator - .connect(riskAdmin.signer) - .setUnbackedMintCap(dai.address, MAX_UNBACKED_MINT_CAP) - ); - }); - - it('User 2 perform another fast withdraw 100 aDai from L2', async () => { - const { users, pool, dai, helpersContract } = testEnv; - const reserveDataBefore = await getReserveData(helpersContract, dai.address); - const tx = await waitForTx( - await pool.connect(users[2].signer).mintUnbacked(dai.address, mintAmount, users[2].address, 0) - ); - const { txTimestamp } = await getTxCostAndTimestamp(tx); - const reserveDataAfter = await getReserveData(helpersContract, dai.address); - const expectedDataAfter = calcExpectedReserveDataAfterMintUnbacked( - mintAmount.toString(), - reserveDataBefore, - txTimestamp - ); - expectEqual(reserveDataAfter, expectedDataAfter); - }); - - it('Wait 1 days', async () => { - await advanceTimeAndBlock(60 * 60 * 24); - }); - - it('User 2 perform invalid fast withdraw 100 aDai from L2', async () => { - const { users, pool, dai, helpersContract } = testEnv; - const reserveDataBefore = await getReserveData(helpersContract, dai.address); - const tx = await waitForTx( - await pool.connect(users[2].signer).mintUnbacked(dai.address, mintAmount, users[2].address, 0) - ); - const { txTimestamp } = await getTxCostAndTimestamp(tx); - const reserveDataAfter = await getReserveData(helpersContract, dai.address); - const expectedDataAfter = calcExpectedReserveDataAfterMintUnbacked( - mintAmount.toString(), - reserveDataBefore, - txTimestamp - ); - expectEqual(reserveDataAfter, expectedDataAfter); - }); - - it('Wait 6 days', async () => { - await advanceTimeAndBlock(60 * 60 * 24 * 6); - }); - - it('100 bridged dai used to back unbacked', async () => { - // Let user 3 be bridge for now - const { users, pool, dai, aDai, helpersContract } = testEnv; - await waitForTx(await dai.connect(users[3].signer)['mint(uint256)'](withdrawAmount)); - await waitForTx(await dai.connect(users[3].signer).approve(pool.address, MAX_UINT_AMOUNT)); - - const reserveDataBefore = await getReserveData(helpersContract, dai.address); - - const tx = await waitForTx( - await pool.connect(users[3].signer).backUnbacked(dai.address, mintAmount, feeAmount) - ); - - const { txTimestamp } = await getTxCostAndTimestamp(tx); - - const reserveDataAfter = await getReserveData(helpersContract, dai.address); - - const expectedReserveDataAfter = calcExpectedReserveDataAfterBackUnbacked( - await aDai.scaledTotalSupply(), - mintAmount.toString(), - feeAmount.toString(), - bridgeProtocolFeeBps.toString(), - reserveDataBefore, - txTimestamp - ); - - expectEqual(reserveDataAfter, expectedReserveDataAfter); - - // Check event values for `ReserveDataUpdated` - const reserveDataUpdatedEvent = tx.events?.find( - ({ event }) => event === 'ReserveDataUpdated' - ) as Event; - if (reserveDataUpdatedEvent) { - const { - reserve: eventReserve, - liquidityRate: eventLiquidityRate, - stableBorrowRate: eventStableBorrowRate, - variableBorrowRate: eventVariableBorrowRate, - liquidityIndex: eventLiquidityIndex, - variableBorrowIndex: eventVariableBorrowIndex, - } = reserveDataUpdatedEvent.args as utils.Result; - expect(expectedReserveDataAfter.address).to.be.eq(eventReserve); - expect(expectedReserveDataAfter.liquidityRate).to.be.eq(eventLiquidityRate); - expect(expectedReserveDataAfter.stableBorrowRate).to.be.eq(eventStableBorrowRate); - expect(expectedReserveDataAfter.variableBorrowRate).to.be.eq(eventVariableBorrowRate); - expect(expectedReserveDataAfter.liquidityIndex).to.be.eq(eventLiquidityIndex); - expect(expectedReserveDataAfter.variableBorrowIndex).to.be.eq(eventVariableBorrowIndex); - } - }); - - it('user 1 performs unauthorized backing', async () => { - const { users, pool, dai } = testEnv; - await dai.connect(users[1].signer)['mint(uint256)'](withdrawAmount); - await dai.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - - await expect( - pool.connect(users[1].signer).backUnbacked(dai.address, mintAmount, feeAmount) - ).to.be.revertedWith(CALLER_NOT_BRIDGE); - }); - - it('100 bridged dai used to back unbacked', async () => { - // Let user 3 be bridge for now - const { users, pool, dai, aDai, helpersContract } = testEnv; - await dai.connect(users[3].signer)['mint(uint256)'](withdrawAmount); - await dai.connect(users[3].signer).approve(pool.address, MAX_UINT_AMOUNT); - - const reserveDataBefore = await getReserveData(helpersContract, dai.address); - - const tx = await waitForTx( - await pool.connect(users[3].signer).backUnbacked(dai.address, mintAmount, feeAmount) - ); - - const { txTimestamp } = await getTxCostAndTimestamp(tx); - - const reserveDataAfter = await getReserveData(helpersContract, dai.address); - - const expectedReserveDataAfter = calcExpectedReserveDataAfterBackUnbacked( - await aDai.scaledTotalSupply(), - mintAmount.toString(), - feeAmount.toString(), - bridgeProtocolFeeBps.toString(), - reserveDataBefore, - txTimestamp - ); - - expectEqual(reserveDataAfter, expectedReserveDataAfter); - }); - - it('User donates 100 dai to aDai holders', async () => { - // Let user 3 be bridge for now - const { users, pool, dai, aDai, helpersContract } = testEnv; - await dai.connect(users[3].signer)['mint(uint256)'](withdrawAmount); - await dai.connect(users[3].signer).approve(pool.address, MAX_UINT_AMOUNT); - - const reserveDataBefore = await getReserveData(helpersContract, dai.address); - - const tx = await waitForTx( - await pool.connect(users[3].signer).backUnbacked(dai.address, '0', withdrawAmount) - ); - - const { txTimestamp } = await getTxCostAndTimestamp(tx); - const reserveDataAfter = await getReserveData(helpersContract, dai.address); - - const expectedReserveDataAfter = calcExpectedReserveDataAfterBackUnbacked( - await aDai.scaledTotalSupply(), - '0', - withdrawAmount.toString(), - bridgeProtocolFeeBps.toString(), - reserveDataBefore, - txTimestamp - ); - - expectEqual(reserveDataAfter, expectedReserveDataAfter); - expect(reserveDataBefore.unbacked).to.be.eq(mintAmount); - expect(reserveDataAfter.unbacked).to.be.eq(mintAmount); - expect(reserveDataAfter.liquidityIndex.gt(reserveDataBefore.liquidityIndex)).to.be.eq(true); - }); - - it('Safety module cover 100 unbacked dai', async () => { - // Let user 3 be bridge for now - const { users, pool, dai, aDai, helpersContract } = testEnv; - await dai.connect(users[3].signer)['mint(uint256)'](withdrawAmount); - await dai.connect(users[3].signer).approve(pool.address, MAX_UINT_AMOUNT); - - const reserveDataBefore = await getReserveData(helpersContract, dai.address); - - const tx = await waitForTx( - await pool.connect(users[3].signer).backUnbacked(dai.address, mintAmount, '0') - ); - - const { txTimestamp } = await getTxCostAndTimestamp(tx); - const reserveDataAfter = await getReserveData(helpersContract, dai.address); - - const expectedReserveDataAfter = calcExpectedReserveDataAfterBackUnbacked( - await aDai.scaledTotalSupply(), - mintAmount.toString(), - '0', - bridgeProtocolFeeBps.toString(), - reserveDataBefore, - txTimestamp - ); - - expectEqual(reserveDataAfter, expectedReserveDataAfter); - expect(reserveDataBefore.unbacked).to.be.eq(mintAmount); - expect(reserveDataAfter.unbacked).to.be.eq('0'); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-borrow-cap.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-borrow-cap.spec.ts deleted file mode 100644 index 962dd80..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-borrow-cap.spec.ts +++ /dev/null @@ -1,439 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { advanceTimeAndBlock } from '@aave/deploy-v3'; -import { MAX_UINT_AMOUNT, MAX_BORROW_CAP } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; - -makeSuite('PoolConfigurator: Borrow Cap', (testEnv: TestEnv) => { - const { BORROW_CAP_EXCEEDED, INVALID_BORROW_CAP } = ProtocolErrors; - - before(async () => { - const { - weth, - pool, - dai, - usdc, - users: [user1], - } = testEnv; - - const mintedAmount = utils.parseEther('1000000000'); - // minting for main user - expect(await dai['mint(uint256)'](mintedAmount)); - expect(await weth['mint(uint256)'](mintedAmount)); - expect(await usdc['mint(uint256)'](mintedAmount)); - - // minting for lp user - expect(await dai.connect(user1.signer)['mint(uint256)'](mintedAmount)); - expect(await weth.connect(user1.signer)['mint(uint256)'](mintedAmount)); - expect(await usdc.connect(user1.signer)['mint(uint256)'](mintedAmount)); - - expect(await dai.approve(pool.address, MAX_UINT_AMOUNT)); - expect(await weth.approve(pool.address, MAX_UINT_AMOUNT)); - expect(await usdc.approve(pool.address, MAX_UINT_AMOUNT)); - expect(await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect(await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect(await usdc.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - }); - - it('Reserves should initially have borrow cap disabled (borrowCap = 0)', async () => { - const { dai, usdc, helpersContract } = testEnv; - - const { borrowCap: usdcBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcBorrowCap).to.be.equal('0'); - expect(daiBorrowCap).to.be.equal('0'); - }); - - it('Borrows 10 stable DAI, 10 variable USDC', async () => { - const { - weth, - pool, - dai, - usdc, - deployer, - users: [user1], - } = testEnv; - - const suppliedAmount = '1000'; - const borrowedAmount = '10'; - - // Deposit collateral - expect( - await pool.deposit( - weth.address, - await convertToCurrencyDecimals(weth.address, suppliedAmount), - deployer.address, - 0 - ) - ); - // User 1 deposit more DAI and USDC to be able to borrow - expect( - await pool - .connect(user1.signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - user1.address, - 0 - ) - ); - - expect( - await pool - .connect(user1.signer) - .deposit( - usdc.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - user1.address, - 0 - ) - ); - - // Borrow - expect( - await pool.borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, borrowedAmount), - 2, - 0, - deployer.address - ) - ); - - expect( - await pool.borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, borrowedAmount), - 1, - 0, - deployer.address - ) - ); - }); - - it('Sets the borrow cap for DAI and USDC to 10 Units', async () => { - const { configurator, dai, usdc, helpersContract } = testEnv; - - const { borrowCap: usdcOldBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiOldBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = 10; - expect(await configurator.setBorrowCap(usdc.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(usdc.address, daiOldBorrowCap, newCap); - expect(await configurator.setBorrowCap(dai.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(dai.address, usdcOldBorrowCap, newCap); - - const { borrowCap: usdcBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcBorrowCap).to.be.equal(newCap); - expect(daiBorrowCap).to.be.equal(newCap); - }); - - it('Tries to borrow any DAI or USDC, stable or variable, (> BORROW_CAP) (revert expected)', async () => { - const { usdc, pool, dai, deployer } = testEnv; - const borrowedAmount = '10'; - - await expect( - pool.borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, borrowedAmount), - 2, - 0, - deployer.address - ) - ).to.be.revertedWith(BORROW_CAP_EXCEEDED); - - await expect( - pool.borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, borrowedAmount), - 2, - 0, - deployer.address - ) - ).to.be.revertedWith(BORROW_CAP_EXCEEDED); - }); - - it('Tries to set the borrow cap for USDC and DAI to > MAX_BORROW_CAP (revert expected)', async () => { - const { configurator, usdc, dai } = testEnv; - const newCap = Number(MAX_BORROW_CAP) + 1; - - await expect(configurator.setBorrowCap(usdc.address, newCap)).to.be.revertedWith( - INVALID_BORROW_CAP - ); - await expect(configurator.setBorrowCap(dai.address, newCap)).to.be.revertedWith( - INVALID_BORROW_CAP - ); - }); - - it('Sets the borrow cap for DAI and USDC to 120 Units', async () => { - const { configurator, usdc, dai, helpersContract } = testEnv; - const newCap = '120'; - - const { borrowCap: usdcOldBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiOldBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - expect(await configurator.setBorrowCap(usdc.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(usdc.address, usdcOldBorrowCap, newCap); - expect(await configurator.setBorrowCap(dai.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(dai.address, daiOldBorrowCap, newCap); - - const { borrowCap: usdcBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcBorrowCap).to.be.equal(newCap); - expect(daiBorrowCap).to.be.equal(newCap); - }); - - it('Borrows 10 stable DAI and 10 variable USDC', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const borrowedAmount = '10'; - expect( - await pool.borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, borrowedAmount), - 2, - 0, - deployer.address - ) - ); - - expect( - await pool.borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, borrowedAmount), - 1, - 0, - deployer.address - ) - ); - }); - - it('Sets the borrow cap for WETH to 2 Units', async () => { - const { configurator, weth, helpersContract } = testEnv; - - const { borrowCap: wethOldBorrowCap } = await helpersContract.getReserveCaps(weth.address); - - const newCap = 2; - expect(await configurator.setBorrowCap(weth.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(weth.address, wethOldBorrowCap, newCap); - - const wethBorrowCap = (await helpersContract.getReserveCaps(weth.address)).borrowCap; - - expect(wethBorrowCap).to.be.equal(newCap); - }); - - it('Borrows 2 variable WETH (= BORROW_CAP)', async () => { - const { weth, pool, deployer, helpersContract } = testEnv; - - const borrowedAmount = '2'; - - await pool.borrow( - weth.address, - await convertToCurrencyDecimals(weth.address, borrowedAmount), - RateMode.Variable, - 0, - deployer.address - ); - }); - - it('Time flies and ETH debt amount goes above the limit due to accrued interests', async () => { - const { weth, helpersContract } = testEnv; - - // Advance blocks - await advanceTimeAndBlock(3600); - - const wethData = await helpersContract.getReserveData(weth.address); - const totalDebt = wethData.totalVariableDebt.add(wethData.totalStableDebt); - const wethCaps = await helpersContract.getReserveCaps(weth.address); - - expect(totalDebt).gt(wethCaps.borrowCap); - }); - - it('Tries to borrow any variable ETH (> BORROW_CAP) (revert expected)', async () => { - const { weth, pool, deployer } = testEnv; - - const borrowedAmount = '1'; - await expect( - pool.borrow( - weth.address, - await convertToCurrencyDecimals(weth.address, borrowedAmount), - RateMode.Variable, - 0, - deployer.address - ) - ).to.be.revertedWith(BORROW_CAP_EXCEEDED); - }); - - it('Borrows 99 variable DAI and 99 stable USDC (< BORROW_CAP)', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const borrowedAmount = '99'; - expect( - await pool.borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, borrowedAmount), - 2, - 0, - deployer.address - ) - ); - - expect( - await pool.borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, borrowedAmount), - 1, - 0, - deployer.address - ) - ); - }); - - it('Raises the borrow cap for USDC and DAI to 1000 Units', async () => { - const { configurator, usdc, dai, helpersContract } = testEnv; - - const { borrowCap: usdcOldBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiOldBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = '1000'; - expect(await configurator.setBorrowCap(usdc.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(usdc.address, usdcOldBorrowCap, newCap); - expect(await configurator.setBorrowCap(dai.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(dai.address, daiOldBorrowCap, newCap); - - const { borrowCap: usdcBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcBorrowCap).to.be.equal(newCap); - expect(daiBorrowCap).to.be.equal(newCap); - }); - - it('Borrows 100 variable DAI and 100 stable USDC (< BORROW_CAP)', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const borrowedAmount = '100'; - expect( - await pool.borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, borrowedAmount), - 1, - 0, - deployer.address - ) - ); - - expect( - await pool.borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, borrowedAmount), - 2, - 0, - deployer.address - ) - ); - }); - - it('Lowers the borrow cap for USDC and DAI to 200 Units', async () => { - const { configurator, usdc, dai, helpersContract } = testEnv; - - const { borrowCap: usdcOldBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiOldBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = '200'; - expect(await configurator.setBorrowCap(usdc.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(usdc.address, usdcOldBorrowCap, newCap); - expect(await configurator.setBorrowCap(dai.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(dai.address, daiOldBorrowCap, newCap); - - const { borrowCap: usdcBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcBorrowCap).to.be.equal(newCap); - expect(daiBorrowCap).to.be.equal(newCap); - }); - - it('Tries to borrows 100 variable DAI and 100 stable USDC (> BORROW_CAP) (revert expected)', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const borrowedAmount = '100'; - await expect( - pool.borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, borrowedAmount), - 1, - 0, - deployer.address - ) - ).to.be.revertedWith(BORROW_CAP_EXCEEDED); - - await expect( - pool.borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, borrowedAmount), - 2, - 0, - deployer.address - ) - ).to.be.revertedWith(BORROW_CAP_EXCEEDED); - }); - - it('Raises the borrow cap for USDC and DAI to MAX_BORROW_CAP', async () => { - const { configurator, usdc, dai, helpersContract } = testEnv; - - const { borrowCap: usdcOldBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiOldBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = MAX_BORROW_CAP; - expect(await configurator.setBorrowCap(usdc.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(usdc.address, usdcOldBorrowCap, newCap); - expect(await configurator.setBorrowCap(dai.address, newCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(dai.address, daiOldBorrowCap, newCap); - - const { borrowCap: usdcBorrowCap } = await helpersContract.getReserveCaps(usdc.address); - const { borrowCap: daiBorrowCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcBorrowCap).to.be.equal(newCap); - expect(daiBorrowCap).to.be.equal(newCap); - }); - - it('Borrows 100 variable DAI and 100 stable USDC (< BORROW_CAP)', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const borrowedAmount = '100'; - expect( - await pool.borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, borrowedAmount), - 1, - 0, - deployer.address - ) - ); - expect( - await pool.borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, borrowedAmount), - 2, - 0, - deployer.address - ) - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-edge.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-edge.spec.ts deleted file mode 100644 index 6d1eb3d..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-edge.spec.ts +++ /dev/null @@ -1,322 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber } from 'ethers'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { ProtocolErrors } from '../helpers/types'; -import { - MAX_BORROW_CAP, - MAX_UNBACKED_MINT_CAP, - MAX_UINT_AMOUNT, - MAX_SUPPLY_CAP, - ZERO_ADDRESS, -} from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { impersonateAddress } from '@aave/deploy-v3'; -import { topUpNonPayableWithEther } from './helpers/utils/funds'; -import { parseUnits } from 'ethers/lib/utils'; - -makeSuite('PoolConfigurator: Edge cases', (testEnv: TestEnv) => { - const { - INVALID_RESERVE_FACTOR, - INVALID_RESERVE_PARAMS, - INVALID_LIQ_BONUS, - FLASHLOAN_PREMIUM_INVALID, - RESERVE_LIQUIDITY_NOT_ZERO, - INVALID_BORROW_CAP, - INVALID_SUPPLY_CAP, - INVALID_UNBACKED_MINT_CAP, - EMODE_CATEGORY_RESERVED, - INVALID_EMODE_CATEGORY_PARAMS, - INVALID_EMODE_CATEGORY_ASSIGNMENT, - BRIDGE_PROTOCOL_FEE_INVALID, - ASSET_NOT_LISTED, - } = ProtocolErrors; - - it('ReserveConfiguration setLiquidationBonus() threshold > MAX_VALID_LIQUIDATION_THRESHOLD', async () => { - const { poolAdmin, dai, configurator } = testEnv; - await expect( - configurator - .connect(poolAdmin.signer) - .configureReserveAsCollateral(dai.address, 5, 10, 65535 + 1) - ).to.be.revertedWith(INVALID_LIQ_BONUS); - }); - - it('PoolConfigurator setReserveFactor() reserveFactor > PERCENTAGE_FACTOR (revert expected)', async () => { - const { dai, configurator } = testEnv; - const invalidReserveFactor = 20000; - await expect( - configurator.setReserveFactor(dai.address, invalidReserveFactor) - ).to.be.revertedWith(INVALID_RESERVE_FACTOR); - }); - - it('ReserveConfiguration setReserveFactor() reserveFactor > MAX_VALID_RESERVE_FACTOR', async () => { - const { dai, configurator } = testEnv; - const invalidReserveFactor = 65536; - await expect( - configurator.setReserveFactor(dai.address, invalidReserveFactor) - ).to.be.revertedWith(INVALID_RESERVE_FACTOR); - }); - - it('PoolConfigurator configureReserveAsCollateral() ltv > liquidationThreshold', async () => { - const { poolAdmin, dai, configurator, helpersContract } = testEnv; - - const config = await helpersContract.getReserveConfigurationData(dai.address); - - await expect( - configurator - .connect(poolAdmin.signer) - .configureReserveAsCollateral( - dai.address, - 65535 + 1, - config.liquidationThreshold, - config.liquidationBonus - ) - ).to.be.revertedWith(INVALID_RESERVE_PARAMS); - }); - - it('PoolConfigurator configureReserveAsCollateral() liquidationBonus < 10000', async () => { - const { poolAdmin, dai, configurator, helpersContract } = testEnv; - - const config = await helpersContract.getReserveConfigurationData(dai.address); - - await expect( - configurator - .connect(poolAdmin.signer) - .configureReserveAsCollateral(dai.address, config.ltv, config.liquidationThreshold, 10000) - ).to.be.revertedWith(INVALID_RESERVE_PARAMS); - }); - - it('PoolConfigurator configureReserveAsCollateral() liquidationThreshold.percentMul(liquidationBonus) > PercentageMath.PERCENTAGE_FACTOR', async () => { - const { poolAdmin, dai, configurator } = testEnv; - - await expect( - configurator - .connect(poolAdmin.signer) - .configureReserveAsCollateral(dai.address, 10001, 10001, 10001) - ).to.be.revertedWith(INVALID_RESERVE_PARAMS); - }); - - it('PoolConfigurator configureReserveAsCollateral() liquidationThreshold == 0 && liquidationBonus > 0', async () => { - const { poolAdmin, dai, configurator } = testEnv; - - await expect( - configurator.connect(poolAdmin.signer).configureReserveAsCollateral(dai.address, 0, 0, 10500) - ).to.be.revertedWith(INVALID_RESERVE_PARAMS); - }); - - it('Tries to bridge protocol fee > PERCENTAGE_FACTOR (revert expected)', async () => { - const { configurator } = testEnv; - const newProtocolFee = 10001; - await expect(configurator.updateBridgeProtocolFee(newProtocolFee)).to.be.revertedWith( - BRIDGE_PROTOCOL_FEE_INVALID - ); - }); - - it('Tries to update flashloan premium total > PERCENTAGE_FACTOR (revert expected)', async () => { - const { configurator } = testEnv; - - const newPremiumTotal = 10001; - await expect(configurator.updateFlashloanPremiumTotal(newPremiumTotal)).to.be.revertedWith( - FLASHLOAN_PREMIUM_INVALID - ); - }); - - it('Tries to update flashloan premium to protocol > PERCENTAGE_FACTOR (revert expected)', async () => { - const { configurator } = testEnv; - - const newPremiumToProtocol = 10001; - await expect( - configurator.updateFlashloanPremiumToProtocol(newPremiumToProtocol) - ).to.be.revertedWith(FLASHLOAN_PREMIUM_INVALID); - }); - - it('Tries to update borrowCap > MAX_BORROW_CAP (revert expected)', async () => { - const { configurator, weth } = testEnv; - await expect( - configurator.setBorrowCap(weth.address, BigNumber.from(MAX_BORROW_CAP).add(1)) - ).to.be.revertedWith(INVALID_BORROW_CAP); - }); - - it('Tries to update supplyCap > MAX_SUPPLY_CAP (revert expected)', async () => { - const { configurator, weth } = testEnv; - await expect( - configurator.setSupplyCap(weth.address, BigNumber.from(MAX_SUPPLY_CAP).add(1)) - ).to.be.revertedWith(INVALID_SUPPLY_CAP); - }); - - it('Tries to update unbackedMintCap > MAX_UNBACKED_MINT_CAP (revert expected)', async () => { - const { configurator, weth } = testEnv; - await expect( - configurator.setUnbackedMintCap(weth.address, BigNumber.from(MAX_UNBACKED_MINT_CAP).add(1)) - ).to.be.revertedWith(INVALID_UNBACKED_MINT_CAP); - }); - - it('Tries to set borrowCap of MAX_BORROW_CAP an unlisted asset', async () => { - const { configurator, users } = testEnv; - const newCap = 10; - await expect(configurator.setBorrowCap(users[5].address, newCap)).to.be.revertedWith( - ASSET_NOT_LISTED - ); - }); - - it('Tries to add a category with id 0 (revert expected)', async () => { - const { configurator, poolAdmin } = testEnv; - - await expect( - configurator - .connect(poolAdmin.signer) - .setEModeCategory(0, '9800', '9800', '10100', ZERO_ADDRESS, 'INVALID_ID_CATEGORY') - ).to.be.revertedWith(EMODE_CATEGORY_RESERVED); - }); - - it('Tries to add an eMode category with ltv > liquidation threshold (revert expected)', async () => { - const { configurator, poolAdmin } = testEnv; - - const id = BigNumber.from('16'); - const ltv = BigNumber.from('9900'); - const lt = BigNumber.from('9800'); - const lb = BigNumber.from('10100'); - const oracle = ZERO_ADDRESS; - const label = 'STABLECOINS'; - - await expect( - configurator.connect(poolAdmin.signer).setEModeCategory(id, ltv, lt, lb, oracle, label) - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_PARAMS); - }); - - it('Tries to add an eMode category with no liquidation bonus (revert expected)', async () => { - const { configurator, poolAdmin } = testEnv; - - const id = BigNumber.from('16'); - const ltv = BigNumber.from('9800'); - const lt = BigNumber.from('9800'); - const lb = BigNumber.from('10000'); - const oracle = ZERO_ADDRESS; - const label = 'STABLECOINS'; - - await expect( - configurator.connect(poolAdmin.signer).setEModeCategory(id, ltv, lt, lb, oracle, label) - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_PARAMS); - }); - - it('Tries to add an eMode category with too large liquidation bonus (revert expected)', async () => { - const { configurator, poolAdmin } = testEnv; - - const id = BigNumber.from('16'); - const ltv = BigNumber.from('9800'); - const lt = BigNumber.from('9800'); - const lb = BigNumber.from('11000'); - const oracle = ZERO_ADDRESS; - const label = 'STABLECOINS'; - - await expect( - configurator.connect(poolAdmin.signer).setEModeCategory(id, ltv, lt, lb, oracle, label) - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_PARAMS); - }); - - it('Tries to add an eMode category with liquidation threshold > 1 (revert expected)', async () => { - const { configurator, poolAdmin } = testEnv; - - const id = BigNumber.from('16'); - const ltv = BigNumber.from('9800'); - const lt = BigNumber.from('10100'); - const lb = BigNumber.from('10100'); - const oracle = ZERO_ADDRESS; - const label = 'STABLECOINS'; - - await expect( - configurator.connect(poolAdmin.signer).setEModeCategory(id, ltv, lt, lb, oracle, label) - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_PARAMS); - }); - - it('Tries to set DAI eMode category to undefined category (revert expected)', async () => { - const { configurator, poolAdmin, dai } = testEnv; - - await expect( - configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, '100') - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_ASSIGNMENT); - }); - - it('Tries to set DAI eMode category to category with too low LT (revert expected)', async () => { - const { configurator, helpersContract, poolAdmin, dai } = testEnv; - - const { liquidationThreshold, ltv } = await helpersContract.getReserveConfigurationData( - dai.address - ); - - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory( - '100', - ltv, - liquidationThreshold.sub(1), - '10100', - ZERO_ADDRESS, - 'LT_TOO_LOW_FOR_DAI' - ) - ); - - await expect( - configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, '100') - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_ASSIGNMENT); - }); - - it('Tries to disable the DAI reserve with liquidity on it (revert expected)', async () => { - const { dai, pool, configurator } = testEnv; - const userAddress = await pool.signer.getAddress(); - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - // Top up user - expect(await dai['mint(uint256)'](amountDAItoDeposit)); - - // Approve protocol to access depositor wallet - expect(await dai.approve(pool.address, MAX_UINT_AMOUNT)); - - // User 1 deposits 1000 DAI - expect(await pool.deposit(dai.address, amountDAItoDeposit, userAddress, '0')); - - await expect( - configurator.setReserveActive(dai.address, false), - RESERVE_LIQUIDITY_NOT_ZERO - ).to.be.revertedWith(RESERVE_LIQUIDITY_NOT_ZERO); - }); - - it('Tries to withdraw from an inactive reserve (revert expected)', async () => { - const { dai, pool, configurator, helpersContract } = testEnv; - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - const userAddress = await pool.signer.getAddress(); - - // Impersonate configurator - const impConfig = await impersonateAddress(configurator.address); - await topUpNonPayableWithEther(pool.signer, [configurator.address], parseUnits('10', 18)); - - // Top up user - expect(await dai['mint(uint256)'](amountDAItoDeposit)); - - // Approve protocol to access depositor wallet - expect(await dai.approve(pool.address, MAX_UINT_AMOUNT)); - - // User 1 deposits 1000 DAI - expect(await pool.deposit(dai.address, amountDAItoDeposit, userAddress, '0')); - - // get configuration - const daiConfiguration: BigNumber = (await pool.getConfiguration(dai.address)).data; - const activeMask = BigNumber.from( - '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFF' - ); - - // Set new configuration with active turned off - expect( - await pool - .connect(impConfig.signer) - .setConfiguration(dai.address, { data: daiConfiguration.and(activeMask) }) - ); - - const updatedConfiguration = await helpersContract.getReserveConfigurationData(dai.address); - expect(updatedConfiguration.isActive).to.false; - - await expect(pool.withdraw(dai.address, amountDAItoDeposit, userAddress)).to.be.revertedWith( - ProtocolErrors.RESERVE_INACTIVE - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-liquidation-protocol-fee.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-liquidation-protocol-fee.spec.ts deleted file mode 100644 index 013dcd6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-liquidation-protocol-fee.spec.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { ProtocolErrors } from '../helpers/types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; - -makeSuite('PoolConfigurator: Liquidation Protocol Fee', (testEnv: TestEnv) => { - const { INVALID_LIQUIDATION_PROTOCOL_FEE } = ProtocolErrors; - - before(async () => { - const { weth, pool, dai, usdc } = testEnv; - - const mintedAmount = utils.parseEther('1000000000'); - await dai['mint(uint256)'](mintedAmount); - await weth['mint(uint256)'](mintedAmount); - await usdc['mint(uint256)'](mintedAmount); - - await dai.approve(pool.address, MAX_UINT_AMOUNT); - await weth.approve(pool.address, MAX_UINT_AMOUNT); - await usdc.approve(pool.address, MAX_UINT_AMOUNT); - }); - - it('Reserves should initially have protocol liquidation fee set to 0', async () => { - const { dai, usdc, helpersContract } = testEnv; - - const usdcLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - usdc.address - ); - const daiLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee(dai.address); - - expect(usdcLiquidationProtocolFee).to.be.equal('0'); - expect(daiLiquidationProtocolFee).to.be.equal('0'); - }); - - it('Sets the protocol liquidation fee to 1000 (10.00%)', async () => { - const { configurator, dai, usdc, helpersContract } = testEnv; - - const oldUsdcLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - usdc.address - ); - const oldDaiLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - dai.address - ); - - const liquidationProtocolFee = 1000; - - expect(await configurator.setLiquidationProtocolFee(usdc.address, liquidationProtocolFee)) - .to.emit(configurator, 'LiquidationProtocolFeeChanged') - .withArgs(usdc.address, oldUsdcLiquidationProtocolFee, liquidationProtocolFee); - expect(await configurator.setLiquidationProtocolFee(dai.address, liquidationProtocolFee)) - .to.emit(configurator, 'LiquidationProtocolFeeChanged') - .withArgs(dai.address, oldDaiLiquidationProtocolFee, liquidationProtocolFee); - - const usdcLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - usdc.address - ); - const daiLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee(dai.address); - - expect(usdcLiquidationProtocolFee).to.be.equal(liquidationProtocolFee); - expect(daiLiquidationProtocolFee).to.be.equal(liquidationProtocolFee); - }); - - it('Sets the protocol liquidation fee to 10000 (100.00%) equal to PERCENTAGE_FACTOR', async () => { - const { configurator, dai, usdc, helpersContract } = testEnv; - - const oldUsdcLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - usdc.address - ); - const oldDaiLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - dai.address - ); - - const liquidationProtocolFee = 10000; - - expect(await configurator.setLiquidationProtocolFee(usdc.address, liquidationProtocolFee)) - .to.emit(configurator, 'LiquidationProtocolFeeChanged') - .withArgs(usdc.address, oldUsdcLiquidationProtocolFee, liquidationProtocolFee); - expect(await configurator.setLiquidationProtocolFee(dai.address, liquidationProtocolFee)) - .to.emit(configurator, 'LiquidationProtocolFeeChanged') - .withArgs(dai.address, oldDaiLiquidationProtocolFee, liquidationProtocolFee); - - const usdcLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - usdc.address - ); - const daiLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee(dai.address); - - expect(usdcLiquidationProtocolFee).to.be.equal(liquidationProtocolFee); - expect(daiLiquidationProtocolFee).to.be.equal(liquidationProtocolFee); - }); - - it('Tries to set the protocol liquidation fee to 10001 (100.01%) > PERCENTAGE_FACTOR (revert expected)', async () => { - const { configurator, dai, usdc } = testEnv; - - const liquidationProtocolFee = 10001; - - expect( - configurator.setLiquidationProtocolFee(usdc.address, liquidationProtocolFee) - ).to.be.revertedWith(INVALID_LIQUIDATION_PROTOCOL_FEE); - expect( - configurator.setLiquidationProtocolFee(dai.address, liquidationProtocolFee) - ).to.be.revertedWith(INVALID_LIQUIDATION_PROTOCOL_FEE); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-modifiers.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-modifiers.spec.ts deleted file mode 100644 index e28e672..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-modifiers.spec.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { expect } from 'chai'; -import { ONE_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors } from '../helpers/types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; - -makeSuite('PoolConfigurator: Modifiers', (testEnv: TestEnv) => { - const { - CALLER_NOT_POOL_ADMIN, - CALLER_NOT_POOL_OR_EMERGENCY_ADMIN, - CALLER_NOT_RISK_OR_POOL_ADMIN, - CALLER_NOT_EMERGENCY_ADMIN, - CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN, - } = ProtocolErrors; - - it('Test the accessibility of onlyAssetListingOrPoolAdmins modified functions', async () => { - const { configurator, users } = testEnv; - const nonPoolAdmin = users[2]; - - const randomAddress = ONE_ADDRESS; - const randomNumber = '0'; - const randomInitReserve = [ - { - aTokenImpl: randomAddress, - stableDebtTokenImpl: randomAddress, - variableDebtTokenImpl: randomAddress, - underlyingAssetDecimals: randomNumber, - interestRateStrategyAddress: randomAddress, - underlyingAsset: randomAddress, - treasury: randomAddress, - incentivesController: randomAddress, - aTokenName: 'MOCK', - aTokenSymbol: 'MOCK', - variableDebtTokenName: 'MOCK', - variableDebtTokenSymbol: 'MOCK', - stableDebtTokenName: 'MOCK', - stableDebtTokenSymbol: 'MOCK', - params: '0x10', - }, - ]; - - const calls = [{ fn: 'initReserves', args: [randomInitReserve] }]; - for (const call of calls) { - await expect( - configurator.connect(nonPoolAdmin.signer)[call.fn](...call.args) - ).to.be.revertedWith(CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN); - } - }); - - it('Test the accessibility of onlyPoolAdmin modified functions', async () => { - const { configurator, users } = testEnv; - const nonPoolAdmin = users[2]; - - const randomAddress = ONE_ADDRESS; - const randomNumber = '0'; - const randomUpdateAToken = { - asset: randomAddress, - treasury: randomAddress, - incentivesController: randomAddress, - name: 'MOCK', - symbol: 'MOCK', - implementation: randomAddress, - params: '0x10', - }; - const randomUpdateDebtToken = { - asset: randomAddress, - incentivesController: randomAddress, - name: 'MOCK', - symbol: 'MOCK', - implementation: randomAddress, - params: '0x10', - }; - - const calls = [ - { fn: 'dropReserve', args: [randomAddress] }, - { fn: 'updateAToken', args: [randomUpdateAToken] }, - { fn: 'updateStableDebtToken', args: [randomUpdateDebtToken] }, - { fn: 'updateVariableDebtToken', args: [randomUpdateDebtToken] }, - { fn: 'setReserveActive', args: [randomAddress, true] }, - { fn: 'setReserveActive', args: [randomAddress, false] }, - { fn: 'updateFlashloanPremiumTotal', args: [randomNumber] }, - { fn: 'updateFlashloanPremiumToProtocol', args: [randomNumber] }, - { fn: 'updateFlashloanPremiumToProtocol', args: [randomNumber] }, - ]; - for (const call of calls) { - await expect( - configurator.connect(nonPoolAdmin.signer)[call.fn](...call.args) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - } - }); - - it('Test the accessibility of onlyRiskOrPoolAdmins modified functions', async () => { - const { configurator, users } = testEnv; - const nonRiskOrPoolAdmins = users[3]; - - const randomAddress = ONE_ADDRESS; - const randomNumber = '0'; - - const calls = [ - { fn: 'setReserveBorrowing', args: [randomAddress, false] }, - { fn: 'setReserveBorrowing', args: [randomAddress, true] }, - { - fn: 'configureReserveAsCollateral', - args: [randomAddress, randomNumber, randomNumber, randomNumber], - }, - { fn: 'setReserveStableRateBorrowing', args: [randomAddress, true] }, - { fn: 'setReserveStableRateBorrowing', args: [randomAddress, false] }, - { fn: 'setReserveFreeze', args: [randomAddress, true] }, - { fn: 'setReserveFreeze', args: [randomAddress, false] }, - { fn: 'setReserveFactor', args: [randomAddress, randomNumber] }, - { fn: 'setBorrowCap', args: [randomAddress, randomNumber] }, - { fn: 'setSupplyCap', args: [randomAddress, randomNumber] }, - { fn: 'setReserveInterestRateStrategyAddress', args: [randomAddress, randomAddress] }, - { - fn: 'setEModeCategory', - args: [randomNumber, randomNumber, randomNumber, randomNumber, randomAddress, ''], - }, - { fn: 'setAssetEModeCategory', args: [randomAddress, randomNumber] }, - { fn: 'setDebtCeiling', args: [randomAddress, randomNumber] }, - ]; - for (const call of calls) { - await expect( - configurator.connect(nonRiskOrPoolAdmins.signer)[call.fn](...call.args) - ).to.be.revertedWith(CALLER_NOT_RISK_OR_POOL_ADMIN); - } - }); - - it('Tries to pause reserve with non-emergency-admin account (revert expected)', async () => { - const { configurator, weth, riskAdmin } = testEnv; - await expect( - configurator.connect(riskAdmin.signer).setReservePause(weth.address, true), - CALLER_NOT_POOL_ADMIN - ).to.be.revertedWith(CALLER_NOT_POOL_OR_EMERGENCY_ADMIN); - }); - - it('Tries to unpause reserve with non-emergency-admin account (revert expected)', async () => { - const { configurator, weth, riskAdmin } = testEnv; - await expect( - configurator.connect(riskAdmin.signer).setReservePause(weth.address, false), - CALLER_NOT_POOL_ADMIN - ).to.be.revertedWith(CALLER_NOT_POOL_OR_EMERGENCY_ADMIN); - }); - - it('Tries to pause pool with not emergency admin (revert expected)', async () => { - const { users, configurator } = testEnv; - await expect(configurator.connect(users[0].signer).setPoolPause(true)).to.be.revertedWith( - CALLER_NOT_EMERGENCY_ADMIN - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-supply-cap.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-supply-cap.spec.ts deleted file mode 100644 index bff166e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator-supply-cap.spec.ts +++ /dev/null @@ -1,354 +0,0 @@ -import { advanceTimeAndBlock } from '@aave/deploy-v3'; -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { MAX_UINT_AMOUNT, MAX_SUPPLY_CAP } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors } from '../helpers/types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; - -makeSuite('PoolConfigurator: Supply Cap', (testEnv: TestEnv) => { - const { SUPPLY_CAP_EXCEEDED, INVALID_SUPPLY_CAP } = ProtocolErrors; - - before(async () => { - const { weth, pool, dai, usdc } = testEnv; - - const mintedAmount = utils.parseEther('1000000000'); - await dai['mint(uint256)'](mintedAmount); - await weth['mint(uint256)'](mintedAmount); - await usdc['mint(uint256)'](mintedAmount); - - await dai.approve(pool.address, MAX_UINT_AMOUNT); - await weth.approve(pool.address, MAX_UINT_AMOUNT); - await usdc.approve(pool.address, MAX_UINT_AMOUNT); - }); - - it('Reserves should initially have supply cap disabled (supplyCap = 0)', async () => { - const { dai, usdc, helpersContract } = testEnv; - - let usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap; - let daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap; - - expect(usdcSupplyCap).to.be.equal('0'); - expect(daiSupplyCap).to.be.equal('0'); - }); - - it('Supply 1000 Dai, 1000 USDC and 1000 WETH', async () => { - const { weth, pool, dai, usdc, deployer } = testEnv; - - const suppliedAmount = '1000'; - - await pool.deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, suppliedAmount), - deployer.address, - 0 - ); - - await pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ); - await pool.deposit( - weth.address, - await convertToCurrencyDecimals(weth.address, suppliedAmount), - deployer.address, - 0 - ); - }); - - it('Sets the supply cap for DAI and USDC to 1000 Unit, leaving 0 Units to reach the limit', async () => { - const { configurator, dai, usdc, helpersContract } = testEnv; - - const { supplyCap: oldUsdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: oldDaiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = '1000'; - - expect(await configurator.setSupplyCap(usdc.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(usdc.address, oldUsdcSupplyCap, newCap); - expect(await configurator.setSupplyCap(dai.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(dai.address, oldDaiSupplyCap, newCap); - - const { supplyCap: usdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: daiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcSupplyCap).to.be.equal(newCap); - expect(daiSupplyCap).to.be.equal(newCap); - }); - - it('Tries to supply any DAI or USDC (> SUPPLY_CAP) (revert expected)', async () => { - const { usdc, pool, dai, deployer } = testEnv; - const suppliedAmount = '10'; - - await expect( - pool.deposit(usdc.address, suppliedAmount, deployer.address, 0) - ).to.be.revertedWith(SUPPLY_CAP_EXCEEDED); - - await expect( - pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ) - ).to.be.revertedWith(SUPPLY_CAP_EXCEEDED); - }); - - it('Tries to set the supply cap for USDC and DAI to > MAX_SUPPLY_CAP (revert expected)', async () => { - const { configurator, usdc, dai } = testEnv; - const newCap = Number(MAX_SUPPLY_CAP) + 1; - - await expect(configurator.setSupplyCap(usdc.address, newCap)).to.be.revertedWith( - INVALID_SUPPLY_CAP - ); - await expect(configurator.setSupplyCap(dai.address, newCap)).to.be.revertedWith( - INVALID_SUPPLY_CAP - ); - }); - - it('Sets the supply cap for usdc and DAI to 1110 Units, leaving 110 Units to reach the limit', async () => { - const { configurator, usdc, dai, helpersContract } = testEnv; - - const { supplyCap: oldUsdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: oldDaiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = '1110'; - expect(await configurator.setSupplyCap(usdc.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(usdc.address, oldUsdcSupplyCap, newCap); - expect(await configurator.setSupplyCap(dai.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(dai.address, oldDaiSupplyCap, newCap); - - const { supplyCap: usdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: daiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcSupplyCap).to.be.equal(newCap); - expect(daiSupplyCap).to.be.equal(newCap); - }); - - it('Supply 10 DAI and 10 USDC, leaving 100 Units to reach the limit', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const suppliedAmount = '10'; - await pool.deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, suppliedAmount), - deployer.address, - 0 - ); - - await pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ); - }); - - it('Tries to supply 101 DAI and 101 USDC (> SUPPLY_CAP) 1 unit above the limit (revert expected)', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const suppliedAmount = '101'; - - await expect( - pool.deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, suppliedAmount), - deployer.address, - 0 - ) - ).to.be.revertedWith(SUPPLY_CAP_EXCEEDED); - - await expect( - pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ) - ).to.be.revertedWith(SUPPLY_CAP_EXCEEDED); - }); - - it('Supply 99 DAI and 99 USDC (< SUPPLY_CAP), leaving 1 Units to reach the limit', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const suppliedAmount = '99'; - await pool.deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, suppliedAmount), - deployer.address, - 0 - ); - - await pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ); - }); - - it('Supply 1 DAI and 1 USDC (= SUPPLY_CAP), reaching the limit', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const suppliedAmount = '1'; - await pool.deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, suppliedAmount), - deployer.address, - 0 - ); - - await pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ); - }); - - it('Time flies and DAI and USDC supply amount goes above the limit due to accrued interests', async () => { - const { usdc, pool, dai, deployer, helpersContract } = testEnv; - - // Advance blocks - await advanceTimeAndBlock(3600); - - const daiData = await helpersContract.getReserveData(dai.address); - const daiCaps = await helpersContract.getReserveCaps(dai.address); - const usdcData = await helpersContract.getReserveData(usdc.address); - const usdcCaps = await helpersContract.getReserveCaps(usdc.address); - - expect(daiData.totalAToken).gt(daiCaps.supplyCap); - expect(usdcData.totalAToken).gt(usdcCaps.supplyCap); - }); - - it('Raises the supply cap for USDC and DAI to 2000 Units, leaving 800 Units to reach the limit', async () => { - const { configurator, usdc, dai, helpersContract } = testEnv; - - const { supplyCap: oldUsdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: oldDaiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = '2000'; - expect(await configurator.setSupplyCap(usdc.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(usdc.address, oldUsdcSupplyCap, newCap); - expect(await configurator.setSupplyCap(dai.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(dai.address, oldDaiSupplyCap, newCap); - - const { supplyCap: usdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: daiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcSupplyCap).to.be.equal(newCap); - expect(daiSupplyCap).to.be.equal(newCap); - }); - - it('Supply 100 DAI and 100 USDC, leaving 700 Units to reach the limit', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const suppliedAmount = '100'; - await pool.deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, suppliedAmount), - deployer.address, - 0 - ); - - await pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ); - }); - - it('Lowers the supply cap for USDC and DAI to 1200 Units (suppliedAmount > supplyCap)', async () => { - const { configurator, usdc, dai, helpersContract } = testEnv; - - const { supplyCap: oldUsdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: oldDaiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = '1200'; - expect(await configurator.setSupplyCap(usdc.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(usdc.address, oldUsdcSupplyCap, newCap); - expect(await configurator.setSupplyCap(dai.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(dai.address, oldDaiSupplyCap, newCap); - - const { supplyCap: usdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: daiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcSupplyCap).to.be.equal(newCap); - expect(daiSupplyCap).to.be.equal(newCap); - }); - - it('Tries to supply 100 DAI and 100 USDC (> SUPPLY_CAP) (revert expected)', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const suppliedAmount = '100'; - - await expect( - pool.deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, suppliedAmount), - deployer.address, - 0 - ) - ).to.be.revertedWith(SUPPLY_CAP_EXCEEDED); - - await expect( - pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ) - ).to.be.revertedWith(SUPPLY_CAP_EXCEEDED); - }); - - it('Raises the supply cap for USDC and DAI to MAX_SUPPLY_CAP', async () => { - const { configurator, usdc, dai, helpersContract } = testEnv; - - const { supplyCap: oldUsdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: oldDaiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - const newCap = MAX_SUPPLY_CAP; - expect(await configurator.setSupplyCap(usdc.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(usdc.address, oldUsdcSupplyCap, newCap); - expect(await configurator.setSupplyCap(dai.address, newCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(dai.address, oldDaiSupplyCap, newCap); - - const { supplyCap: usdcSupplyCap } = await helpersContract.getReserveCaps(usdc.address); - const { supplyCap: daiSupplyCap } = await helpersContract.getReserveCaps(dai.address); - - expect(usdcSupplyCap).to.be.equal(newCap); - expect(daiSupplyCap).to.be.equal(newCap); - }); - - it('Supply 100 DAI and 100 USDC', async () => { - const { usdc, pool, dai, deployer } = testEnv; - - const suppliedAmount = '100'; - await pool.deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, suppliedAmount), - deployer.address, - 0 - ); - - await pool.deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, suppliedAmount), - deployer.address, - 0 - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator.spec.ts deleted file mode 100644 index ea2ddae..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/configurator.spec.ts +++ /dev/null @@ -1,1078 +0,0 @@ -import { expect } from 'chai'; -import { utils, BigNumber, BigNumberish } from 'ethers'; -import { strategyWETH } from '@aave/deploy-v3/dist/markets/aave/reservesConfigs'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { MAX_UINT_AMOUNT, ONE_ADDRESS, RAY, ZERO_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors } from '../helpers/types'; -import { - AaveProtocolDataProvider, - AToken__factory, - MintableERC20__factory, - MockReserveInterestRateStrategy__factory, - StableDebtToken__factory, - VariableDebtToken__factory, -} from '../types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import { advanceTimeAndBlock, evmRevert, evmSnapshot } from '@aave/deploy-v3'; - -type ReserveConfigurationValues = { - reserveDecimals: string; - baseLTVAsCollateral: string; - liquidationThreshold: string; - liquidationBonus: string; - reserveFactor: string; - usageAsCollateralEnabled: boolean; - borrowingEnabled: boolean; - stableBorrowRateEnabled: boolean; - isActive: boolean; - isFrozen: boolean; - isPaused: boolean; - eModeCategory: BigNumber; - borrowCap: string; - supplyCap: string; -}; - -const expectReserveConfigurationData = async ( - helpersContract: AaveProtocolDataProvider, - asset: string, - values: ReserveConfigurationValues -) => { - const [reserveCfg, eModeCategory, reserveCaps, isPaused] = await getReserveData( - helpersContract, - asset - ); - expect(reserveCfg.decimals).to.be.eq(values.reserveDecimals, 'reserveDecimals is not correct'); - expect(reserveCfg.ltv).to.be.eq(values.baseLTVAsCollateral, 'ltv is not correct'); - expect(reserveCfg.liquidationThreshold).to.be.eq( - values.liquidationThreshold, - 'liquidationThreshold is not correct' - ); - expect(reserveCfg.liquidationBonus).to.be.eq( - values.liquidationBonus, - 'liquidationBonus is not correct' - ); - expect(reserveCfg.reserveFactor).to.be.eq(values.reserveFactor, 'reserveFactor is not correct'); - expect(reserveCfg.usageAsCollateralEnabled).to.be.eq( - values.usageAsCollateralEnabled, - 'usageAsCollateralEnabled is not correct' - ); - expect(reserveCfg.borrowingEnabled).to.be.eq( - values.borrowingEnabled, - 'borrowingEnabled is not correct' - ); - expect(reserveCfg.stableBorrowRateEnabled).to.be.eq( - values.stableBorrowRateEnabled, - 'stableBorrowRateEnabled is not correct' - ); - expect(reserveCfg.isActive).to.be.eq(values.isActive, 'isActive is not correct'); - expect(reserveCfg.isFrozen).to.be.eq(values.isFrozen, 'isFrozen is not correct'); - expect(isPaused).to.be.equal(values.isPaused, 'isPaused is not correct'); - expect(eModeCategory).to.be.eq(values.eModeCategory, 'eModeCategory is not correct'); - expect(reserveCaps.borrowCap).to.be.eq(values.borrowCap, 'borrowCap is not correct'); - expect(reserveCaps.supplyCap).to.be.eq(values.supplyCap, 'supplyCap is not correct'); -}; - -const getReserveData = async (helpersContract: AaveProtocolDataProvider, asset: string) => { - return Promise.all([ - helpersContract.getReserveConfigurationData(asset), - helpersContract.getReserveEModeCategory(asset), - helpersContract.getReserveCaps(asset), - helpersContract.getPaused(asset), - helpersContract.getLiquidationProtocolFee(asset), - helpersContract.getUnbackedMintCap(asset), - ]); -}; - -makeSuite('PoolConfigurator', (testEnv: TestEnv) => { - let baseConfigValues: ReserveConfigurationValues; - const { RESERVE_LIQUIDITY_NOT_ZERO, INVALID_DEBT_CEILING, RESERVE_DEBT_NOT_ZERO } = - ProtocolErrors; - - before(() => { - const { - reserveDecimals, - baseLTVAsCollateral, - liquidationThreshold, - liquidationBonus, - reserveFactor, - borrowingEnabled, - stableBorrowRateEnabled, - borrowCap, - supplyCap, - } = strategyWETH; - baseConfigValues = { - reserveDecimals, - baseLTVAsCollateral, - liquidationThreshold, - liquidationBonus, - reserveFactor, - usageAsCollateralEnabled: true, - borrowingEnabled, - stableBorrowRateEnabled, - isActive: true, - isFrozen: false, - isPaused: false, - eModeCategory: BigNumber.from(0), - borrowCap: borrowCap, - supplyCap: supplyCap, - }; - }); - - it('InitReserves via AssetListing admin', async () => { - const { addressesProvider, configurator, poolAdmin, aclManager, users, pool } = testEnv; - - // const snapId - const assetListingAdmin = users[4]; - // Add new AssetListingAdmin - expect( - await aclManager.connect(poolAdmin.signer).addAssetListingAdmin(assetListingAdmin.address) - ); - - // Deploy mock `InitReserveInput` - const mockToken = await new MintableERC20__factory(await getFirstSigner()).deploy( - 'MOCK', - 'MOCK', - '18' - ); - const stableDebtTokenImplementation = await new StableDebtToken__factory( - await getFirstSigner() - ).deploy(pool.address); - const variableDebtTokenImplementation = await new VariableDebtToken__factory( - await getFirstSigner() - ).deploy(pool.address); - const aTokenImplementation = await new AToken__factory(await getFirstSigner()).deploy( - pool.address - ); - const mockRateStrategy = await new MockReserveInterestRateStrategy__factory( - await getFirstSigner() - ).deploy(addressesProvider.address, 0, 0, 0, 0, 0, 0); - - // Init the reserve - const initInputParams: { - aTokenImpl: string; - stableDebtTokenImpl: string; - variableDebtTokenImpl: string; - underlyingAssetDecimals: BigNumberish; - interestRateStrategyAddress: string; - underlyingAsset: string; - treasury: string; - incentivesController: string; - aTokenName: string; - aTokenSymbol: string; - variableDebtTokenName: string; - variableDebtTokenSymbol: string; - stableDebtTokenName: string; - stableDebtTokenSymbol: string; - params: string; - }[] = [ - { - aTokenImpl: aTokenImplementation.address, - stableDebtTokenImpl: stableDebtTokenImplementation.address, - variableDebtTokenImpl: variableDebtTokenImplementation.address, - underlyingAssetDecimals: 18, - interestRateStrategyAddress: mockRateStrategy.address, - underlyingAsset: mockToken.address, - treasury: ZERO_ADDRESS, - incentivesController: ZERO_ADDRESS, - aTokenName: 'AMOCK', - aTokenSymbol: 'AMOCK', - variableDebtTokenName: 'VMOCK', - variableDebtTokenSymbol: 'VMOCK', - stableDebtTokenName: 'SMOCK', - stableDebtTokenSymbol: 'SMOCK', - params: '0x10', - }, - ]; - - expect(await configurator.connect(assetListingAdmin.signer).initReserves(initInputParams)); - }); - - it('Deactivates the ETH reserve', async () => { - const { configurator, weth, helpersContract } = testEnv; - expect(await configurator.setReserveActive(weth.address, false)); - const { isActive } = await helpersContract.getReserveConfigurationData(weth.address); - expect(isActive).to.be.equal(false); - }); - - it('Reactivates the ETH reserve', async () => { - const { configurator, weth, helpersContract } = testEnv; - expect(await configurator.setReserveActive(weth.address, true)); - const { isActive } = await helpersContract.getReserveConfigurationData(weth.address); - expect(isActive).to.be.equal(true); - }); - - it('Pauses the ETH reserve by pool admin', async () => { - const { configurator, weth, helpersContract } = testEnv; - expect(await configurator.setReservePause(weth.address, true)) - .to.emit(configurator, 'ReservePaused') - .withArgs(weth.address, true); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - isPaused: true, - }); - }); - - it('Unpauses the ETH reserve by pool admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - expect(await configurator.setReservePause(weth.address, false)) - .to.emit(configurator, 'ReservePaused') - .withArgs(weth.address, false); - - await expectReserveConfigurationData(helpersContract, weth.address, { ...baseConfigValues }); - }); - - it('Pauses the ETH reserve by emergency admin', async () => { - const { configurator, weth, helpersContract, emergencyAdmin } = testEnv; - expect(await configurator.connect(emergencyAdmin.signer).setReservePause(weth.address, true)) - .to.emit(configurator, 'ReservePaused') - .withArgs(weth.address, true); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - isPaused: true, - }); - }); - - it('Unpauses the ETH reserve by emergency admin', async () => { - const { configurator, helpersContract, weth, emergencyAdmin } = testEnv; - expect(await configurator.connect(emergencyAdmin.signer).setReservePause(weth.address, false)) - .to.emit(configurator, 'ReservePaused') - .withArgs(weth.address, false); - - await expectReserveConfigurationData(helpersContract, weth.address, { ...baseConfigValues }); - }); - - it('Freezes the ETH reserve by pool Admin', async () => { - const { configurator, weth, helpersContract } = testEnv; - - expect(await configurator.setReserveFreeze(weth.address, true)) - .to.emit(configurator, 'ReserveFrozen') - .withArgs(weth.address, true); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - isFrozen: true, - }); - }); - - it('Unfreezes the ETH reserve by Pool admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - expect(await configurator.setReserveFreeze(weth.address, false)) - .to.emit(configurator, 'ReserveFrozen') - .withArgs(weth.address, false); - - await expectReserveConfigurationData(helpersContract, weth.address, { ...baseConfigValues }); - }); - - it('Freezes the ETH reserve by Risk Admin', async () => { - const { configurator, weth, helpersContract, riskAdmin } = testEnv; - expect(await configurator.connect(riskAdmin.signer).setReserveFreeze(weth.address, true)) - .to.emit(configurator, 'ReserveFrozen') - .withArgs(weth.address, true); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - isFrozen: true, - }); - }); - - it('Unfreezes the ETH reserve by Risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - expect(await configurator.connect(riskAdmin.signer).setReserveFreeze(weth.address, false)) - .to.emit(configurator, 'ReserveFrozen') - .withArgs(weth.address, false); - - await expectReserveConfigurationData(helpersContract, weth.address, { ...baseConfigValues }); - }); - - it('Deactivates the ETH reserve for borrowing via pool admin while stable borrowing is active (revert expected)', async () => { - const { configurator, helpersContract, weth } = testEnv; - await expect(configurator.setReserveBorrowing(weth.address, false)).to.be.revertedWith( - ProtocolErrors.STABLE_BORROWING_ENABLED - ); - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - }); - }); - - it('Deactivates the ETH reserve for borrowing via risk admin while stable borrowing is active (revert expected)', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - - await expect( - configurator.connect(riskAdmin.signer).setReserveBorrowing(weth.address, false) - ).to.be.revertedWith(ProtocolErrors.STABLE_BORROWING_ENABLED); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - }); - }); - - it('Disable stable borrow rate on the ETH reserve via pool admin', async () => { - const snap = await evmSnapshot(); - const { configurator, helpersContract, weth } = testEnv; - expect(await configurator.setReserveStableRateBorrowing(weth.address, false)) - .to.emit(configurator, 'ReserveStableRateBorrowing') - .withArgs(weth.address, false); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - stableBorrowRateEnabled: false, - }); - await evmRevert(snap); - }); - - it('Disable stable borrow rate on the ETH reserve via risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - expect( - await configurator - .connect(riskAdmin.signer) - .setReserveStableRateBorrowing(weth.address, false) - ) - .to.emit(configurator, 'ReserveStableRateBorrowing') - .withArgs(weth.address, false); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - stableBorrowRateEnabled: false, - }); - }); - - it('Deactivates the ETH reserve for borrowing via pool admin', async () => { - const snap = await evmSnapshot(); - const { configurator, helpersContract, weth } = testEnv; - expect(await configurator.setReserveBorrowing(weth.address, false)) - .to.emit(configurator, 'ReserveBorrowing') - .withArgs(weth.address, false); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - borrowingEnabled: false, - stableBorrowRateEnabled: false, - }); - await evmRevert(snap); - }); - - it('Deactivates the ETH reserve for borrowing via risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - expect(await configurator.connect(riskAdmin.signer).setReserveBorrowing(weth.address, false)) - .to.emit(configurator, 'ReserveBorrowing') - .withArgs(weth.address, false); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - borrowingEnabled: false, - stableBorrowRateEnabled: false, - }); - }); - - it('Enables stable borrow rate on the ETH reserve via pool admin while borrowing is disabled (revert expected)', async () => { - const { configurator, helpersContract, weth } = testEnv; - await expect(configurator.setReserveStableRateBorrowing(weth.address, true)).to.be.revertedWith( - ProtocolErrors.BORROWING_NOT_ENABLED - ); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - borrowingEnabled: false, - stableBorrowRateEnabled: false, - }); - }); - - it('Enables stable borrow rate on the ETH reserve via risk admin while borrowing is disabled (revert expected)', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - await expect( - configurator.connect(riskAdmin.signer).setReserveStableRateBorrowing(weth.address, true) - ).to.be.revertedWith(ProtocolErrors.BORROWING_NOT_ENABLED); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - borrowingEnabled: false, - stableBorrowRateEnabled: false, - }); - }); - - it('Activates the ETH reserve for borrowing via pool admin', async () => { - const snap = await evmSnapshot(); - const { configurator, weth, helpersContract } = testEnv; - expect(await configurator.setReserveBorrowing(weth.address, true)) - .to.emit(configurator, 'ReserveBorrowing') - .withArgs(weth.address, true); - - const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - stableBorrowRateEnabled: false, - }); - expect(variableBorrowIndex.toString()).to.be.equal(RAY); - await evmRevert(snap); - }); - - it('Activates the ETH reserve for borrowing via risk admin', async () => { - const { configurator, weth, helpersContract, riskAdmin } = testEnv; - expect(await configurator.connect(riskAdmin.signer).setReserveBorrowing(weth.address, true)) - .to.emit(configurator, 'ReserveBorrowing') - .withArgs(weth.address, true); - - const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - stableBorrowRateEnabled: false, - }); - expect(variableBorrowIndex.toString()).to.be.equal(RAY); - }); - - it('Enables stable borrow rate on the ETH reserve via pool admin', async () => { - const snap = await evmSnapshot(); - const { configurator, helpersContract, weth } = testEnv; - expect(await configurator.setReserveStableRateBorrowing(weth.address, true)) - .to.emit(configurator, 'ReserveStableRateBorrowing') - .withArgs(weth.address, true); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - }); - await evmRevert(snap); - }); - - it('Enables stable borrow rate on the ETH reserve via risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - expect( - await configurator.connect(riskAdmin.signer).setReserveStableRateBorrowing(weth.address, true) - ) - .to.emit(configurator, 'ReserveStableRateBorrowing') - .withArgs(weth.address, true); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - }); - }); - - it('Deactivates the ETH reserve as collateral via pool admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - expect(await configurator.configureReserveAsCollateral(weth.address, 0, 0, 0)) - .to.emit(configurator, 'CollateralConfigurationChanged') - .withArgs(weth.address, 0, 0, 0); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - baseLTVAsCollateral: '0', - liquidationThreshold: '0', - liquidationBonus: '0', - usageAsCollateralEnabled: false, - }); - }); - - it('Activates the ETH reserve as collateral via pool admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - expect(await configurator.configureReserveAsCollateral(weth.address, '8000', '8250', '10500')) - .to.emit(configurator, 'CollateralConfigurationChanged') - .withArgs(weth.address, '8000', '8250', '10500'); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - baseLTVAsCollateral: '8000', - liquidationThreshold: '8250', - liquidationBonus: '10500', - }); - }); - - it('Deactivates the ETH reserve as collateral via risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - expect( - await configurator - .connect(riskAdmin.signer) - .configureReserveAsCollateral(weth.address, 0, 0, 0) - ) - .to.emit(configurator, 'CollateralConfigurationChanged') - .withArgs(weth.address, 0, 0, 0); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - baseLTVAsCollateral: '0', - liquidationThreshold: '0', - liquidationBonus: '0', - usageAsCollateralEnabled: false, - }); - }); - - it('Activates the ETH reserve as collateral via risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - expect( - await configurator - .connect(riskAdmin.signer) - .configureReserveAsCollateral(weth.address, '8000', '8250', '10500') - ) - .to.emit(configurator, 'CollateralConfigurationChanged') - .withArgs(weth.address, '8000', '8250', '10500'); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - baseLTVAsCollateral: '8000', - liquidationThreshold: '8250', - liquidationBonus: '10500', - }); - }); - - it('Changes the reserve factor of WETH via pool admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - - const { reserveFactor: oldReserveFactor } = await helpersContract.getReserveConfigurationData( - weth.address - ); - - const newReserveFactor = '1000'; - expect(await configurator.setReserveFactor(weth.address, newReserveFactor)) - .to.emit(configurator, 'ReserveFactorChanged') - .withArgs(weth.address, oldReserveFactor, newReserveFactor); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - reserveFactor: newReserveFactor, - }); - }); - - it('Changes the reserve factor of WETH via risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - - const { reserveFactor: oldReserveFactor } = await helpersContract.getReserveConfigurationData( - weth.address - ); - - const newReserveFactor = '1000'; - expect( - await configurator.connect(riskAdmin.signer).setReserveFactor(weth.address, newReserveFactor) - ) - .to.emit(configurator, 'ReserveFactorChanged') - .withArgs(weth.address, oldReserveFactor, newReserveFactor); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - reserveFactor: newReserveFactor, - }); - }); - - it('Updates the reserve factor of WETH equal to PERCENTAGE_FACTOR', async () => { - const snapId = await evmSnapshot(); - const { configurator, helpersContract, weth, poolAdmin } = testEnv; - - const { reserveFactor: oldReserveFactor } = await helpersContract.getReserveConfigurationData( - weth.address - ); - - const newReserveFactor = '10000'; - expect( - await configurator.connect(poolAdmin.signer).setReserveFactor(weth.address, newReserveFactor) - ) - .to.emit(configurator, 'ReserveFactorChanged') - .withArgs(weth.address, oldReserveFactor, newReserveFactor); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - reserveFactor: newReserveFactor, - }); - await evmRevert(snapId); - }); - - it('Updates the unbackedMintCap of WETH via pool admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - - const oldWethUnbackedMintCap = await helpersContract.getUnbackedMintCap(weth.address); - - const newUnbackedMintCap = '10000'; - expect(await configurator.setUnbackedMintCap(weth.address, newUnbackedMintCap)) - .to.emit(configurator, 'UnbackedMintCapChanged') - .withArgs(weth.address, oldWethUnbackedMintCap, newUnbackedMintCap); - - expect(await helpersContract.getUnbackedMintCap(weth.address)).to.be.eq(newUnbackedMintCap); - }); - - it('Updates the unbackedMintCap of WETH via risk admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - - const oldWethUnbackedMintCap = await helpersContract.getUnbackedMintCap(weth.address); - - const newUnbackedMintCap = '20000'; - expect(await configurator.setUnbackedMintCap(weth.address, newUnbackedMintCap)) - .to.emit(configurator, 'UnbackedMintCapChanged') - .withArgs(weth.address, oldWethUnbackedMintCap, newUnbackedMintCap); - - expect(await helpersContract.getUnbackedMintCap(weth.address)).to.be.eq(newUnbackedMintCap); - }); - - it('Updates the borrowCap of WETH via pool admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - - const { borrowCap: wethOldBorrowCap } = await helpersContract.getReserveCaps(weth.address); - - const newBorrowCap = '3000000'; - expect(await configurator.setBorrowCap(weth.address, newBorrowCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(weth.address, wethOldBorrowCap, newBorrowCap); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - borrowCap: newBorrowCap, - }); - }); - - it('Updates the borrowCap of WETH risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - - const { borrowCap: wethOldBorrowCap } = await helpersContract.getReserveCaps(weth.address); - - const newBorrowCap = '3000000'; - expect(await configurator.connect(riskAdmin.signer).setBorrowCap(weth.address, newBorrowCap)) - .to.emit(configurator, 'BorrowCapChanged') - .withArgs(weth.address, wethOldBorrowCap, newBorrowCap); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - borrowCap: newBorrowCap, - }); - }); - - it('Updates the supplyCap of WETH via pool admin', async () => { - const { configurator, helpersContract, weth } = testEnv; - - const { supplyCap: oldWethSupplyCap } = await helpersContract.getReserveCaps(weth.address); - - const newBorrowCap = '3000000'; - const newSupplyCap = '3000000'; - expect(await configurator.setSupplyCap(weth.address, newSupplyCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(weth.address, oldWethSupplyCap, newSupplyCap); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - borrowCap: newBorrowCap, - supplyCap: newSupplyCap, - }); - }); - - it('Updates the supplyCap of WETH via risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - - const { supplyCap: oldWethSupplyCap } = await helpersContract.getReserveCaps(weth.address); - - const newBorrowCap = '3000000'; - const newSupplyCap = '3000000'; - expect(await configurator.connect(riskAdmin.signer).setSupplyCap(weth.address, newSupplyCap)) - .to.emit(configurator, 'SupplyCapChanged') - .withArgs(weth.address, oldWethSupplyCap, newSupplyCap); - - await expectReserveConfigurationData(helpersContract, weth.address, { - ...baseConfigValues, - borrowCap: newBorrowCap, - supplyCap: newSupplyCap, - }); - }); - - it('Updates the ReserveInterestRateStrategy address of WETH via pool admin', async () => { - const { poolAdmin, pool, configurator, weth } = testEnv; - - const { interestRateStrategyAddress: interestRateStrategyAddressBefore } = - await pool.getReserveData(weth.address); - - expect( - await configurator - .connect(poolAdmin.signer) - .setReserveInterestRateStrategyAddress(weth.address, ZERO_ADDRESS) - ) - .to.emit(configurator, 'ReserveInterestRateStrategyChanged') - .withArgs(weth.address, interestRateStrategyAddressBefore, ZERO_ADDRESS); - const { interestRateStrategyAddress: interestRateStrategyAddressAfter } = - await pool.getReserveData(weth.address); - - expect(interestRateStrategyAddressBefore).to.not.be.eq(ZERO_ADDRESS); - expect(interestRateStrategyAddressAfter).to.be.eq(ZERO_ADDRESS); - - //reset interest rate strategy to the correct one - await configurator - .connect(poolAdmin.signer) - .setReserveInterestRateStrategyAddress(weth.address, interestRateStrategyAddressBefore); - }); - - it('Updates the ReserveInterestRateStrategy address of WETH via risk admin', async () => { - const { riskAdmin, pool, configurator, weth } = testEnv; - - const { interestRateStrategyAddress: interestRateStrategyAddressBefore } = - await pool.getReserveData(weth.address); - - expect( - await configurator - .connect(riskAdmin.signer) - .setReserveInterestRateStrategyAddress(weth.address, ONE_ADDRESS) - ) - .to.emit(configurator, 'ReserveInterestRateStrategyChanged') - .withArgs(weth.address, interestRateStrategyAddressBefore, ONE_ADDRESS); - const { interestRateStrategyAddress: interestRateStrategyAddressAfter } = - await pool.getReserveData(weth.address); - - expect(interestRateStrategyAddressBefore).to.not.be.eq(ONE_ADDRESS); - expect(interestRateStrategyAddressAfter).to.be.eq(ONE_ADDRESS); - - //reset interest rate strategy to the correct one - await configurator - .connect(riskAdmin.signer) - .setReserveInterestRateStrategyAddress(weth.address, interestRateStrategyAddressBefore); - }); - - it('Register a new risk Admin', async () => { - const { aclManager, poolAdmin, users, riskAdmin } = testEnv; - - const riskAdminRole = await aclManager.RISK_ADMIN_ROLE(); - - const newRiskAdmin = users[3].address; - expect(await aclManager.addRiskAdmin(newRiskAdmin)) - .to.emit(aclManager, 'RoleGranted') - .withArgs(riskAdminRole, newRiskAdmin, poolAdmin.address); - - expect(await aclManager.isRiskAdmin(riskAdmin.address)).to.be.true; - expect(await aclManager.isRiskAdmin(newRiskAdmin)).to.be.true; - }); - - it('Unregister the new risk admin', async () => { - const { aclManager, poolAdmin, users, riskAdmin } = testEnv; - - const riskAdminRole = await aclManager.RISK_ADMIN_ROLE(); - - const newRiskAdmin = users[3].address; - expect(await aclManager.removeRiskAdmin(newRiskAdmin)) - .to.emit(aclManager, 'RoleRevoked') - .withArgs(riskAdminRole, newRiskAdmin, poolAdmin.address); - - expect(await aclManager.isRiskAdmin(riskAdmin.address)).to.be.true; - expect(await aclManager.isRiskAdmin(newRiskAdmin)).to.be.false; - }); - - it('Authorized a new flash borrower', async () => { - const { aclManager, poolAdmin, users } = testEnv; - - const authorizedFlashBorrowerRole = await aclManager.FLASH_BORROWER_ROLE(); - - const authorizedFlashBorrower = users[4].address; - expect(await aclManager.addFlashBorrower(authorizedFlashBorrower)) - .to.emit(aclManager, 'RoleGranted') - .withArgs(authorizedFlashBorrowerRole, authorizedFlashBorrower, poolAdmin.address); - - expect(await aclManager.isFlashBorrower(authorizedFlashBorrower)).to.be.true; - }); - - it('Unauthorized flash borrower', async () => { - const { aclManager, poolAdmin, users } = testEnv; - - const authorizedFlashBorrowerRole = await aclManager.FLASH_BORROWER_ROLE(); - - const authorizedFlashBorrower = users[4].address; - expect(await aclManager.removeFlashBorrower(authorizedFlashBorrower)) - .to.emit(aclManager, 'RoleRevoked') - .withArgs(authorizedFlashBorrowerRole, authorizedFlashBorrower, poolAdmin.address); - - expect(await aclManager.isFlashBorrower(authorizedFlashBorrower)).to.be.false; - }); - - it('Updates bridge protocol fee equal to PERCENTAGE_FACTOR', async () => { - const { pool, configurator } = testEnv; - const newProtocolFee = 10000; - - const oldBridgeProtocolFee = await pool.BRIDGE_PROTOCOL_FEE(); - - expect(await configurator.updateBridgeProtocolFee(newProtocolFee)) - .to.emit(configurator, 'BridgeProtocolFeeUpdated') - .withArgs(oldBridgeProtocolFee, newProtocolFee); - - expect(await pool.BRIDGE_PROTOCOL_FEE()).to.be.eq(newProtocolFee); - }); - - it('Updates bridge protocol fee', async () => { - const { pool, configurator } = testEnv; - - const oldBridgeProtocolFee = await pool.BRIDGE_PROTOCOL_FEE(); - - const newProtocolFee = 2000; - - expect(await configurator.updateBridgeProtocolFee(newProtocolFee)) - .to.emit(configurator, 'BridgeProtocolFeeUpdated') - .withArgs(oldBridgeProtocolFee, newProtocolFee); - - expect(await pool.BRIDGE_PROTOCOL_FEE()).to.be.eq(newProtocolFee); - }); - - it('Updates flash loan premiums equal to PERCENTAGE_FACTOR: 10000 toProtocol, 10000 total', async () => { - const snapId = await evmSnapshot(); - - const { pool, configurator } = testEnv; - - const oldFlashloanPremiumTotal = await pool.FLASHLOAN_PREMIUM_TOTAL(); - const oldFlashloanPremiumToProtocol = await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL(); - - const newPremiumTotal = 10000; - const newPremiumToProtocol = 10000; - - expect(await configurator.updateFlashloanPremiumTotal(newPremiumTotal)) - .to.emit(configurator, 'FlashloanPremiumTotalUpdated') - .withArgs(oldFlashloanPremiumTotal, newPremiumTotal); - expect(await configurator.updateFlashloanPremiumToProtocol(newPremiumToProtocol)) - .to.emit(configurator, 'FlashloanPremiumToProtocolUpdated') - .withArgs(oldFlashloanPremiumToProtocol, newPremiumToProtocol); - - expect(await pool.FLASHLOAN_PREMIUM_TOTAL()).to.be.eq(newPremiumTotal); - expect(await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()).to.be.eq(newPremiumToProtocol); - - await evmRevert(snapId); - }); - - it('Updates flash loan premiums: 10 toProtocol, 40 total', async () => { - const { pool, configurator } = testEnv; - - const oldFlashloanPremiumTotal = await pool.FLASHLOAN_PREMIUM_TOTAL(); - const oldFlashloanPremiumToProtocol = await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL(); - - const newPremiumTotal = 40; - const newPremiumToProtocol = 10; - - expect(await configurator.updateFlashloanPremiumTotal(newPremiumTotal)) - .to.emit(configurator, 'FlashloanPremiumTotalUpdated') - .withArgs(oldFlashloanPremiumTotal, newPremiumTotal); - expect(await configurator.updateFlashloanPremiumToProtocol(newPremiumToProtocol)) - .to.emit(configurator, 'FlashloanPremiumToProtocolUpdated') - .withArgs(oldFlashloanPremiumToProtocol, newPremiumToProtocol); - - expect(await pool.FLASHLOAN_PREMIUM_TOTAL()).to.be.eq(newPremiumTotal); - expect(await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()).to.be.eq(newPremiumToProtocol); - }); - - it('Adds a new eMode category for stablecoins', async () => { - const { configurator, pool, poolAdmin } = testEnv; - - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory('1', '9800', '9800', '10100', ONE_ADDRESS, 'STABLECOINS') - ) - .to.emit(configurator, 'EModeCategoryAdded') - .withArgs(1, 9800, 9800, 10100, ONE_ADDRESS, 'STABLECOINS'); - - const categoryData = await pool.getEModeCategoryData(1); - expect(categoryData.ltv).to.be.equal(9800, 'invalid eMode category ltv'); - expect(categoryData.liquidationThreshold).to.be.equal( - 9800, - 'invalid eMode category liq threshold' - ); - expect(categoryData.liquidationBonus).to.be.equal(10100, 'invalid eMode category liq bonus'); - expect(categoryData.priceSource).to.be.equal( - ONE_ADDRESS, - 'invalid eMode category price source' - ); - }); - - it('Set a eMode category to an asset', async () => { - const { configurator, pool, helpersContract, poolAdmin, dai } = testEnv; - - const oldCategoryId = await helpersContract.getReserveEModeCategory(dai.address); - - const newCategoryId = 1; - - expect(await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, '1')) - .to.emit(configurator, 'EModeAssetCategoryChanged') - .withArgs(dai.address, oldCategoryId, newCategoryId); - - const categoryData = await pool.getEModeCategoryData(newCategoryId); - expect(categoryData.ltv).to.be.equal(9800, 'invalid eMode category ltv'); - expect(categoryData.liquidationThreshold).to.be.equal( - 9800, - 'invalid eMode category liq threshold' - ); - expect(categoryData.liquidationBonus).to.be.equal(10100, 'invalid eMode category liq bonus'); - expect(categoryData.priceSource).to.be.equal( - ONE_ADDRESS, - 'invalid eMode category price source' - ); - }); - - it('Sets siloed borrowing through the pool admin', async () => { - const { configurator, helpersContract, weth, poolAdmin } = testEnv; - - const oldSiloedBorrowing = await helpersContract.getSiloedBorrowing(weth.address); - - expect(await configurator.connect(poolAdmin.signer).setSiloedBorrowing(weth.address, true)) - .to.emit(configurator, 'SiloedBorrowingChanged') - .withArgs(weth.address, oldSiloedBorrowing, true); - - const newSiloedBorrowing = await helpersContract.getSiloedBorrowing(weth.address); - - expect(newSiloedBorrowing).to.be.eq(true, 'Invalid siloed borrowing state'); - }); - - it('Sets siloed borrowing through the risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - - const oldSiloedBorrowing = await helpersContract.getSiloedBorrowing(weth.address); - - expect(await configurator.connect(riskAdmin.signer).setSiloedBorrowing(weth.address, false)) - .to.emit(configurator, 'SiloedBorrowingChanged') - .withArgs(weth.address, oldSiloedBorrowing, false); - - const newSiloedBorrowing = await helpersContract.getSiloedBorrowing(weth.address); - - expect(newSiloedBorrowing).to.be.eq(false, 'Invalid siloed borrowing state'); - }); - - it('Resets the siloed borrowing mode. Tries to set siloed borrowing after the asset has been borrowed (revert expected)', async () => { - const snap = await evmSnapshot(); - - const { - configurator, - weth, - dai, - riskAdmin, - pool, - users: [user1, user2], - } = testEnv; - - await configurator.connect(riskAdmin.signer).setSiloedBorrowing(weth.address, false); - - const wethAmount = utils.parseEther('1'); - const daiAmount = utils.parseEther('1000'); - // user 1 supplies WETH - await weth.connect(user1.signer)['mint(uint256)'](wethAmount); - - await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool.connect(user1.signer).supply(weth.address, wethAmount, user1.address, '0'); - - // user 2 supplies DAI, borrows WETH - await dai.connect(user2.signer)['mint(uint256)'](daiAmount); - - await dai.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool.connect(user2.signer).supply(dai.address, daiAmount, user2.address, '0'); - - await pool.connect(user2.signer).borrow(weth.address, '100', 2, '0', user2.address); - - await expect(configurator.setSiloedBorrowing(weth.address, true)).to.be.revertedWith( - RESERVE_DEBT_NOT_ZERO - ); - - await evmRevert(snap); - }); - - it('Sets a debt ceiling through the pool admin', async () => { - const { configurator, helpersContract, weth, poolAdmin } = testEnv; - - const oldDebtCeiling = await helpersContract.getDebtCeiling(weth.address); - - const newDebtCeiling = '1'; - expect( - await configurator.connect(poolAdmin.signer).setDebtCeiling(weth.address, newDebtCeiling) - ) - .to.emit(configurator, 'DebtCeilingChanged') - .withArgs(weth.address, oldDebtCeiling, newDebtCeiling); - - const newCeiling = await helpersContract.getDebtCeiling(weth.address); - - expect(newCeiling).to.be.eq(newDebtCeiling, 'Invalid debt ceiling'); - }); - - it('Sets a debt ceiling through the risk admin', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - - const oldDebtCeiling = await helpersContract.getDebtCeiling(weth.address); - - const newDebtCeiling = '10'; - expect( - await configurator.connect(riskAdmin.signer).setDebtCeiling(weth.address, newDebtCeiling) - ) - .to.emit(configurator, 'DebtCeilingChanged') - .withArgs(weth.address, oldDebtCeiling, newDebtCeiling); - - const newCeiling = await helpersContract.getDebtCeiling(weth.address); - - expect(newCeiling).to.be.eq(newDebtCeiling, 'Invalid debt ceiling'); - }); - - it('Sets a debt ceiling larger than max (revert expected)', async () => { - const { configurator, helpersContract, weth, riskAdmin } = testEnv; - - const MAX_VALID_DEBT_CEILING = BigNumber.from('1099511627775'); - const debtCeiling = MAX_VALID_DEBT_CEILING.add(1); - - const currentCeiling = await helpersContract.getDebtCeiling(weth.address); - - await expect( - configurator.connect(riskAdmin.signer).setDebtCeiling(weth.address, debtCeiling) - ).to.be.revertedWith(INVALID_DEBT_CEILING); - - const newCeiling = await helpersContract.getDebtCeiling(weth.address); - expect(newCeiling).to.be.eq(currentCeiling, 'Invalid debt ceiling'); - }); - - it('Resets the WETH debt ceiling. Tries to set debt ceiling after liquidity has been provided (revert expected)', async () => { - const { - configurator, - weth, - riskAdmin, - pool, - users: [user1], - } = testEnv; - - await configurator.connect(riskAdmin.signer).setDebtCeiling(weth.address, '0'); - - // user 1 deposits - await weth.connect(user1.signer)['mint(uint256)']('100'); - - await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool.connect(user1.signer).supply(weth.address, '100', user1.address, '0'); - - await expect(configurator.setDebtCeiling(weth.address, '100')).to.be.revertedWith( - RESERVE_LIQUIDITY_NOT_ZERO - ); - }); - - it('Withdraws supplied liquidity, sets WETH debt ceiling', async () => { - const { - configurator, - helpersContract, - weth, - riskAdmin, - pool, - users: [user1], - } = testEnv; - - await pool.connect(user1.signer).withdraw(weth.address, MAX_UINT_AMOUNT, user1.address); - - await configurator.connect(riskAdmin.signer).setDebtCeiling(weth.address, '100'); - - const newCeiling = await helpersContract.getDebtCeiling(weth.address); - - expect(newCeiling).to.be.eq('100'); - }); - - it('Readds liquidity, increases WETH debt ceiling', async () => { - const { - configurator, - helpersContract, - weth, - riskAdmin, - pool, - users: [user1], - } = testEnv; - - await pool.connect(user1.signer).supply(weth.address, '100', user1.address, '0'); - - await configurator.connect(riskAdmin.signer).setDebtCeiling(weth.address, '200'); - - const newCeiling = await helpersContract.getDebtCeiling(weth.address); - - expect(newCeiling).to.be.eq('200'); - }); - - it('Read debt ceiling decimals', async () => { - const { helpersContract } = testEnv; - expect(await helpersContract.getDebtCeilingDecimals()).to.be.eq(2); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/debt-token-delegation-permit.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/debt-token-delegation-permit.spec.ts deleted file mode 100644 index 5961382..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/debt-token-delegation-permit.spec.ts +++ /dev/null @@ -1,424 +0,0 @@ -import { evmSnapshot, evmRevert } from '@aave/deploy-v3'; -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { HARDHAT_CHAINID, MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { - buildDelegationWithSigParams, - convertToCurrencyDecimals, - getSignatureFromTypedData, -} from '../helpers/contracts-helpers'; -import { timeLatest } from '../helpers/misc-utils'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { getTestWallets } from './helpers/utils/wallets'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { ProtocolErrors } from '../helpers/types'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('DebtToken: Permit Delegation', (testEnv: TestEnv) => { - let snapId; - - beforeEach(async () => { - snapId = await evmSnapshot(); - }); - afterEach(async () => { - await evmRevert(snapId); - }); - - let daiMintedAmount: BigNumber; - let wethMintedAmount: BigNumber; - let testWallets; - - const MINT_AMOUNT = '1000'; - const EIP712_REVISION = '1'; - - before(async () => { - const { - pool, - weth, - dai, - deployer: user1, - users: [user2], - } = testEnv; - testWallets = getTestWallets(); - - // Setup the pool - daiMintedAmount = await convertToCurrencyDecimals(dai.address, MINT_AMOUNT); - wethMintedAmount = await convertToCurrencyDecimals(weth.address, MINT_AMOUNT); - - expect(await dai['mint(uint256)'](daiMintedAmount)); - expect(await dai.approve(pool.address, daiMintedAmount)); - expect(await pool.deposit(dai.address, daiMintedAmount, user1.address, 0)); - expect(await weth.connect(user2.signer)['mint(uint256)'](wethMintedAmount)); - expect(await weth.connect(user2.signer).approve(pool.address, wethMintedAmount)); - expect( - await pool.connect(user2.signer).deposit(weth.address, wethMintedAmount, user2.address, 0) - ); - }); - - it('Checks the domain separator', async () => { - const { variableDebtDai, stableDebtDai } = testEnv; - const variableSeparator = await variableDebtDai.DOMAIN_SEPARATOR(); - const stableSeparator = await stableDebtDai.DOMAIN_SEPARATOR(); - - const variableDomain = { - name: await variableDebtDai.name(), - version: EIP712_REVISION, - chainId: hre.network.config.chainId, - verifyingContract: variableDebtDai.address, - }; - const stableDomain = { - name: await stableDebtDai.name(), - version: EIP712_REVISION, - chainId: hre.network.config.chainId, - verifyingContract: stableDebtDai.address, - }; - const variableDomainSeparator = utils._TypedDataEncoder.hashDomain(variableDomain); - const stableDomainSeparator = utils._TypedDataEncoder.hashDomain(stableDomain); - - expect(variableSeparator).to.be.equal( - variableDomainSeparator, - 'Invalid variable domain separator' - ); - expect(stableSeparator).to.be.equal(stableDomainSeparator, 'Invalid stable domain separator'); - }); - - it('User 3 borrows variable interest dai on behalf of user 2 via permit', async () => { - const { - pool, - variableDebtDai, - dai, - deployer: user1, - users: [user2, user3], - } = testEnv; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = MAX_UINT_AMOUNT; - const nonce = (await variableDebtDai.nonces(user2.address)).toNumber(); - const permitAmount = daiMintedAmount.div(3); - const msgParams = buildDelegationWithSigParams( - chainId, - variableDebtDai.address, - EIP712_REVISION, - await variableDebtDai.name(), - user3.address, - nonce, - expiration, - permitAmount.toString() - ); - - const user2PrivateKey = testWallets[1].secretKey; - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - - const { v, r, s } = getSignatureFromTypedData(user2PrivateKey, msgParams); - - expect( - await variableDebtDai - .connect(user1.signer) - .delegationWithSig(user2.address, user3.address, permitAmount, expiration, v, r, s) - ); - - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal(permitAmount); - - await pool.connect(user3.signer).borrow(dai.address, permitAmount, 2, 0, user2.address); - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - }); - - it('User 3 borrows stable interest dai on behalf of user 2 via permit', async () => { - const { - pool, - stableDebtDai, - dai, - deployer: user1, - users: [user2, user3], - } = testEnv; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = MAX_UINT_AMOUNT; - const nonce = (await stableDebtDai.nonces(user2.address)).toNumber(); - const permitAmount = daiMintedAmount.div(3); - const msgParams = buildDelegationWithSigParams( - chainId, - stableDebtDai.address, - EIP712_REVISION, - await stableDebtDai.name(), - user3.address, - nonce, - expiration, - permitAmount.toString() - ); - - const user2PrivateKey = testWallets[1].secretKey; - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - - const { v, r, s } = getSignatureFromTypedData(user2PrivateKey, msgParams); - - expect( - await stableDebtDai - .connect(user1.signer) - .delegationWithSig(user2.address, user3.address, permitAmount, expiration, v, r, s) - ); - - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal(permitAmount); - - await pool - .connect(user3.signer) - .borrow(dai.address, daiMintedAmount.div(10), 1, 0, user2.address); - - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal(permitAmount.sub(daiMintedAmount.div(10))); - }); - - it('Stable debt delegation with delegator == address(0)', async () => { - const { - stableDebtDai, - deployer: user1, - users: [user2, user3], - } = testEnv; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = MAX_UINT_AMOUNT; - const nonce = (await stableDebtDai.nonces(user2.address)).toNumber(); - const EIP712_REVISION = await stableDebtDai.EIP712_REVISION(); - const permitAmount = daiMintedAmount.div(3); - const msgParams = buildDelegationWithSigParams( - chainId, - stableDebtDai.address, - EIP712_REVISION, - await stableDebtDai.name(), - user3.address, - nonce, - expiration, - permitAmount.toString() - ); - - const user2PrivateKey = testWallets[1].secretKey; - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - - const { v, r, s } = getSignatureFromTypedData(user2PrivateKey, msgParams); - - await expect( - stableDebtDai - .connect(user1.signer) - .delegationWithSig(ZERO_ADDRESS, user3.address, permitAmount, expiration, v, r, s) - ).to.be.revertedWith(ProtocolErrors.ZERO_ADDRESS_NOT_VALID); - - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - }); - - it('Stable debt delegation with block.timestamp > deadline', async () => { - const { - stableDebtDai, - deployer: user1, - users: [user2, user3], - } = testEnv; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = (await timeLatest()).sub(500).toString(); - const nonce = (await stableDebtDai.nonces(user2.address)).toNumber(); - const permitAmount = daiMintedAmount.div(3); - const msgParams = buildDelegationWithSigParams( - chainId, - stableDebtDai.address, - EIP712_REVISION, - await stableDebtDai.name(), - user3.address, - nonce, - expiration, - permitAmount.toString() - ); - - const user2PrivateKey = testWallets[1].secretKey; - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - - const { v, r, s } = getSignatureFromTypedData(user2PrivateKey, msgParams); - - await expect( - stableDebtDai - .connect(user1.signer) - .delegationWithSig(user2.address, user3.address, permitAmount, expiration, v, r, s) - ).to.be.revertedWith(ProtocolErrors.INVALID_EXPIRATION); - - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - }); - - it('Stable debt delegation with wrong delegator', async () => { - const { - stableDebtDai, - deployer: user1, - users: [user2, user3], - } = testEnv; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = MAX_UINT_AMOUNT; - const nonce = (await stableDebtDai.nonces(user2.address)).toNumber(); - const EIP712_REVISION = await stableDebtDai.EIP712_REVISION(); - const permitAmount = daiMintedAmount.div(3); - const msgParams = buildDelegationWithSigParams( - chainId, - stableDebtDai.address, - EIP712_REVISION, - await stableDebtDai.name(), - user3.address, - nonce, - expiration, - permitAmount.toString() - ); - - const user2PrivateKey = testWallets[1].secretKey; - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - - const { v, r, s } = getSignatureFromTypedData(user2PrivateKey, msgParams); - - await expect( - stableDebtDai - .connect(user1.signer) - .delegationWithSig(user1.address, user3.address, permitAmount, expiration, v, r, s) - ).to.be.revertedWith(ProtocolErrors.INVALID_SIGNATURE); - - expect( - (await stableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - }); - - it('Variable debt delegation with delegator == address(0)', async () => { - const { - variableDebtDai, - deployer: user1, - users: [user2, user3], - } = testEnv; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = MAX_UINT_AMOUNT; - const nonce = (await variableDebtDai.nonces(user2.address)).toNumber(); - const permitAmount = daiMintedAmount.div(3); - const msgParams = buildDelegationWithSigParams( - chainId, - variableDebtDai.address, - EIP712_REVISION, - await variableDebtDai.name(), - user3.address, - nonce, - expiration, - permitAmount.toString() - ); - - const user2PrivateKey = testWallets[1].secretKey; - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - - const { v, r, s } = getSignatureFromTypedData(user2PrivateKey, msgParams); - - await expect( - variableDebtDai - .connect(user1.signer) - .delegationWithSig(ZERO_ADDRESS, user3.address, permitAmount, expiration, v, r, s) - ).to.be.revertedWith(ProtocolErrors.ZERO_ADDRESS_NOT_VALID); - - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - }); - - it('Variable debt delegation with block.timestamp > deadline', async () => { - const { - variableDebtDai, - deployer: user1, - users: [user2, user3], - } = testEnv; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = (await timeLatest()).sub(500).toString(); - const nonce = (await variableDebtDai.nonces(user2.address)).toNumber(); - const permitAmount = daiMintedAmount.div(3); - const msgParams = buildDelegationWithSigParams( - chainId, - variableDebtDai.address, - EIP712_REVISION, - await variableDebtDai.name(), - user3.address, - nonce, - expiration, - permitAmount.toString() - ); - - const user2PrivateKey = testWallets[1].secretKey; - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - - const { v, r, s } = getSignatureFromTypedData(user2PrivateKey, msgParams); - - await expect( - variableDebtDai - .connect(user1.signer) - .delegationWithSig(user2.address, user3.address, permitAmount, expiration, v, r, s) - ).to.be.revertedWith(ProtocolErrors.INVALID_EXPIRATION); - - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - }); - - it('Variable debt delegation with wrong delegator', async () => { - const { - variableDebtDai, - deployer: user1, - users: [user2, user3], - } = testEnv; - - const chainId = hre.network.config.chainId || HARDHAT_CHAINID; - const expiration = MAX_UINT_AMOUNT; - const nonce = (await variableDebtDai.nonces(user2.address)).toNumber(); - const permitAmount = daiMintedAmount.div(3); - const msgParams = buildDelegationWithSigParams( - chainId, - variableDebtDai.address, - EIP712_REVISION, - await variableDebtDai.name(), - user3.address, - nonce, - expiration, - permitAmount.toString() - ); - - const user2PrivateKey = testWallets[1].secretKey; - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - - const { v, r, s } = getSignatureFromTypedData(user2PrivateKey, msgParams); - - await expect( - variableDebtDai - .connect(user1.signer) - .delegationWithSig(user1.address, user3.address, permitAmount, expiration, v, r, s) - ).to.be.revertedWith(ProtocolErrors.INVALID_SIGNATURE); - - expect( - (await variableDebtDai.borrowAllowance(user2.address, user3.address)).toString() - ).to.be.equal('0'); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/emode.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/emode.spec.ts deleted file mode 100644 index 542b4e7..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/emode.spec.ts +++ /dev/null @@ -1,863 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; -import { parseUnits, formatUnits, parseEther } from '@ethersproject/units'; -import { evmSnapshot, evmRevert, VariableDebtToken__factory } from '@aave/deploy-v3'; - -makeSuite('EfficiencyMode', (testEnv: TestEnv) => { - const { - INCONSISTENT_EMODE_CATEGORY, - HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD, - COLLATERAL_CANNOT_COVER_NEW_BORROW, - INVALID_EMODE_CATEGORY_PARAMS, - } = ProtocolErrors; - - let snapSetup: string; - - const CATEGORIES = { - STABLECOINS: { - id: BigNumber.from('1'), - ltv: BigNumber.from('9800'), - lt: BigNumber.from('9800'), - lb: BigNumber.from('10100'), - oracle: ZERO_ADDRESS, - label: 'STABLECOINS', - }, - ETHEREUM: { - id: BigNumber.from('2'), - ltv: BigNumber.from('9800'), - lt: BigNumber.from('9800'), - lb: BigNumber.from('10100'), - oracle: ZERO_ADDRESS, - label: 'ETHEREUM', - }, - }; - - before(async () => { - const { - pool, - dai, - usdc, - weth, - users: [user0, user1, user2], - aaveOracle, - } = testEnv; - const mintAmount = utils.parseEther('10000'); - - await dai.connect(user0.signer)['mint(uint256)'](mintAmount); - await usdc.connect(user0.signer)['mint(uint256)'](mintAmount); - await weth.connect(user0.signer)['mint(uint256)'](mintAmount); - await usdc.connect(user1.signer)['mint(uint256)'](mintAmount); - await weth.connect(user1.signer)['mint(uint256)'](mintAmount); - await dai.connect(user2.signer)['mint(uint256)'](mintAmount); - - await dai.connect(user0.signer).approve(pool.address, MAX_UINT_AMOUNT); - await usdc.connect(user0.signer).approve(pool.address, MAX_UINT_AMOUNT); - await weth.connect(user0.signer).approve(pool.address, MAX_UINT_AMOUNT); - await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await usdc.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await dai.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT); - - snapSetup = await evmSnapshot(); - }); - - it('Admin adds a category for stablecoins with DAI and USDC', async () => { - const { configurator, helpersContract, dai, usdc, poolAdmin } = testEnv; - - const { id, ltv, lt, lb, oracle, label } = CATEGORIES.STABLECOINS; - - expect( - await configurator.connect(poolAdmin.signer).setEModeCategory(id, ltv, lt, lb, oracle, label) - ); - expect(await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, id)); - expect(await configurator.connect(poolAdmin.signer).setAssetEModeCategory(usdc.address, id)); - - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.be.eq(id); - expect(await helpersContract.getReserveEModeCategory(usdc.address)).to.be.eq(id); - }); - - it('Admin adds a category for ethereum with WETH', async () => { - const { configurator, helpersContract, weth, poolAdmin } = testEnv; - - const { id, ltv, lt, lb, oracle, label } = CATEGORIES.ETHEREUM; - - expect( - await configurator.connect(poolAdmin.signer).setEModeCategory(id, ltv, lt, lb, oracle, label) - ); - expect(await configurator.connect(poolAdmin.signer).setAssetEModeCategory(weth.address, id)); - - expect(await helpersContract.getReserveEModeCategory(weth.address)).to.be.eq(id); - }); - - it('User 0 activates eMode for stablecoins category', async () => { - const { - pool, - users: [user0], - } = testEnv; - - expect(await pool.connect(user0.signer).setUserEMode(CATEGORIES.STABLECOINS.id)) - .to.emit(pool, 'UserEModeSet') - .withArgs(user0.address, CATEGORIES.STABLECOINS.id); - - expect(await pool.getUserEMode(user0.address)).to.be.eq(CATEGORIES.STABLECOINS.id); - }); - - it('User 0 supplies 100 DAI, user 1 supplies 100 USDC', async () => { - const { - pool, - dai, - usdc, - helpersContract, - users: [user0, user1], - } = testEnv; - - expect( - await pool - .connect(user0.signer) - .supply(dai.address, await convertToCurrencyDecimals(dai.address, '100'), user0.address, 0) - ); - const { usageAsCollateralEnabled: user0UseAsCollateral } = - await helpersContract.getUserReserveData(dai.address, user0.address); - expect(user0UseAsCollateral).to.be.true; - - expect( - await pool - .connect(user1.signer) - .supply( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '100'), - user1.address, - 0 - ) - ); - const { usageAsCollateralEnabled: user1UseAsCollateral } = - await helpersContract.getUserReserveData(usdc.address, user1.address); - expect(user1UseAsCollateral).to.be.true; - }); - - it('User 0 borrows 98 USDC and tries to deactivate eMode (revert expected)', async () => { - const { - pool, - usdc, - users: [user0], - } = testEnv; - expect( - await pool - .connect(user0.signer) - .borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '98'), - RateMode.Variable, - 0, - user0.address - ) - ); - - const userCategory = await pool.getUserEMode(user0.address); - await expect(pool.connect(user0.signer).setUserEMode(0)).to.be.revertedWith( - HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD - ); - expect(await pool.getUserEMode(user0.address)).to.be.eq(userCategory); - }); - - it('User 0 tries to sends aTokens to user 3 (revert expected)', async () => { - const { - pool, - dai, - aDai, - users: [user0, , , user3], - } = testEnv; - - expect(await pool.getUserEMode(user0.address)).to.be.eq(CATEGORIES.STABLECOINS.id); - expect(await pool.getUserEMode(user3.address)).to.be.eq(0); - - await expect( - aDai - .connect(user0.signer) - .transfer(user3.address, await convertToCurrencyDecimals(dai.address, '10')) - ).to.be.revertedWith(HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD); - - expect(await pool.getUserEMode(user0.address)).to.be.eq(CATEGORIES.STABLECOINS.id); - expect(await pool.getUserEMode(user3.address)).to.be.eq(0); - }); - - it('User 0 repays 50 USDC and withdraws 10 DAI', async () => { - const { - pool, - dai, - usdc, - users: [user0], - } = testEnv; - expect( - await pool - .connect(user0.signer) - .repay( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '50'), - RateMode.Variable, - user0.address - ) - ) - .to.emit(pool, 'Repay') - .withArgs( - usdc.address, - user0.address, - user0.address, - await convertToCurrencyDecimals(usdc.address, '50'), - false - ); - expect( - await pool - .connect(user0.signer) - .withdraw(dai.address, await convertToCurrencyDecimals(dai.address, '10'), user0.address) - ); - }); - - it('User 0 supplies WETH (non-category asset), increasing borrowing power', async () => { - const { - pool, - helpersContract, - weth, - users: [user0], - } = testEnv; - const userDataBefore = await pool.getUserAccountData(user0.address); - - expect( - await pool - .connect(user0.signer) - .supply(weth.address, await convertToCurrencyDecimals(weth.address, '1'), user0.address, 0) - ); - const { usageAsCollateralEnabled } = await helpersContract.getUserReserveData( - weth.address, - user0.address - ); - expect(usageAsCollateralEnabled).to.be.true; - - const userDataAfter = await pool.getUserAccountData(user0.address); - expect(userDataBefore.availableBorrowsBase).to.be.lt(userDataAfter.availableBorrowsBase); - expect(userDataBefore.totalCollateralBase).to.be.lt(userDataAfter.totalCollateralBase); - expect(userDataBefore.totalDebtBase).to.be.eq(userDataAfter.totalDebtBase); - expect(userDataBefore.healthFactor).to.be.lt(userDataAfter.healthFactor); - }); - - it('User 1 supplies 1 WETH and activates eMode for ethereum category', async () => { - const { - pool, - helpersContract, - weth, - users: [, user1], - oracle, - } = testEnv; - const wethPrice = await oracle.getAssetPrice(weth.address); - - const userDataBeforeSupply = await pool.getUserAccountData(user1.address); - - // Supply 1 WETH, increasing totalCollateralBase - const wethToSupply = await convertToCurrencyDecimals(weth.address, '1'); - expect(await pool.connect(user1.signer).supply(weth.address, wethToSupply, user1.address, 0)); - const { usageAsCollateralEnabled } = await helpersContract.getUserReserveData( - weth.address, - user1.address - ); - expect(usageAsCollateralEnabled).to.be.true; - const userDataBeforeEMode = await pool.getUserAccountData(user1.address); - expect(userDataBeforeSupply.totalCollateralBase).to.be.eq( - userDataBeforeEMode.totalCollateralBase.sub(wethToSupply.wadMul(wethPrice)) - ); - - // Activate EMode, increasing availableBorrowsBase - expect(await pool.connect(user1.signer).setUserEMode(CATEGORIES.ETHEREUM.id)) - .to.emit(pool, 'UserEModeSet') - .withArgs(user1.address, CATEGORIES.ETHEREUM.id); - expect(await pool.getUserEMode(user1.address)).to.be.eq(CATEGORIES.ETHEREUM.id); - - const userDataAfterEMode = await pool.getUserAccountData(user1.address); - expect(userDataBeforeEMode.totalCollateralBase).to.be.eq( - userDataAfterEMode.totalCollateralBase - ); - expect(userDataBeforeEMode.availableBorrowsBase).to.be.lt( - userDataAfterEMode.availableBorrowsBase - ); - }); - - it('User 0 tries to activate eMode for ethereum category (revert expected)', async () => { - const { - pool, - users: [user0], - } = testEnv; - - const userCategory = await pool.getUserEMode(user0.address); - await expect( - pool.connect(user0.signer).setUserEMode(CATEGORIES.ETHEREUM.id) - ).to.be.revertedWith(INCONSISTENT_EMODE_CATEGORY); - expect(await pool.getUserEMode(user0.address)).to.be.eq(userCategory); - }); - - it('User 0 tries to borrow (non-category asset) WETH (revert expected)', async () => { - const { - pool, - weth, - users: [user0], - } = testEnv; - - await expect( - pool - .connect(user0.signer) - .borrow( - weth.address, - await convertToCurrencyDecimals(weth.address, '0.0001'), - RateMode.Variable, - 0, - user0.address - ) - ).to.be.revertedWith(INCONSISTENT_EMODE_CATEGORY); - }); - - it('User 1 tries to borrow (non-category asset) DAI (revert expected)', async () => { - const { - pool, - dai, - users: [, user1], - } = testEnv; - - await expect( - pool - .connect(user1.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '10'), - RateMode.Variable, - 0, - user1.address - ) - ).to.be.revertedWith(INCONSISTENT_EMODE_CATEGORY); - }); - - it('User 0 repays USDC debt and activates eMode for ethereum category', async () => { - const { - pool, - usdc, - users: [user0], - } = testEnv; - - expect( - await pool - .connect(user0.signer) - .repay(usdc.address, MAX_UINT_AMOUNT, RateMode.Variable, user0.address) - ); - - expect(await pool.connect(user0.signer).setUserEMode(CATEGORIES.ETHEREUM.id)); - expect(await pool.getUserEMode(user0.address)).to.be.eq(CATEGORIES.ETHEREUM.id); - }); - - it('User 1 activates eMode for stablecoins category', async () => { - const { - pool, - users: [, user1], - } = testEnv; - - expect(await pool.connect(user1.signer).setUserEMode(CATEGORIES.STABLECOINS.id)); - expect(await pool.getUserEMode(user1.address)).to.be.eq(CATEGORIES.STABLECOINS.id); - }); - - it('User 0 tries to borrow (non-category asset) USDC (revert expected)', async () => { - const { - pool, - usdc, - users: [user0], - } = testEnv; - - await expect( - pool - .connect(user0.signer) - .borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '5'), - RateMode.Stable, - 0, - user0.address - ) - ).to.be.revertedWith(INCONSISTENT_EMODE_CATEGORY); - }); - - it('User 0 sends aTokens to user 3', async () => { - const { - pool, - dai, - aDai, - users: [user0, , , user3], - } = testEnv; - - expect(await pool.getUserEMode(user0.address)).to.be.eq(CATEGORIES.ETHEREUM.id); - expect(await pool.getUserEMode(user3.address)).to.be.eq(0); - - const transferAmount = await convertToCurrencyDecimals(dai.address, '10'); - - const balanceBeforeUser0 = await aDai.balanceOf(user0.address); - const balanceBeforeUser3 = await aDai.balanceOf(user3.address); - - expect(await aDai.connect(user0.signer).transfer(user3.address, transferAmount)); - - expect(await pool.getUserEMode(user0.address)).to.be.eq(CATEGORIES.ETHEREUM.id); - expect(await pool.getUserEMode(user3.address)).to.be.eq(0); - - expect(await aDai.balanceOf(user0.address)).to.be.eq(balanceBeforeUser0.sub(transferAmount)); - expect(await aDai.balanceOf(user3.address)).to.be.eq(balanceBeforeUser3.add(transferAmount)); - }); - - it('User 0 sends aTokens to user 3', async () => { - const { - pool, - dai, - aDai, - users: [user0, , , user3], - } = testEnv; - - expect(await pool.getUserEMode(user0.address)).to.be.eq(CATEGORIES.ETHEREUM.id); - expect(await pool.getUserEMode(user3.address)).to.be.eq(0); - - const balanceBeforeUser0 = await aDai.balanceOf(user0.address); - const balanceBeforeUser3 = await aDai.balanceOf(user3.address); - - const transferAmount = await convertToCurrencyDecimals(dai.address, '10'); - expect(await aDai.connect(user0.signer).transfer(user3.address, transferAmount)); - - expect(await pool.getUserEMode(user0.address)).to.be.eq(CATEGORIES.ETHEREUM.id); - expect(await pool.getUserEMode(user3.address)).to.be.eq(0); - - expect(await aDai.balanceOf(user0.address)).to.be.eq(balanceBeforeUser0.sub(transferAmount)); - expect(await aDai.balanceOf(user3.address)).to.be.eq(balanceBeforeUser3.add(transferAmount)); - }); - - it('Credit delegation from EMode user, delegatee borrows non EMode asset (revert expected)', async () => { - const snap = await evmSnapshot(); - const { - pool, - helpersContract, - dai, - weth, - usdc, - users: [, , , user3, user4, user5], - } = testEnv; - const { id } = CATEGORIES.STABLECOINS; - - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.be.eq(id); - expect(await helpersContract.getReserveEModeCategory(usdc.address)).to.be.eq(id); - expect(await helpersContract.getReserveEModeCategory(weth.address)).to.not.be.eq(id); - - const wethData = await pool.getReserveData(weth.address); - const variableDebtWETH = VariableDebtToken__factory.connect( - wethData.variableDebtTokenAddress, - user4.signer - ); - - expect(await weth.connect(user3.signer)['mint(uint256)'](parseUnits('100', 18))); - expect(await weth.connect(user3.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect( - await pool.connect(user3.signer).supply(weth.address, parseUnits('100', 18), user3.address, 0) - ); - - expect(await dai.connect(user4.signer)['mint(uint256)'](parseUnits('100', 18))); - expect(await dai.connect(user4.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - // Alice deposit 100 dai - expect( - await pool.connect(user4.signer).supply(dai.address, parseUnits('100', 18), user4.address, 0) - ); - - // Alice set eMode to stablecoins - expect(await pool.connect(user4.signer).setUserEMode(CATEGORIES.STABLECOINS.id)); - expect(await pool.getUserEMode(user4.address)).to.be.eq(CATEGORIES.STABLECOINS.id); - - // Alice delegates 1 weth with variable rate to Bob. - expect( - await variableDebtWETH - .connect(user4.signer) - .approveDelegation(user5.address, parseUnits('1', 18)) - ); - - const bobWethBalanceBefore = await weth.balanceOf(user5.address); - - // Bob borrows 0.01 weth on behalf of Alice (should revert) - await expect( - pool.connect(user5.signer).borrow(weth.address, parseUnits('0.01', 18), 2, 0, user4.address) - ).to.be.revertedWith(INCONSISTENT_EMODE_CATEGORY); - - expect(await weth.balanceOf(user5.address)).to.be.eq( - bobWethBalanceBefore, - 'Bob forced Alice to borrow WETH while in stablecoin emode' - ); - await evmRevert(snap); - }); - - it('Credit delegation to EMode user, user tries do abuse EMode to liquidate delegator (revert expected)', async () => { - const { - pool, - helpersContract, - dai, - usdc, - users: [, , , user3, user4, user5], - } = testEnv; - const { id } = CATEGORIES.STABLECOINS; - - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.be.eq(id); - expect(await helpersContract.getReserveEModeCategory(usdc.address)).to.be.eq(id); - - const usdcData = await pool.getReserveData(usdc.address); - const variableDebtUSDC = VariableDebtToken__factory.connect( - usdcData.variableDebtTokenAddress, - user4.signer - ); - - expect(await usdc.connect(user3.signer)['mint(uint256)'](parseUnits('100', 6))); - expect(await usdc.connect(user3.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect( - await pool.connect(user3.signer).supply(usdc.address, parseUnits('100', 6), user3.address, 0) - ); - - expect(await dai.connect(user4.signer)['mint(uint256)'](parseUnits('100', 18))); - expect(await dai.connect(user4.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - // Alice deposit 100 dai - expect( - await pool.connect(user4.signer).supply(dai.address, parseUnits('100', 18), user4.address, 0) - ); - - // Alice delegates 100 usdc with variable rate to Bob. - expect( - await variableDebtUSDC - .connect(user4.signer) - .approveDelegation(user5.address, parseUnits('100', 6)) - ); - - // Bob set eMode to stablecoins - expect(await pool.connect(user5.signer).setUserEMode(CATEGORIES.STABLECOINS.id)); - expect(await pool.getUserEMode(user5.address)).to.be.eq(CATEGORIES.STABLECOINS.id); - - // Bob borrows 90 usdc on behalf of Alice - await expect( - pool.connect(user5.signer).borrow(usdc.address, parseUnits('90', 6), 2, 0, user4.address) - ).to.be.revertedWith(COLLATERAL_CANNOT_COVER_NEW_BORROW); - - // Alice is still in a position where she CANNOT be liquidated - const user4Data = await pool.getUserAccountData(user4.address); - expect(user4Data.healthFactor).to.be.gt(parseEther('1')); - }); - - it('Admin sets LTV of stablecoins eMode category to zero (revert expected)', async () => { - const { - configurator, - pool, - users: [, user1], - } = testEnv; - - const { id } = CATEGORIES.STABLECOINS; - - const eModeData = await pool.getEModeCategoryData(id); - const newLtv = BigNumber.from(0); - - await expect( - configurator.setEModeCategory( - id, - newLtv, - eModeData.liquidationThreshold, - eModeData.liquidationBonus, - eModeData.priceSource, - eModeData.label - ) - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_PARAMS); - }); - - it('Admin sets Liquidation Threshold of stablecoins eMode category to zero (revert expected)', async () => { - const { configurator, pool } = testEnv; - - const { id } = CATEGORIES.STABLECOINS; - - const eModeData = await pool.getEModeCategoryData(id); - const newLiquidationThreshold = BigNumber.from(0); - - await expect( - configurator.setEModeCategory( - id, - eModeData.ltv, - newLiquidationThreshold, - eModeData.liquidationBonus, - eModeData.priceSource, - eModeData.label - ) - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_PARAMS); - }); - - it('Admin lowers LTV of stablecoins eMode category below an asset within the eModes individual LTV (revert expected)', async () => { - const { configurator, pool, dai, usdc, helpersContract } = testEnv; - - const { id } = CATEGORIES.STABLECOINS; - - const eModeData = await pool.getEModeCategoryData(id); - - // find the min LTV of assets in eMode and submit a new LTV lower - const daiLtv = (await helpersContract.getReserveConfigurationData(dai.address)).ltv; - const usdcLtv = (await helpersContract.getReserveConfigurationData(usdc.address)).ltv; - const maxExistingLtv = daiLtv.sub(usdcLtv).gte(0) ? daiLtv : usdcLtv; - const newLtv = maxExistingLtv.sub(1); - - await expect( - configurator.setEModeCategory( - id, - newLtv, - eModeData.liquidationThreshold, - eModeData.liquidationBonus, - eModeData.priceSource, - eModeData.label - ) - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_PARAMS); - }); - - it('Admin lowers LTV of stablecoins eMode category, decreasing user borrowing power', async () => { - const { - configurator, - pool, - users: [, user1], - } = testEnv; - - const { id } = CATEGORIES.STABLECOINS; - - const userDataBefore = await pool.getUserAccountData(user1.address); - - const eModeData = await pool.getEModeCategoryData(id); - const newLtv = BigNumber.from('9500'); - - expect( - await configurator.setEModeCategory( - id, - newLtv, - eModeData.liquidationThreshold, - eModeData.liquidationBonus, - eModeData.priceSource, - eModeData.label - ) - ); - - const userDataAfter = await pool.getUserAccountData(user1.address); - - expect(userDataAfter.availableBorrowsBase).to.be.lt(userDataBefore.availableBorrowsBase); - }); - - it('User 1 withdraws 0.7 WETH and borrows 100 USDC', async () => { - const { - pool, - weth, - usdc, - users: [, user1], - } = testEnv; - - expect( - await pool - .connect(user1.signer) - .withdraw(weth.address, await convertToCurrencyDecimals(weth.address, '0.7'), user1.address) - ); - - expect( - await pool - .connect(user1.signer) - .borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '100'), - RateMode.Variable, - 0, - user1.address - ) - ); - }); - - it('Admin lowers LT of stablecoins eMode category below an asset within the eModes individual LT (revert expected)', async () => { - const { configurator, pool } = testEnv; - - const { id } = CATEGORIES.STABLECOINS; - - const eModeData = await pool.getEModeCategoryData(id); - - const newLtv = BigNumber.from(8300); - const newLt = BigNumber.from(8500); - - await expect( - configurator.setEModeCategory( - id, - newLtv, - newLt, - eModeData.liquidationBonus, - eModeData.priceSource, - eModeData.label - ) - ).to.be.revertedWith(INVALID_EMODE_CATEGORY_PARAMS); - }); - - it('Admin lowers LT of stablecoins eMode category, decreasing user health factor', async () => { - const { - configurator, - pool, - users: [, user1], - } = testEnv; - - const { id } = CATEGORIES.STABLECOINS; - - const userDataBefore = await pool.getUserAccountData(user1.address); - - const eModeData = await pool.getEModeCategoryData(id); - const newLt = eModeData.ltv; - - expect( - await configurator.setEModeCategory( - id, - eModeData.ltv, - newLt, - eModeData.liquidationBonus, - eModeData.priceSource, - eModeData.label - ) - ); - - const userDataAfter = await pool.getUserAccountData(user1.address); - expect(userDataAfter.healthFactor).to.be.lt(userDataBefore.healthFactor); - }); - - it('Admin adds a category for stablecoins with DAI (own price feed)', async () => { - const { configurator, pool, poolAdmin, dai, usdc } = testEnv; - const { ltv, lt, lb, label } = CATEGORIES.STABLECOINS; - - const id = 3; - const categoryOracle = usdc.address; - - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory(id, ltv, lt, lb, categoryOracle, label) - ) - .to.emit(configurator, 'EModeCategoryAdded') - .withArgs(id, ltv, lt, lb, categoryOracle, label); - - const categoryData = await pool.getEModeCategoryData(id); - expect(categoryData.ltv).to.be.equal(ltv, 'invalid eMode category ltv'); - expect(categoryData.liquidationThreshold).to.be.equal( - lt, - 'invalid eMode category liq threshold' - ); - expect(categoryData.liquidationBonus).to.be.equal(lb, 'invalid eMode category liq bonus'); - expect(categoryData.priceSource).to.be.equal( - categoryOracle, - 'invalid eMode category price source' - ); - expect(await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, id)); - }); - - it('User 2 supplies DAI and activates eMode for stablecoins (own price feed)', async () => { - const { - pool, - dai, - usdc, - oracle, - users: [, , user2], - } = testEnv; - - const id = 3; - const daiAmount = utils.parseUnits('1000', 18); - - expect(await pool.connect(user2.signer).supply(dai.address, daiAmount, user2.address, 0)); - - const daiPrice = await oracle.getAssetPrice(dai.address); - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - const dataBefore = await pool.getUserAccountData(user2.address); - const expectedCollateralDaiPrice = daiAmount.wadMul(daiPrice); - expect(dataBefore.totalCollateralBase).to.be.eq(expectedCollateralDaiPrice); - - expect(await pool.connect(user2.signer).setUserEMode(id)); - expect(await pool.getUserEMode(user2.address)).to.be.eq(id); - - const dataAfter = await pool.getUserAccountData(user2.address); - const expectedCollateralUsdcPrice = daiAmount.wadMul(usdcPrice); - expect(dataAfter.totalCollateralBase).to.be.eq(expectedCollateralUsdcPrice); - }); - - it('User 0 deactivate eMode', async () => { - const { - pool, - users: [user0], - } = testEnv; - - const userDataBefore = await pool.getUserAccountData(user0.address); - - expect(await pool.connect(user0.signer).setUserEMode(0)); - expect(await pool.getUserEMode(user0.address)).to.be.eq(0); - - const userDataAfter = await pool.getUserAccountData(user0.address); - expect(userDataAfter.totalCollateralBase).to.be.eq(userDataBefore.totalCollateralBase); - expect(userDataAfter.availableBorrowsBase).to.be.lt(userDataBefore.availableBorrowsBase); - expect(userDataAfter.healthFactor).to.be.eq(userDataBefore.healthFactor); - }); - - it('Remove DAI from stablecoin eMode category', async () => { - const { configurator, poolAdmin, dai, helpersContract } = testEnv; - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.not.be.eq(0); - expect(await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, 0)); - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.be.eq(0); - }); - - it('User supplies USDC, activates eMode for ethereum category and borrowing power keeps the same', async () => { - await evmRevert(snapSetup); - - const { - configurator, - helpersContract, - weth, - usdc, - poolAdmin, - pool, - users: [user], - } = testEnv; - - // Setup eMode category for eth, use weth oracle as price source. - const { id, ltv, lt, lb, label } = CATEGORIES.ETHEREUM; - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory(id, ltv, lt, lb, weth.address, label) - ); - expect(await configurator.connect(poolAdmin.signer).setAssetEModeCategory(weth.address, id)); - expect(await helpersContract.getReserveEModeCategory(weth.address)).to.be.eq(id); - const data = await pool.getEModeCategoryData(id); - expect(data.priceSource).to.be.eq(weth.address); - - // Deposit USDC - expect( - await pool - .connect(user.signer) - .supply(usdc.address, utils.parseUnits('100', 6), user.address, 0) - ); - - // Look at power - const baseUnit = utils.parseUnits('1', 8); - const userDataBefore = await pool.getUserAccountData(user.address); - expect(userDataBefore.totalCollateralBase).to.be.eq(baseUnit.mul(100)); - - // Activate eMode for ETH - expect(await pool.connect(user.signer).setUserEMode(id)); - - // Look at power - const userDataAfter = await pool.getUserAccountData(user.address); - - // Expect collateral to have equal value - expect(userDataAfter.totalCollateralBase).to.be.eq(userDataBefore.totalCollateralBase); - expect(userDataAfter.availableBorrowsBase).to.be.eq(userDataBefore.availableBorrowsBase); - expect(userDataAfter.currentLiquidationThreshold).to.be.eq( - userDataBefore.currentLiquidationThreshold - ); - expect(userDataAfter.ltv).to.be.eq(userDataBefore.ltv); - expect(userDataAfter.healthFactor).to.be.eq(userDataBefore.healthFactor); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/emptyrun.coverage.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/emptyrun.coverage.spec.ts deleted file mode 100644 index fa3f168..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/emptyrun.coverage.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { makeSuite } from './helpers/make-suite'; - -/* Workaround to fix 0 coverage report issue */ - -makeSuite('Empty run for coverage', () => {}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/actions.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/actions.ts deleted file mode 100644 index 0f7427c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/actions.ts +++ /dev/null @@ -1,1049 +0,0 @@ -import { - calcExpectedReserveDataAfterBorrow, - calcExpectedReserveDataAfterDeposit, - calcExpectedReserveDataAfterRepay, - calcExpectedReserveDataAfterStableRateRebalance, - calcExpectedReserveDataAfterSwapRateMode, - calcExpectedReserveDataAfterWithdraw, - calcExpectedUserDataAfterBorrow, - calcExpectedUserDataAfterDeposit, - calcExpectedUserDataAfterRepay, - calcExpectedUserDataAfterSetUseAsCollateral, - calcExpectedUserDataAfterStableRateRebalance, - calcExpectedUserDataAfterSwapRateMode, - calcExpectedUserDataAfterWithdraw, -} from './utils/calculations'; -import { getReserveData, getUserData } from './utils/helpers'; -import { buildPermitParams, getSignatureFromTypedData } from '../../helpers/contracts-helpers'; - -import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers'; -import { - getAToken, - getMintableERC20, - getStableDebtToken, - getVariableDebtToken, - getTestnetReserveAddressFromSymbol, -} from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { MAX_UINT_AMOUNT, ONE_YEAR } from '../../helpers/constants'; -import { SignerWithAddress, TestEnv } from './make-suite'; -import chai from 'chai'; -import { ReserveData, UserReserveData } from './utils/interfaces'; -import { BigNumber, ContractReceipt, Wallet } from 'ethers'; -import { AToken } from '../../types/AToken'; -import { RateMode, tEthereumAddress } from '../../helpers/types'; -import { MintableERC20__factory } from '../../types'; -import { waitForTx, advanceTimeAndBlock } from '@aave/deploy-v3'; -import { getChainId } from 'hardhat'; -import { timeLatest } from '../../helpers/misc-utils'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; - -declare var hre: HardhatRuntimeEnvironment; - -const { expect } = chai; - -const almostEqualOrEqual = function ( - this: any, - expected: ReserveData | UserReserveData, - actual: ReserveData | UserReserveData -) { - const keys = Object.keys(actual); - - keys.forEach((key) => { - if ( - key === 'lastUpdateTimestamp' || - key === 'marketStableRate' || - key === 'symbol' || - key === 'aTokenAddress' || - key === 'decimals' || - key === 'totalStableDebtLastUpdated' - ) { - // skipping consistency check on accessory data - return; - } - - this.assert(actual[key] != undefined, `Property ${key} is undefined in the actual data`); - expect(expected[key] != undefined, `Property ${key} is undefined in the expected data`); - - if (expected[key] == null || actual[key] == null) { - console.log('Found a undefined value for Key ', key, ' value ', expected[key], actual[key]); - } - - if (actual[key] instanceof BigNumber) { - const actualValue = actual[key]; - const expectedValue = expected[key]; - - this.assert( - actualValue.eq(expectedValue) || - actualValue.add(1).eq(expectedValue) || - actualValue.eq(expectedValue.add(1)) || - actualValue.add(2).eq(expectedValue) || - actualValue.eq(expectedValue.add(2)) || - actualValue.add(3).eq(expectedValue) || - actualValue.eq(expectedValue.add(3)), - `expected #{act} to be almost equal or equal #{exp} for property ${key}`, - `expected #{act} to be almost equal or equal #{exp} for property ${key}`, - expectedValue.toString(), - actualValue.toString() - ); - } else { - this.assert( - actual[key] !== null && - expected[key] !== null && - actual[key].toString() === expected[key].toString(), - `expected #{act} to be equal #{exp} for property ${key}`, - `expected #{act} to be equal #{exp} for property ${key}`, - expected[key], - actual[key] - ); - } - }); -}; - -chai.use(function (chai: any, utils: any) { - chai.Assertion.overwriteMethod('almostEqualOrEqual', function (original: any) { - return function (this: any, expected: ReserveData | UserReserveData) { - const actual = (expected as ReserveData) - ? this._obj - : this._obj; - - almostEqualOrEqual.apply(this, [expected, actual]); - }; - }); -}); - -interface ActionsConfig { - skipIntegrityCheck: boolean; -} - -export const configuration: ActionsConfig = {}; - -export const mint = async (reserveSymbol: string, amount: string, user: SignerWithAddress) => { - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const token = await getMintableERC20(reserve); - - await waitForTx( - await token - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(reserve, amount)) - ); -}; - -export const approve = async (reserveSymbol: string, user: SignerWithAddress, testEnv: TestEnv) => { - const { pool } = testEnv; - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const token = await getMintableERC20(reserve); - - await waitForTx( - await token.connect(user.signer).approve(pool.address, '100000000000000000000000000000') - ); -}; - -export const deposit = async ( - reserveSymbol: string, - amount: string, - sender: SignerWithAddress, - onBehalfOf: tEthereumAddress, - sendValue: string, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool } = testEnv; - - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const amountToDeposit = await convertToCurrencyDecimals(reserve, amount); - - const txOptions: any = {}; - - const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( - reserve, - onBehalfOf, - testEnv, - sender.address - ); - - if (sendValue) { - txOptions.value = await convertToCurrencyDecimals(reserve, sendValue); - } - - if (expectedResult === 'success') { - const txResult = await waitForTx( - await pool - .connect(sender.signer) - .deposit(reserve, amountToDeposit, onBehalfOf, '0', txOptions) - ); - - const { - reserveData: reserveDataAfter, - userData: userDataAfter, - timestamp, - } = await getContractsData(reserve, onBehalfOf, testEnv, sender.address); - - const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); - - const expectedReserveData = calcExpectedReserveDataAfterDeposit( - amountToDeposit.toString(), - reserveDataBefore, - txTimestamp - ); - - const expectedUserReserveData = calcExpectedUserDataAfterDeposit( - amountToDeposit.toString(), - reserveDataBefore, - expectedReserveData, - userDataBefore, - txTimestamp, - timestamp, - txCost - ); - - expectEqual(reserveDataAfter, expectedReserveData); - expectEqual(userDataAfter, expectedUserReserveData); - - // truffleAssert.eventEmitted(txResult, "Deposit", (ev: any) => { - // const {_reserve, _user, _amount} = ev; - // return ( - // _reserve === reserve && - // _user === user && - // new BigNumber(_amount).isEqualTo(new BigNumber(amountToDeposit)) - // ); - // }); - } else if (expectedResult === 'revert') { - await expect( - pool.connect(sender.signer).deposit(reserve, amountToDeposit, onBehalfOf, '0', txOptions), - revertMessage - ).to.be.reverted; - } -}; - -export const withdraw = async ( - reserveSymbol: string, - amount: string, - user: SignerWithAddress, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool } = testEnv; - - const { - aTokenInstance, - reserve, - userData: userDataBefore, - reserveData: reserveDataBefore, - } = await getDataBeforeAction(reserveSymbol, user.address, testEnv); - - let amountToWithdraw = '0'; - - if (amount !== '-1') { - amountToWithdraw = (await convertToCurrencyDecimals(reserve, amount)).toString(); - } else { - amountToWithdraw = MAX_UINT_AMOUNT; - } - - if (expectedResult === 'success') { - const txResult = await waitForTx( - await pool.connect(user.signer).withdraw(reserve, amountToWithdraw, user.address) - ); - - const { - reserveData: reserveDataAfter, - userData: userDataAfter, - timestamp, - } = await getContractsData(reserve, user.address, testEnv); - - const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); - - const expectedReserveData = calcExpectedReserveDataAfterWithdraw( - amountToWithdraw, - reserveDataBefore, - userDataBefore, - txTimestamp - ); - - const expectedUserData = calcExpectedUserDataAfterWithdraw( - amountToWithdraw, - reserveDataBefore, - expectedReserveData, - userDataBefore, - txTimestamp, - timestamp, - txCost - ); - - expectEqual(reserveDataAfter, expectedReserveData); - expectEqual(userDataAfter, expectedUserData); - - // truffleAssert.eventEmitted(txResult, "Redeem", (ev: any) => { - // const {_from, _value} = ev; - // return ( - // _from === user && new BigNumber(_value).isEqualTo(actualAmountRedeemed) - // ); - // }); - } else if (expectedResult === 'revert') { - await expect( - pool.connect(user.signer).withdraw(reserve, amountToWithdraw, user.address), - revertMessage - ).to.be.reverted; - } -}; - -export const delegateBorrowAllowance = async ( - reserve: string, - amount: string, - interestRateMode: string, - user: SignerWithAddress, - receiver: tEthereumAddress, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool } = testEnv; - - const reserveAddress: tEthereumAddress = await getTestnetReserveAddressFromSymbol(reserve); - - const amountToDelegate: string = await ( - await convertToCurrencyDecimals(reserveAddress, amount) - ).toString(); - - const reserveData = await pool.getReserveData(reserveAddress); - - const debtToken = - interestRateMode === '1' - ? await getStableDebtToken(reserveData.stableDebtTokenAddress) - : await getVariableDebtToken(reserveData.variableDebtTokenAddress); - - const delegateAllowancePromise = debtToken - .connect(user.signer) - .approveDelegation(receiver, amountToDelegate); - - if (expectedResult === 'revert' && revertMessage) { - await expect(delegateAllowancePromise, revertMessage).to.be.revertedWith(revertMessage); - return; - } else { - await waitForTx(await delegateAllowancePromise); - const allowance = await debtToken.borrowAllowance(user.address, receiver); - expect(allowance.toString()).to.be.equal( - amountToDelegate, - 'borrowAllowance is set incorrectly' - ); - } -}; - -export const borrow = async ( - reserveSymbol: string, - amount: string, - interestRateMode: string, - user: SignerWithAddress, - onBehalfOf: tEthereumAddress, - timeTravel: string, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool, helpersContract } = testEnv; - - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( - reserve, - onBehalfOf, - testEnv, - user.address - ); - - const reserveTokens = await helpersContract.getReserveTokensAddresses(reserve); - const debtToken = - interestRateMode === '1' - ? await getStableDebtToken(reserveTokens.stableDebtTokenAddress) - : await getVariableDebtToken(reserveTokens.variableDebtTokenAddress); - - const borrowAllowanceBefore = await debtToken.borrowAllowance(onBehalfOf, user.address); - - const amountToBorrow = await convertToCurrencyDecimals(reserve, amount); - - const tx = pool - .connect(user.signer) - .borrow(reserve, amountToBorrow, interestRateMode, '0', onBehalfOf); - - if (expectedResult === 'success') { - const txResult = await waitForTx(await tx); - - const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); - - if (timeTravel) { - const secondsToTravel = BigNumber.from(timeTravel).mul(ONE_YEAR).div(365).toNumber(); - - await advanceTimeAndBlock(secondsToTravel); - } - - const { - reserveData: reserveDataAfter, - userData: userDataAfter, - timestamp, - } = await getContractsData(reserve, onBehalfOf, testEnv, user.address); - - const expectedReserveData = calcExpectedReserveDataAfterBorrow( - amountToBorrow.toString(), - interestRateMode, - reserveDataBefore, - userDataBefore, - txTimestamp, - timestamp - ); - - const expectedUserData = calcExpectedUserDataAfterBorrow( - amountToBorrow.toString(), - interestRateMode, - reserveDataBefore, - expectedReserveData, - userDataBefore, - txTimestamp, - timestamp - ); - - expectEqual(reserveDataAfter, expectedReserveData); - expectEqual(userDataAfter, expectedUserData); - - if (user.address !== onBehalfOf) { - const borrowAllowanceAfter = await debtToken.borrowAllowance(onBehalfOf, user.address); - expect(borrowAllowanceAfter).to.be.equal( - borrowAllowanceBefore.sub(amountToBorrow), - 'borrowAllowance is updated incorrectly' - ); - } - - // truffleAssert.eventEmitted(txResult, "Borrow", (ev: any) => { - // const { - // _reserve, - // _user, - // _amount, - // _borrowRateMode, - // _borrowRate, - // _originationFee, - // } = ev; - // return ( - // _reserve.toLowerCase() === reserve.toLowerCase() && - // _user.toLowerCase() === user.toLowerCase() && - // new BigNumber(_amount).eq(amountToBorrow) && - // new BigNumber(_borrowRateMode).eq(expectedUserData.borrowRateMode) && - // new BigNumber(_borrowRate).eq(expectedUserData.borrowRate) && - // new BigNumber(_originationFee).eq( - // expectedUserData.originationFee.minus(userDataBefore.originationFee) - // ) - // ); - // }); - } else if (expectedResult === 'revert') { - await expect(tx, revertMessage).to.be.reverted; - } -}; - -export const repay = async ( - reserveSymbol: string, - amount: string, - rateMode: string, - user: SignerWithAddress, - onBehalfOf: SignerWithAddress, - sendValue: string, - expectedResult: string, - testEnv: TestEnv, - timeTravel: string, - revertMessage?: string -) => { - const { pool } = testEnv; - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( - reserve, - onBehalfOf.address, - testEnv - ); - - let amountToRepay = '0'; - - if (amount !== '-1') { - amountToRepay = (await convertToCurrencyDecimals(reserve, amount)).toString(); - } else { - amountToRepay = MAX_UINT_AMOUNT; - } - amountToRepay = BigNumber.from(amountToRepay).toHexString(); - - const txOptions: any = {}; - - if (sendValue) { - const valueToSend = await convertToCurrencyDecimals(reserve, sendValue); - txOptions.value = valueToSend.toHexString(); // '0x' + BigNumber.from(valueToSend.toString()).toString(16); - } - - if (timeTravel) { - const secondsToTravel = BigNumber.from(timeTravel).mul(ONE_YEAR).div(365).toNumber(); - await advanceTimeAndBlock(secondsToTravel); - } - - if (expectedResult === 'success') { - const txResult = await waitForTx( - await pool - .connect(user.signer) - .repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions) - ); - - const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); - - const { - reserveData: reserveDataAfter, - userData: userDataAfter, - timestamp, - } = await getContractsData(reserve, onBehalfOf.address, testEnv); - - const expectedReserveData = calcExpectedReserveDataAfterRepay( - amountToRepay, - rateMode, - reserveDataBefore, - userDataBefore, - txTimestamp, - timestamp - ); - - const expectedUserData = calcExpectedUserDataAfterRepay( - amountToRepay, - rateMode, - reserveDataBefore, - expectedReserveData, - userDataBefore, - user.address, - onBehalfOf.address, - txTimestamp, - timestamp - ); - - expectEqual(reserveDataAfter, expectedReserveData); - expectEqual(userDataAfter, expectedUserData); - - // truffleAssert.eventEmitted(txResult, "Repay", (ev: any) => { - // const {_reserve, _user, _repayer} = ev; - - // return ( - // _reserve.toLowerCase() === reserve.toLowerCase() && - // _user.toLowerCase() === onBehalfOf.toLowerCase() && - // _repayer.toLowerCase() === user.toLowerCase() - // ); - // }); - } else if (expectedResult === 'revert') { - await expect( - pool - .connect(user.signer) - .repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions), - revertMessage - ).to.be.reverted; - } -}; - -export const supplyWithPermit = async ( - reserveSymbol: string, - amount: string, - sender: SignerWithAddress, - senderPk: string, - onBehalfOf: tEthereumAddress, - useAsCollateral: boolean, - sendValue: string, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool } = testEnv; - - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - const amountToDeposit = await convertToCurrencyDecimals(reserve, amount); - - const chainId = Number(await getChainId()); - const token = new MintableERC20__factory(sender.signer).attach(reserve); - const highDeadline = '100000000000000000000000000'; - const nonce = await token.nonces(sender.address); - - const msgParams = buildPermitParams( - chainId, - reserve, - '1', - reserveSymbol, - sender.address, - pool.address, - nonce.toNumber(), - highDeadline, - amountToDeposit.toString() - ); - const { v, r, s } = getSignatureFromTypedData(senderPk, msgParams); - - const txOptions: any = {}; - - const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( - reserve, - onBehalfOf, - testEnv, - sender.address - ); - - if (sendValue) { - txOptions.value = await convertToCurrencyDecimals(reserve, sendValue); - } - - if (expectedResult === 'success') { - const txResult = await waitForTx( - await pool - .connect(sender.signer) - .supplyWithPermit( - reserve, - amountToDeposit, - onBehalfOf, - '0', - highDeadline, - v, - r, - s, - txOptions - ) - ); - - const { - reserveData: reserveDataAfter, - userData: userDataAfter, - timestamp, - } = await getContractsData(reserve, onBehalfOf, testEnv, sender.address); - - const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); - - const expectedReserveData = calcExpectedReserveDataAfterDeposit( - amountToDeposit.toString(), - reserveDataBefore, - txTimestamp - ); - - const expectedUserReserveData = calcExpectedUserDataAfterDeposit( - amountToDeposit.toString(), - reserveDataBefore, - expectedReserveData, - userDataBefore, - txTimestamp, - timestamp, - txCost - ); - - expectEqual(reserveDataAfter, expectedReserveData); - expectEqual(userDataAfter, expectedUserReserveData); - - // truffleAssert.eventEmitted(txResult, "Deposit", (ev: any) => { - // const {_reserve, _user, _amount} = ev; - // return ( - // _reserve === reserve && - // _user === user && - // new BigNumber(_amount).isEqualTo(new BigNumber(amountToDeposit)) - // ); - // }); - } else if (expectedResult === 'revert') { - await expect( - pool - .connect(sender.signer) - .supplyWithPermit( - reserve, - amountToDeposit, - onBehalfOf, - '0', - highDeadline, - v, - r, - s, - txOptions - ), - revertMessage - ).to.be.reverted; - } -}; - -export const repayWithPermit = async ( - reserveSymbol: string, - amount: string, - rateMode: string, - user: SignerWithAddress, - userPk: string, - onBehalfOf: SignerWithAddress, - sendValue: string, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool } = testEnv; - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - const highDeadline = '100000000000000000000000000'; - - const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( - reserve, - onBehalfOf.address, - testEnv - ); - - let amountToRepay = '0'; - - if (amount !== '-1') { - amountToRepay = (await convertToCurrencyDecimals(reserve, amount)).toString(); - } else { - amountToRepay = MAX_UINT_AMOUNT; - } - amountToRepay = BigNumber.from(amountToRepay).toHexString(); - - const chainId = Number(await getChainId()); - const token = new MintableERC20__factory(user.signer).attach(reserve); - const nonce = await token.nonces(user.address); - - const msgParams = buildPermitParams( - chainId, - reserve, - '1', - reserveSymbol, - user.address, - pool.address, - nonce.toNumber(), - highDeadline, - amountToRepay - ); - const { v, r, s } = getSignatureFromTypedData(userPk, msgParams); - const txOptions: any = {}; - - if (sendValue) { - const valueToSend = await convertToCurrencyDecimals(reserve, sendValue); - txOptions.value = valueToSend.toHexString(); - } - - if (expectedResult === 'success') { - const txResult = await waitForTx( - await pool - .connect(user.signer) - .repayWithPermit( - reserve, - amountToRepay, - rateMode, - onBehalfOf.address, - highDeadline, - v, - r, - s, - txOptions - ) - ); - - const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); - - const { - reserveData: reserveDataAfter, - userData: userDataAfter, - timestamp, - } = await getContractsData(reserve, onBehalfOf.address, testEnv); - - const expectedReserveData = calcExpectedReserveDataAfterRepay( - amountToRepay, - rateMode, - reserveDataBefore, - userDataBefore, - txTimestamp, - timestamp - ); - - const expectedUserData = calcExpectedUserDataAfterRepay( - amountToRepay, - rateMode, - reserveDataBefore, - expectedReserveData, - userDataBefore, - user.address, - onBehalfOf.address, - txTimestamp, - timestamp - ); - - expectEqual(reserveDataAfter, expectedReserveData); - expectEqual(userDataAfter, expectedUserData); - - // truffleAssert.eventEmitted(txResult, "Repay", (ev: any) => { - // const {_reserve, _user, _repayer} = ev; - - // return ( - // _reserve.toLowerCase() === reserve.toLowerCase() && - // _user.toLowerCase() === onBehalfOf.toLowerCase() && - // _repayer.toLowerCase() === user.toLowerCase() - // ); - // }); - } else if (expectedResult === 'revert') { - await expect( - pool - .connect(user.signer) - .repayWithPermit( - reserve, - amountToRepay, - rateMode, - onBehalfOf.address, - highDeadline, - v, - r, - s, - txOptions - ), - revertMessage - ).to.be.reverted; - } -}; - -export const setUseAsCollateral = async ( - reserveSymbol: string, - user: SignerWithAddress, - useAsCollateral: string, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool } = testEnv; - - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( - reserve, - user.address, - testEnv - ); - - const useAsCollateralBool = useAsCollateral.toLowerCase() === 'true'; - - if (expectedResult === 'success') { - const txResult = await waitForTx( - await pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool) - ); - - const { txCost } = await getTxCostAndTimestamp(txResult); - - const { userData: userDataAfter } = await getContractsData(reserve, user.address, testEnv); - - const expectedUserData = calcExpectedUserDataAfterSetUseAsCollateral( - useAsCollateral.toLocaleLowerCase() === 'true', - reserveDataBefore, - userDataBefore, - txCost - ); - - expectEqual(userDataAfter, expectedUserData); - // if (useAsCollateralBool) { - // truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralEnabled', (ev: any) => { - // const {_reserve, _user} = ev; - // return _reserve === reserve && _user === user; - // }); - // } else { - // truffleAssert.eventEmitted(txResult, 'ReserveUsedAsCollateralDisabled', (ev: any) => { - // const {_reserve, _user} = ev; - // return _reserve === reserve && _user === user; - // }); - // } - } else if (expectedResult === 'revert') { - await expect( - pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool), - revertMessage - ).to.be.reverted; - } -}; - -export const swapBorrowRateMode = async ( - reserveSymbol: string, - user: SignerWithAddress, - rateMode: string, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool } = testEnv; - - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( - reserve, - user.address, - testEnv - ); - - if (expectedResult === 'success') { - const txResult = await waitForTx( - await pool.connect(user.signer).swapBorrowRateMode(reserve, rateMode) - ); - - const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); - - const { reserveData: reserveDataAfter, userData: userDataAfter } = await getContractsData( - reserve, - user.address, - testEnv - ); - - const expectedReserveData = calcExpectedReserveDataAfterSwapRateMode( - reserveDataBefore, - userDataBefore, - rateMode, - txTimestamp - ); - - const expectedUserData = calcExpectedUserDataAfterSwapRateMode( - reserveDataBefore, - expectedReserveData, - userDataBefore, - rateMode, - txCost, - txTimestamp - ); - - expectEqual(reserveDataAfter, expectedReserveData); - expectEqual(userDataAfter, expectedUserData); - - // truffleAssert.eventEmitted(txResult, "Swap", (ev: any) => { - // const {_user, _reserve, _newRateMode, _newRate} = ev; - // return ( - // _user === user && - // _reserve == reserve && - // new BigNumber(_newRateMode).eq(expectedUserData.borrowRateMode) && - // new BigNumber(_newRate).eq(expectedUserData.borrowRate) - // ); - // }); - } else if (expectedResult === 'revert') { - await expect(pool.connect(user.signer).swapBorrowRateMode(reserve, rateMode), revertMessage).to - .be.reverted; - } -}; - -export const rebalanceStableBorrowRate = async ( - reserveSymbol: string, - user: SignerWithAddress, - target: SignerWithAddress, - expectedResult: string, - testEnv: TestEnv, - revertMessage?: string -) => { - const { pool } = testEnv; - - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( - reserve, - target.address, - testEnv - ); - - if (expectedResult === 'success') { - const txResult = await waitForTx( - await pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address) - ); - - const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); - - const { reserveData: reserveDataAfter, userData: userDataAfter } = await getContractsData( - reserve, - target.address, - testEnv - ); - - const expectedReserveData = calcExpectedReserveDataAfterStableRateRebalance( - reserveDataBefore, - userDataBefore, - txTimestamp - ); - - const expectedUserData = calcExpectedUserDataAfterStableRateRebalance( - reserveDataBefore, - expectedReserveData, - userDataBefore, - txCost, - txTimestamp - ); - - expectEqual(reserveDataAfter, expectedReserveData); - expectEqual(userDataAfter, expectedUserData); - - // truffleAssert.eventEmitted(txResult, 'RebalanceStableBorrowRate', (ev: any) => { - // const {_user, _reserve, _newStableRate} = ev; - // return ( - // _user.toLowerCase() === target.toLowerCase() && - // _reserve.toLowerCase() === reserve.toLowerCase() && - // new BigNumber(_newStableRate).eq(expectedUserData.borrowRate) - // ); - // }); - } else if (expectedResult === 'revert') { - await expect( - pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address), - revertMessage - ).to.be.reverted; - } -}; - -const expectEqual = ( - actual: UserReserveData | ReserveData, - expected: UserReserveData | ReserveData -) => { - if (!configuration.skipIntegrityCheck) { - // @ts-ignore - expect(actual).to.be.almostEqualOrEqual(expected); - } -}; - -interface ActionData { - reserve: string; - reserveData: ReserveData; - userData: UserReserveData; - aTokenInstance: AToken; -} - -const getDataBeforeAction = async ( - reserveSymbol: string, - user: tEthereumAddress, - testEnv: TestEnv -): Promise => { - const reserve = await getTestnetReserveAddressFromSymbol(reserveSymbol); - - const { reserveData, userData } = await getContractsData(reserve, user, testEnv); - const aTokenInstance = await getAToken(reserveData.aTokenAddress); - return { - reserve, - reserveData, - userData, - aTokenInstance, - }; -}; - -export const getTxCostAndTimestamp = async (tx: ContractReceipt) => { - if (!tx.blockNumber || !tx.transactionHash || !tx.cumulativeGasUsed) { - throw new Error('No tx blocknumber'); - } - const txTimestamp = BigNumber.from( - (await hre.ethers.provider.getBlock(tx.blockNumber)).timestamp - ); - - const txInfo = await hre.ethers.provider.getTransaction(tx.transactionHash); - const gasPrice = txInfo.gasPrice ? txInfo.gasPrice : tx.effectiveGasPrice; - const txCost = BigNumber.from(tx.cumulativeGasUsed).mul(gasPrice); - - return { txCost, txTimestamp }; -}; - -export const getContractsData = async ( - reserve: string, - user: string, - testEnv: TestEnv, - sender?: string -) => { - const { pool, helpersContract } = testEnv; - - const [userData, reserveData, timestamp] = await Promise.all([ - getUserData(pool, helpersContract, reserve, user, sender || user), - getReserveData(helpersContract, reserve), - timeLatest(), - ]); - - return { - reserveData, - userData, - timestamp, - }; -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/make-suite.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/make-suite.ts deleted file mode 100644 index a81255e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/make-suite.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { Signer } from 'ethers'; -import { - getPool, - getPoolAddressesProvider, - getAaveProtocolDataProvider, - getAToken, - getMintableERC20, - getPoolConfiguratorProxy, - getPoolAddressesProviderRegistry, - getWETHMocked, - getVariableDebtToken, - getStableDebtToken, - getAaveOracle, - getACLManager, - getFallbackOracle, -} from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { tEthereumAddress } from '../../helpers/types'; -import { Pool } from '../../types/Pool'; -import { AaveProtocolDataProvider } from '../../types/AaveProtocolDataProvider'; -import { MintableERC20 } from '../../types/MintableERC20'; -import { AToken } from '../../types/AToken'; -import { PoolConfigurator } from '../../types/PoolConfigurator'; - -import chai from 'chai'; -// @ts-ignore -import bignumberChai from 'chai-bignumber'; -import { PriceOracle } from '../../types/PriceOracle'; -import { PoolAddressesProvider } from '../../types/PoolAddressesProvider'; -import { PoolAddressesProviderRegistry } from '../../types/PoolAddressesProviderRegistry'; -import { WETH9Mocked } from '../../types/WETH9Mocked'; -import { solidity } from 'ethereum-waffle'; -import { AaveOracle, ACLManager, StableDebtToken, VariableDebtToken } from '../../types'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { usingTenderly } from '../../helpers/tenderly-utils'; -import { waitForTx, evmSnapshot, evmRevert, getEthersSigners } from '@aave/deploy-v3'; - -declare var hre: HardhatRuntimeEnvironment; - -chai.use(bignumberChai()); -chai.use(solidity); - -export interface SignerWithAddress { - signer: Signer; - address: tEthereumAddress; -} -export interface TestEnv { - deployer: SignerWithAddress; - poolAdmin: SignerWithAddress; - emergencyAdmin: SignerWithAddress; - riskAdmin: SignerWithAddress; - users: SignerWithAddress[]; - pool: Pool; - configurator: PoolConfigurator; - oracle: PriceOracle; - aaveOracle: AaveOracle; - helpersContract: AaveProtocolDataProvider; - weth: WETH9Mocked; - aWETH: AToken; - dai: MintableERC20; - aDai: AToken; - aAave: AToken; - variableDebtDai: VariableDebtToken; - stableDebtDai: StableDebtToken; - aUsdc: AToken; - usdc: MintableERC20; - aave: MintableERC20; - addressesProvider: PoolAddressesProvider; - registry: PoolAddressesProviderRegistry; - aclManager: ACLManager; -} - -let HardhatSnapshotId: string = '0x1'; -const setHardhatSnapshotId = (id: string) => { - HardhatSnapshotId = id; -}; - -const testEnv: TestEnv = { - deployer: {} as SignerWithAddress, - poolAdmin: {} as SignerWithAddress, - emergencyAdmin: {} as SignerWithAddress, - riskAdmin: {} as SignerWithAddress, - users: [] as SignerWithAddress[], - pool: {} as Pool, - configurator: {} as PoolConfigurator, - helpersContract: {} as AaveProtocolDataProvider, - oracle: {} as PriceOracle, - aaveOracle: {} as AaveOracle, - weth: {} as WETH9Mocked, - aWETH: {} as AToken, - dai: {} as MintableERC20, - aDai: {} as AToken, - variableDebtDai: {} as VariableDebtToken, - stableDebtDai: {} as StableDebtToken, - aUsdc: {} as AToken, - usdc: {} as MintableERC20, - aave: {} as MintableERC20, - addressesProvider: {} as PoolAddressesProvider, - registry: {} as PoolAddressesProviderRegistry, - aclManager: {} as ACLManager, -} as TestEnv; - -export async function initializeMakeSuite() { - const [_deployer, ...restSigners] = await getEthersSigners(); - const deployer: SignerWithAddress = { - address: await _deployer.getAddress(), - signer: _deployer, - }; - - for (const signer of restSigners) { - testEnv.users.push({ - signer, - address: await signer.getAddress(), - }); - } - testEnv.deployer = deployer; - testEnv.poolAdmin = deployer; - testEnv.emergencyAdmin = testEnv.users[1]; - testEnv.riskAdmin = testEnv.users[2]; - testEnv.pool = await getPool(); - testEnv.configurator = await getPoolConfiguratorProxy(); - - testEnv.addressesProvider = await getPoolAddressesProvider(); - - testEnv.registry = await getPoolAddressesProviderRegistry(); - testEnv.aclManager = await getACLManager(); - - testEnv.oracle = await getFallbackOracle(); - testEnv.aaveOracle = await getAaveOracle(); - - testEnv.helpersContract = await getAaveProtocolDataProvider(); - - const allTokens = await testEnv.helpersContract.getAllATokens(); - const aDaiAddress = allTokens.find((aToken) => aToken.symbol === 'aDAI')?.tokenAddress; - const aUsdcAddress = allTokens.find((aToken) => aToken.symbol === 'aUSDC')?.tokenAddress; - const aWEthAddress = allTokens.find((aToken) => aToken.symbol === 'aWETH')?.tokenAddress; - const aAaveAddress = allTokens.find((aToken) => aToken.symbol === 'aAAVE')?.tokenAddress; - - const reservesTokens = await testEnv.helpersContract.getAllReservesTokens(); - - const daiAddress = reservesTokens.find((token) => token.symbol === 'DAI')?.tokenAddress; - const { - variableDebtTokenAddress: variableDebtDaiAddress, - stableDebtTokenAddress: stableDebtDaiAddress, - } = await testEnv.helpersContract.getReserveTokensAddresses(daiAddress || ''); - const usdcAddress = reservesTokens.find((token) => token.symbol === 'USDC')?.tokenAddress; - const aaveAddress = reservesTokens.find((token) => token.symbol === 'AAVE')?.tokenAddress; - const wethAddress = reservesTokens.find((token) => token.symbol === 'WETH')?.tokenAddress; - - if (!aDaiAddress || !aWEthAddress) { - throw 'Missing mandatory atokens'; - } - if (!daiAddress || !usdcAddress || !aaveAddress || !wethAddress) { - throw 'Missing mandatory tokens'; - } - - testEnv.aDai = await getAToken(aDaiAddress); - testEnv.variableDebtDai = await getVariableDebtToken(variableDebtDaiAddress); - testEnv.stableDebtDai = await getStableDebtToken(stableDebtDaiAddress); - testEnv.aUsdc = await getAToken(aUsdcAddress); - testEnv.aWETH = await getAToken(aWEthAddress); - testEnv.aAave = await getAToken(aAaveAddress); - - testEnv.dai = await getMintableERC20(daiAddress); - testEnv.aave = await getMintableERC20(aaveAddress); - testEnv.usdc = await getMintableERC20(usdcAddress); - testEnv.weth = await getWETHMocked(wethAddress); - - // Setup admins - await waitForTx(await testEnv.aclManager.addRiskAdmin(testEnv.riskAdmin.address)); - await waitForTx(await testEnv.aclManager.addEmergencyAdmin(testEnv.emergencyAdmin.address)); -} - -const setSnapshot = async () => { - if (usingTenderly()) { - setHardhatSnapshotId((await hre.tenderlyNetwork.getHead()) || '0x1'); - return; - } - setHardhatSnapshotId(await evmSnapshot()); -}; - -const revertHead = async () => { - if (usingTenderly()) { - await hre.tenderlyNetwork.setHead(HardhatSnapshotId); - return; - } - await evmRevert(HardhatSnapshotId); -}; - -export function makeSuite(name: string, tests: (testEnv: TestEnv) => void) { - describe(name, () => { - before(async () => { - await setSnapshot(); - }); - tests(testEnv); - after(async () => { - await revertHead(); - }); - }); -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenario-engine.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenario-engine.ts deleted file mode 100644 index 772cdad..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenario-engine.ts +++ /dev/null @@ -1,302 +0,0 @@ -import { TestEnv, SignerWithAddress } from './make-suite'; -import { - mint, - approve, - deposit, - borrow, - withdraw, - repay, - setUseAsCollateral, - swapBorrowRateMode, - rebalanceStableBorrowRate, - delegateBorrowAllowance, - repayWithPermit, - supplyWithPermit, -} from './actions'; -import { RateMode } from '../../helpers/types'; -import { getTestWallets } from './utils/wallets'; - -export interface Action { - name: string; - args?: any; - expected: string; - revertMessage?: string; -} - -export interface Story { - description: string; - actions: Action[]; -} - -export interface Scenario { - title: string; - description: string; - stories: Story[]; -} - -export const executeStory = async (story: Story, testEnv: TestEnv) => { - for (const action of story.actions) { - const { users } = testEnv; - await executeAction(action, users, testEnv); - } -}; - -const executeAction = async (action: Action, users: SignerWithAddress[], testEnv: TestEnv) => { - const { reserve, user: userIndex, borrowRateMode } = action.args; - const { name, expected, revertMessage } = action; - - if (!name || name === '') { - throw 'Action name is missing'; - } - if (!reserve || reserve === '') { - throw 'Invalid reserve selected for deposit'; - } - if (!userIndex || userIndex === '') { - throw `Invalid user selected to deposit into the ${reserve} reserve`; - } - - if (!expected || expected === '') { - throw `An expected resut for action ${name} is required`; - } - - let rateMode: string = RateMode.None; - - if (borrowRateMode) { - if (borrowRateMode === 'none') { - rateMode = RateMode.None; - } else if (borrowRateMode === 'stable') { - rateMode = RateMode.Stable; - } else if (borrowRateMode === 'variable') { - rateMode = RateMode.Variable; - } else { - //random value, to test improper selection of the parameter - rateMode = '4'; - } - } - - const user = users[parseInt(userIndex)]; - - const userPrivateKey = getTestWallets()[parseInt(userIndex) + 1].secretKey; - - switch (name) { - case 'mint': - const { amount } = action.args; - - if (!amount || amount === '') { - throw `Invalid amount of ${reserve} to mint`; - } - - await mint(reserve, amount, user); - break; - - case 'approve': - await approve(reserve, user, testEnv); - break; - - case 'deposit': - { - const { amount, sendValue, onBehalfOf: onBehalfOfIndex } = action.args; - const onBehalfOf = onBehalfOfIndex - ? users[parseInt(onBehalfOfIndex)].address - : user.address; - - if (!amount || amount === '') { - throw `Invalid amount to deposit into the ${reserve} reserve`; - } - - await deposit( - reserve, - amount, - user, - onBehalfOf, - sendValue, - expected, - testEnv, - revertMessage - ); - } - break; - case 'supplyWithPermit': - { - const { amount, sendValue, onBehalfOf: onBehalfOfIndex, useAsCollateral } = action.args; - const onBehalfOf = onBehalfOfIndex - ? users[parseInt(onBehalfOfIndex)].address - : user.address; - - if (!amount || amount === '') { - throw `Invalid amount to deposit into the ${reserve} reserve`; - } - - await supplyWithPermit( - reserve, - amount, - user, - userPrivateKey, - onBehalfOf, - useAsCollateral, - sendValue, - expected, - testEnv, - revertMessage - ); - } - break; - - case 'delegateBorrowAllowance': - { - const { amount, toUser: toUserIndex } = action.args; - const toUser = users[parseInt(toUserIndex, 10)].address; - if (!amount || amount === '') { - throw `Invalid amount to deposit into the ${reserve} reserve`; - } - - await delegateBorrowAllowance( - reserve, - amount, - rateMode, - user, - toUser, - expected, - testEnv, - revertMessage - ); - } - break; - - case 'withdraw': - { - const { amount } = action.args; - - if (!amount || amount === '') { - throw `Invalid amount to withdraw from the ${reserve} reserve`; - } - - await withdraw(reserve, amount, user, expected, testEnv, revertMessage); - } - break; - case 'borrow': - { - const { amount, timeTravel, onBehalfOf: onBehalfOfIndex } = action.args; - - const onBehalfOf = onBehalfOfIndex - ? users[parseInt(onBehalfOfIndex)].address - : user.address; - - if (!amount || amount === '') { - throw `Invalid amount to borrow from the ${reserve} reserve`; - } - - await borrow( - reserve, - amount, - rateMode, - user, - onBehalfOf, - timeTravel, - expected, - testEnv, - revertMessage - ); - } - break; - - case 'repay': - { - const { amount, timeTravel, sendValue } = action.args; - let { onBehalfOf: onBehalfOfIndex } = action.args; - - if (!amount || amount === '') { - throw `Invalid amount to repay into the ${reserve} reserve`; - } - - let userToRepayOnBehalf: SignerWithAddress; - if (!onBehalfOfIndex || onBehalfOfIndex === '') { - console.log( - 'WARNING: No onBehalfOf specified for a repay action. Defaulting to the repayer address' - ); - userToRepayOnBehalf = user; - } else { - userToRepayOnBehalf = users[parseInt(onBehalfOfIndex)]; - } - - await repay( - reserve, - amount, - rateMode, - user, - userToRepayOnBehalf, - sendValue, - expected, - testEnv, - timeTravel, - revertMessage - ); - } - break; - - case 'repayWithPermit': - { - const { amount, borrowRateMode, sendValue, deadline } = action.args; - let { onBehalfOf: onBehalfOfIndex } = action.args; - - if (!amount || amount === '') { - throw `Invalid amount to repay into the ${reserve} reserve`; - } - - let userToRepayOnBehalf: SignerWithAddress; - if (!onBehalfOfIndex || onBehalfOfIndex === '') { - console.log( - 'WARNING: No onBehalfOf specified for a repay action. Defaulting to the repayer address' - ); - userToRepayOnBehalf = user; - } else { - userToRepayOnBehalf = users[parseInt(onBehalfOfIndex)]; - } - - await repayWithPermit( - reserve, - amount, - rateMode, - user, - userPrivateKey, - userToRepayOnBehalf, - sendValue, - expected, - testEnv, - revertMessage - ); - } - break; - - case 'setUseAsCollateral': - { - const { useAsCollateral } = action.args; - - if (!useAsCollateral || useAsCollateral === '') { - throw `A valid value for useAsCollateral needs to be set when calling setUseReserveAsCollateral on reserve ${reserve}`; - } - await setUseAsCollateral(reserve, user, useAsCollateral, expected, testEnv, revertMessage); - } - break; - - case 'swapBorrowRateMode': - await swapBorrowRateMode(reserve, user, rateMode, expected, testEnv, revertMessage); - break; - - case 'rebalanceStableBorrowRate': - { - const { target: targetIndex } = action.args; - - if (!targetIndex || targetIndex === '') { - throw `A target must be selected when trying to rebalance a stable rate`; - } - const target = users[parseInt(targetIndex)]; - - await rebalanceStableBorrowRate(reserve, user, target, expected, testEnv, revertMessage); - } - break; - - default: - throw `Invalid action requested: ${name}`; - } -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-negatives.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-negatives.json deleted file mode 100644 index b4c1121..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-negatives.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "title": "Pool: Borrow negatives (revert expected)", - "description": "Test cases for the deposit function.", - "stories": [ - { - "description": "User 0 deposits 14760.147 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 1476.01 DAI with rate mode NONE (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "none", - "user": "1" - }, - "expected": "revert", - "revertMessage": "Invalid interest rate mode selected" - } - ] - }, - { - "description": "User 0 deposits 14760.147 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 1476.01 DAI with an invalid rate mode (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "invalid", - "user": "1" - }, - "expected": "revert", - "revertMessage": "Invalid interest rate mode selected" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-stable-edge.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-stable-edge.json deleted file mode 100644 index 0833e7c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-stable-edge.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "title": "Pool: Borrow/repay (stable rate) edge cases", - "description": "Edge test cases for the borrow function, stable mode.", - "stories": [ - { - "description": "repay, burn () balanceIncrease > amount", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "stable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "0.00000001", - "user": "1", - "borrowRateMode": "stable", - "onBehalfOf": "1", - "timeTravel": "365" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-stable.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-stable.json deleted file mode 100644 index 3c1ecc8..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-stable.json +++ /dev/null @@ -1,656 +0,0 @@ -{ - "title": "Pool: Borrow/repay (stable rate)", - "description": "Test cases for the borrow function, stable mode.", - "stories": [ - { - "description": "User 0 deposits 14760.147 DAI, user 1 deposits 1 WETH as collateral and borrows 1476.01 DAI at stable rate", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "stable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "13284.132", - "borrowRateMode": "stable", - "user": "1" - }, - "expected": "revert", - "revertMessage": "There is not enough collateral to cover a new borrow" - } - ] - }, - { - "description": "User 1 repays half of the DAI borrow after one year", - "actions": [ - { - "name": "mint", - "description": "Mint 10 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "147.60", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "738", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "stable" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 repays the rest of the DAI borrow after one year", - "actions": [ - { - "name": "mint", - "description": "Mint 221.40 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "221.40", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "stable" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws the deposited DAI plus interest", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 deposits 14760.147 DAI, user 2 tries to borrow 14760.147 DAI at a stable rate without any collateral (revert expected) User 1 withdrawws", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "borrowRateMode": "stable", - "user": "2" - }, - "expected": "revert", - "revertMessage": "The collateral balance is 0" - }, - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 14760.147 DAI, user 1,2,3,4 deposit 1 WETH each and borrow 1476.01 DAI at stable rate. Everything is repaid, user 0 withdraws", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "stable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "2" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "2" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "2" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "stable", - "user": "2", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "3" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "3" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "3" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "stable", - "user": "3", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "4" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "4" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "4" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "stable", - "user": "4", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "mint", - "description": "Mint 1476.01 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "mint", - "description": "Mint 1476.01 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "user": "2" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "2" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "2", - "onBehalfOf": "2", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "mint", - "description": "Mint 1476.01 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "user": "3" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "3" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "3", - "onBehalfOf": "3", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "mint", - "description": "Mint 1476.01 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "user": "4" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "4" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "4", - "onBehalfOf": "4", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 14760.147 DAI, user 1 deposits 2 WETH and borrow 1476.01 DAI at stable rate first, then 1476.01 DAI at variable rate, repays everything. User 0 withdraws", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "stable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "variable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "mint", - "description": "Mint 738 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "738", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "variable" - }, - "expected": "success" - }, - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-variable.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-variable.json deleted file mode 100644 index 10285da..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repay-variable.json +++ /dev/null @@ -1,946 +0,0 @@ -{ - "title": "Pool: Borrow/repay (variable rate)", - "description": "Test cases for the borrow function, variable mode.", - "stories": [ - { - "description": "User 2 deposits 1 DAI to account for rounding errors", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "1", - "user": "2" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "2" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "1", - "user": "2" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 14760.147 DAI, user 1 deposits 1 WETH as collateral and borrows 1476.01 DAI at variable rate", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "variable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "13284.132", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "revert", - "revertMessage": "There is not enough collateral to cover a new borrow" - } - ] - }, - { - "description": "User 1 tries to repay 0 DAI (revert expected)", - "actions": [ - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "0", - "user": "1", - "onBehalfOf": "1" - }, - "expected": "revert", - "revertMessage": "Amount must be greater than 0" - } - ] - }, - { - "description": "User 1 repays a small amount of DAI, enough to cover a small part of the interest", - "actions": [ - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "1.25", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "variable" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 repays the DAI borrow after one year", - "actions": [ - { - "name": "mint", - "description": "Mint 10 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "147.60", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "variable", - "timeTravel": "365" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws the deposited DAI plus interest", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 withdraws the collateral", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 2 deposits a small amount of WETH to account for rounding errors", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "0.001", - "user": "2" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "2" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "0.001", - "user": "2" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 1 WETH, user 1 deposits 1476.01 LINK as collateral and borrows 0.5 WETH at variable rate", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "LINK", - "amount": "100", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "LINK", - "user": "1" - }, - "expected": "success" - }, - - { - "name": "deposit", - "args": { - "reserve": "LINK", - "amount": "100", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "WETH", - "amount": "0.5", - "borrowRateMode": "variable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 tries to repay 0 WETH", - "actions": [ - { - "name": "repay", - "args": { - "reserve": "WETH", - "amount": "0", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "variable" - }, - "expected": "revert", - "revertMessage": "Amount must be greater than 0" - } - ] - }, - { - "description": "User 2 tries to repay everything on behalf of user 1 using uint(-1) (revert expected)", - "actions": [ - { - "name": "repay", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "2", - "borrowRateMode": "variable", - "onBehalfOf": "1" - }, - "expected": "revert", - "revertMessage": "To repay on behalf of an user an explicit amount to repay is needed" - } - ] - }, - { - "description": "User 3 repays a small amount of WETH on behalf of user 1", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "3" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "3" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "WETH", - "amount": "0.2", - "user": "3", - "borrowRateMode": "variable", - "onBehalfOf": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 repays the WETH borrow after one year", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "2" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "2" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "WETH", - "amount": "-1", - "borrowRateMode": "variable", - "user": "1", - "onBehalfOf": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws the deposited WETH plus interest", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 withdraws the collateral", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "LINK", - "amount": "-1", - "user": "1" - }, - "expected": "success" - } - ] - }, - - { - "description": "User 2 deposits 1 USDC to account for rounding errors", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "1", - "user": "2" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "2" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "1", - "user": "2" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 14760.147 USDC, user 1 deposits 1 WETH as collateral and borrows 1476.01 USDC at variable rate", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "1476.01", - "borrowRateMode": "variable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 tries to borrow the rest of the USDC liquidity (revert expected)", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "13284.132", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "revert", - "revertMessage": "There is not enough collateral to cover a new borrow" - } - ] - }, - { - "description": "User 1 repays the USDC borrow after one year", - "actions": [ - { - "name": "mint", - "description": "Mint 10 USDC to cover the interest", - "args": { - "reserve": "USDC", - "amount": "147.60", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "USDC", - "amount": "-1", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "variable" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws the deposited USDC plus interest", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "USDC", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 withdraws the collateral", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 deposits 14760.147 DAI, user 3 tries to borrow 14760.147 DAI without any collateral (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "borrowRateMode": "variable", - "user": "3" - }, - "expected": "revert", - "revertMessage": "The collateral balance is 0" - } - ] - }, - { - "description": "user 3 deposits 0.1 WETH collateral to borrow 1476.01 DAI; 0.1 WETH is not enough to borrow 1476.01 DAI (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "0.1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "0.1", - "user": "3" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "variable", - "user": "3" - }, - "expected": "revert", - "revertMessage": "There is not enough collateral to cover a new borrow" - } - ] - }, - { - "description": "user 3 withdraws the 0.1 WETH", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "3" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 deposits 14760.147 USDC, user 3 tries to borrow 14760.147 USDC without any collateral (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "borrowRateMode": "variable", - "user": "3" - }, - "expected": "revert", - "revertMessage": "The collateral balance is 0" - } - ] - }, - { - "description": "user 3 deposits 0.1 WETH collateral to borrow 1476.01 USDC; 0.1 WETH is not enough to borrow 1476.01 USDC (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "3" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "0.1", - "user": "3" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "1476.01", - "borrowRateMode": "variable", - "user": "3" - }, - "expected": "revert", - "revertMessage": "There is not enough collateral to cover a new borrow" - } - ] - }, - { - "description": "user 3 withdraws the 0.1 WETH", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "3" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 14760.147 DAI, user 6 deposits 2 WETH and borrow 1476.01 DAI at variable rate first, then 1476.01 DAI at stable rate, repays everything. User 0 withdraws", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "6" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "6" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "6" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "variable", - "user": "6", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "stable", - "user": "6", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "mint", - "description": "Mint 738 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "738", - "user": "6" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "6" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "6", - "onBehalfOf": "6", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "6", - "onBehalfOf": "6", - "borrowRateMode": "variable" - }, - "expected": "success" - }, - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repayWithPermit-variable.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repayWithPermit-variable.json deleted file mode 100644 index 328eea9..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/borrow-repayWithPermit-variable.json +++ /dev/null @@ -1,194 +0,0 @@ -{ - "title": "Pool: Borrow/repay with permit with Permit (variable rate)", - "description": "Test cases for the borrow function, variable mode.", - "stories": [ - { - "description": "User 2 deposits with permit 1 DAI to account for rounding errors", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "1", - "user": "2" - }, - "expected": "success" - }, - { - "name": "supplyWithPermit", - "args": { - "reserve": "DAI", - "amount": "1", - "user": "2", - "useAsCollateral": true - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits with permit 14760.147 DAI, user 1 deposits 1 WETH as collateral and borrows 1476.01 DAI at variable rate", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "supplyWithPermit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0", - "useAsCollateral": true - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "borrowRateMode": "variable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "13284.132", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "revert", - "revertMessage": "There is not enough collateral to cover a new borrow" - } - ] - }, - { - "description": "User 1 tries to repay with permit 0 DAI (revert expected)", - "actions": [ - { - "name": "repayWithPermit", - "args": { - "reserve": "DAI", - "amount": "0", - "user": "1", - "onBehalfOf": "1" - }, - "expected": "revert", - "revertMessage": "Amount must be greater than 0" - } - ] - }, - { - "description": "User 1 repays with permit a small amount of DAI, enough to cover a small part of the interest", - "actions": [ - { - "name": "repayWithPermit", - "args": { - "reserve": "DAI", - "amount": "1.25", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "variable" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 repays with permit the DAI borrow after one year", - "actions": [ - { - "name": "mint", - "description": "Mint 10 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "147.60", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repayWithPermit", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "variable", - "timeTravel" : "365" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws the deposited DAI plus interest", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 withdraws the collateral", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "1" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/credit-delegation.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/credit-delegation.json deleted file mode 100644 index 7727c44..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/credit-delegation.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "title": "Pool: Credit delegation", - "description": "Test cases for the credit delegation related functions.", - "stories": [ - { - "description": "User 3 deposits 1476.010 WETH. User 0 deposits 14760.147 DAI, user 0 delegates borrowing of 2 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1476.010", - "user": "3" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "3" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1476.010", - "user": "3" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "delegateBorrowAllowance", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "0", - "borrowRateMode": "variable", - "toUser": "4" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "4", - "onBehalfOf": "0", - "borrowRateMode": "variable" - }, - "expected": "success" - } - ] - }, - { - "description": "User 4 trying to borrow 1 WETH stable on behalf of user 0, revert expected", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "4", - "onBehalfOf": "0", - "borrowRateMode": "stable" - }, - "expected": "revert", - "revertMessage": "59" - } - ] - }, - { - "description": "User 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 3 WETH variable on behalf of user 0, revert expected", - "actions": [ - { - "name": "delegateBorrowAllowance", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0", - "borrowRateMode": "variable", - "toUser": "4" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "WETH", - "amount": "3", - "user": "4", - "onBehalfOf": "0", - "borrowRateMode": "variable" - }, - "expected": "revert", - "revertMessage": "59" - } - ] - }, - { - "description": "User 0 delegates borrowing of 1 WETH on stable to user 2, user 2 borrows 1 WETH stable on behalf of user 0", - "actions": [ - { - "name": "delegateBorrowAllowance", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0", - "borrowRateMode": "stable", - "toUser": "2" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "2", - "onBehalfOf": "0", - "borrowRateMode": "stable" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/deposit.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/deposit.json deleted file mode 100644 index 3751108..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/deposit.json +++ /dev/null @@ -1,266 +0,0 @@ -{ - "title": "Pool: Deposit", - "description": "Test cases for the deposit function.", - "stories": [ - { - "description": "User 0 Deposits 14760.147 DAI in an empty reserve", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 deposits 14760.147 DAI after user 0", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 14760.147 USDC in an empty reserve", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 deposits 14760.147 USDC after user 0", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 1 WETH in an empty reserve", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 deposits 1 WETH after user 0", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 deposits 0 WETH (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "0", - "user": "1" - }, - "expected": "revert", - "revertMessage": "Amount must be greater than 0" - } - ] - }, - { - "description": "User 1 deposits 0 DAI", - "actions": [ - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "0", - "user": "1" - }, - "expected": "revert", - "revertMessage": "Amount must be greater than 0" - } - ] - }, - { - "description": "User 1 deposits 1476.01 DAI on behalf of user 2, user 2 tries to borrow 0.1 WETH", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "1476.01", - "user": "1", - "onBehalfOf": "2" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "WETH", - "amount": "0.1", - "borrowRateMode": "variable", - "user": "2" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/rebalance-stable-rate.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/rebalance-stable-rate.json deleted file mode 100644 index 8588952..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/rebalance-stable-rate.json +++ /dev/null @@ -1,274 +0,0 @@ -{ - "title": "Pool: Rebalance stable rate", - "description": "Test cases for the rebalanceStableBorrowRate() function.", - "stories": [ - { - "description": "User 0 tries to rebalance user 1 who has no borrows in progress (revert expected)", - "actions": [ - { - "name": "rebalanceStableBorrowRate", - "args": { - "reserve": "USDC", - "user": "0", - "target": "1" - }, - "expected": "revert", - "revertMessage": "User does not have any stable rate loan for this reserve" - } - ] - }, - { - "description": "User 0 deposits 1000 USDC, user 1 deposits 7 WETH, borrows 250 USDC at a stable rate, user 0 rebalances user 1 (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "1000", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "1000", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "7", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "7", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "250", - "borrowRateMode": "stable", - "user": "1" - }, - "expected": "success" - }, - { - "name": "rebalanceStableBorrowRate", - "args": { - "reserve": "USDC", - "user": "0", - "target": "1" - }, - "expected": "revert", - "revertMessage": "The user borrow is variable and cannot be rebalanced" - } - ] - }, - { - "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "200", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "success" - }, - { - "name": "rebalanceStableBorrowRate", - "args": { - "reserve": "USDC", - "user": "0", - "target": "1" - }, - "expected": "revert", - "revertMessage": "Interest rate rebalance conditions were not met" - } - ] - }, - { - "description": "User 1 borrows another 200 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "200", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "success" - }, - { - "name": "rebalanceStableBorrowRate", - "args": { - "reserve": "USDC", - "user": "0", - "target": "1" - }, - "expected": "revert", - "revertMessage": "Interest rate rebalance conditions were not met" - } - ] - }, - { - "description": "User 1 borrows another 100 at variable, user 0 tries to rebalance but the conditions are not met (revert expected)", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "180", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "success" - }, - { - "name": "rebalanceStableBorrowRate", - "args": { - "reserve": "USDC", - "user": "0", - "target": "1" - }, - "expected": "revert", - "revertMessage": "Interest rate rebalance conditions were not met" - } - ] - }, - { - "description": "User 1 borrows the remaining USDC (usage ratio = 100%) at variable. User 0 rebalances user 1", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "170", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "success" - }, - { - "name": "rebalanceStableBorrowRate", - "args": { - "reserve": "USDC", - "user": "0", - "target": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 deposits 1000 USDC, user 1 deposits 7 WETH, borrows 950 USDC at a variable rate, user 0 rebalances user 1 (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "1000", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "1000", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "7", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "7", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "USDC", - "amount": "950", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "success" - }, - { - "name": "rebalanceStableBorrowRate", - "args": { - "reserve": "USDC", - "user": "0", - "target": "1" - }, - "expected": "revert", - "revertMessage": "The user borrow is variable and cannot be rebalanced" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/set-use-as-collateral.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/set-use-as-collateral.json deleted file mode 100644 index edb49d2..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/set-use-as-collateral.json +++ /dev/null @@ -1,236 +0,0 @@ -{ - "title": "Pool: Usage as collateral", - "description": "Test cases for the setUserUseReserveAsCollateral() function.", - "stories": [ - { - "description": "User 0 Deposits 14760.147 DAI, disables DAI as collateral", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "setUseAsCollateral", - "args": { - "reserve": "DAI", - "user": "0", - "useAsCollateral": "false" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 5904.05 DAI (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "1" - }, - "expected": "success" - }, - { - "name": "setUseAsCollateral", - "args": { - "reserve": "WETH", - "user": "1", - "useAsCollateral": "false" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "5904.05", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "revert", - "revertMessage": "The collateral balance is 0" - } - ] - }, - { - "description": "User 1 enables WETH as collateral, borrows 5904.05 DAI", - "actions": [ - { - "name": "setUseAsCollateral", - "args": { - "reserve": "WETH", - "user": "1", - "useAsCollateral": "true" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "5904.05", - "borrowRateMode": "variable", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 disables WETH as collateral (revert expected)", - "actions": [ - { - "name": "setUseAsCollateral", - "args": { - "reserve": "WETH", - "user": "1", - "useAsCollateral": "false" - }, - "expected": "revert", - "revertMessage": "User deposit is already being used as collateral" - } - ] - }, - { - "description": "User 1 Deposits 10 AAVE, disables WETH as collateral. Should revert as 10 AAVE are not enough to cover the debt (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "AAVE", - "amount": "10", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "AAVE", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "AAVE", - "amount": "10", - "user": "1" - }, - "expected": "success" - }, - { - "name": "setUseAsCollateral", - "args": { - "reserve": "WETH", - "user": "1", - "useAsCollateral": "false" - }, - "expected": "revert" - } - ] - }, - { - "description": "User 1 Deposits 640 more AAVE (enough to cover the DAI debt), disables WETH as collateral", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "AAVE", - "amount": "640", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "AAVE", - "amount": "640", - "user": "1" - }, - "expected": "success" - }, - { - "name": "setUseAsCollateral", - "args": { - "reserve": "WETH", - "user": "1", - "useAsCollateral": "false" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 disables AAVE as collateral (revert expected)", - "actions": [ - { - "name": "setUseAsCollateral", - "args": { - "reserve": "AAVE", - "user": "1", - "useAsCollateral": "false" - }, - "expected": "revert" - } - ] - }, - { - "description": "User 1 reenables WETH as collateral", - "actions": [ - { - "name": "setUseAsCollateral", - "args": { - "reserve": "WETH", - "user": "1", - "useAsCollateral": "true" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/swap-rate-mode.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/swap-rate-mode.json deleted file mode 100644 index a68bc08..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/swap-rate-mode.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "title": "Pool: Swap rate mode", - "description": "Test cases for the swapBorrowRateMode() function.", - "stories": [ - { - "description": "User 0 tries to swap rate mode without any variable rate loan in progress (revert expected)", - "actions": [ - { - "name": "swapBorrowRateMode", - "args": { - "reserve": "DAI", - "user": "1", - "borrowRateMode": "variable" - }, - "expected": "revert", - "revertMessage": "User does not have a variable rate loan in progress on this reserve" - } - ] - }, - { - "description": "User 0 tries to swap rate mode without any stable rate loan in progress (revert expected)", - "actions": [ - { - "name": "swapBorrowRateMode", - "args": { - "reserve": "DAI", - "user": "1", - "borrowRateMode": "stable" - }, - "expected": "revert", - "revertMessage": "User does not have a stable rate loan in progress on this reserve" - } - ] - }, - { - "description": "User 0 deposits 1000 DAI, user 1 deposits 2 WETH as collateral, borrows 100 DAI at variable rate and swaps to stable after one year", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "1000", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "1000", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "2", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "100", - "borrowRateMode": "variable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "swapBorrowRateMode", - "args": { - "reserve": "DAI", - "user": "1", - "borrowRateMode": "variable" - }, - "expected": "success" - } - ] - }, - { - "description": "User 1 borrows another 100 DAI, and swaps back to variable after one year, repays the loan", - "actions": [ - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "100", - "borrowRateMode": "stable", - "user": "1", - "timeTravel": "365" - }, - "expected": "success" - }, - { - "name": "swapBorrowRateMode", - "args": { - "reserve": "DAI", - "user": "1", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "mint", - "description": "Mint 50 DAI to cover the interest", - "args": { - "reserve": "DAI", - "amount": "50", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "repay", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "1", - "onBehalfOf": "1", - "borrowRateMode": "variable" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/withdraw-negatives.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/withdraw-negatives.json deleted file mode 100644 index 3f79ca7..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/withdraw-negatives.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "title": "Pool: Redeem negative test cases", - "description": "Redeem function.", - "stories": [ - { - "description": "Users 0 Deposits 14760.147 DAI and tries to redeem 0 DAI (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "0", - "user": "0" - }, - "expected": "revert", - "revertMessage": "Amount to redeem needs to be > 0" - } - ] - }, - { - "description": "Users 0 tries to redeem 16236.16 DAI from the 14760.147 DAI deposited (revert expected)", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "16236.16", - "user": "0" - }, - "expected": "revert", - "revertMessage": "User cannot redeem more than the available balance" - } - ] - }, - { - "description": "Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected)", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "100", - "user": "1", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "1" - }, - "expected": "revert", - "revertMessage": "Transfer cannot be allowed." - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/withdraw.json b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/withdraw.json deleted file mode 100644 index e90df1c..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/scenarios/withdraw.json +++ /dev/null @@ -1,389 +0,0 @@ -{ - "title": "Pool: Withdraw", - "description": "withdraw function.", - "stories": [ - { - "description": "Users 3 Deposit 14760.147 DAI, set using as collateral = false, then withdraw 14760.147 dai", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "3" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "3" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "3" - }, - "expected": "success" - }, - { - "name": "setUseAsCollateral", - "args": { - "reserve": "DAI", - "user": "3", - "useAsCollateral": "false" - }, - "expected": "success" - }, - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "3" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 Deposits 14760.147 DAI in an empty reserve", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws half of the deposited DAI", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "500", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws remaining half of the deposited DAI", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 Deposits 14760.147 USDC in an empty reserve", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws half of the deposited USDC", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "USDC", - "amount": "500", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws remaining half of the deposited USDC", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "USDC", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 Deposits 1 WETH in an empty reserve", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws half of the deposited WETH", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "0.5", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "User 0 withdraws remaining half of the deposited WETH", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "-1", - "user": "0" - }, - "expected": "success" - } - ] - }, - { - "description": "Users 0 and 1 Deposit 14760.147 DAI, both withdraw", - "actions": [ - { - "name": "mint", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "DAI", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "0" - }, - "expected": "success" - }, - { - "name": "withdraw", - "args": { - "reserve": "DAI", - "amount": "-1", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "Users 0 deposits 14760.147 DAI, user 1 Deposit 14760.147 USDC and 1 WETH, borrows 100 DAI. User 1 tries to withdraw all the USDC", - "actions": [ - { - "name": "deposit", - "args": { - "reserve": "DAI", - "amount": "14760.147", - "user": "0" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "USDC", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "USDC", - "amount": "14760.147", - "user": "1" - }, - "expected": "success" - }, - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "1" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - "amount": "1", - "user": "1" - }, - "expected": "success" - }, - { - "name": "borrow", - "args": { - "reserve": "DAI", - "amount": "100", - "user": "1", - "borrowRateMode": "stable" - }, - "expected": "success" - }, - { - "name": "withdraw", - "args": { - "reserve": "USDC", - "amount": "-1", - "user": "1" - }, - "expected": "success" - } - ] - }, - { - "description": "Users 1 tries to withdraw 0.05 WETH, which does not bring the HF below 1", - "actions": [ - { - "name": "withdraw", - "args": { - "reserve": "WETH", - "amount": "0.05", - "user": "1" - }, - "expected": "success" - } - ] - } - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/calculations.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/calculations.ts deleted file mode 100644 index 9484c54..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/calculations.ts +++ /dev/null @@ -1,1585 +0,0 @@ -import { ONE_YEAR, RAY, MAX_UINT_AMOUNT, PERCENTAGE_FACTOR } from '../../../helpers/constants'; -import { IReserveParams, iMultiPoolsAssets, RateMode } from '../../../helpers/types'; -import './wadraymath'; -import { ReserveData, UserReserveData } from './interfaces'; -import { BigNumber } from 'ethers'; -import { expect } from 'chai'; - -interface Configuration { - reservesParams: iMultiPoolsAssets; -} - -export const configuration: Configuration = {}; - -export const calcExpectedUserDataAfterDeposit = ( - amountDeposited: string, - reserveDataBeforeAction: ReserveData, - reserveDataAfterAction: ReserveData, - userDataBeforeAction: UserReserveData, - txTimestamp: BigNumber, - currentTimestamp: BigNumber, - txCost: BigNumber -): UserReserveData => { - const expectedUserData = {}; - - expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; - expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex; - expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; - expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; - expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate; - - expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance( - userDataBeforeAction, - reserveDataAfterAction.liquidityIndex, - BigNumber.from(amountDeposited), - BigNumber.from(0) - ); - expectedUserData.currentATokenBalance = calcExpectedATokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ).add(amountDeposited); - - if (userDataBeforeAction.currentATokenBalance.eq(0)) { - expectedUserData.usageAsCollateralEnabled = true; - } else { - expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled; - } - - expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex; - expectedUserData.walletBalance = userDataBeforeAction.walletBalance.sub(amountDeposited); - - expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = - calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - expectedUserData.currentVariableDebt = expectedUserData.principalStableDebt = - calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - return expectedUserData; -}; - -export const calcExpectedUserDataAfterWithdraw = ( - amountWithdrawn: string, - reserveDataBeforeAction: ReserveData, - reserveDataAfterAction: ReserveData, - userDataBeforeAction: UserReserveData, - txTimestamp: BigNumber, - currentTimestamp: BigNumber, - txCost: BigNumber -): UserReserveData => { - const expectedUserData = {}; - - const aTokenBalance = calcExpectedATokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - if (amountWithdrawn == MAX_UINT_AMOUNT) { - amountWithdrawn = aTokenBalance.toString(); - } - - expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance( - userDataBeforeAction, - reserveDataAfterAction.liquidityIndex, - BigNumber.from(0), - BigNumber.from(amountWithdrawn) - ); - - expectedUserData.currentATokenBalance = aTokenBalance.sub(amountWithdrawn); - expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; - expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex; - expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; - expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; - - expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate; - - if (userDataBeforeAction.currentATokenBalance.eq(0)) { - expectedUserData.usageAsCollateralEnabled = true; - } else { - //if the user is withdrawing everything, usageAsCollateralEnabled must be false - if (expectedUserData.currentATokenBalance.eq(0)) { - expectedUserData.usageAsCollateralEnabled = false; - } else { - expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled; - } - } - - expectedUserData.walletBalance = userDataBeforeAction.walletBalance.add(amountWithdrawn); - - return expectedUserData; -}; - -export const calcExpectedReserveDataAfterDeposit = ( - amountDeposited: string, - reserveDataBeforeAction: ReserveData, - txTimestamp: BigNumber -): ReserveData => { - const expectedReserveData: ReserveData = {}; - expectedReserveData.unbacked = reserveDataBeforeAction.unbacked; - expectedReserveData.address = reserveDataBeforeAction.address; - expectedReserveData.reserveFactor = reserveDataBeforeAction.reserveFactor; - - updateState(reserveDataBeforeAction, expectedReserveData, txTimestamp); - updateLiquidityAndUsageRatios( - reserveDataBeforeAction, - expectedReserveData, - BigNumber.from(amountDeposited), - BigNumber.from(0) - ); - - expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - expectedReserveData.liquidityRate = rates[0]; - expectedReserveData.stableBorrowRate = rates[1]; - expectedReserveData.variableBorrowRate = rates[2]; - - updateTotalLiquidityAndUsageRatio(expectedReserveData); - - return expectedReserveData; -}; - -export const calcExpectedReserveDataAfterMintUnbacked = ( - amountMinted: string, - reserveDataBeforeAction: ReserveData, - txTimestamp: BigNumber -): ReserveData => { - const expectedReserveData: ReserveData = {}; - const amountMintedBN = BigNumber.from(amountMinted); - - expectedReserveData.address = reserveDataBeforeAction.address; - expectedReserveData.reserveFactor = reserveDataBeforeAction.reserveFactor; - - updateState(reserveDataBeforeAction, expectedReserveData, txTimestamp); - - expectedReserveData.unbacked = reserveDataBeforeAction.unbacked.add(amountMintedBN); - updateLiquidityAndUsageRatios( - reserveDataBeforeAction, - expectedReserveData, - BigNumber.from(0), - BigNumber.from(0) - ); - - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt, - BigNumber.from(0), - reserveDataBeforeAction.stableBorrowRate - ); - - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - expectedReserveData.liquidityRate = rates[0]; - expectedReserveData.stableBorrowRate = rates[1]; - expectedReserveData.variableBorrowRate = rates[2]; - - updateTotalLiquidityAndUsageRatio(expectedReserveData); - - return expectedReserveData; -}; - -export const calcExpectedReserveDataAfterBackUnbacked = ( - scaledATokenSupply: BigNumber, - amount: string, - fee: string, - bridgeProtocolFee: string, - reserveDataBeforeAction: ReserveData, - txTimestamp: BigNumber -): ReserveData => { - const cumulateToLiquidityIndex = ( - liquidityIndex: BigNumber, - totalLiquidity: BigNumber, - amount: BigNumber - ) => { - const amountToLiquidityRatio = amount.wadToRay().rayDiv(totalLiquidity.wadToRay()); - return amountToLiquidityRatio.add(RAY).rayMul(liquidityIndex); - }; - const expectedReserveData: ReserveData = {}; - expectedReserveData.address = reserveDataBeforeAction.address; - expectedReserveData.reserveFactor = reserveDataBeforeAction.reserveFactor; - updateState(reserveDataBeforeAction, expectedReserveData, txTimestamp); - - const amountBN = BigNumber.from(amount); - const backingAmount = amountBN.lt(reserveDataBeforeAction.unbacked) - ? amountBN - : reserveDataBeforeAction.unbacked; - - const feeBN = BigNumber.from(fee); - - const protocolFeePercentage = BigNumber.from(bridgeProtocolFee); - - const premiumToProtocol = feeBN.percentMul(protocolFeePercentage); - const premiumToLP = feeBN.sub(premiumToProtocol); - - const totalSupply = scaledATokenSupply.rayMul(expectedReserveData.liquidityIndex); - // The fee is added directly to total liquidity, the backing will not change this liquidity. - // We only update the liquidity index at the end, because it will otherwise influence computations midway - - expectedReserveData.liquidityIndex = cumulateToLiquidityIndex( - expectedReserveData.liquidityIndex, - totalSupply, - premiumToLP - ); - - expectedReserveData.accruedToTreasuryScaled = expectedReserveData.accruedToTreasuryScaled.add( - premiumToProtocol.rayDiv(expectedReserveData.liquidityIndex) - ); - - expectedReserveData.unbacked = reserveDataBeforeAction.unbacked.sub(backingAmount); - - updateLiquidityAndUsageRatios( - reserveDataBeforeAction, - expectedReserveData, - backingAmount.add(feeBN), - BigNumber.from(0) - ); - - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt, - BigNumber.from(0), - reserveDataBeforeAction.stableBorrowRate - ); - - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - - expectedReserveData.liquidityRate = rates[0]; - expectedReserveData.stableBorrowRate = rates[1]; - expectedReserveData.variableBorrowRate = rates[2]; - - updateTotalLiquidityAndUsageRatio(expectedReserveData); - - return expectedReserveData; -}; - -export const calcExpectedReserveDataAfterWithdraw = ( - amountWithdrawn: string, - reserveDataBeforeAction: ReserveData, - userDataBeforeAction: UserReserveData, - txTimestamp: BigNumber -): ReserveData => { - const expectedReserveData: ReserveData = {}; - expectedReserveData.unbacked = reserveDataBeforeAction.unbacked; - expectedReserveData.address = reserveDataBeforeAction.address; - expectedReserveData.reserveFactor = reserveDataBeforeAction.reserveFactor; - - if (amountWithdrawn == MAX_UINT_AMOUNT) { - amountWithdrawn = calcExpectedATokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ).toString(); - } - - updateState(reserveDataBeforeAction, expectedReserveData, txTimestamp); - updateLiquidityAndUsageRatios( - reserveDataBeforeAction, - expectedReserveData, - BigNumber.from(0), - BigNumber.from(amountWithdrawn) - ); - - expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - expectedReserveData.liquidityRate = rates[0]; - expectedReserveData.stableBorrowRate = rates[1]; - expectedReserveData.variableBorrowRate = rates[2]; - - updateTotalLiquidityAndUsageRatio(expectedReserveData); - - return expectedReserveData; -}; - -export const calcExpectedReserveDataAfterBorrow = ( - amountBorrowed: string, - borrowRateMode: string, - reserveDataBeforeAction: ReserveData, - userDataBeforeAction: UserReserveData, - txTimestamp: BigNumber, - currentTimestamp: BigNumber -): ReserveData => { - const expectedReserveData: ReserveData = {}; - expectedReserveData.unbacked = reserveDataBeforeAction.unbacked; - expectedReserveData.address = reserveDataBeforeAction.address; - expectedReserveData.reserveFactor = reserveDataBeforeAction.reserveFactor; - expectedReserveData.lastUpdateTimestamp = txTimestamp; - - const amountBorrowedBN = BigNumber.from(amountBorrowed); - - // Update indexes - updateState(reserveDataBeforeAction, expectedReserveData, txTimestamp); - updateLiquidityAndUsageRatios( - reserveDataBeforeAction, - expectedReserveData, - BigNumber.from(0), - BigNumber.from(amountBorrowed) - ); - - // Now we can perform the borrow THERE MUST BE SOMETHING IN HERE THAN CAN BE SIMPLIFIED - if (borrowRateMode == RateMode.Stable) { - const expectedStableDebtUntilTx = calcExpectedTotalStableDebt( - reserveDataBeforeAction.principalStableDebt, - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebtLastUpdated, - txTimestamp - ); - - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( - reserveDataBeforeAction.averageStableBorrowRate, - expectedStableDebtUntilTx, - amountBorrowedBN, - reserveDataBeforeAction.stableBorrowRate - ); - - expectedReserveData.principalStableDebt = expectedStableDebtUntilTx.add(amountBorrowedBN); - - const ratesAfterTx = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.principalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - - expectedReserveData.liquidityRate = ratesAfterTx[0]; - expectedReserveData.stableBorrowRate = ratesAfterTx[1]; - expectedReserveData.variableBorrowRate = ratesAfterTx[2]; - - expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( - expectedReserveData.principalStableDebt, - expectedReserveData.averageStableBorrowRate, - txTimestamp, - currentTimestamp - ); - - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul( - calcExpectedReserveNormalizedDebt( - expectedReserveData.variableBorrowRate, - expectedReserveData.variableBorrowIndex, - txTimestamp, - currentTimestamp - ) - ); - - [expectedReserveData.borrowUsageRatio, expectedReserveData.supplyUsageRatio] = - calcExpectedUsageRatios( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - } else { - expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; - - const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance( - reserveDataBeforeAction.principalStableDebt, - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebtLastUpdated, - txTimestamp - ); - - expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( - reserveDataBeforeAction.principalStableDebt, - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebtLastUpdated, - currentTimestamp - ); - - expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; - - expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.add( - amountBorrowedBN.rayDiv(expectedReserveData.variableBorrowIndex) - ); - - const totalVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul( - expectedReserveData.variableBorrowIndex - ); - - [expectedReserveData.borrowUsageRatio, expectedReserveData.supplyUsageRatio] = - calcExpectedUsageRatios( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - totalStableDebtAfterTx, - totalVariableDebtAfterTx, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - - expectedReserveData.liquidityRate = rates[0]; - expectedReserveData.stableBorrowRate = rates[1]; - expectedReserveData.variableBorrowRate = rates[2]; - - expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( - calcExpectedReserveNormalizedDebt( - expectedReserveData.variableBorrowRate, - expectedReserveData.variableBorrowIndex, - txTimestamp, - currentTimestamp - ) - ); - - [expectedReserveData.borrowUsageRatio, expectedReserveData.supplyUsageRatio] = - calcExpectedUsageRatios( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - } - - return expectedReserveData; -}; - -export const calcExpectedReserveDataAfterRepay = ( - amountRepaid: string, - borrowRateMode: RateMode, - reserveDataBeforeAction: ReserveData, - userDataBeforeAction: UserReserveData, - txTimestamp: BigNumber, - currentTimestamp: BigNumber -): ReserveData => { - const expectedReserveData: ReserveData = {}; - expectedReserveData.unbacked = reserveDataBeforeAction.unbacked; - expectedReserveData.address = reserveDataBeforeAction.address; - expectedReserveData.reserveFactor = reserveDataBeforeAction.reserveFactor; - - // TODO: The repay amount here need to be capped to the balance. - - let amountRepaidBN = BigNumber.from(amountRepaid); - - const userStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - const userVariableDebt = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - //if amount repaid == MAX_UINT_AMOUNT, user is repaying everything - if (amountRepaidBN.abs().eq(MAX_UINT_AMOUNT)) { - if (borrowRateMode == RateMode.Stable) { - amountRepaidBN = userStableDebt; - } else { - amountRepaidBN = userVariableDebt; - } - } - - updateState(reserveDataBeforeAction, expectedReserveData, txTimestamp); - updateLiquidityAndUsageRatios( - reserveDataBeforeAction, - expectedReserveData, - amountRepaidBN, - BigNumber.from(0) - ); - - if (borrowRateMode == RateMode.Stable) { - const expectedDebt = calcExpectedTotalStableDebt( - reserveDataBeforeAction.principalStableDebt, - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebtLastUpdated, - txTimestamp - ); - - expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = - expectedDebt.sub(amountRepaidBN); - - //due to accumulation errors, the total stable debt might be smaller than the last user debt. - //in this case we simply set the total supply and avg stable rate to 0. - if (expectedReserveData.totalStableDebt.lt(0)) { - expectedReserveData.principalStableDebt = - expectedReserveData.totalStableDebt = - expectedReserveData.averageStableBorrowRate = - BigNumber.from(0); - } else { - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( - reserveDataBeforeAction.averageStableBorrowRate, - expectedDebt, - amountRepaidBN.negated(), - userDataBeforeAction.stableBorrowRate - ); - - //also due to accumulation errors, the final avg stable rate when the last user repays might be negative. - //if that is the case, it means a small leftover of total stable debt is left, which can be erased. - if (expectedReserveData.averageStableBorrowRate.lt(0)) { - expectedReserveData.principalStableDebt = - expectedReserveData.totalStableDebt = - expectedReserveData.averageStableBorrowRate = - BigNumber.from(0); - } - } - } else { - expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.sub( - amountRepaidBN.rayDiv(expectedReserveData.variableBorrowIndex) - ); - expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( - expectedReserveData.variableBorrowIndex - ); - - expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; - } - - // Update usage ratio because of debt change - [expectedReserveData.borrowUsageRatio, expectedReserveData.supplyUsageRatio] = - calcExpectedUsageRatios( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - expectedReserveData.liquidityRate = rates[0]; - expectedReserveData.stableBorrowRate = rates[1]; - expectedReserveData.variableBorrowRate = rates[2]; - - expectedReserveData.lastUpdateTimestamp = txTimestamp; - - updateTotalLiquidityAndUsageRatio(expectedReserveData); - - return expectedReserveData; -}; - -export const calcExpectedUserDataAfterBorrow = ( - amountBorrowed: string, - interestRateMode: string, - reserveDataBeforeAction: ReserveData, - expectedDataAfterAction: ReserveData, - userDataBeforeAction: UserReserveData, - txTimestamp: BigNumber, - currentTimestamp: BigNumber -): UserReserveData => { - const expectedUserData = {}; - - const amountBorrowedBN = BigNumber.from(amountBorrowed); - - if (interestRateMode == RateMode.Stable) { - const stableDebtUntilTx = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - expectedUserData.principalStableDebt = stableDebtUntilTx.add(amountBorrowed); - expectedUserData.stableRateLastUpdated = txTimestamp; - - expectedUserData.stableBorrowRate = calcExpectedUserStableRate( - stableDebtUntilTx, - userDataBeforeAction.stableBorrowRate, - amountBorrowedBN, - reserveDataBeforeAction.stableBorrowRate - ); - - expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( - expectedUserData.principalStableDebt, - expectedUserData.stableBorrowRate, - txTimestamp, - currentTimestamp - ); - - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; - } else { - expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.add( - amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex) - ); - - expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; - - expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; - - expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; - - expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - currentTimestamp - ); - } - - expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( - expectedDataAfterAction, - expectedUserData, - currentTimestamp - ); - - expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; - - expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled; - - expectedUserData.currentATokenBalance = calcExpectedATokenBalance( - expectedDataAfterAction, - userDataBeforeAction, - currentTimestamp - ); - - expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance; - - expectedUserData.walletBalance = userDataBeforeAction.walletBalance.add(amountBorrowed); - - return expectedUserData; -}; - -export const calcExpectedUserDataAfterRepay = ( - totalRepaid: string, - rateMode: RateMode, - reserveDataBeforeAction: ReserveData, - expectedDataAfterAction: ReserveData, - userDataBeforeAction: UserReserveData, - user: string, - onBehalfOf: string, - txTimestamp: BigNumber, - currentTimestamp: BigNumber -): UserReserveData => { - const expectedUserData = {}; - - const variableDebt = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - currentTimestamp - ); - - const stableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - currentTimestamp - ); - - let totalRepaidBN = BigNumber.from(totalRepaid); - if (totalRepaidBN.abs().eq(MAX_UINT_AMOUNT)) { - totalRepaidBN = rateMode == RateMode.Stable ? stableDebt : variableDebt; - } - - if (rateMode == RateMode.Stable) { - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; - expectedUserData.currentVariableDebt = variableDebt; - - expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = - stableDebt.sub(totalRepaidBN); - - if (expectedUserData.currentStableDebt.eq('0')) { - //user repaid everything - expectedUserData.stableBorrowRate = expectedUserData.stableRateLastUpdated = - BigNumber.from('0'); - } else { - expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; - expectedUserData.stableRateLastUpdated = txTimestamp; - } - } else { - expectedUserData.currentStableDebt = userDataBeforeAction.principalStableDebt; - expectedUserData.principalStableDebt = stableDebt; - expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; - expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; - - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.sub( - totalRepaidBN.rayDiv(expectedDataAfterAction.variableBorrowIndex) - ); - expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul( - expectedDataAfterAction.variableBorrowIndex - ); - } - - expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; - - expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled; - - expectedUserData.currentATokenBalance = calcExpectedATokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance; - - if (user === onBehalfOf) { - expectedUserData.walletBalance = userDataBeforeAction.walletBalance.sub(totalRepaidBN); - } else { - //wallet balance didn't change - expectedUserData.walletBalance = userDataBeforeAction.walletBalance; - } - - return expectedUserData; -}; - -export const calcExpectedUserDataAfterSetUseAsCollateral = ( - useAsCollateral: boolean, - reserveDataBeforeAction: ReserveData, - userDataBeforeAction: UserReserveData, - txCost: BigNumber -): UserReserveData => { - const expectedUserData = { ...userDataBeforeAction }; - - expectedUserData.usageAsCollateralEnabled = useAsCollateral; - - return expectedUserData; -}; - -export const calcExpectedReserveDataAfterSwapRateMode = ( - reserveDataBeforeAction: ReserveData, - userDataBeforeAction: UserReserveData, - rateMode: string, - txTimestamp: BigNumber -): ReserveData => { - const expectedReserveData: ReserveData = {}; - expectedReserveData.unbacked = reserveDataBeforeAction.unbacked; - expectedReserveData.address = reserveDataBeforeAction.address; - expectedReserveData.reserveFactor = reserveDataBeforeAction.reserveFactor; - - updateState(reserveDataBeforeAction, expectedReserveData, txTimestamp); - - updateLiquidityAndUsageRatios( - reserveDataBeforeAction, - expectedReserveData, - BigNumber.from(0), - BigNumber.from(0) - ); - - const variableDebt = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - const stableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - const totalStableDebtUntilTx = expectedReserveData.totalStableDebt; - - if (rateMode === RateMode.Stable) { - //swap user stable debt to variable - expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.add( - stableDebt.rayDiv(expectedReserveData.variableBorrowIndex) - ); - - expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( - expectedReserveData.variableBorrowIndex - ); - - expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = - totalStableDebtUntilTx.sub(stableDebt); - - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( - reserveDataBeforeAction.averageStableBorrowRate, - expectedReserveData.principalStableDebt.add(stableDebt), - stableDebt.negated(), - userDataBeforeAction.stableBorrowRate - ); - } else { - //swap variable to stable - expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = - totalStableDebtUntilTx.add(variableDebt); - - expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.sub( - variableDebt.rayDiv(expectedReserveData.variableBorrowIndex) - ); - - expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( - expectedReserveData.variableBorrowIndex - ); - - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt, - variableDebt, - reserveDataBeforeAction.stableBorrowRate - ); - } - - [expectedReserveData.borrowUsageRatio, expectedReserveData.supplyUsageRatio] = - calcExpectedUsageRatios( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - expectedReserveData.liquidityRate = rates[0]; - expectedReserveData.stableBorrowRate = rates[1]; - expectedReserveData.variableBorrowRate = rates[2]; - - updateTotalLiquidityAndUsageRatio(expectedReserveData); - - return expectedReserveData; -}; - -export const calcExpectedUserDataAfterSwapRateMode = ( - reserveDataBeforeAction: ReserveData, - expectedDataAfterAction: ReserveData, - userDataBeforeAction: UserReserveData, - rateMode: string, - txCost: BigNumber, - txTimestamp: BigNumber -): UserReserveData => { - const expectedUserData = { ...userDataBeforeAction }; - - const stableDebtBalance = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - const variableDebtBalance = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - expectedUserData.currentATokenBalance = calcExpectedATokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - if (rateMode === RateMode.Stable) { - // swap to variable - expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = BigNumber.from(0); - - expectedUserData.stableBorrowRate = BigNumber.from(0); - - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.add( - stableDebtBalance.rayDiv(expectedDataAfterAction.variableBorrowIndex) - ); - expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul( - expectedDataAfterAction.variableBorrowIndex - ); - - expectedUserData.stableRateLastUpdated = BigNumber.from(0); - } else { - expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = - userDataBeforeAction.currentStableDebt.add(variableDebtBalance); - - //weighted average of the previous and the current - expectedUserData.stableBorrowRate = calcExpectedUserStableRate( - stableDebtBalance, - userDataBeforeAction.stableBorrowRate, - variableDebtBalance, - reserveDataBeforeAction.stableBorrowRate - ); - - expectedUserData.stableRateLastUpdated = txTimestamp; - - expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt = BigNumber.from(0); - } - - expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; - - return expectedUserData; -}; - -export const calcExpectedReserveDataAfterStableRateRebalance = ( - reserveDataBeforeAction: ReserveData, - userDataBeforeAction: UserReserveData, - txTimestamp: BigNumber -): ReserveData => { - const expectedReserveData: ReserveData = {}; - expectedReserveData.unbacked = reserveDataBeforeAction.unbacked; - expectedReserveData.address = reserveDataBeforeAction.address; - expectedReserveData.reserveFactor = reserveDataBeforeAction.reserveFactor; - - updateState(reserveDataBeforeAction, expectedReserveData, txTimestamp); - updateLiquidityAndUsageRatios( - reserveDataBeforeAction, - expectedReserveData, - BigNumber.from(0), - BigNumber.from(0) - ); - - const userStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = - calcExpectedTotalStableDebt( - reserveDataBeforeAction.principalStableDebt, - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebtLastUpdated, - txTimestamp - ); - - //removing the stable liquidity at the old rate - - const avgRateBefore = calcExpectedAverageStableBorrowRateRebalance( - reserveDataBeforeAction.averageStableBorrowRate, - expectedReserveData.totalStableDebt, - userStableDebt.negated(), - userDataBeforeAction.stableBorrowRate - ); - // adding it again at the new rate - - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRateRebalance( - avgRateBefore, - expectedReserveData.totalStableDebt.sub(userStableDebt), - userStableDebt, - reserveDataBeforeAction.stableBorrowRate - ); - - [expectedReserveData.borrowUsageRatio, expectedReserveData.supplyUsageRatio] = - calcExpectedUsageRatios( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); - - expectedReserveData.liquidityRate = rates[0]; - expectedReserveData.stableBorrowRate = rates[1]; - expectedReserveData.variableBorrowRate = rates[2]; - - updateTotalLiquidityAndUsageRatio(expectedReserveData); - - return expectedReserveData; -}; - -export const calcExpectedUserDataAfterStableRateRebalance = ( - reserveDataBeforeAction: ReserveData, - expectedDataAfterAction: ReserveData, - userDataBeforeAction: UserReserveData, - txCost: BigNumber, - txTimestamp: BigNumber -): UserReserveData => { - const expectedUserData = { ...userDataBeforeAction }; - - expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; - - expectedUserData.principalVariableDebt = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = - calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, - txTimestamp - ); - - expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - expectedUserData.stableRateLastUpdated = txTimestamp; - - expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt; - - // Stable rate after burn - expectedUserData.stableBorrowRate = expectedDataAfterAction.averageStableBorrowRate; - expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; - - expectedUserData.currentATokenBalance = calcExpectedATokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - return expectedUserData; -}; - -const calcExpectedScaledATokenBalance = ( - userDataBeforeAction: UserReserveData, - index: BigNumber, - amountAdded: BigNumber, - amountTaken: BigNumber -) => { - return userDataBeforeAction.scaledATokenBalance - .add(amountAdded.rayDiv(index)) - .sub(amountTaken.rayDiv(index)); -}; - -export const calcExpectedATokenBalance = ( - reserveData: ReserveData, - userData: UserReserveData, - currentTimestamp: BigNumber -) => { - const index = calcExpectedReserveNormalizedIncome(reserveData, currentTimestamp); - - const { scaledATokenBalance: scaledBalanceBeforeAction } = userData; - - return scaledBalanceBeforeAction.rayMul(index); -}; - -const calcExpectedAverageStableBorrowRate = ( - avgStableRateBefore: BigNumber, - totalStableDebtBefore: BigNumber, - amountChanged: string | BigNumber, - rate: BigNumber -) => { - const weightedTotalBorrows = avgStableRateBefore.mul(totalStableDebtBefore); - const weightedAmountBorrowed = rate.mul(amountChanged); - const totalBorrowedStable = totalStableDebtBefore.add(amountChanged); - - if (totalBorrowedStable.eq(0)) return BigNumber.from('0'); - - return weightedTotalBorrows.add(weightedAmountBorrowed).div(totalBorrowedStable); -}; - -const calcExpectedAverageStableBorrowRateRebalance = ( - avgStableRateBefore: BigNumber, - totalStableDebtBefore: BigNumber, - amountChanged: BigNumber, - rate: BigNumber -) => { - const weightedTotalBorrows = avgStableRateBefore.rayMul(totalStableDebtBefore); - const weightedAmountBorrowed = rate.rayMul(amountChanged.wadToRay()); - const totalBorrowedStable = totalStableDebtBefore.add(amountChanged.wadToRay()); - - if (totalBorrowedStable.eq(0)) return BigNumber.from('0'); - - return weightedTotalBorrows.add(weightedAmountBorrowed).rayDiv(totalBorrowedStable); -}; - -export const calcExpectedVariableDebtTokenBalance = ( - reserveData: ReserveData, - userData: UserReserveData, - currentTimestamp: BigNumber -) => { - const normalizedDebt = calcExpectedReserveNormalizedDebt( - reserveData.variableBorrowRate, - reserveData.variableBorrowIndex, - reserveData.lastUpdateTimestamp, - currentTimestamp - ); - - const { scaledVariableDebt } = userData; - - return scaledVariableDebt.rayMul(normalizedDebt); -}; - -export const calcExpectedStableDebtTokenBalance = ( - principalStableDebt: BigNumber, - stableBorrowRate: BigNumber, - stableRateLastUpdated: BigNumber, - currentTimestamp: BigNumber -) => { - if ( - stableBorrowRate.eq(0) || - currentTimestamp.eq(stableRateLastUpdated) || - stableRateLastUpdated.eq(0) - ) { - return principalStableDebt; - } - - const cumulatedInterest = calcCompoundedInterest( - stableBorrowRate, - currentTimestamp, - stableRateLastUpdated - ); - - return principalStableDebt.rayMul(cumulatedInterest); -}; - -const calcLinearInterest = ( - rate: BigNumber, - currentTimestamp: BigNumber, - lastUpdateTimestamp: BigNumber -) => { - const timeDifference = currentTimestamp.sub(lastUpdateTimestamp); - - const cumulatedInterest = rate.mul(timeDifference).div(BigNumber.from(ONE_YEAR)).add(RAY); - - return cumulatedInterest; -}; - -export const calcCompoundedInterest = ( - rate: BigNumber, - currentTimestamp: BigNumber, - lastUpdateTimestamp: BigNumber -) => { - const timeDifference = currentTimestamp.sub(lastUpdateTimestamp); - const SECONDS_PER_YEAR = BigNumber.from(ONE_YEAR); - - if (timeDifference.eq(0)) { - return BigNumber.from(RAY); - } - - const expMinusOne = timeDifference.sub(1); - const expMinusTwo = timeDifference.gt(2) ? timeDifference.sub(2) : 0; - - const basePowerTwo = rate.rayMul(rate).div(SECONDS_PER_YEAR.mul(SECONDS_PER_YEAR)); - const basePowerThree = basePowerTwo.rayMul(rate).div(SECONDS_PER_YEAR); - - const secondTerm = timeDifference.mul(expMinusOne).mul(basePowerTwo).div(2); - const thirdTerm = timeDifference.mul(expMinusOne).mul(expMinusTwo).mul(basePowerThree).div(6); - - return BigNumber.from(RAY) - .add(rate.mul(timeDifference).div(SECONDS_PER_YEAR)) - .add(secondTerm) - .add(thirdTerm); -}; - -export const calcExpectedInterestRates = ( - reserveSymbol: string, - marketStableRate: BigNumber, - totalStableDebt: BigNumber, - totalVariableDebt: BigNumber, - averageStableBorrowRate: BigNumber, - availableLiquidity: BigNumber, - totalLiquidity: BigNumber -): BigNumber[] => { - const { reservesParams } = configuration; - const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol); - const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[ - reserveIndex - ]; - - const [borrowUsageRatio, supplyUsageRatio] = calcExpectedUsageRatios( - totalStableDebt, - totalVariableDebt, - availableLiquidity, - totalLiquidity - ); - - let stableBorrowRate: BigNumber = marketStableRate; - let variableBorrowRate: BigNumber = BigNumber.from( - reserveConfiguration.strategy.baseVariableBorrowRate - ); - - const OPTIMAL_USAGE_RATIO = BigNumber.from(reserveConfiguration.strategy.optimalUsageRatio); - const MAX_EXCESS_USAGE_RATIO = BigNumber.from(RAY).sub(OPTIMAL_USAGE_RATIO); - const OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = BigNumber.from( - reserveConfiguration.strategy.optimalStableToTotalDebtRatio - ); - const MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO = BigNumber.from(RAY).sub( - OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO - ); - - const totalDebt = totalStableDebt.add(totalVariableDebt); - - const stableToTotalDebtRatio = totalStableDebt.gt(0) - ? totalStableDebt.rayDiv(totalDebt) - : BigNumber.from(0); - - if (borrowUsageRatio.gt(OPTIMAL_USAGE_RATIO)) { - const excessBorrowUsageRatio = borrowUsageRatio - .sub(reserveConfiguration.strategy.optimalUsageRatio) - .rayDiv(MAX_EXCESS_USAGE_RATIO); - - stableBorrowRate = stableBorrowRate - .add(reserveConfiguration.strategy.stableRateSlope1) - .add( - BigNumber.from(reserveConfiguration.strategy.stableRateSlope2).rayMul( - excessBorrowUsageRatio - ) - ); - - variableBorrowRate = variableBorrowRate - .add(reserveConfiguration.strategy.variableRateSlope1) - .add( - BigNumber.from(reserveConfiguration.strategy.variableRateSlope2).rayMul( - excessBorrowUsageRatio - ) - ); - } else { - stableBorrowRate = stableBorrowRate.add( - BigNumber.from(reserveConfiguration.strategy.stableRateSlope1) - .rayMul(borrowUsageRatio) - .rayDiv(BigNumber.from(OPTIMAL_USAGE_RATIO)) - ); - variableBorrowRate = variableBorrowRate.add( - BigNumber.from(reserveConfiguration.strategy.variableRateSlope1) - .rayMul(borrowUsageRatio) - .rayDiv(OPTIMAL_USAGE_RATIO) - ); - } - - if (stableToTotalDebtRatio.gt(OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO)) { - const excessStableDebtRatio = stableToTotalDebtRatio - .sub(OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO) - .rayDiv(MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO); - stableBorrowRate = stableBorrowRate.add( - BigNumber.from(reserveConfiguration.strategy.stableRateExcessOffset).rayMul( - excessStableDebtRatio - ) - ); - } - - const expectedOverallRate = calcExpectedOverallBorrowRate( - totalStableDebt, - totalVariableDebt, - variableBorrowRate, - averageStableBorrowRate - ); - const liquidityRate = expectedOverallRate - .rayMul(supplyUsageRatio) - .percentMul(BigNumber.from(PERCENTAGE_FACTOR).sub(reserveConfiguration.reserveFactor)); - - return [liquidityRate, stableBorrowRate, variableBorrowRate]; -}; - -export const calcExpectedOverallBorrowRate = ( - totalStableDebt: BigNumber, - totalVariableDebt: BigNumber, - currentVariableBorrowRate: BigNumber, - currentAverageStableBorrowRate: BigNumber -): BigNumber => { - const totalBorrows = totalStableDebt.add(totalVariableDebt); - - if (totalBorrows.eq(0)) return BigNumber.from(0); - - const weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate); - - const weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate); - - const overallBorrowRate = weightedVariableRate - .add(weightedStableRate) - .rayDiv(totalBorrows.wadToRay()); - - return overallBorrowRate; -}; - -export const calcExpectedUsageRatios = ( - totalStableDebt: BigNumber, - totalVariableDebt: BigNumber, - availableLiquidity: BigNumber, - totalLiquidity: BigNumber -): BigNumber[] => { - const totalDebt = totalStableDebt.add(totalVariableDebt); - const borrowUsageRatio = totalDebt.eq(0) - ? BigNumber.from(0) - : totalDebt.rayDiv(availableLiquidity.add(totalDebt)); - - let supplyUsageRatio = totalDebt.eq(0) - ? BigNumber.from(0) - : totalDebt.rayDiv(totalLiquidity.add(totalDebt)); - - expect(supplyUsageRatio).to.be.lte(borrowUsageRatio, 'Supply usage ratio > borrow usage ratio'); - - return [borrowUsageRatio, supplyUsageRatio]; -}; - -export const calcExpectedReserveNormalizedIncome = ( - reserveData: ReserveData, - currentTimestamp: BigNumber -) => { - const { liquidityRate, liquidityIndex, lastUpdateTimestamp } = reserveData; - - //if usage ratio is 0, nothing to compound - if (liquidityRate.eq('0')) { - return liquidityIndex; - } - - const cumulatedInterest = calcLinearInterest( - liquidityRate, - currentTimestamp, - lastUpdateTimestamp - ); - - const income = cumulatedInterest.rayMul(liquidityIndex); - - return income; -}; - -export const calcExpectedReserveNormalizedDebt = ( - variableBorrowRate: BigNumber, - variableBorrowIndex: BigNumber, - lastUpdateTimestamp: BigNumber, - currentTimestamp: BigNumber -) => { - //if usage ratio is 0, nothing to compound - if (variableBorrowRate.eq('0')) { - return variableBorrowIndex; - } - - const cumulatedInterest = calcCompoundedInterest( - variableBorrowRate, - currentTimestamp, - lastUpdateTimestamp - ); - - const debt = cumulatedInterest.rayMul(variableBorrowIndex); - - return debt; -}; - -const calcExpectedUserStableRate = ( - balanceBefore: BigNumber, - rateBefore: BigNumber, - amount: BigNumber, - rateNew: BigNumber -) => { - return balanceBefore.mul(rateBefore).add(amount.mul(rateNew)).div(balanceBefore.add(amount)); -}; - -const calcExpectedLiquidityIndex = (reserveData: ReserveData, timestamp: BigNumber) => { - //if usage ratio is 0, nothing to compound - if (reserveData.supplyUsageRatio.eq(0)) { - return reserveData.liquidityIndex; - } - - const cumulatedInterest = calcLinearInterest( - reserveData.liquidityRate, - timestamp, - reserveData.lastUpdateTimestamp - ); - - return cumulatedInterest.rayMul(reserveData.liquidityIndex); -}; - -const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: BigNumber) => { - //if totalVariableDebt is 0, nothing to compound - if (reserveData.totalVariableDebt.eq('0')) { - return reserveData.variableBorrowIndex; - } - - const cumulatedInterest = calcCompoundedInterest( - reserveData.variableBorrowRate, - timestamp, - reserveData.lastUpdateTimestamp - ); - - return cumulatedInterest.rayMul(reserveData.variableBorrowIndex); -}; - -const calcExpectedTotalStableDebt = ( - principalStableDebt: BigNumber, - averageStableBorrowRate: BigNumber, - lastUpdateTimestamp: BigNumber, - currentTimestamp: BigNumber -) => { - const cumulatedInterest = calcCompoundedInterest( - averageStableBorrowRate, - currentTimestamp, - lastUpdateTimestamp - ); - - return cumulatedInterest.rayMul(principalStableDebt); -}; - -const calcExpectedTotalVariableDebt = ( - reserveData: ReserveData, - expectedVariableDebtIndex: BigNumber -) => { - return reserveData.scaledVariableDebt.rayMul(expectedVariableDebtIndex); -}; - -const calcExpectedAccrueToTreasury = (reserveData: ReserveData, nextReserveData: ReserveData) => { - const reserveFactor = reserveData.reserveFactor; - if (reserveFactor.eq(0)) { - return reserveData.accruedToTreasuryScaled; - } - - const prevTotalVariableDebt = reserveData.scaledVariableDebt.rayMul( - reserveData.variableBorrowIndex - ); - - const currTotalVariableDebt = nextReserveData.scaledVariableDebt.rayMul( - nextReserveData.variableBorrowIndex - ); - - // Be aware that the ordering in the calcCompoundInterest is NOT the same as the solidity `calculateCompoundedInterest` - const cumulatedStableInterest = calcCompoundedInterest( - reserveData.averageStableBorrowRate, - reserveData.lastUpdateTimestamp, - reserveData.totalStableDebtLastUpdated - ); - - const prevTotalStableDebt = reserveData.principalStableDebt.rayMul(cumulatedStableInterest); - - const totalDebtAccrued = currTotalVariableDebt - .add(nextReserveData.totalStableDebt) - .sub(prevTotalVariableDebt) - .sub(prevTotalStableDebt); - - const amountToMint = totalDebtAccrued.percentMul(reserveFactor); - - if (amountToMint.gt(0)) { - return reserveData.accruedToTreasuryScaled.add( - amountToMint.rayDiv(nextReserveData.liquidityIndex) - ); - } else { - return reserveData.accruedToTreasuryScaled; - } -}; - -const updateState = ( - reserveDataBeforeAction: ReserveData, - expectedReserveData: ReserveData, - txTimestamp: BigNumber -) => { - // Update indexes - expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( - reserveDataBeforeAction, - txTimestamp - ); - - // Update debts - expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( - reserveDataBeforeAction.principalStableDebt, - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebtLastUpdated, - txTimestamp - ); - expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt( - reserveDataBeforeAction, - expectedReserveData.variableBorrowIndex - ); - - expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; - expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; - - // Accrue to treasury - expectedReserveData.accruedToTreasuryScaled = calcExpectedAccrueToTreasury( - reserveDataBeforeAction, - expectedReserveData - ); -}; - -const updateLiquidityAndUsageRatios = ( - reserveDataBeforeAction: ReserveData, - expectedReserveData: ReserveData, - liquidityAdded: BigNumber, - liquidityTaken: BigNumber -) => { - expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity - .add(liquidityAdded) - .sub(liquidityTaken); - - expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity.add( - expectedReserveData.unbacked - ); - - [expectedReserveData.borrowUsageRatio, expectedReserveData.supplyUsageRatio] = - calcExpectedUsageRatios( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); -}; - -const updateTotalLiquidityAndUsageRatio = (expectedReserveData: ReserveData) => { - expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity.add( - expectedReserveData.unbacked - ); - - [expectedReserveData.borrowUsageRatio, expectedReserveData.supplyUsageRatio] = - calcExpectedUsageRatios( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.availableLiquidity, - expectedReserveData.totalLiquidity - ); -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/funds.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/funds.ts deleted file mode 100644 index d7f7c79..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/funds.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { BigNumber, Signer } from 'ethers'; -import { SelfdestructTransfer__factory } from '../../../types'; - -export const topUpNonPayableWithEther = async ( - holder: Signer, - accounts: string[], - amount: BigNumber -) => { - let selfdestructContract; - let factory = new SelfdestructTransfer__factory(holder); - for (const account of accounts) { - selfdestructContract = await factory.deploy(); - await selfdestructContract.deployed(); - await selfdestructContract.destroyAndTransfer(account, { - value: amount, - }); - } -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/helpers.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/helpers.ts deleted file mode 100644 index 3654ed3..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/helpers.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { Pool } from '../../../types/Pool'; -import { ReserveData, UserReserveData } from './interfaces'; -import { - getMintableERC20, - getAToken, - getStableDebtToken, - getVariableDebtToken, - getIRStrategy, -} from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { tEthereumAddress } from '../../../helpers/types'; -import { AaveProtocolDataProvider } from '../../../types/AaveProtocolDataProvider'; -import { BigNumber } from 'ethers'; -import { AToken } from '../../../types'; -import { getContract } from '@aave/deploy-v3'; -import { expect } from 'chai'; - -export const getReserveData = async ( - helper: AaveProtocolDataProvider, - reserve: tEthereumAddress -): Promise => { - const [reserveData, tokenAddresses, irStrategyAddress, reserveConfiguration, token] = - await Promise.all([ - helper.getReserveData(reserve), - helper.getReserveTokensAddresses(reserve), - helper.getInterestRateStrategyAddress(reserve), - helper.getReserveConfigurationData(reserve), - getContract('IERC20Detailed', reserve), - ]); - - const stableDebtToken = await getStableDebtToken(tokenAddresses.stableDebtTokenAddress); - const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress); - const irStrategy = await getIRStrategy(irStrategyAddress); - - const baseStableRate = await irStrategy.getBaseStableBorrowRate(); - - const { 0: principalStableDebt } = await stableDebtToken.getSupplyData(); - const totalStableDebtLastUpdated = await stableDebtToken.getTotalSupplyLastUpdated(); - - const scaledVariableDebt = await variableDebtToken.scaledTotalSupply(); - - const symbol = await token.symbol(); - const decimals = BigNumber.from(await token.decimals()); - - const accruedToTreasuryScaled = reserveData.accruedToTreasuryScaled; - const unbacked = reserveData.unbacked; - const aToken = (await getAToken(tokenAddresses.aTokenAddress)) as AToken; - - // Need the reserve factor - const reserveFactor = reserveConfiguration.reserveFactor; - - const availableLiquidity = await token.balanceOf(aToken.address); - - const totalLiquidity = availableLiquidity.add(unbacked); - - const totalDebt = reserveData.totalStableDebt.add(reserveData.totalVariableDebt); - - const borrowUsageRatio = totalDebt.eq(0) - ? BigNumber.from(0) - : totalDebt.rayDiv(availableLiquidity.add(totalDebt)); - - let supplyUsageRatio = totalDebt.eq(0) - ? BigNumber.from(0) - : totalDebt.rayDiv(totalLiquidity.add(totalDebt)); - - expect(supplyUsageRatio).to.be.lte(borrowUsageRatio, 'Supply usage ratio > borrow usage ratio'); - - return { - reserveFactor, - unbacked, - accruedToTreasuryScaled, - availableLiquidity, - totalLiquidity, - borrowUsageRatio, - supplyUsageRatio, - totalStableDebt: reserveData.totalStableDebt, - totalVariableDebt: reserveData.totalVariableDebt, - liquidityRate: reserveData.liquidityRate, - variableBorrowRate: reserveData.variableBorrowRate, - stableBorrowRate: reserveData.stableBorrowRate, - averageStableBorrowRate: reserveData.averageStableBorrowRate, - liquidityIndex: reserveData.liquidityIndex, - variableBorrowIndex: reserveData.variableBorrowIndex, - lastUpdateTimestamp: BigNumber.from(reserveData.lastUpdateTimestamp), - totalStableDebtLastUpdated: BigNumber.from(totalStableDebtLastUpdated), - principalStableDebt: principalStableDebt, - scaledVariableDebt: scaledVariableDebt, - address: reserve, - aTokenAddress: tokenAddresses.aTokenAddress, - symbol, - decimals, - marketStableRate: BigNumber.from(baseStableRate), - }; -}; - -export const getUserData = async ( - pool: Pool, - helper: AaveProtocolDataProvider, - reserve: string, - user: tEthereumAddress, - sender?: tEthereumAddress -): Promise => { - const [userData, scaledATokenBalance] = await Promise.all([ - helper.getUserReserveData(reserve, user), - getATokenUserData(reserve, user, helper), - ]); - - const token = await getMintableERC20(reserve); - const walletBalance = await token.balanceOf(sender || user); - - return { - scaledATokenBalance: BigNumber.from(scaledATokenBalance), - currentATokenBalance: userData.currentATokenBalance, - currentStableDebt: userData.currentStableDebt, - currentVariableDebt: userData.currentVariableDebt, - principalStableDebt: userData.principalStableDebt, - scaledVariableDebt: userData.scaledVariableDebt, - stableBorrowRate: userData.stableBorrowRate, - liquidityRate: userData.liquidityRate, - usageAsCollateralEnabled: userData.usageAsCollateralEnabled, - stableRateLastUpdated: BigNumber.from(userData.stableRateLastUpdated), - walletBalance, - }; -}; - -const getATokenUserData = async ( - reserve: string, - user: string, - helpersContract: AaveProtocolDataProvider -) => { - const aTokenAddress: string = (await helpersContract.getReserveTokensAddresses(reserve)) - .aTokenAddress; - - const aToken = await getAToken(aTokenAddress); - - const scaledBalance = await aToken.scaledBalanceOf(user); - return scaledBalance.toString(); -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/interfaces/index.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/interfaces/index.ts deleted file mode 100644 index fcf3265..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/interfaces/index.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { BigNumber } from 'ethers'; - -export interface UserReserveData { - scaledATokenBalance: BigNumber; - currentATokenBalance: BigNumber; - currentStableDebt: BigNumber; - currentVariableDebt: BigNumber; - principalStableDebt: BigNumber; - scaledVariableDebt: BigNumber; - liquidityRate: BigNumber; - stableBorrowRate: BigNumber; - stableRateLastUpdated: BigNumber; - usageAsCollateralEnabled: Boolean; - walletBalance: BigNumber; - [key: string]: BigNumber | string | Boolean; -} - -export interface ReserveData { - address: string; - symbol: string; - decimals: BigNumber; - reserveFactor: BigNumber; - availableLiquidity: BigNumber; - totalLiquidity: BigNumber; - totalStableDebt: BigNumber; - totalVariableDebt: BigNumber; - principalStableDebt: BigNumber; - scaledVariableDebt: BigNumber; - averageStableBorrowRate: BigNumber; - variableBorrowRate: BigNumber; - stableBorrowRate: BigNumber; - supplyUsageRatio: BigNumber; - borrowUsageRatio: BigNumber; - liquidityIndex: BigNumber; - variableBorrowIndex: BigNumber; - aTokenAddress: string; - marketStableRate: BigNumber; - lastUpdateTimestamp: BigNumber; - totalStableDebtLastUpdated: BigNumber; - liquidityRate: BigNumber; - unbacked: BigNumber; - accruedToTreasuryScaled: BigNumber; - [key: string]: BigNumber | string; -} diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/wadraymath.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/wadraymath.ts deleted file mode 100644 index 782fbed..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/wadraymath.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { BigNumber } from '@ethersproject/bignumber'; -import { BigNumberish } from 'ethers'; - -import { - RAY, - WAD, - HALF_RAY, - HALF_WAD, - WAD_RAY_RATIO, - HALF_PERCENTAGE, - PERCENTAGE_FACTOR, -} from '../../../helpers/constants'; - -declare module '@ethersproject/bignumber' { - interface BigNumber { - ray: () => BigNumber; - wad: () => BigNumber; - halfRay: () => BigNumber; - halfWad: () => BigNumber; - halfPercentage: () => BigNumber; - percentageFactor: () => BigNumber; - wadMul: (a: BigNumber) => BigNumber; - wadDiv: (a: BigNumber) => BigNumber; - rayMul: (a: BigNumber) => BigNumber; - rayDiv: (a: BigNumber) => BigNumber; - percentMul: (a: BigNumberish) => BigNumber; - percentDiv: (a: BigNumberish) => BigNumber; - rayToWad: () => BigNumber; - wadToRay: () => BigNumber; - negated: () => BigNumber; - } -} - -BigNumber.prototype.ray = (): BigNumber => BigNumber.from(RAY); -BigNumber.prototype.wad = (): BigNumber => BigNumber.from(WAD); -BigNumber.prototype.halfRay = (): BigNumber => BigNumber.from(HALF_RAY); -BigNumber.prototype.halfWad = (): BigNumber => BigNumber.from(HALF_WAD); -BigNumber.prototype.halfPercentage = (): BigNumber => BigNumber.from(HALF_PERCENTAGE); -BigNumber.prototype.percentageFactor = (): BigNumber => BigNumber.from(PERCENTAGE_FACTOR); - -BigNumber.prototype.wadMul = function (other: BigNumber): BigNumber { - return this.halfWad().add(this.mul(other)).div(this.wad()); -}; - -BigNumber.prototype.wadDiv = function (other: BigNumber): BigNumber { - const halfOther = other.div(2); - return halfOther.add(this.mul(this.wad())).div(other); -}; - -BigNumber.prototype.rayMul = function (other: BigNumber): BigNumber { - return this.halfRay().add(this.mul(other)).div(this.ray()); -}; - -BigNumber.prototype.rayDiv = function (other: BigNumber): BigNumber { - const halfOther = other.div(2); - return halfOther.add(this.mul(this.ray())).div(other); -}; - -BigNumber.prototype.percentMul = function (bps: BigNumberish): BigNumber { - return this.halfPercentage().add(this.mul(bps)).div(PERCENTAGE_FACTOR); -}; - -BigNumber.prototype.percentDiv = function (bps: BigNumberish): BigNumber { - const halfBps = BigNumber.from(bps).div(2); - return halfBps.add(this.mul(PERCENTAGE_FACTOR)).div(bps); -}; - -BigNumber.prototype.rayToWad = function (): BigNumber { - const halfRatio = BigNumber.from(WAD_RAY_RATIO).div(2); - return halfRatio.add(this).div(WAD_RAY_RATIO); -}; - -BigNumber.prototype.wadToRay = function (): BigNumber { - return this.mul(WAD_RAY_RATIO); -}; - -BigNumber.prototype.negated = function (): BigNumber { - return this.mul(-1); -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/wallets.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/wallets.ts deleted file mode 100644 index 5295850..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/helpers/utils/wallets.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { accounts } from '../../../test-wallets.js'; - -export const getTestWallets = (): [{ secretKey: string; balance: string }] => { - if (!accounts.every((element) => element.secretKey) || accounts.length === 0) - throw new Error('INVALID_TEST_WALLETS'); - return accounts; -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/interest-overflow.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/interest-overflow.spec.ts deleted file mode 100644 index 759fdc0..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/interest-overflow.spec.ts +++ /dev/null @@ -1,420 +0,0 @@ -import { expect } from 'chai'; -import { BigNumberish, BigNumber, utils } from 'ethers'; -import { impersonateAccountsHardhat } from '../helpers/misc-utils'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { topUpNonPayableWithEther } from './helpers/utils/funds'; -import { makeSuite } from './helpers/make-suite'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { - MintableERC20, - StableDebtToken, - MockReserveInterestRateStrategy, - MintableERC20__factory, - MockReserveInterestRateStrategy__factory, - AToken__factory, - VariableDebtToken__factory, - StableDebtToken__factory, - MockFlashLoanReceiver__factory, -} from '../types'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { evmSnapshot, evmRevert, increaseTime } from '@aave/deploy-v3'; - -declare var hre: HardhatRuntimeEnvironment; -makeSuite('Interest Rate and Index Overflow', (testEnv) => { - const { SAFECAST_UINT128_OVERFLOW } = ProtocolErrors; - - let mockToken: MintableERC20; - let mockStableDebtToken: StableDebtToken; - let mockRateStrategy: MockReserveInterestRateStrategy; - - let snap: string; - - before(async () => { - const { pool, poolAdmin, configurator, dai, helpersContract, addressesProvider } = testEnv; - - mockToken = await new MintableERC20__factory(await getFirstSigner()).deploy( - 'MOCK', - 'MOCK', - '18' - ); - - let stableDebtTokenImplementation = await new StableDebtToken__factory( - await getFirstSigner() - ).deploy(pool.address); - let variableDebtTokenImplementation = await new VariableDebtToken__factory( - await getFirstSigner() - ).deploy(pool.address); - const aTokenImplementation = await new AToken__factory(await getFirstSigner()).deploy( - pool.address - ); - - mockRateStrategy = await new MockReserveInterestRateStrategy__factory( - await getFirstSigner() - ).deploy(addressesProvider.address, 0, 0, 0, 0, 0, 0); - - // Init the reserve - let initInputParams: { - aTokenImpl: string; - stableDebtTokenImpl: string; - variableDebtTokenImpl: string; - underlyingAssetDecimals: BigNumberish; - interestRateStrategyAddress: string; - underlyingAsset: string; - treasury: string; - incentivesController: string; - aTokenName: string; - aTokenSymbol: string; - variableDebtTokenName: string; - variableDebtTokenSymbol: string; - stableDebtTokenName: string; - stableDebtTokenSymbol: string; - params: string; - }[] = [ - { - aTokenImpl: aTokenImplementation.address, - stableDebtTokenImpl: stableDebtTokenImplementation.address, - variableDebtTokenImpl: variableDebtTokenImplementation.address, - underlyingAssetDecimals: 18, - interestRateStrategyAddress: mockRateStrategy.address, - underlyingAsset: mockToken.address, - treasury: ZERO_ADDRESS, - incentivesController: ZERO_ADDRESS, - aTokenName: 'AMOCK', - aTokenSymbol: 'AMOCK', - variableDebtTokenName: 'VMOCK', - variableDebtTokenSymbol: 'VMOCK', - stableDebtTokenName: 'SMOCK', - stableDebtTokenSymbol: 'SMOCK', - params: '0x10', - }, - ]; - - await configurator.connect(poolAdmin.signer).initReserves(initInputParams); - - // Configuration - const daiReserveConfigurationData = await helpersContract.getReserveConfigurationData( - dai.address - ); - - const maxCap = 68719476735; - const inputParams: { - asset: string; - baseLTV: BigNumberish; - liquidationThreshold: BigNumberish; - liquidationBonus: BigNumberish; - reserveFactor: BigNumberish; - borrowCap: BigNumberish; - supplyCap: BigNumberish; - stableBorrowingEnabled: boolean; - borrowingEnabled: boolean; - }[] = [ - { - asset: mockToken.address, - baseLTV: daiReserveConfigurationData.ltv, - liquidationThreshold: daiReserveConfigurationData.liquidationThreshold, - liquidationBonus: daiReserveConfigurationData.liquidationBonus, - reserveFactor: daiReserveConfigurationData.reserveFactor, - borrowCap: maxCap, - supplyCap: maxCap, - stableBorrowingEnabled: true, - borrowingEnabled: true, - }, - ]; - - const i = 0; - await configurator - .connect(poolAdmin.signer) - .configureReserveAsCollateral( - inputParams[i].asset, - inputParams[i].baseLTV, - inputParams[i].liquidationThreshold, - inputParams[i].liquidationBonus - ); - await configurator.connect(poolAdmin.signer).setReserveBorrowing(inputParams[i].asset, true); - - await configurator - .connect(poolAdmin.signer) - .setSupplyCap(inputParams[i].asset, inputParams[i].supplyCap); - await configurator - .connect(poolAdmin.signer) - .setReserveFactor(inputParams[i].asset, inputParams[i].reserveFactor); - - const reserveData = await pool.getReserveData(mockToken.address); - mockStableDebtToken = StableDebtToken__factory.connect( - reserveData.stableDebtTokenAddress, - await getFirstSigner() - ); - }); - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - - afterEach(async () => { - await evmRevert(snap); - }); - - it('ReserveLogic `updateInterestRates` with nextLiquidityRate > type(uint128).max (revert expected)', async () => { - const { - pool, - users: [user], - } = testEnv; - - await mockToken - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(mockToken.address, '10000')); - await mockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await mockRateStrategy.setLiquidityRate(MAX_UINT_AMOUNT); - - await expect( - pool - .connect(user.signer) - .deposit( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ) - ).to.be.revertedWith(SAFECAST_UINT128_OVERFLOW); - }); - - it('ReserveLogic `updateInterestRates` with nextStableRate > type(uint128).max (revert expected)', async () => { - const { - pool, - users: [user], - } = testEnv; - - await mockToken - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(mockToken.address, '10000')); - await mockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await mockRateStrategy.setStableBorrowRate(MAX_UINT_AMOUNT); - - await expect( - pool - .connect(user.signer) - .deposit( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ) - ).to.be.revertedWith(SAFECAST_UINT128_OVERFLOW); - }); - - it('ReserveLogic `updateInterestRates` with nextVariableRate > type(uint128).max (revert expected)', async () => { - const { - pool, - users: [user], - } = testEnv; - - await mockToken - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(mockToken.address, '10000')); - await mockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await mockRateStrategy.setVariableBorrowRate(MAX_UINT_AMOUNT); - - await expect( - pool - .connect(user.signer) - .deposit( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ) - ).to.be.revertedWith(SAFECAST_UINT128_OVERFLOW); - }); - - it('ReserveLogic `_updateIndexes` with nextLiquidityIndex > type(uint128).max (revert expected)', async () => { - const { - pool, - users: [user], - dai, - } = testEnv; - - await dai - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(mockToken.address, '10000')); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ); - - await mockToken - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(mockToken.address, '1000')); - await mockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(user.signer) - .deposit( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ); - - // Set liquidity rate to max - await mockRateStrategy.setLiquidityRate(BigNumber.from(2).pow(128).sub(1)); - // Borrow funds - await pool - .connect(user.signer) - .borrow( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '100'), - RateMode.Variable, - 0, - user.address - ); - - // set borrow rate to max - await mockRateStrategy.setVariableBorrowRate(BigNumber.from(2).pow(128).sub(1)); - - // Increase time such that the next liquidity index overflow because of interest - await increaseTime(60 * 60 * 24 * 500); - - await expect( - pool - .connect(user.signer) - .deposit( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ) - ).to.be.revertedWith(SAFECAST_UINT128_OVERFLOW); - }); - - it('ReserveLogic `_updateIndexes` with nextVariableBorrowIndex > type(uint128).max (revert expected)', async () => { - const { - pool, - users: [user], - dai, - } = testEnv; - - await dai - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(mockToken.address, '10000')); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(mockToken.address, '10000'), - user.address, - 0 - ); - - await mockToken - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(mockToken.address, '10000')); - await mockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(user.signer) - .deposit( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ); - - await mockRateStrategy.setLiquidityRate(BigNumber.from(10).pow(27)); - await mockRateStrategy.setVariableBorrowRate(BigNumber.from(2).pow(110).sub(1)); - await pool - .connect(user.signer) - .borrow( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '100'), - RateMode.Variable, - 0, - user.address - ); - - await increaseTime(60 * 60 * 24 * 365); - - await expect( - pool - .connect(user.signer) - .deposit( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ) - ).to.be.revertedWith(SAFECAST_UINT128_OVERFLOW); - }); - - it('ReserveLogic `cumulateToLiquidityIndex` with liquidityIndex > type(uint128).max (revert expected)', async () => { - const { - pool, - users: [user], - dai, - aDai, - addressesProvider, - } = testEnv; - - const toBorrow = BigNumber.from(2).pow(80); - - await dai.connect(user.signer)['mint(uint256)'](toBorrow.add(1)); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool.connect(user.signer).deposit(dai.address, 1, user.address, 0); - await dai.connect(user.signer).transfer(aDai.address, toBorrow); - - const mockFlashLoan = await new MockFlashLoanReceiver__factory(await getFirstSigner()).deploy( - addressesProvider.address - ); - - await expect( - pool - .connect(user.signer) - .flashLoan( - mockFlashLoan.address, - [dai.address], - [toBorrow], - [RateMode.None], - user.address, - '0x00', - 0 - ) - ).to.be.revertedWith(SAFECAST_UINT128_OVERFLOW); - }); - - it('StableDebtToken `mint` with nextStableRate > type(uint128).max (revert expected)', async () => { - const { - deployer, - pool, - users: [user], - } = testEnv; - - // Impersonate the Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - const rate = BigNumber.from(2).pow(128); // Max + 1 - - await expect( - mockStableDebtToken - .connect(poolSigner) - .mint( - user.address, - user.address, - await convertToCurrencyDecimals(mockStableDebtToken.address, '100'), - rate - ) - ).to.be.revertedWith(SAFECAST_UINT128_OVERFLOW); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/isolation-mode.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/isolation-mode.spec.ts deleted file mode 100644 index 58f2660..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/isolation-mode.spec.ts +++ /dev/null @@ -1,571 +0,0 @@ -const { expect } = require('chai'); -import { utils, BigNumber } from 'ethers'; -import { ReserveData, UserReserveData } from './helpers/utils/interfaces'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { AAVE_REFERRAL, MAX_UINT_AMOUNT, MAX_UNBACKED_MINT_CAP } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; -import { - increaseTime, - waitForTx, - evmSnapshot, - evmRevert, - advanceTimeAndBlock, -} from '@aave/deploy-v3'; -import { getReserveData, getUserData } from './helpers/utils/helpers'; -import { getTxCostAndTimestamp } from './helpers/actions'; -import AaveConfig from '@aave/deploy-v3/dist/markets/aave'; -import { getACLManager } from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { - calcExpectedReserveDataAfterMintUnbacked, - configuration as calculationsConfiguration, -} from './helpers/utils/calculations'; - -const expectEqual = ( - actual: UserReserveData | ReserveData, - expected: UserReserveData | ReserveData -) => { - expect(actual).to.be.almostEqualOrEqual(expected); -}; - -makeSuite('Isolation mode', (testEnv: TestEnv) => { - const depositAmount = utils.parseEther('1000'); - const borrowAmount = utils.parseEther('200'); - const ceilingAmount = '10000'; - - const withdrawAmount = utils.parseEther('100'); - const feeBps = BigNumber.from(30); - const denominatorBP = BigNumber.from(10000); - const mintAmount = withdrawAmount.mul(denominatorBP.sub(feeBps)).div(denominatorBP); - const bridgeProtocolFeeBps = BigNumber.from(2000); - - const { ASSET_NOT_BORROWABLE_IN_ISOLATION, DEBT_CEILING_EXCEEDED, USER_IN_ISOLATION_MODE } = - ProtocolErrors; - - let aclManager; - let oracleBaseDecimals; - let snapshot; - - before(async () => { - const { configurator, dai, usdc, aave, users, poolAdmin } = testEnv; - calculationsConfiguration.reservesParams = AaveConfig.ReservesConfig; - - //set debt ceiling for aave - await configurator.setDebtCeiling(aave.address, ceilingAmount); - - //set category 1 for DAI and USDC - await configurator.setBorrowableInIsolation(dai.address, true); - await configurator.setBorrowableInIsolation(usdc.address, true); - - // configure bridge - aclManager = await getACLManager(); - await waitForTx(await aclManager.addBridge(users[2].address)); - - await waitForTx( - await configurator.connect(poolAdmin.signer).updateBridgeProtocolFee(bridgeProtocolFeeBps) - ); - - // configure oracle - const { aaveOracle, addressesProvider, oracle } = testEnv; - oracleBaseDecimals = (await aaveOracle.BASE_CURRENCY_UNIT()).toString().length - 1; - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - - snapshot = await evmSnapshot(); - }); - - it('User 0 supply 1000 dai.', async () => { - const { users, pool, dai } = testEnv; - await dai.connect(users[0].signer)['mint(uint256)'](depositAmount); - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[0].signer).supply(dai.address, depositAmount, users[0].address, 0); - }); - - it('User 1 supply 2 aave. Checks that aave is activated as collateral ', async () => { - const { users, pool, aave, helpersContract } = testEnv; - await aave.connect(users[1].signer)['mint(uint256)'](utils.parseEther('2')); - await aave.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .supply(aave.address, utils.parseEther('2'), users[1].address, 0); - - const userData = await helpersContract.getUserReserveData(aave.address, users[1].address); - - expect(userData.usageAsCollateralEnabled).to.be.eq(true); - }); - - it('User 1 supply 1 eth. Checks that eth is NOT activated as collateral ', async () => { - const { users, pool, weth, helpersContract } = testEnv; - await weth.connect(users[1].signer)['mint(uint256)'](utils.parseEther('1')); - await weth.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .supply(weth.address, utils.parseEther('1'), users[1].address, 0); - - const userData = await helpersContract.getUserReserveData(weth.address, users[1].address); - - expect(userData.usageAsCollateralEnabled).to.be.eq(false); - }); - - it('User 1 tries to use eth as collateral (revert expected)', async () => { - const { users, pool, weth, helpersContract } = testEnv; - - const userDataBefore = await helpersContract.getUserReserveData(weth.address, users[1].address); - expect(userDataBefore.usageAsCollateralEnabled).to.be.eq(false); - - await expect( - pool.connect(users[1].signer).setUserUseReserveAsCollateral(weth.address, true) - ).to.be.revertedWith(USER_IN_ISOLATION_MODE); - - const userDataAfter = await helpersContract.getUserReserveData(weth.address, users[1].address); - expect(userDataAfter.usageAsCollateralEnabled).to.be.eq(false); - }); - - it('User 2 deposit dai and aave, then tries to use aave as collateral (revert expected)', async () => { - const snap = await evmSnapshot(); - const { - users: [, , user2], - pool, - dai, - aave, - helpersContract, - } = testEnv; - - await dai.connect(user2.signer)['mint(uint256)'](utils.parseEther('1')); - await dai.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user2.signer).supply(dai.address, utils.parseEther('1'), user2.address, 0); - - await aave.connect(user2.signer)['mint(uint256)'](utils.parseEther('1')); - await aave.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user2.signer).supply(aave.address, utils.parseEther('1'), user2.address, 0); - - const userDaiDataBefore = await helpersContract.getUserReserveData(dai.address, user2.address); - expect(userDaiDataBefore.usageAsCollateralEnabled).to.be.eq(true); - - const userAaveDataBefore = await helpersContract.getUserReserveData( - aave.address, - user2.address - ); - expect(userAaveDataBefore.usageAsCollateralEnabled).to.be.eq(false); - - await expect( - pool.connect(user2.signer).setUserUseReserveAsCollateral(aave.address, true) - ).to.be.revertedWith(USER_IN_ISOLATION_MODE); - - const userDataAfter = await helpersContract.getUserReserveData(aave.address, user2.address); - expect(userDataAfter.usageAsCollateralEnabled).to.be.eq(false); - - await evmRevert(snap); - }); - - it('User 2 (as bridge) mint 100 unbacked dai to user 1. Checks that dai is NOT activated as collateral', async () => { - const { users, riskAdmin, pool, configurator, dai, helpersContract } = testEnv; - - // configure unbacked cap for dai - expect(await configurator.connect(riskAdmin.signer).setUnbackedMintCap(dai.address, '10')); - expect( - await configurator - .connect(riskAdmin.signer) - .setUnbackedMintCap(dai.address, MAX_UNBACKED_MINT_CAP) - ); - - const reserveDataBefore = await getReserveData(helpersContract, dai.address); - const tx = await waitForTx( - await pool.connect(users[2].signer).mintUnbacked(dai.address, mintAmount, users[1].address, 0) - ); - const { txTimestamp } = await getTxCostAndTimestamp(tx); - const expectedDataAfter = calcExpectedReserveDataAfterMintUnbacked( - mintAmount.toString(), - reserveDataBefore, - txTimestamp - ); - const reserveDataAfter = await getReserveData(helpersContract, dai.address); - expectEqual(reserveDataAfter, expectedDataAfter); - - const userData = await helpersContract.getUserReserveData(dai.address, users[1].address); - expect(userData.usageAsCollateralEnabled).to.be.eq(false); - }); - - it('User 2 supply 100 DAI, transfers to user 1. Checks that DAI is NOT activated as collateral for user 1', async () => { - const { dai, aDai, users, pool, helpersContract } = testEnv; - - const amount = utils.parseEther('100'); - await dai.connect(users[2].signer)['mint(uint256)'](amount); - await dai.connect(users[2].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[2].signer).supply(dai.address, amount, users[2].address, 0); - - await aDai.connect(users[2].signer).transfer(users[1].address, amount); - - const userData = await helpersContract.getUserReserveData(dai.address, users[1].address); - - expect(userData.usageAsCollateralEnabled).to.be.eq(false); - }); - - it('User 1 withdraws everything. User supplies WETH then AAVE. Checks AAVE is not enabled as collateral', async () => { - const { dai, aave, weth, users, pool, helpersContract } = testEnv; - - await pool - .connect(users[1].signer) - .withdraw(weth.address, utils.parseEther('1'), users[1].address); - - await pool - .connect(users[1].signer) - .withdraw(aave.address, utils.parseEther('2'), users[1].address); - - await pool.connect(users[1].signer).withdraw(dai.address, MAX_UINT_AMOUNT, users[1].address); - - const amount = utils.parseEther('1'); - - await pool.connect(users[1].signer).supply(weth.address, amount, users[1].address, 0); - - await pool.connect(users[1].signer).supply(aave.address, amount, users[1].address, 0); - - const userData = await helpersContract.getUserReserveData(aave.address, users[1].address); - - expect(userData.usageAsCollateralEnabled).to.be.eq(false); - }); - - it('User 2 supplies DAI, transfers to user 1. Checks DAI is enabled as collateral', async () => { - const { dai, aDai, users, pool, helpersContract } = testEnv; - - const amount = utils.parseEther('100'); - await dai.connect(users[2].signer)['mint(uint256)'](amount); - await pool.connect(users[2].signer).supply(dai.address, amount, users[2].address, 0); - - await aDai.connect(users[2].signer).transfer(users[1].address, amount); - - const userData = await helpersContract.getUserReserveData(dai.address, users[1].address); - expect(userData.usageAsCollateralEnabled).to.be.eq(true); - }); - - it('User 1 withdraws everything. User 2 supplies ETH, User 1 supplies AAVE, tries to borrow ETH (revert expected)', async () => { - const { dai, aave, weth, users, pool } = testEnv; - - await pool - .connect(users[1].signer) - .withdraw(weth.address, utils.parseEther('1'), users[1].address); - - await pool - .connect(users[1].signer) - .withdraw(aave.address, utils.parseEther('1'), users[1].address); - - await pool - .connect(users[1].signer) - .withdraw(dai.address, utils.parseEther('100'), users[1].address); - - const wethAmount = utils.parseEther('1'); - await weth.connect(users[2].signer)['mint(uint256)'](wethAmount); - await weth.connect(users[2].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[2].signer).supply(weth.address, wethAmount, users[2].address, 0); - - const aaveAmount = utils.parseEther('100'); - await aave.connect(users[1].signer)['mint(uint256)'](aaveAmount); - await aave.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[1].signer).supply(aave.address, aaveAmount, users[1].address, 0); - - await expect( - pool - .connect(users[1].signer) - .borrow(weth.address, utils.parseEther('0.01'), '2', 0, users[1].address) - ).to.be.revertedWith(ASSET_NOT_BORROWABLE_IN_ISOLATION); - }); - - it('User 2 tries to borrow some ETH on behalf of User 1 (revert expected)', async () => { - const { users, pool, dai, weth } = testEnv; - - await expect( - pool - .connect(users[2].signer) - .borrow( - weth.address, - utils.parseEther('0.0000001'), - RateMode.Variable, - AAVE_REFERRAL, - users[1].address - ) - ).to.be.revertedWith(ASSET_NOT_BORROWABLE_IN_ISOLATION); - }); - - it('User 1 borrows 10 DAI. Check debt ceiling', async () => { - const { dai, aave, users, pool } = testEnv; - - const borrowAmount = utils.parseEther('10'); - await expect( - pool.connect(users[1].signer).borrow(dai.address, borrowAmount, '2', 0, users[1].address) - ) - .to.emit(pool, 'IsolationModeTotalDebtUpdated') - .withArgs(aave.address, 1000); - - const reserveData = await pool.getReserveData(aave.address); - - expect(reserveData.isolationModeTotalDebt).to.be.eq('1000'); - }); - - it('User 3 deposits 100 AAVE, borrows 10 DAI. Check debt ceiling', async () => { - const { dai, aave, users, pool } = testEnv; - - const aaveAmount = utils.parseEther('100'); - await aave.connect(users[3].signer)['mint(uint256)'](aaveAmount); - await aave.connect(users[3].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[3].signer).supply(aave.address, aaveAmount, users[3].address, 0); - - const borrowAmount = utils.parseEther('10'); - await expect( - pool.connect(users[3].signer).borrow(dai.address, borrowAmount, '2', 0, users[3].address) - ) - .to.emit(pool, 'IsolationModeTotalDebtUpdated') - .withArgs(aave.address, 2000); - const reserveData = await pool.getReserveData(aave.address); - - expect(reserveData.isolationModeTotalDebt).to.be.eq('2000'); - }); - - it('User 4 deposits 500 AAVE, tries to borrow past the debt ceiling (revert expected)', async () => { - const { dai, aave, users, pool } = testEnv; - - const aaveAmount = utils.parseEther('500'); - await aave.connect(users[3].signer)['mint(uint256)'](aaveAmount); - await aave.connect(users[3].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[3].signer).supply(aave.address, aaveAmount, users[3].address, 0); - - const borrowAmount = utils.parseEther('100'); - await expect( - pool.connect(users[3].signer).borrow(dai.address, borrowAmount, '2', 0, users[3].address) - ).to.be.revertedWith(DEBT_CEILING_EXCEEDED); - }); - - it('Push time forward one year. User 1, User 3 repay debt. Ensure debt ceiling is 0', async () => { - const { dai, aave, users, pool } = testEnv; - - await increaseTime(60 * 60 * 24 * 365); - - const mintAmount = utils.parseEther('100'); - await dai.connect(users[3].signer)['mint(uint256)'](mintAmount); - await dai.connect(users[3].signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool.connect(users[3].signer).repay(dai.address, MAX_UINT_AMOUNT, '2', users[3].address); - - await dai.connect(users[1].signer)['mint(uint256)'](mintAmount); - await dai.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - - await expect( - pool.connect(users[1].signer).repay(dai.address, MAX_UINT_AMOUNT, '2', users[1].address) - ) - .to.emit(pool, 'IsolationModeTotalDebtUpdated') - .withArgs(aave.address, 0); - const reserveData = await pool.getReserveData(aave.address); - - expect(reserveData.isolationModeTotalDebt).to.be.eq('0'); - }); - - it('Perform liquidation of isolation mode asset', async () => { - // We need to look at how the user getting liquidated was positioned. If the asset is isolation mode, then it needs to impact that as well - const { - dai, - aave, - oracle, - addressesProvider, - helpersContract, - users: [, , , , borrower, liquidator], - pool, - } = testEnv; - - // Fund depositor and liquidator - const liquidatorAmount = utils.parseUnits('1000', 18); - await dai.connect(liquidator.signer)['mint(uint256)'](liquidatorAmount.mul(2)); - await dai.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(liquidator.signer) - .supply(dai.address, liquidatorAmount, liquidator.address, 0); - - const userGlobalDataBefore = await pool.getUserAccountData(borrower.address); - expect(userGlobalDataBefore.totalCollateralBase).to.be.eq(0); - - const depositAmount = utils.parseUnits('1', 18); - await aave.connect(borrower.signer)['mint(uint256)'](depositAmount); - await aave.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(borrower.signer).supply(aave.address, depositAmount, borrower.address, 0); - - const userData = await helpersContract.getUserReserveData(aave.address, borrower.address); - expect(userData.usageAsCollateralEnabled).to.be.eq(true); - - const borrowAmount = utils.parseUnits('50', 18); - await pool - .connect(borrower.signer) - .borrow(dai.address, borrowAmount, RateMode.Variable, '0', borrower.address); - - const daiPrice = await oracle.getAssetPrice(dai.address); - await oracle.setAssetPrice(dai.address, daiPrice.mul(10)); - - const userGlobalData = await pool.getUserAccountData(borrower.address); - - expect(userGlobalData.healthFactor).to.be.lt(utils.parseEther('1')); - - const isolationModeTotalDebtBefore = (await pool.getReserveData(aave.address)) - .isolationModeTotalDebt; - const expectedAmountAfter = isolationModeTotalDebtBefore.sub( - borrowAmount.div(2).div(BigNumber.from(10).pow(16)) - ); - - await expect( - pool - .connect(liquidator.signer) - .liquidationCall(aave.address, dai.address, borrower.address, borrowAmount.div(2), false) - ) - .to.emit(pool, 'IsolationModeTotalDebtUpdated') - .withArgs(aave.address, expectedAmountAfter); - - const isolationModeTotalDebtAfter = (await pool.getReserveData(aave.address)) - .isolationModeTotalDebt; - - expect(isolationModeTotalDebtAfter).to.be.eq(expectedAmountAfter); - }); - - it('User 5 supplies weth and dai. User 6 supplies AAVE and transfers to User 5', async () => { - const { weth, dai, aave, aAave, users, pool, helpersContract } = testEnv; - - const wethAmount = utils.parseEther('1'); - await weth.connect(users[5].signer)['mint(uint256)'](wethAmount); - await weth.connect(users[5].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[5].signer).supply(weth.address, wethAmount, users[5].address, 0); - - const daiAmount = utils.parseEther('100'); - await dai.connect(users[5].signer)['mint(uint256)'](daiAmount); - await dai.connect(users[5].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[5].signer).supply(dai.address, daiAmount, users[5].address, 0); - - const aaveAmount = utils.parseEther('100'); - await aave.connect(users[6].signer)['mint(uint256)'](aaveAmount); - await aave.connect(users[6].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[6].signer).supply(aave.address, aaveAmount, users[6].address, 0); - await aAave.connect(users[6].signer).transfer(users[5].address, aaveAmount); - - const wethUserData = await helpersContract.getUserReserveData(weth.address, users[5].address); - const daiUserData = await helpersContract.getUserReserveData(dai.address, users[5].address); - const aaveUserData = await helpersContract.getUserReserveData(aave.address, users[5].address); - expect(daiUserData.usageAsCollateralEnabled).to.be.eq(true); - expect(wethUserData.usageAsCollateralEnabled).to.be.eq(true); - expect(aaveUserData.usageAsCollateralEnabled).to.be.eq(false); - }); - - it('User 5s isolation mode asset is liquidated by User 6', async () => { - const { weth, dai, aave, aAave, users, pool, helpersContract, oracle } = testEnv; - - await evmRevert(snapshot); - snapshot = await evmSnapshot(); - - const daiAmount = utils.parseEther('700'); - await dai.connect(users[5].signer)['mint(uint256)'](daiAmount); - await dai.connect(users[5].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[5].signer).supply(dai.address, daiAmount, users[5].address, 0); - - const aaveAmount = utils.parseEther('.3'); - await aave.connect(users[6].signer)['mint(uint256)'](aaveAmount); - await aave.connect(users[6].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[6].signer).supply(aave.address, aaveAmount, users[6].address, 0); - - // borrow with health factor just above 1 - const userGlobalData = await pool.getUserAccountData(users[6].address); - const daiPrice = await oracle.getAssetPrice(dai.address); - let amountDAIToBorrow = await convertToCurrencyDecimals( - dai.address, - userGlobalData.availableBorrowsBase.div(daiPrice.toString()).percentMul(9999).toString() - ); - await pool - .connect(users[6].signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Variable, 0, users[6].address); - - // advance time so health factor is less than one and liquidate - await advanceTimeAndBlock(86400 * 365 * 100); - const userDaiReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - users[6].address - ); - const amountToLiquidate = userDaiReserveDataBefore.currentVariableDebt.div(2); - await dai.connect(users[5].signer)['mint(uint256)'](daiAmount); - const tx = await pool - .connect(users[5].signer) - .liquidationCall(aave.address, dai.address, users[6].address, amountToLiquidate, true); - await tx.wait(); - - // confirm the newly received aave tokens (in isolation mode) cannot be used as collateral - const userData = await helpersContract.getUserReserveData(aave.address, users[5].address); - expect(userData.usageAsCollateralEnabled).to.be.eq(false); - }); - - it('User 1 supplies AAVE and borrows DAI in isolation, AAVE exits isolation. User 1 repay and withdraw. AAVE enters isolation again', async () => { - await evmRevert(snapshot); - - const { pool, configurator, helpersContract, users, poolAdmin, dai, aave } = testEnv; - - // Depositor supplies DAI - await dai.connect(users[0].signer)['mint(uint256)'](depositAmount); - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[0].signer).supply(dai.address, depositAmount, users[0].address, 0); - - // User 1 supplies AAVE in isolation mode - const aaveAmountToSupply = utils.parseEther('2'); - await aave.connect(users[1].signer)['mint(uint256)'](aaveAmountToSupply); - await aave.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .supply(aave.address, aaveAmountToSupply, users[1].address, 0); - - // User 1 borrows DAI against isolated AAVE - const { isolationModeTotalDebt: isolationModeTotalDebtBeforeBorrow } = - await pool.getReserveData(aave.address); - const isolationModeTotalDebtAfterBorrow = isolationModeTotalDebtBeforeBorrow.add(1000); - const daiAmountToBorrow = utils.parseEther('10'); - expect( - await pool - .connect(users[1].signer) - .borrow(dai.address, daiAmountToBorrow, '2', 0, users[1].address) - ) - .to.emit(pool, 'IsolationModeTotalDebtUpdated') - .withArgs(aave.address, isolationModeTotalDebtAfterBorrow); - - const reserveDataAfterBorrow = await pool.getReserveData(aave.address); - expect(reserveDataAfterBorrow.isolationModeTotalDebt).to.be.eq( - isolationModeTotalDebtAfterBorrow - ); - - // AAVE exits isolation mode (debt ceiling = 0) - const oldAaveDebtCeiling = await helpersContract.getDebtCeiling(aave.address); - const newAaveDebtCeiling = 0; - expect( - await configurator.connect(poolAdmin.signer).setDebtCeiling(aave.address, newAaveDebtCeiling) - ) - .to.emit(configurator, 'DebtCeilingChanged') - .withArgs(aave.address, oldAaveDebtCeiling, newAaveDebtCeiling); - - expect(await helpersContract.getDebtCeiling(aave.address)).to.be.eq(newAaveDebtCeiling); - expect((await pool.getReserveData(aave.address)).isolationModeTotalDebt).to.be.eq( - 0, - 'isolationModeTotalDebt when entering isolation mode' - ); - - // User 1 borrows 1 DAI - await pool - .connect(users[1].signer) - .borrow(dai.address, utils.parseEther('1'), '2', 0, users[1].address); - - // User 1 repays debt and withdraw - await dai.connect(users[1].signer)['mint(uint256)'](utils.parseEther('20')); - await dai.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[1].signer).repay(dai.address, MAX_UINT_AMOUNT, '2', users[1].address); - await pool.connect(users[1].signer).withdraw(aave.address, MAX_UINT_AMOUNT, users[1].address); - - // AAVE enters isolation mode again - expect(await configurator.connect(poolAdmin.signer).setDebtCeiling(aave.address, 100)) - .to.emit(configurator, 'DebtCeilingChanged') - .withArgs(aave.address, 0, 100); - - expect(await helpersContract.getDebtCeiling(aave.address)).to.be.eq(100); - expect((await pool.getReserveData(aave.address)).isolationModeTotalDebt).to.be.eq( - 0, - 'isolationModeTotalDebt when entering isolation mode' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-atoken.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-atoken.spec.ts deleted file mode 100644 index baa272f..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-atoken.spec.ts +++ /dev/null @@ -1,454 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber } from 'ethers'; -import { MAX_UINT_AMOUNT, oneEther } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations'; -import { getUserData, getReserveData } from './helpers/utils/helpers'; -import { makeSuite } from './helpers/make-suite'; -import { waitForTx } from '@aave/deploy-v3'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('Pool Liquidation: Liquidator receiving aToken', (testEnv) => { - const { - HEALTH_FACTOR_NOT_BELOW_THRESHOLD, - INVALID_HF, - SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER, - COLLATERAL_CANNOT_BE_LIQUIDATED, - } = ProtocolErrors; - - let oracleBaseDecimals: number; - - before(async () => { - const { aaveOracle, addressesProvider, oracle } = testEnv; - oracleBaseDecimals = (await (await aaveOracle.BASE_CURRENCY_UNIT()).toString().length) - 1; - - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - it('Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => { - const { - dai, - weth, - users: [depositor, borrower], - pool, - oracle, - } = testEnv; - - //mints DAI to depositor - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - //approve protocol to access depositor wallet - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 1 deposits DAI - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - await pool - .connect(depositor.signer) - .deposit(dai.address, amountDAItoDeposit, depositor.address, '0'); - - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.3'); - - //mints WETH to borrower - await weth.connect(borrower.signer)['mint(uint256)'](amountETHtoDeposit); - - //approve protocol to access borrower wallet - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 2 deposits WETH - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); - - //user 2 borrows - const userGlobalData = await pool.getUserAccountData(borrower.address); - const daiPrice = await oracle.getAssetPrice(dai.address); - const amountDAIToBorrow = await convertToCurrencyDecimals( - dai.address, - userGlobalData.availableBorrowsBase.div(daiPrice.toString()).percentMul(9500).toString() - ); - await pool - .connect(borrower.signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Variable, '0', borrower.address); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - expect(userGlobalDataAfter.currentLiquidationThreshold).to.be.equal( - 8250, - 'Invalid liquidation threshold' - ); - - //someone tries to liquidate user 2 - await expect( - pool.liquidationCall(weth.address, dai.address, borrower.address, 1, true) - ).to.be.revertedWith(HEALTH_FACTOR_NOT_BELOW_THRESHOLD); - }); - - it('Drop the health factor below 1', async () => { - const { - dai, - users: [, borrower], - pool, - oracle, - aaveOracle, - } = testEnv; - - const daiPrice = await oracle.getAssetPrice(dai.address); - - await oracle.setAssetPrice(dai.address, daiPrice.percentMul(11500)); - - const userGlobalData = await pool.getUserAccountData(borrower.address); - - expect(userGlobalData.healthFactor).to.be.lt(oneEther, INVALID_HF); - }); - - it('Tries to liquidate a different currency than the loan principal (revert expected)', async () => { - const { - pool, - users: [, borrower], - weth, - } = testEnv; - //user 2 tries to borrow - await expect( - pool.liquidationCall(weth.address, weth.address, borrower.address, oneEther, true) - ).to.be.revertedWith(SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER); - }); - - it('Tries to liquidate a different collateral than the borrower collateral (revert expected)', async () => { - const { - pool, - dai, - users: [, borrower], - } = testEnv; - - await expect( - pool.liquidationCall(dai.address, dai.address, borrower.address, oneEther, true) - ).to.be.revertedWith(COLLATERAL_CANNOT_BE_LIQUIDATED); - }); - - it('Liquidates the borrow', async () => { - const { - pool, - dai, - weth, - users: [, borrower], - oracle, - helpersContract, - deployer, - } = testEnv; - - //mints dai to the caller - - await dai['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - //approve protocol to access depositor wallet - await dai.approve(pool.address, MAX_UINT_AMOUNT); - - const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); - const ethReserveDataBefore = await getReserveData(helpersContract, weth.address); - - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const userWethReserveDataBefore = await getUserData( - pool, - helpersContract, - weth.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2); - - // The supply is the same, but there should be a change in who has what. The liquidator should have received what the borrower lost. - const tx = await pool.liquidationCall( - weth.address, - dai.address, - borrower.address, - amountToLiquidate, - true - ); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - dai.address, - borrower.address - ); - - const userWethReserveDataAfter = await helpersContract.getUserReserveData( - weth.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - const daiReserveDataAfter = await getReserveData(helpersContract, dai.address); - const ethReserveDataAfter = await getReserveData(helpersContract, weth.address); - - const collateralPrice = await oracle.getAssetPrice(weth.address); - const principalPrice = await oracle.getAssetPrice(dai.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(weth.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(dai.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(amountToLiquidate) - .percentMul(10500) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - expect(expectedCollateralLiquidated).to.be.closeTo( - userWethReserveDataBefore.currentATokenBalance.sub( - userWethReserveDataAfter.currentATokenBalance - ), - 2, - 'Invalid collateral amount liquidated' - ); - - if (!tx.blockNumber) { - expect(false, 'Invalid block number'); - return; - } - - const txTimestamp = BigNumber.from( - (await hre.ethers.provider.getBlock(tx.blockNumber)).timestamp - ); - - const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance( - daiReserveDataBefore, - userReserveDataBefore, - txTimestamp - ); - - expect(userGlobalDataAfter.healthFactor).to.be.gt(oneEther, 'Invalid health factor'); - - expect(userReserveDataAfter.currentVariableDebt).to.be.closeTo( - variableDebtBeforeTx.sub(amountToLiquidate), - 2, - 'Invalid user borrow balance after liquidation' - ); - - expect(daiReserveDataAfter.availableLiquidity).to.be.closeTo( - daiReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(ethReserveDataAfter.availableLiquidity).to.be.closeTo( - ethReserveDataBefore.availableLiquidity, - 2, - 'Invalid collateral available liquidity' - ); - - expect(daiReserveDataAfter.totalLiquidity).to.be.closeTo( - daiReserveDataBefore.totalLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal total liquidity' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(daiReserveDataAfter.liquidityIndex).to.be.gte( - daiReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(daiReserveDataAfter.liquidityRate).to.be.lt( - daiReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - // We need the scaled balances here - expect(ethReserveDataAfter.totalLiquidity).to.be.closeTo( - ethReserveDataBefore.totalLiquidity, - 2, - 'Invalid collateral total liquidity' - ); - - expect( - (await helpersContract.getUserReserveData(weth.address, deployer.address)) - .usageAsCollateralEnabled - ).to.be.true; - }); - - it('User 3 deposits 2000 USDC, user 4 0.12 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => { - const { - users: [, , , depositor, borrower], - pool, - usdc, - oracle, - weth, - helpersContract, - } = testEnv; - - //mints USDC to depositor - await usdc - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '2000')); - - //approve protocol to access depositor wallet - await usdc.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 3 deposits 1000 USDC - const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '2000'); - - await pool - .connect(depositor.signer) - .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0'); - - //user 4 deposits ETH - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.12'); - - //mints WETH to borrower - await weth.connect(borrower.signer)['mint(uint256)'](amountETHtoDeposit); - - //approve protocol to access borrower wallet - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); - - //user 4 borrows - const userGlobalData = await pool.getUserAccountData(borrower.address); - - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - const amountUSDCToBorrow = await convertToCurrencyDecimals( - usdc.address, - userGlobalData.availableBorrowsBase.div(usdcPrice).percentMul(9502).toString() - ); - - await pool - .connect(borrower.signer) - .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address); - - //drops HF below 1 - - await oracle.setAssetPrice(usdc.address, usdcPrice.percentMul(11200)); - - //mints dai to the liquidator - - await usdc['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access depositor wallet - await usdc.approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - const ethReserveDataBefore = await getReserveData(helpersContract, weth.address); - const userWethReserveDataBefore = await getUserData( - pool, - helpersContract, - weth.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - await pool.liquidationCall( - weth.address, - usdc.address, - borrower.address, - amountToLiquidate, - true - ); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const userWethReserveDataAfter = await helpersContract.getUserReserveData( - weth.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - const ethReserveDataAfter = await getReserveData(helpersContract, weth.address); - - const collateralPrice = await oracle.getAssetPrice(weth.address); - const principalPrice = await oracle.getAssetPrice(usdc.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(weth.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(amountToLiquidate) - .percentMul(10500) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - expect(expectedCollateralLiquidated).to.be.eq( - userWethReserveDataBefore.currentATokenBalance.sub( - userWethReserveDataAfter.currentATokenBalance - ), - 'Invalid collateral amount liquidated' - ); - - expect(userGlobalDataAfter.healthFactor).to.be.gt(oneEther, 'Invalid health factor'); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - userReserveDataBefore.currentStableDebt.sub(amountToLiquidate), - 2, - 'Invalid user borrow balance after liquidation' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(usdcReserveDataAfter.totalLiquidity).to.be.closeTo( - usdcReserveDataBefore.totalLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal total liquidity' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(usdcReserveDataAfter.liquidityIndex).to.be.gte( - usdcReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(usdcReserveDataAfter.liquidityRate).to.be.lt( - usdcReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(ethReserveDataAfter.availableLiquidity).to.be.closeTo( - ethReserveDataBefore.availableLiquidity, - 2, - 'Invalid collateral available liquidity' - ); - - expect(ethReserveDataAfter.totalLiquidity).to.be.closeTo( - ethReserveDataBefore.totalLiquidity, - 2, - 'Invalid collateral total liquidity' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-edge.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-edge.spec.ts deleted file mode 100644 index ab5189d..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-edge.spec.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { RateMode } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; - -import './helpers/utils/wadraymath'; -import { - evmSnapshot, - evmRevert, - waitForTx, - StableDebtToken__factory, - VariableDebtToken__factory, -} from '@aave/deploy-v3'; - -makeSuite('Pool Liquidation: Edge cases', (testEnv: TestEnv) => { - let snap: string; - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - afterEach(async () => { - await evmRevert(snap); - }); - - before(async () => { - const { addressesProvider, oracle } = testEnv; - - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - it('ValidationLogic `executeLiquidationCall` where user has variable and stable debt, but variable debt is insufficient to cover the full liquidation amount', async () => { - const { pool, users, dai, weth, oracle } = testEnv; - - const depositor = users[0]; - const borrower = users[1]; - - // Deposit dai - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000000')); - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(depositor.signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, '10000'), - depositor.address, - 0 - ); - - // Deposit eth, borrow dai - await weth.connect(borrower.signer)['mint(uint256)'](utils.parseEther('0.9')); - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(borrower.signer) - .deposit(weth.address, utils.parseEther('0.9'), borrower.address, 0); - - const daiPrice = await oracle.getAssetPrice(dai.address); - - await oracle.setAssetPrice(dai.address, daiPrice.percentDiv('2700')); - - // Borrow - await pool - .connect(borrower.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '500'), - RateMode.Stable, - 0, - borrower.address - ); - - // Borrow - await pool - .connect(borrower.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '220'), - RateMode.Variable, - 0, - borrower.address - ); - - await oracle.setAssetPrice(dai.address, daiPrice.percentMul(600_00)); - - expect( - await pool - .connect(depositor.signer) - .liquidationCall(weth.address, dai.address, borrower.address, MAX_UINT_AMOUNT, false) - ); - }); - - it('Liquidation repay asset completely, asset should not be set as borrowed anymore', async () => { - const { pool, users, dai, usdc, weth, oracle } = testEnv; - - const depositor = users[0]; - const borrower = users[1]; - - // Deposit dai - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000000')); - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(depositor.signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, '10000'), - depositor.address, - 0 - ); - - // Deposit usdc - await usdc - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - await usdc.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(depositor.signer) - .deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '1000'), - depositor.address, - 0 - ); - - // Deposit eth, borrow dai - await weth.connect(borrower.signer)['mint(uint256)'](utils.parseEther('0.9')); - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(borrower.signer) - .deposit(weth.address, utils.parseEther('0.9'), borrower.address, 0); - - // Borrow usdc - await pool - .connect(borrower.signer) - .borrow( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '1000'), - RateMode.Variable, - 0, - borrower.address - ); - - // Borrow dai stable - await pool - .connect(borrower.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '100'), - RateMode.Stable, - 0, - borrower.address - ); - - // Borrow dai variable - await pool - .connect(borrower.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '100'), - RateMode.Variable, - 0, - borrower.address - ); - - // Increase usdc price to allow liquidation - const usdcPrice = await oracle.getAssetPrice(usdc.address); - await oracle.setAssetPrice(usdc.address, usdcPrice.mul(10)); - - const daiData = await pool.getReserveData(dai.address); - const variableDebtToken = VariableDebtToken__factory.connect( - daiData.variableDebtTokenAddress, - depositor.signer - ); - const stableDebtToken = StableDebtToken__factory.connect( - daiData.stableDebtTokenAddress, - depositor.signer - ); - - expect(await variableDebtToken.balanceOf(borrower.address)).to.be.gt(0); - expect(await stableDebtToken.balanceOf(borrower.address)).to.be.gt(0); - - const userConfigBefore = BigNumber.from( - (await pool.getUserConfiguration(borrower.address)).data - ); - - expect( - await pool - .connect(depositor.signer) - .liquidationCall(weth.address, dai.address, borrower.address, MAX_UINT_AMOUNT, false) - ); - - const userConfigAfter = BigNumber.from( - (await pool.getUserConfiguration(borrower.address)).data - ); - - const isBorrowing = (conf, id) => - conf - .div(BigNumber.from(2).pow(BigNumber.from(id).mul(2))) - .and(1) - .gt(0); - - expect(await variableDebtToken.balanceOf(borrower.address)).to.be.eq(0); - expect(await stableDebtToken.balanceOf(borrower.address)).to.be.eq(0); - - expect(isBorrowing(userConfigBefore, daiData.id)).to.be.true; - expect(isBorrowing(userConfigAfter, daiData.id)).to.be.false; - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-emode-interest.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-emode-interest.spec.ts deleted file mode 100644 index d34593d..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-emode-interest.spec.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations'; -import { getReserveData, getUserData } from './helpers/utils/helpers'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { waitForTx, increaseTime } from '@aave/deploy-v3'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('Pool Liquidation: Liquidates borrows in eMode through interest', (testEnv: TestEnv) => { - const { INVALID_HF } = ProtocolErrors; - - const CATEGORY = { - id: BigNumber.from('1'), - ltv: BigNumber.from('9800'), - lt: BigNumber.from('9850'), - lb: BigNumber.from('10100'), - oracle: ZERO_ADDRESS, - label: 'STABLECOINS', - }; - - before(async () => { - const { addressesProvider, oracle } = testEnv; - - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - it('Adds category id 1 (stablecoins)', async () => { - const { configurator, pool, poolAdmin } = testEnv; - - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory( - CATEGORY.id, - CATEGORY.ltv, - CATEGORY.lt, - CATEGORY.lb, - CATEGORY.oracle, - CATEGORY.label - ) - ); - - const categoryData = await pool.getEModeCategoryData(CATEGORY.id); - - expect(categoryData.ltv).to.be.equal(CATEGORY.ltv, 'invalid eMode category ltv'); - expect(categoryData.liquidationThreshold).to.be.equal( - CATEGORY.lt, - 'invalid eMode category liq threshold' - ); - expect(categoryData.liquidationBonus).to.be.equal( - CATEGORY.lb, - 'invalid eMode category liq bonus' - ); - expect(categoryData.priceSource).to.be.equal( - CATEGORY.oracle, - 'invalid eMode category price source' - ); - }); - - it('Add DAI and USDC to category id 1', async () => { - const { configurator, poolAdmin, dai, usdc } = testEnv; - - expect( - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, CATEGORY.id) - ); - expect( - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(usdc.address, CATEGORY.id) - ); - }); - - it('Someone funds the DAI pool', async () => { - const { - pool, - users: [daiFunder], - dai, - } = testEnv; - const supplyAmount = utils.parseUnits('10000', 18); - - await dai.connect(daiFunder.signer)['mint(uint256)'](supplyAmount); - await dai.connect(daiFunder.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool.connect(daiFunder.signer).supply(dai.address, supplyAmount, daiFunder.address, 0); - }); - - it('Deposit USDC with eMode', async () => { - const { - pool, - users: [, borrower], - usdc, - } = testEnv; - - await usdc.connect(borrower.signer)['mint(uint256)'](utils.parseUnits('10000', 6)); - await usdc.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(borrower.signer) - .supply(usdc.address, utils.parseUnits('10000', 6), borrower.address, 0); - - await pool.connect(borrower.signer).setUserEMode(CATEGORY.id); - }); - - it('Borrow as much DAI as possible', async () => { - const { - pool, - users: [, borrower], - dai, - oracle, - } = testEnv; - - const userGlobalData = await pool.getUserAccountData(borrower.address); - const daiPrice = await oracle.getAssetPrice(dai.address); - - const amountDAIToBorrow = await convertToCurrencyDecimals( - dai.address, - userGlobalData.availableBorrowsBase.div(daiPrice).toString() - ); - - await pool - .connect(borrower.signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Variable, 0, borrower.address); - }); - - it('Drop HF below 1', async () => { - const { - users: [, borrower], - pool, - } = testEnv; - - const userGlobalDataBefore = await pool.getUserAccountData(borrower.address); - expect(userGlobalDataBefore.healthFactor).to.be.gt(utils.parseUnits('1', 18), INVALID_HF); - await increaseTime(60 * 60 * 24 * 3); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - expect(userGlobalDataAfter.healthFactor).to.be.lt(utils.parseUnits('1', 18), INVALID_HF); - }); - - it('Liquidates the borrow', async () => { - const { - dai, - usdc, - users: [, borrower, liquidator], - pool, - oracle, - helpersContract, - } = testEnv; - - await dai.connect(liquidator.signer)['mint(uint256)'](utils.parseUnits('100000', 18)); - await dai.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2); - const userGlobalDataBefore = await pool.getUserAccountData(borrower.address); - - const tx = await pool - .connect(liquidator.signer) - .liquidationCall(usdc.address, dai.address, borrower.address, amountToLiquidate, false); - - const daiReserveDataAfter = await getReserveData(helpersContract, dai.address); - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - const userReserveDataAfter = await helpersContract.getUserReserveData( - dai.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - expect(userGlobalDataAfter.healthFactor).to.be.gt(userGlobalDataBefore.healthFactor); - expect(userGlobalDataAfter.totalCollateralBase).to.be.lt( - userGlobalDataBefore.totalCollateralBase - ); - expect(userGlobalDataAfter.totalDebtBase).to.be.lt(userGlobalDataBefore.totalDebtBase); - - const collateralPrice = await oracle.getAssetPrice(usdc.address); - const principalPrice = await oracle.getAssetPrice(dai.address); - const collateralDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(dai.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(amountToLiquidate) - .percentMul(CATEGORY.lb) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - if (!tx.blockNumber) { - expect(false, 'Invalid block number'); - return; - } - - const txTimestamp = BigNumber.from( - (await hre.ethers.provider.getBlock(tx.blockNumber)).timestamp - ); - - const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance( - daiReserveDataBefore, - userReserveDataBefore, - txTimestamp - ); - - expect(userReserveDataAfter.currentVariableDebt).to.be.closeTo( - variableDebtBeforeTx.sub(amountToLiquidate), - 2, - 'Invalid user borrow balance after liquidation' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(daiReserveDataAfter.liquidityIndex).to.be.gte( - daiReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(daiReserveDataAfter.liquidityRate).to.be.lt( - daiReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(daiReserveDataAfter.availableLiquidity).to.be.closeTo( - daiReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral available liquidity' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-emode.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-emode.spec.ts deleted file mode 100644 index a398b98..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-emode.spec.ts +++ /dev/null @@ -1,621 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { getReserveData, getUserData } from './helpers/utils/helpers'; -import './helpers/utils/wadraymath'; -import { evmRevert, evmSnapshot, waitForTx } from '@aave/deploy-v3'; - -makeSuite('Pool Liquidation: Liquidates borrows in eMode with price change', (testEnv: TestEnv) => { - const { INVALID_HF } = ProtocolErrors; - - const CATEGORY = { - id: BigNumber.from('1'), - ltv: BigNumber.from('9800'), - lt: BigNumber.from('9850'), - lb: BigNumber.from('10100'), - oracle: ZERO_ADDRESS, - label: 'STABLECOINS', - }; - - let snap: string; - - before(async () => { - const { addressesProvider, oracle } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - snap = await evmSnapshot(); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - it('Adds category id 1 (stablecoins)', async () => { - const { configurator, pool, poolAdmin } = testEnv; - - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory( - 1, - CATEGORY.ltv, - CATEGORY.lt, - CATEGORY.lb, - CATEGORY.oracle, - CATEGORY.label - ) - ); - - const categoryData = await pool.getEModeCategoryData(CATEGORY.id); - - expect(categoryData.ltv).to.be.equal(CATEGORY.ltv, 'invalid eMode category ltv'); - expect(categoryData.liquidationThreshold).to.be.equal( - CATEGORY.lt, - 'invalid eMode category liq threshold' - ); - expect(categoryData.liquidationBonus).to.be.equal( - CATEGORY.lb, - 'invalid eMode category liq bonus' - ); - expect(categoryData.priceSource).to.be.equal( - CATEGORY.oracle, - 'invalid eMode category price source' - ); - }); - - it('Add DAI and USDC to category id 1', async () => { - const { configurator, pool, helpersContract, poolAdmin, dai, usdc } = testEnv; - - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, CATEGORY.id); - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(usdc.address, CATEGORY.id); - - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.be.eq(CATEGORY.id); - expect(await helpersContract.getReserveEModeCategory(usdc.address)).to.be.eq(CATEGORY.id); - }); - - it('Someone funds the DAI pool', async () => { - const { - pool, - users: [daiFunder], - dai, - } = testEnv; - const supplyAmount = utils.parseUnits('1', 36); - - await dai.connect(daiFunder.signer)['mint(uint256)'](supplyAmount); - await dai.connect(daiFunder.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool.connect(daiFunder.signer).supply(dai.address, supplyAmount, daiFunder.address, 0); - }); - - it('Deposit USDC with eMode', async () => { - const { - pool, - users: [, depositor], - usdc, - } = testEnv; - - await usdc.connect(depositor.signer)['mint(uint256)'](utils.parseUnits('10000', 6)); - await usdc.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(depositor.signer) - .supply(usdc.address, utils.parseUnits('10000', 6), depositor.address, 0); - - await pool.connect(depositor.signer).setUserEMode(CATEGORY.id); - expect(await pool.getUserEMode(depositor.address)).to.be.eq(CATEGORY.id); - }); - - it('Borrow 98% LTV in dai', async () => { - const { - pool, - users: [, depositor], - dai, - oracle, - } = testEnv; - - const userGlobalData = await pool.getUserAccountData(depositor.address); - const daiPrice = await oracle.getAssetPrice(dai.address); - - const amountDAIToBorrow = await convertToCurrencyDecimals( - dai.address, - userGlobalData.availableBorrowsBase.div(daiPrice).toString() - ); - - await pool - .connect(depositor.signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Variable, 0, depositor.address); - }); - - it('Drop HF below 1', async () => { - const { - dai, - users: [, depositor], - pool, - oracle, - } = testEnv; - - const daiPrice = await oracle.getAssetPrice(dai.address); - - const userGlobalDataBefore = await pool.getUserAccountData(depositor.address); - expect(userGlobalDataBefore.healthFactor).to.be.gt(utils.parseUnits('1', 18)); - - await oracle.setAssetPrice( - dai.address, - daiPrice.mul(userGlobalDataBefore.healthFactor).div(utils.parseUnits('1', 18)) - ); - - const userGlobalDataMid = await pool.getUserAccountData(depositor.address); - expect(userGlobalDataMid.healthFactor).to.be.gt(utils.parseUnits('1', 18)); - - await oracle.setAssetPrice(dai.address, (await oracle.getAssetPrice(dai.address)).add(1)); - - const userGlobalDataAfter = await pool.getUserAccountData(depositor.address); - expect(userGlobalDataAfter.healthFactor).to.be.lt(utils.parseUnits('1', 18), INVALID_HF); - }); - - it('Liquidates the borrow', async () => { - const { - dai, - usdc, - users: [, borrower, , liquidator], - pool, - oracle, - helpersContract, - } = testEnv; - - await dai.connect(liquidator.signer)['mint(uint256)'](utils.parseUnits('100000', 18)); - await dai.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2); - - const userGlobalDataBefore = await pool.getUserAccountData(borrower.address); - - await pool - .connect(liquidator.signer) - .liquidationCall(usdc.address, dai.address, borrower.address, amountToLiquidate, false); - - const daiReserveDataAfter = await getReserveData(helpersContract, dai.address); - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - const userReserveDataAfter = await helpersContract.getUserReserveData( - dai.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - expect(userGlobalDataAfter.healthFactor).to.be.gt(userGlobalDataBefore.healthFactor); - expect(userGlobalDataAfter.totalCollateralBase).to.be.lt( - userGlobalDataBefore.totalCollateralBase - ); - expect(userGlobalDataAfter.totalDebtBase).to.be.lt(userGlobalDataBefore.totalDebtBase); - - const collateralPrice = await oracle.getAssetPrice(usdc.address); - const principalPrice = await oracle.getAssetPrice(dai.address); - const collateralDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(dai.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(amountToLiquidate) - .percentMul(CATEGORY.lb) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - expect(userReserveDataAfter.currentVariableDebt).to.be.closeTo( - userReserveDataBefore.currentVariableDebt.sub(amountToLiquidate), - 2, - 'Invalid user borrow balance after liquidation' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(daiReserveDataAfter.liquidityIndex).to.be.eq( - daiReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(daiReserveDataAfter.liquidityRate).to.be.eq(0, 'Invalid liquidity APY'); - - expect(daiReserveDataAfter.availableLiquidity).to.be.closeTo( - daiReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral available liquidity' - ); - }); - - it('Liquidation of non-eMode collateral with eMode debt for user in EMode', async () => { - await evmRevert(snap); - snap = await evmSnapshot(); - - const { - helpersContract, - oracle, - configurator, - pool, - poolAdmin, - dai, - usdc, - weth, - aWETH, - users: [user1, user2], - } = testEnv; - - // Create category - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory( - 1, - CATEGORY.ltv, - CATEGORY.lt, - CATEGORY.lb, - CATEGORY.oracle, - CATEGORY.label - ) - ); - - const categoryData = await pool.getEModeCategoryData(CATEGORY.id); - - expect(categoryData.ltv).to.be.equal(CATEGORY.ltv, 'invalid eMode category ltv'); - expect(categoryData.liquidationThreshold).to.be.equal( - CATEGORY.lt, - 'invalid eMode category liq threshold' - ); - expect(categoryData.liquidationBonus).to.be.equal( - CATEGORY.lb, - 'invalid eMode category liq bonus' - ); - expect(categoryData.priceSource).to.be.equal( - CATEGORY.oracle, - 'invalid eMode category price source' - ); - - // Add Dai and USDC to category - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, CATEGORY.id); - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(usdc.address, CATEGORY.id); - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.be.eq(CATEGORY.id); - expect(await helpersContract.getReserveEModeCategory(usdc.address)).to.be.eq(CATEGORY.id); - - // User 1 supply 1 dai + 1 eth, user 2 supply 10000 usdc - const wethSupplyAmount = utils.parseUnits('1', 18); - const daiSupplyAmount = utils.parseUnits('1', 18); - const usdcSupplyAmount = utils.parseUnits('10000', 6); - - expect(await dai.connect(user1.signer)['mint(uint256)'](daiSupplyAmount)); - expect(await weth.connect(user1.signer)['mint(uint256)'](wethSupplyAmount)); - expect(await usdc.connect(user2.signer)['mint(uint256)'](usdcSupplyAmount.mul(2))); - - expect(await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect(await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect(await usdc.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect(await pool.connect(user1.signer).supply(dai.address, daiSupplyAmount, user1.address, 0)); - expect( - await pool.connect(user1.signer).supply(weth.address, wethSupplyAmount, user1.address, 0) - ); - expect( - await pool.connect(user2.signer).supply(usdc.address, usdcSupplyAmount, user2.address, 0) - ); - - // Activate emode - expect(await pool.connect(user1.signer).setUserEMode(CATEGORY.id)); - - // Borrow a as much usdc as possible - const userData = await pool.getUserAccountData(user1.address); - const toBorrow = userData.availableBorrowsBase.div(100); - - expect( - await pool - .connect(user1.signer) - .borrow(usdc.address, toBorrow, RateMode.Variable, 0, user1.address) - ); - - // Drop weth price - const wethPrice = await oracle.getAssetPrice(weth.address); - - const userGlobalDataBefore = await pool.getUserAccountData(user1.address); - expect(userGlobalDataBefore.healthFactor).to.be.gt(utils.parseUnits('1', 18)); - - await oracle.setAssetPrice(weth.address, wethPrice.percentMul(9000)); - - const userGlobalDataAfter = await pool.getUserAccountData(user1.address); - expect(userGlobalDataAfter.healthFactor).to.be.lt(utils.parseUnits('1', 18), INVALID_HF); - - const balanceBefore = await aWETH.balanceOf(user1.address); - - // Liquidate - await pool - .connect(user2.signer) - .liquidationCall(weth.address, usdc.address, user1.address, toBorrow.div(2), false); - - const balanceAfter = await aWETH.balanceOf(user1.address); - - const debtPrice = await oracle.getAssetPrice(usdc.address); - const collateralPrice = await oracle.getAssetPrice(weth.address); - - const wethConfig = await helpersContract.getReserveConfigurationData(weth.address); - - const expectedCollateralLiquidated = debtPrice - .mul(toBorrow.div(2)) - .percentMul(wethConfig.liquidationBonus) - .mul(BigNumber.from(10).pow(18)) - .div(collateralPrice.mul(BigNumber.from(10).pow(6))); - - const collateralLiquidated = balanceBefore.sub(balanceAfter); - expect(collateralLiquidated).to.be.closeTo(expectedCollateralLiquidated, 2); - }); - - it('Liquidation of eMode collateral with eMode debt in EMode with custom price feed', async () => { - await evmRevert(snap); - snap = await evmSnapshot(); - - const { - helpersContract, - oracle, - configurator, - pool, - poolAdmin, - dai, - usdc, - weth, - aDai, - users: [user1, user2], - } = testEnv; - - // We need an extra oracle for prices. USe user address as asset in price oracle - const EMODE_ORACLE_ADDRESS = user1.address; - await oracle.setAssetPrice(EMODE_ORACLE_ADDRESS, utils.parseUnits('1', 8)); - await oracle.setAssetPrice(dai.address, utils.parseUnits('0.99', 8)); - await oracle.setAssetPrice(usdc.address, utils.parseUnits('1.01', 8)); - await oracle.setAssetPrice(weth.address, utils.parseUnits('4000', 8)); - - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory( - 1, - CATEGORY.ltv, - CATEGORY.lt, - CATEGORY.lb, - EMODE_ORACLE_ADDRESS, - CATEGORY.label - ) - ); - - const categoryData = await pool.getEModeCategoryData(CATEGORY.id); - - expect(categoryData.ltv).to.be.equal(CATEGORY.ltv, 'invalid eMode category ltv'); - expect(categoryData.liquidationThreshold).to.be.equal( - CATEGORY.lt, - 'invalid eMode category liq threshold' - ); - expect(categoryData.liquidationBonus).to.be.equal( - CATEGORY.lb, - 'invalid eMode category liq bonus' - ); - expect(categoryData.priceSource).to.be.equal( - EMODE_ORACLE_ADDRESS, - 'invalid eMode category price source' - ); - - // Add Dai and USDC to category - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, CATEGORY.id); - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(usdc.address, CATEGORY.id); - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.be.eq(CATEGORY.id); - expect(await helpersContract.getReserveEModeCategory(usdc.address)).to.be.eq(CATEGORY.id); - - // User 1 supply 5000 dai + 1 eth, user 2 supply 10000 usdc - const wethSupplyAmount = utils.parseUnits('1', 18); - const daiSupplyAmount = utils.parseUnits('5000', 18); - const usdcSupplyAmount = utils.parseUnits('10000', 6); - - expect(await dai.connect(user1.signer)['mint(uint256)'](daiSupplyAmount)); - expect(await weth.connect(user1.signer)['mint(uint256)'](wethSupplyAmount)); - expect(await usdc.connect(user2.signer)['mint(uint256)'](usdcSupplyAmount.mul(2))); - - expect(await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect(await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect(await usdc.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect(await pool.connect(user1.signer).supply(dai.address, daiSupplyAmount, user1.address, 0)); - expect( - await pool.connect(user1.signer).supply(weth.address, wethSupplyAmount, user1.address, 0) - ); - expect( - await pool.connect(user2.signer).supply(usdc.address, usdcSupplyAmount, user2.address, 0) - ); - - // Activate emode - expect(await pool.connect(user1.signer).setUserEMode(CATEGORY.id)); - - // Borrow as much usdc as possible - const userData = await pool.getUserAccountData(user1.address); - const toBorrow = userData.availableBorrowsBase.div(100); - - expect( - await pool - .connect(user1.signer) - .borrow(usdc.address, toBorrow, RateMode.Variable, 0, user1.address) - ); - - // Increase EMODE oracle price - const oraclePrice = await oracle.getAssetPrice(EMODE_ORACLE_ADDRESS); - - const userGlobalDataBefore = await pool.getUserAccountData(user1.address); - expect(userGlobalDataBefore.healthFactor).to.be.gt(utils.parseUnits('1', 18)); - - await oracle.setAssetPrice(EMODE_ORACLE_ADDRESS, oraclePrice.mul(2)); - - const userGlobalDataAfter = await pool.getUserAccountData(user1.address); - expect(userGlobalDataAfter.healthFactor).to.be.lt(utils.parseUnits('1', 18), INVALID_HF); - - const balanceBefore = await aDai.balanceOf(user1.address); - - // Liquidate - await pool - .connect(user2.signer) - .liquidationCall(dai.address, usdc.address, user1.address, toBorrow.div(2), false); - - const balanceAfter = await aDai.balanceOf(user1.address); - - const debtPrice = await oracle.getAssetPrice(EMODE_ORACLE_ADDRESS); - const collateralPrice = await oracle.getAssetPrice(EMODE_ORACLE_ADDRESS); - - const expectedCollateralLiquidated = debtPrice - .mul(toBorrow.div(2)) - .percentMul(CATEGORY.lb) - .mul(BigNumber.from(10).pow(18)) - .div(collateralPrice.mul(BigNumber.from(10).pow(6))); - - const collateralLiquidated = balanceBefore.sub(balanceAfter); - - expect(collateralLiquidated).to.be.closeTo(expectedCollateralLiquidated, 2); - }); - - it('Liquidation of non-eMode collateral with eMode debt in eMode with custom price feed', async () => { - await evmRevert(snap); - snap = await evmSnapshot(); - - const { - helpersContract, - oracle, - configurator, - pool, - poolAdmin, - dai, - usdc, - weth, - aWETH, - users: [user1, user2], - } = testEnv; - - // We need an extra oracle for prices. USe user address as asset in price oracle - const EMODE_ORACLE_ADDRESS = user1.address; - await oracle.setAssetPrice(EMODE_ORACLE_ADDRESS, utils.parseUnits('1', 8)); - await oracle.setAssetPrice(dai.address, utils.parseUnits('0.99', 8)); - await oracle.setAssetPrice(usdc.address, utils.parseUnits('1.01', 8)); - await oracle.setAssetPrice(weth.address, utils.parseUnits('4000', 8)); - - // Create category - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory( - 1, - CATEGORY.ltv, - CATEGORY.lt, - CATEGORY.lb, - EMODE_ORACLE_ADDRESS, - CATEGORY.label - ) - ); - - const categoryData = await pool.getEModeCategoryData(CATEGORY.id); - - expect(categoryData.ltv).to.be.equal(CATEGORY.ltv, 'invalid eMode category ltv'); - expect(categoryData.liquidationThreshold).to.be.equal( - CATEGORY.lt, - 'invalid eMode category liq threshold' - ); - expect(categoryData.liquidationBonus).to.be.equal( - CATEGORY.lb, - 'invalid eMode category liq bonus' - ); - expect(categoryData.priceSource).to.be.equal( - EMODE_ORACLE_ADDRESS, - 'invalid eMode category price source' - ); - - // Add Dai and USDC to category - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(dai.address, CATEGORY.id); - await configurator.connect(poolAdmin.signer).setAssetEModeCategory(usdc.address, CATEGORY.id); - expect(await helpersContract.getReserveEModeCategory(dai.address)).to.be.eq(CATEGORY.id); - expect(await helpersContract.getReserveEModeCategory(usdc.address)).to.be.eq(CATEGORY.id); - - // User 1 supply 1 dai + 1 eth, user 2 supply 10000 usdc - const wethSupplyAmount = utils.parseUnits('1', 18); - const daiSupplyAmount = utils.parseUnits('1', 18); - const usdcSupplyAmount = utils.parseUnits('10000', 6); - - expect(await dai.connect(user1.signer)['mint(uint256)'](daiSupplyAmount)); - expect(await weth.connect(user1.signer)['mint(uint256)'](wethSupplyAmount)); - expect(await usdc.connect(user2.signer)['mint(uint256)'](usdcSupplyAmount.mul(2))); - - expect(await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect(await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT)); - expect(await usdc.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect(await pool.connect(user1.signer).supply(dai.address, daiSupplyAmount, user1.address, 0)); - expect( - await pool.connect(user1.signer).supply(weth.address, wethSupplyAmount, user1.address, 0) - ); - expect( - await pool.connect(user2.signer).supply(usdc.address, usdcSupplyAmount, user2.address, 0) - ); - - // Activate emode - expect(await pool.connect(user1.signer).setUserEMode(CATEGORY.id)); - - // Borrow a as much usdc as possible - const userData = await pool.getUserAccountData(user1.address); - const toBorrow = userData.availableBorrowsBase.div(100); - - expect( - await pool - .connect(user1.signer) - .borrow(usdc.address, toBorrow, RateMode.Variable, 0, user1.address) - ); - - // Drop weth price - const oraclePrice = await oracle.getAssetPrice(EMODE_ORACLE_ADDRESS); - - const userGlobalDataBefore = await pool.getUserAccountData(user1.address); - expect(userGlobalDataBefore.healthFactor).to.be.gt(utils.parseUnits('1', 18)); - - await oracle.setAssetPrice(EMODE_ORACLE_ADDRESS, oraclePrice.mul(2)); - - const userGlobalDataAfter = await pool.getUserAccountData(user1.address); - expect(userGlobalDataAfter.healthFactor).to.be.lt(utils.parseUnits('1', 18), INVALID_HF); - - const balanceBefore = await aWETH.balanceOf(user1.address); - - // Liquidate - await pool - .connect(user2.signer) - .liquidationCall(weth.address, usdc.address, user1.address, toBorrow.div(2), false); - - const balanceAfter = await aWETH.balanceOf(user1.address); - - const debtPrice = await oracle.getAssetPrice(EMODE_ORACLE_ADDRESS); - const collateralPrice = await oracle.getAssetPrice(weth.address); - - const wethConfig = await helpersContract.getReserveConfigurationData(weth.address); - - const expectedCollateralLiquidated = debtPrice - .mul(toBorrow.div(2)) - .percentMul(wethConfig.liquidationBonus) - .mul(BigNumber.from(10).pow(18)) - .div(collateralPrice.mul(BigNumber.from(10).pow(6))); - - const collateralLiquidated = balanceBefore.sub(balanceAfter); - expect(collateralLiquidated).to.be.closeTo(expectedCollateralLiquidated, 2); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-underlying.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-underlying.spec.ts deleted file mode 100644 index de87a82..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-underlying.spec.ts +++ /dev/null @@ -1,506 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { MAX_UINT_AMOUNT, oneEther } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations'; -import { getReserveData, getUserData } from './helpers/utils/helpers'; -import { makeSuite } from './helpers/make-suite'; -import { increaseTime, waitForTx } from '@aave/deploy-v3'; - -import { HardhatRuntimeEnvironment } from 'hardhat/types'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('Pool Liquidation: Liquidator receiving the underlying asset', (testEnv) => { - const { INVALID_HF } = ProtocolErrors; - - before(async () => { - const { addressesProvider, oracle } = testEnv; - - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - it("It's not possible to liquidate on a non-active collateral or a non active principal", async () => { - const { - configurator, - weth, - pool, - users: [, user], - dai, - } = testEnv; - await configurator.setReserveActive(weth.address, false); - - await expect( - pool.liquidationCall(weth.address, dai.address, user.address, utils.parseEther('1000'), false) - ).to.be.revertedWith('2'); - - await configurator.setReserveActive(weth.address, true); - - await configurator.setReserveActive(dai.address, false); - - await expect( - pool.liquidationCall(weth.address, dai.address, user.address, utils.parseEther('1000'), false) - ).to.be.revertedWith('2'); - - await configurator.setReserveActive(dai.address, true); - }); - - it('Deposits WETH, borrows DAI', async () => { - const { - dai, - weth, - users: [depositor, borrower], - pool, - oracle, - } = testEnv; - - //mints DAI to depositor - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - //approve protocol to access depositor wallet - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 1 deposits 1000 DAI - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await pool - .connect(depositor.signer) - .deposit(dai.address, amountDAItoDeposit, depositor.address, '0'); - //user 2 deposits ETH - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.06775'); - - //mints WETH to borrower - await weth - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(weth.address, '1000')); - - //approve protocol to access the borrower wallet - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); - - //user 2 borrows - - const userGlobalData = await pool.getUserAccountData(borrower.address); - const daiPrice = await oracle.getAssetPrice(dai.address); - - const amountDAIToBorrow = await convertToCurrencyDecimals( - dai.address, - userGlobalData.availableBorrowsBase.div(daiPrice).percentMul(9500).toString() - ); - - await pool - .connect(borrower.signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - expect(userGlobalDataAfter.currentLiquidationThreshold).to.be.equal(8250, INVALID_HF); - }); - - it('Drop the health factor below 1', async () => { - const { - dai, - users: [, borrower], - pool, - oracle, - } = testEnv; - - const daiPrice = await oracle.getAssetPrice(dai.address); - - await oracle.setAssetPrice(dai.address, daiPrice.percentMul(11800)); - - const userGlobalData = await pool.getUserAccountData(borrower.address); - - expect(userGlobalData.healthFactor).to.be.lt(oneEther, INVALID_HF); - }); - - it('Liquidates the borrow', async () => { - const { - dai, - weth, - users: [, borrower, , liquidator], - pool, - oracle, - helpersContract, - } = testEnv; - - //mints dai to the liquidator - await dai - .connect(liquidator.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - //approve protocol to access the liquidator wallet - await dai.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); - const ethReserveDataBefore = await getReserveData(helpersContract, weth.address); - - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - await increaseTime(100); - - const tx = await pool - .connect(liquidator.signer) - .liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false); - - const userReserveDataAfter = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const daiReserveDataAfter = await getReserveData(helpersContract, dai.address); - const ethReserveDataAfter = await getReserveData(helpersContract, weth.address); - - const collateralPrice = await oracle.getAssetPrice(weth.address); - const principalPrice = await oracle.getAssetPrice(dai.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(weth.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(dai.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(amountToLiquidate) - .percentMul(10500) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - if (!tx.blockNumber) { - expect(false, 'Invalid block number'); - return; - } - const txTimestamp = BigNumber.from( - (await hre.ethers.provider.getBlock(tx.blockNumber)).timestamp - ); - - const stableDebtBeforeTx = calcExpectedStableDebtTokenBalance( - userReserveDataBefore.principalStableDebt, - userReserveDataBefore.stableBorrowRate, - userReserveDataBefore.stableRateLastUpdated, - txTimestamp - ); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - stableDebtBeforeTx.sub(amountToLiquidate), - 2, - 'Invalid user debt after liquidation' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(daiReserveDataAfter.liquidityIndex).to.be.gte( - daiReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(daiReserveDataAfter.liquidityRate).to.be.lt( - daiReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(daiReserveDataAfter.totalLiquidity).to.be.closeTo( - daiReserveDataBefore.totalLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal total liquidity' - ); - - expect(ethReserveDataAfter.totalLiquidity).to.be.closeTo( - ethReserveDataBefore.totalLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral total liquidity' - ); - - expect(daiReserveDataAfter.availableLiquidity).to.be.closeTo( - daiReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(ethReserveDataAfter.availableLiquidity).to.be.closeTo( - ethReserveDataBefore.availableLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral available liquidity' - ); - }); - - it('User 3 deposits 1000 USDC, user 4 0.06775 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => { - const { - usdc, - users: [, , , depositor, borrower, liquidator], - pool, - oracle, - weth, - helpersContract, - } = testEnv; - - //mints USDC to depositor - await usdc - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access depositor wallet - await usdc.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //depositor deposits 1000 USDC - const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000'); - - await pool - .connect(depositor.signer) - .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0'); - - //borrower deposits ETH - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.06775'); - - //mints WETH to borrower - await weth - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(weth.address, '1000')); - - //approve protocol to access the borrower wallet - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); - - //borrower borrows - const userGlobalData = await pool.getUserAccountData(borrower.address); - - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - const amountUSDCToBorrow = await convertToCurrencyDecimals( - usdc.address, - userGlobalData.availableBorrowsBase.div(usdcPrice).percentMul(9502).toString() - ); - - await pool - .connect(borrower.signer) - .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address); - - //drops HF below 1 - await oracle.setAssetPrice(usdc.address, usdcPrice.percentMul(11200)); - - //mints dai to the liquidator - - await usdc - .connect(liquidator.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access depositor wallet - await usdc.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - const ethReserveDataBefore = await getReserveData(helpersContract, weth.address); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - await pool - .connect(liquidator.signer) - .liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - const ethReserveDataAfter = await getReserveData(helpersContract, weth.address); - - const collateralPrice = await oracle.getAssetPrice(weth.address); - const principalPrice = await oracle.getAssetPrice(usdc.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(weth.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(BigNumber.from(amountToLiquidate)) - .percentMul(10500) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - expect(userGlobalDataAfter.healthFactor).to.be.gt(oneEther, 'Invalid health factor'); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - userReserveDataBefore.currentStableDebt.sub(amountToLiquidate), - 2, - 'Invalid user borrow balance after liquidation' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(usdcReserveDataAfter.liquidityIndex).to.be.gte( - usdcReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(usdcReserveDataAfter.liquidityRate).to.be.lt( - usdcReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(usdcReserveDataAfter.totalLiquidity).to.be.closeTo( - usdcReserveDataBefore.totalLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal total liquidity' - ); - - expect(ethReserveDataAfter.totalLiquidity).to.be.closeTo( - ethReserveDataBefore.totalLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral total liquidity' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(ethReserveDataAfter.availableLiquidity).to.be.closeTo( - ethReserveDataBefore.availableLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral available liquidity' - ); - }); - - it('User 4 deposits 0.033 AAVE - drops HF, liquidates the AAVE, which results on a lower amount being liquidated', async () => { - const { - aave, - usdc, - users: [, , , , borrower, liquidator], - pool, - oracle, - helpersContract, - } = testEnv; - - //mints AAVE to borrower - await aave - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(aave.address, '0.033')); - - //approve protocol to access the borrower wallet - await aave.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //borrower deposits 1 AAVE - const amountToDeposit = await convertToCurrencyDecimals(aave.address, '0.033'); - - await pool - .connect(borrower.signer) - .deposit(aave.address, amountToDeposit, borrower.address, '0'); - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - //drops HF below 1 - await oracle.setAssetPrice(usdc.address, usdcPrice.percentMul(11400)); - - //mints usdc to the liquidator - await usdc - .connect(liquidator.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access liquidator wallet - await usdc.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - const aaveReserveDataBefore = await getReserveData(helpersContract, aave.address); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - const collateralPrice = await oracle.getAssetPrice(aave.address); - const principalPrice = await oracle.getAssetPrice(usdc.address); - - await pool - .connect(liquidator.signer) - .liquidationCall(aave.address, usdc.address, borrower.address, amountToLiquidate, false); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - const aaveReserveDataAfter = await getReserveData(helpersContract, aave.address); - - const aaveConfiguration = await helpersContract.getReserveConfigurationData(aave.address); - const collateralDecimals = aaveConfiguration.decimals; - const liquidationBonus = aaveConfiguration.liquidationBonus; - - const principalDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - - const expectedCollateralLiquidated = oneEther.mul('33').div('1000'); - - const expectedPrincipal = collateralPrice - .mul(expectedCollateralLiquidated) - .mul(BigNumber.from(10).pow(principalDecimals)) - .div(principalPrice.mul(BigNumber.from(10).pow(collateralDecimals))) - .percentDiv(liquidationBonus); - - expect(userGlobalDataAfter.healthFactor).to.be.gt(oneEther, 'Invalid health factor'); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - userReserveDataBefore.currentStableDebt.sub(expectedPrincipal), - 2, - 'Invalid user borrow balance after liquidation' - ); - - expect(usdcReserveDataAfter.totalLiquidity).to.be.closeTo( - usdcReserveDataBefore.totalLiquidity.add(expectedPrincipal), - 2, - 'Invalid principal total liquidity' - ); - - expect(aaveReserveDataAfter.totalLiquidity).to.be.closeTo( - aaveReserveDataBefore.totalLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral total liquidity' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.add(expectedPrincipal), - 2, - 'Invalid principal available liquidity' - ); - - expect(aaveReserveDataAfter.availableLiquidity).to.be.closeTo( - aaveReserveDataBefore.availableLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral available liquidity' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-with-fee.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-with-fee.spec.ts deleted file mode 100644 index ff01fca..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/liquidation-with-fee.spec.ts +++ /dev/null @@ -1,806 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { MAX_UINT_AMOUNT, oneEther } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { AToken__factory } from '../types'; -import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations'; -import { getReserveData, getUserData } from './helpers/utils/helpers'; -import { makeSuite } from './helpers/make-suite'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { waitForTx, increaseTime, evmSnapshot, evmRevert } from '@aave/deploy-v3'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('Pool Liquidation: Add fee to liquidations', (testEnv) => { - const { INVALID_HF } = ProtocolErrors; - - before(async () => { - const { addressesProvider, oracle } = testEnv; - - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - it('Sets the WETH protocol liquidation fee to 1000 (10.00%)', async () => { - const { configurator, weth, aave, helpersContract } = testEnv; - - const oldWethLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - weth.address - ); - const oldAaveLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - aave.address - ); - - const wethLiquidationProtocolFeeInput = 1000; - const aaveLiquidationProtocolFeeInput = 500; - - expect( - await configurator.setLiquidationProtocolFee(weth.address, wethLiquidationProtocolFeeInput) - ) - .to.emit(configurator, 'LiquidationProtocolFeeChanged') - .withArgs(weth.address, oldWethLiquidationProtocolFee, wethLiquidationProtocolFeeInput); - expect( - await configurator.setLiquidationProtocolFee(aave.address, aaveLiquidationProtocolFeeInput) - ) - .to.emit(configurator, 'LiquidationProtocolFeeChanged') - .withArgs(aave.address, oldAaveLiquidationProtocolFee, aaveLiquidationProtocolFeeInput); - - const wethLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - weth.address - ); - const aaveLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - aave.address - ); - - expect(wethLiquidationProtocolFee).to.be.equal(wethLiquidationProtocolFeeInput); - expect(aaveLiquidationProtocolFee).to.be.equal(aaveLiquidationProtocolFeeInput); - }); - - it('Deposits WETH, borrows DAI', async () => { - const { - dai, - weth, - users: [depositor, borrower], - pool, - oracle, - } = testEnv; - - //mints DAI to depositor - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - //approve protocol to access depositor wallet - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 1 deposits 1000 DAI - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await pool - .connect(depositor.signer) - .deposit(dai.address, amountDAItoDeposit, depositor.address, '0'); - //user 2 deposits 1 ETH - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.06775'); - - //mints WETH to borrower - await weth - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(weth.address, '1000')); - - //approve protocol to access the borrower wallet - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); - - //user 2 borrows - - const userGlobalData = await pool.getUserAccountData(borrower.address); - const daiPrice = await oracle.getAssetPrice(dai.address); - - const amountDAIToBorrow = await convertToCurrencyDecimals( - dai.address, - userGlobalData.availableBorrowsBase.div(daiPrice).percentMul(9500).toString() - ); - - await pool - .connect(borrower.signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - expect(userGlobalDataAfter.currentLiquidationThreshold).to.be.equal(8250, INVALID_HF); - }); - - it('Drop the health factor below 1', async () => { - const { - dai, - users: [, borrower], - pool, - oracle, - } = testEnv; - - const daiPrice = await oracle.getAssetPrice(dai.address); - - await oracle.setAssetPrice(dai.address, daiPrice.percentMul(11800)); - - const userGlobalData = await pool.getUserAccountData(borrower.address); - - expect(userGlobalData.healthFactor).to.be.lt(oneEther, INVALID_HF); - }); - - it('Liquidates the borrow', async () => { - const { - dai, - weth, - aWETH, - users: [, borrower, , liquidator], - pool, - oracle, - helpersContract, - } = testEnv; - - //mints dai to the liquidator - await dai - .connect(liquidator.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - //approve protocol to access the liquidator wallet - await dai.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); - const ethReserveDataBefore = await getReserveData(helpersContract, weth.address); - - const liquidatorBalanceBefore = await weth.balanceOf(liquidator.address); - - const treasuryAddress = await aWETH.RESERVE_TREASURY_ADDRESS(); - const treasuryDataBefore = await helpersContract.getUserReserveData( - weth.address, - treasuryAddress - ); - const treasuryBalanceBefore = treasuryDataBefore.currentATokenBalance; - - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - const wethLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - weth.address - ); - - await increaseTime(100); - - const tx = await pool - .connect(liquidator.signer) - .liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false); - - const userReserveDataAfter = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const daiReserveDataAfter = await getReserveData(helpersContract, dai.address); - const ethReserveDataAfter = await getReserveData(helpersContract, weth.address); - - const liquidatorBalanceAfter = await weth.balanceOf(liquidator.address); - - const treasuryDataAfter = await helpersContract.getUserReserveData( - weth.address, - treasuryAddress - ); - const treasuryBalanceAfter = treasuryDataAfter.currentATokenBalance; - - const collateralPrice = await oracle.getAssetPrice(weth.address); - const principalPrice = await oracle.getAssetPrice(dai.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(weth.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(dai.address)) - .decimals; - - const baseCollateral = principalPrice - .mul(amountToLiquidate) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - const bonusCollateral = baseCollateral.percentMul(10500).sub(baseCollateral); - const totalCollateralLiquidated = baseCollateral.add(bonusCollateral); - const liquidationProtocolFees = bonusCollateral.percentMul(wethLiquidationProtocolFee); - const expectedLiquidationReward = totalCollateralLiquidated.sub(liquidationProtocolFees); - - if (!tx.blockNumber) { - expect(false, 'Invalid block number'); - return; - } - const txTimestamp = BigNumber.from( - (await hre.ethers.provider.getBlock(tx.blockNumber)).timestamp - ); - - const stableDebtBeforeTx = calcExpectedStableDebtTokenBalance( - userReserveDataBefore.principalStableDebt, - userReserveDataBefore.stableBorrowRate, - userReserveDataBefore.stableRateLastUpdated, - txTimestamp - ); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - stableDebtBeforeTx.sub(amountToLiquidate), - 2, - 'Invalid user debt after liquidation' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(daiReserveDataAfter.liquidityIndex).to.be.gte( - daiReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(daiReserveDataAfter.liquidityRate).to.be.lt( - daiReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(daiReserveDataAfter.availableLiquidity).to.be.closeTo( - daiReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(ethReserveDataAfter.availableLiquidity).to.be.closeTo( - ethReserveDataBefore.availableLiquidity.sub(expectedLiquidationReward), - 2, - 'Invalid collateral available liquidity' - ); - - expect(treasuryBalanceAfter).to.be.closeTo( - treasuryBalanceBefore.add(liquidationProtocolFees), - 2, - 'Invalid treasury increase' - ); - - expect(liquidatorBalanceAfter).to.be.closeTo( - liquidatorBalanceBefore.add(expectedLiquidationReward), - 2, - 'Invalid liquidator balance' - ); - - expect(daiReserveDataAfter.totalLiquidity).to.be.closeTo( - daiReserveDataBefore.totalLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal total liquidity' - ); - - expect(ethReserveDataAfter.totalLiquidity).to.be.closeTo( - ethReserveDataBefore.totalLiquidity.sub( - totalCollateralLiquidated.sub(liquidationProtocolFees) - ), - 2, - 'Invalid collateral total liquidity' - ); - }); - - it('User 3 deposits 1000 USDC, user 4 0.06775 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => { - const { - usdc, - users: [, , , depositor, borrower, liquidator], - pool, - oracle, - weth, - aWETH, - helpersContract, - } = testEnv; - - //mints USDC to depositor - await usdc - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access depositor wallet - await usdc.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //depositor deposits 1000 USDC - const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000'); - - await pool - .connect(depositor.signer) - .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0'); - - //borrower deposits 1 ETH - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.06775'); - - //mints WETH to borrower - await weth - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(weth.address, '1000')); - - //approve protocol to access the borrower wallet - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); - - //borrower borrows - const userGlobalData = await pool.getUserAccountData(borrower.address); - - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - const amountUSDCToBorrow = await convertToCurrencyDecimals( - usdc.address, - userGlobalData.availableBorrowsBase.div(usdcPrice).percentMul(9502).toString() - ); - - await pool - .connect(borrower.signer) - .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address); - - //drops HF below 1 - await oracle.setAssetPrice(usdc.address, usdcPrice.percentMul(11200)); - - //mints usdc to the liquidator - await usdc - .connect(liquidator.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access liquidator wallet - await usdc.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - const ethReserveDataBefore = await getReserveData(helpersContract, weth.address); - - const liquidatorBalanceBefore = await weth.balanceOf(liquidator.address); - - const treasuryAddress = await aWETH.RESERVE_TREASURY_ADDRESS(); - const treasuryDataBefore = await helpersContract.getUserReserveData( - weth.address, - treasuryAddress - ); - const treasuryBalanceBefore = treasuryDataBefore.currentATokenBalance; - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - const wethLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - weth.address - ); - - await pool - .connect(liquidator.signer) - .liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - const ethReserveDataAfter = await getReserveData(helpersContract, weth.address); - - const liquidatorBalanceAfter = await weth.balanceOf(liquidator.address); - const treasuryDataAfter = await helpersContract.getUserReserveData( - weth.address, - treasuryAddress - ); - const treasuryBalanceAfter = treasuryDataAfter.currentATokenBalance; - - const collateralPrice = await oracle.getAssetPrice(weth.address); - const principalPrice = await oracle.getAssetPrice(usdc.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(weth.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - - const baseCollateral = principalPrice - .mul(amountToLiquidate) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - const bonusCollateral = baseCollateral.percentMul(10500).sub(baseCollateral); - const totalCollateralLiquidated = baseCollateral.add(bonusCollateral); - const liquidationProtocolFees = bonusCollateral.percentMul(wethLiquidationProtocolFee); - const expectedLiquidationReward = totalCollateralLiquidated.sub(liquidationProtocolFees); - - expect(userGlobalDataAfter.healthFactor).to.be.gt(oneEther, 'Invalid health factor'); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - userReserveDataBefore.currentStableDebt.sub(amountToLiquidate), - 2, - 'Invalid user borrow balance after liquidation' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(usdcReserveDataAfter.liquidityIndex).to.be.gte( - usdcReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(usdcReserveDataAfter.liquidityRate).to.be.lt( - usdcReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(ethReserveDataAfter.availableLiquidity).to.be.closeTo( - ethReserveDataBefore.availableLiquidity.sub(expectedLiquidationReward), - 2, - 'Invalid collateral available liquidity' - ); - - expect(treasuryBalanceAfter).to.be.closeTo( - treasuryBalanceBefore.add(liquidationProtocolFees), - 2, - 'Invalid treasury increase' - ); - - expect(liquidatorBalanceAfter).to.be.closeTo( - liquidatorBalanceBefore.add(expectedLiquidationReward), - 2, - 'Invalid liquidator balance' - ); - - expect(usdcReserveDataAfter.totalLiquidity).to.be.closeTo( - usdcReserveDataBefore.totalLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal total liquidity' - ); - - expect(ethReserveDataAfter.totalLiquidity).to.be.closeTo( - ethReserveDataBefore.totalLiquidity.sub( - totalCollateralLiquidated.sub(liquidationProtocolFees) - ), - 2, - 'Invalid collateral total liquidity' - ); - }); - - it('User 4 deposits 0.03 AAVE - drops HF, liquidates the AAVE, which results on a lower amount being liquidated', async () => { - const snap = await evmSnapshot(); - const { - aave, - usdc, - users: [, , , , borrower, liquidator], - pool, - oracle, - helpersContract, - } = testEnv; - - //mints AAVE to borrower - await aave - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(aave.address, '0.03')); - - //approve protocol to access the borrower wallet - await aave.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //borrower deposits AAVE - const amountToDeposit = await convertToCurrencyDecimals(aave.address, '0.03'); - - await pool - .connect(borrower.signer) - .deposit(aave.address, amountToDeposit, borrower.address, '0'); - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - //drops HF below 1 - await oracle.setAssetPrice(usdc.address, usdcPrice.percentMul(11400)); - - //mints usdc to the liquidator - await usdc - .connect(liquidator.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access liquidator wallet - await usdc.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - const aaveReserveDataBefore = await getReserveData(helpersContract, aave.address); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - const collateralPrice = await oracle.getAssetPrice(aave.address); - const principalPrice = await oracle.getAssetPrice(usdc.address); - - const aaveTokenAddresses = await helpersContract.getReserveTokensAddresses(aave.address); - const aAaveTokenAddress = await aaveTokenAddresses.aTokenAddress; - const aAaveTokenContract = await AToken__factory.connect( - aAaveTokenAddress, - hre.ethers.provider - ); - const aAaveTokenBalanceBefore = await aAaveTokenContract.balanceOf(liquidator.address); - const borrowerATokenBalance = await aAaveTokenContract.balanceOf(borrower.address); - - const treasuryAddress = await aAaveTokenContract.RESERVE_TREASURY_ADDRESS(); - const treasuryDataBefore = await helpersContract.getUserReserveData( - aave.address, - treasuryAddress - ); - const treasuryBalanceBefore = treasuryDataBefore.currentATokenBalance; - - await pool - .connect(liquidator.signer) - .liquidationCall(aave.address, usdc.address, borrower.address, amountToLiquidate, true); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - const aaveReserveDataAfter = await getReserveData(helpersContract, aave.address); - - const aaveConfiguration = await helpersContract.getReserveConfigurationData(aave.address); - const collateralDecimals = aaveConfiguration.decimals; - const liquidationBonus = aaveConfiguration.liquidationBonus; - - const principalDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - - const expectedCollateralLiquidated = oneEther.mul(30).div(1000); - - const aaveLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - aave.address - ); - - const expectedPrincipal = collateralPrice - .mul(expectedCollateralLiquidated) - .mul(BigNumber.from(10).pow(principalDecimals)) - .div(principalPrice.mul(BigNumber.from(10).pow(collateralDecimals))) - .percentDiv(liquidationBonus); - - const bonusCollateral = borrowerATokenBalance.sub( - borrowerATokenBalance.percentDiv(liquidationBonus) - ); - const liquidationProtocolFee = bonusCollateral.percentMul(aaveLiquidationProtocolFee); - const expectedLiquidationReward = borrowerATokenBalance.sub(liquidationProtocolFee); - - const aAaveTokenBalanceAfter = await aAaveTokenContract.balanceOf(liquidator.address); - - const treasuryDataAfter = await helpersContract.getUserReserveData( - aave.address, - treasuryAddress - ); - const treasuryBalanceAfter = treasuryDataAfter.currentATokenBalance; - - expect(userGlobalDataAfter.healthFactor).to.be.gt(oneEther, 'Invalid health factor'); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - userReserveDataBefore.currentStableDebt.sub(expectedPrincipal), - 2, - 'Invalid user borrow balance after liquidation' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.add(expectedPrincipal), - 2, - 'Invalid principal available liquidity' - ); - - expect(aaveReserveDataAfter.availableLiquidity).to.be.closeTo( - aaveReserveDataBefore.availableLiquidity, - 2, - 'Invalid collateral available liquidity' - ); - - expect(usdcReserveDataAfter.totalLiquidity).to.be.closeTo( - usdcReserveDataBefore.totalLiquidity.add(expectedPrincipal), - 2, - 'Invalid principal total liquidity' - ); - - expect(aaveReserveDataAfter.totalLiquidity).to.be.closeTo( - aaveReserveDataBefore.totalLiquidity, - 2, - 'Invalid collateral total liquidity' - ); - - expect(aAaveTokenBalanceBefore).to.be.equal( - aAaveTokenBalanceAfter.sub(expectedLiquidationReward), - 'Liquidator aToken balance incorrect' - ); - - expect(treasuryBalanceBefore).to.be.equal( - treasuryBalanceAfter.sub(liquidationProtocolFee), - 'Treasury aToken balance incorrect' - ); - - await evmRevert(snap); - }); - - it('Set liquidationProtocolFee to 0. User 4 deposits 0.03 AAVE - drops HF, liquidates the AAVE, which results on a lower amount being liquidated', async () => { - const { - aave, - usdc, - users: [, , , , borrower, liquidator], - pool, - oracle, - helpersContract, - configurator, - } = testEnv; - - const oldAaveLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - aave.address - ); - - expect(await configurator.setLiquidationProtocolFee(aave.address, 0)) - .to.emit(configurator, 'LiquidationProtocolFeeChanged') - .withArgs(aave.address, oldAaveLiquidationProtocolFee, 0); - - //mints AAVE to borrower - await aave - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(aave.address, '0.03')); - - //approve protocol to access the borrower wallet - await aave.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //borrower deposits AAVE - const amountToDeposit = await convertToCurrencyDecimals(aave.address, '0.03'); - - await pool - .connect(borrower.signer) - .deposit(aave.address, amountToDeposit, borrower.address, '0'); - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - //drops HF below 1 - await oracle.setAssetPrice(usdc.address, usdcPrice.percentMul(11400)); - - //mints usdc to the liquidator - await usdc - .connect(liquidator.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access liquidator wallet - await usdc.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - const aaveReserveDataBefore = await getReserveData(helpersContract, aave.address); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - const collateralPrice = await oracle.getAssetPrice(aave.address); - const principalPrice = await oracle.getAssetPrice(usdc.address); - - const aaveTokenAddresses = await helpersContract.getReserveTokensAddresses(aave.address); - const aAaveTokenAddress = await aaveTokenAddresses.aTokenAddress; - const aAaveTokenContract = await AToken__factory.connect( - aAaveTokenAddress, - hre.ethers.provider - ); - const aAaveTokenBalanceBefore = await aAaveTokenContract.balanceOf(liquidator.address); - const borrowerATokenBalance = await aAaveTokenContract.balanceOf(borrower.address); - - const treasuryAddress = await aAaveTokenContract.RESERVE_TREASURY_ADDRESS(); - const treasuryDataBefore = await helpersContract.getUserReserveData( - aave.address, - treasuryAddress - ); - const treasuryBalanceBefore = treasuryDataBefore.currentATokenBalance; - - await pool - .connect(liquidator.signer) - .liquidationCall(aave.address, usdc.address, borrower.address, amountToLiquidate, true); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - const aaveReserveDataAfter = await getReserveData(helpersContract, aave.address); - - const aaveConfiguration = await helpersContract.getReserveConfigurationData(aave.address); - const collateralDecimals = aaveConfiguration.decimals; - const liquidationBonus = aaveConfiguration.liquidationBonus; - - const principalDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - - const expectedCollateralLiquidated = oneEther.mul(30).div(1000); - - const aaveLiquidationProtocolFee = await helpersContract.getLiquidationProtocolFee( - aave.address - ); - - const expectedPrincipal = collateralPrice - .mul(expectedCollateralLiquidated) - .mul(BigNumber.from(10).pow(principalDecimals)) - .div(principalPrice.mul(BigNumber.from(10).pow(collateralDecimals))) - .percentDiv(liquidationBonus); - - const bonusCollateral = borrowerATokenBalance.sub( - borrowerATokenBalance.percentDiv(liquidationBonus) - ); - const liquidationProtocolFee = bonusCollateral.percentMul(aaveLiquidationProtocolFee); - const expectedLiquidationReward = borrowerATokenBalance.sub(liquidationProtocolFee); - - const aAaveTokenBalanceAfter = await aAaveTokenContract.balanceOf(liquidator.address); - - const treasuryDataAfter = await helpersContract.getUserReserveData( - aave.address, - treasuryAddress - ); - const treasuryBalanceAfter = treasuryDataAfter.currentATokenBalance; - - expect(userGlobalDataAfter.healthFactor).to.be.gt(oneEther, 'Invalid health factor'); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - userReserveDataBefore.currentStableDebt.sub(expectedPrincipal), - 2, - 'Invalid user borrow balance after liquidation' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.add(expectedPrincipal), - 2, - 'Invalid principal available liquidity' - ); - - expect(aaveReserveDataAfter.availableLiquidity).to.be.closeTo( - aaveReserveDataBefore.availableLiquidity, - 2, - 'Invalid collateral available liquidity' - ); - - expect(usdcReserveDataAfter.totalLiquidity).to.be.closeTo( - usdcReserveDataBefore.totalLiquidity.add(expectedPrincipal), - 2, - 'Invalid principal total liquidity' - ); - - expect(aaveReserveDataAfter.totalLiquidity).to.be.closeTo( - aaveReserveDataBefore.totalLiquidity, - 2, - 'Invalid collateral total liquidity' - ); - - expect(aAaveTokenBalanceBefore).to.be.equal( - aAaveTokenBalanceAfter.sub(expectedLiquidationReward), - 'Liquidator aToken balance incorrect' - ); - - expect(treasuryBalanceBefore).to.be.equal( - treasuryBalanceAfter.sub(liquidationProtocolFee), - 'Treasury aToken balance incorrect' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/ltv-validation.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/ltv-validation.spec.ts deleted file mode 100644 index d0fea27..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/ltv-validation.spec.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { expect } from 'chai'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import { evmRevert, evmSnapshot } from '@aave/deploy-v3'; -import { parseUnits } from 'ethers/lib/utils'; - -makeSuite('LTV validation', (testEnv: TestEnv) => { - const { LTV_VALIDATION_FAILED } = ProtocolErrors; - - let snap: string; - before(async () => { - snap = await evmSnapshot(); - }); - - it('User 1 deposits 10 Dai, 10 USDC, user 2 deposits 0.071 WETH', async () => { - const { - pool, - dai, - usdc, - weth, - users: [user1, user2], - } = testEnv; - - const daiAmount = await convertToCurrencyDecimals(dai.address, '10'); - const usdcAmount = await convertToCurrencyDecimals(usdc.address, '10'); - const wethAmount = await convertToCurrencyDecimals(weth.address, '0.071'); - - await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await usdc.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await weth.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await dai.connect(user1.signer)['mint(uint256)'](daiAmount); - await usdc.connect(user1.signer)['mint(uint256)'](usdcAmount); - await weth.connect(user2.signer)['mint(uint256)'](wethAmount); - - await pool.connect(user1.signer).deposit(dai.address, daiAmount, user1.address, 0); - - await pool.connect(user1.signer).deposit(usdc.address, usdcAmount, user1.address, 0); - - await pool.connect(user2.signer).deposit(weth.address, wethAmount, user2.address, 0); - }); - - it('Sets the LTV of DAI to 0', async () => { - const { - configurator, - dai, - helpersContract, - users: [], - } = testEnv; - - expect(await configurator.configureReserveAsCollateral(dai.address, 0, 8000, 10500)) - .to.emit(configurator, 'CollateralConfigurationChanged') - .withArgs(dai.address, 0, 8000, 10500); - - const ltv = (await helpersContract.getReserveConfigurationData(dai.address)).ltv; - - expect(ltv).to.be.equal(0); - }); - - it('Borrows 0.000414 WETH', async () => { - const { - pool, - weth, - users: [user1], - } = testEnv; - const borrowedAmount = await convertToCurrencyDecimals(weth.address, '0.000414'); - - expect( - await pool.connect(user1.signer).borrow(weth.address, borrowedAmount, 1, 0, user1.address) - ); - }); - - it('Tries to withdraw USDC (revert expected)', async () => { - const { - pool, - usdc, - users: [user1], - } = testEnv; - - const withdrawnAmount = await convertToCurrencyDecimals(usdc.address, '1'); - - await expect( - pool.connect(user1.signer).withdraw(usdc.address, withdrawnAmount, user1.address) - ).to.be.revertedWith(LTV_VALIDATION_FAILED); - }); - - it('Withdraws DAI', async () => { - const { - pool, - dai, - aDai, - users: [user1], - } = testEnv; - - const aDaiBalanceBefore = await aDai.balanceOf(user1.address); - - const withdrawnAmount = await convertToCurrencyDecimals(dai.address, '1'); - - expect(await pool.connect(user1.signer).withdraw(dai.address, withdrawnAmount, user1.address)); - - const aDaiBalanceAfter = await aDai.balanceOf(user1.address); - - expect(aDaiBalanceAfter).to.be.eq(aDaiBalanceBefore.sub(withdrawnAmount)); - }); - - it('User 1 deposit dai, DAI ltv drops to 0, then tries borrow', async () => { - await evmRevert(snap); - const { - pool, - dai, - weth, - users: [user1, user2], - configurator, - helpersContract, - } = testEnv; - - const daiAmount = await convertToCurrencyDecimals(dai.address, '10'); - const wethAmount = await convertToCurrencyDecimals(weth.address, '10'); - const borrowWethAmount = await convertToCurrencyDecimals(weth.address, '5'); - - await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await weth.connect(user2.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await dai.connect(user1.signer)['mint(uint256)'](daiAmount); - await weth.connect(user2.signer)['mint(uint256)'](wethAmount); - - await pool.connect(user1.signer).supply(dai.address, daiAmount, user1.address, 0); - await pool.connect(user2.signer).supply(weth.address, wethAmount, user2.address, 0); - - // Set DAI LTV = 0 - expect(await configurator.configureReserveAsCollateral(dai.address, 0, 8000, 10500)) - .to.emit(configurator, 'CollateralConfigurationChanged') - .withArgs(dai.address, 0, 8000, 10500); - const ltv = (await helpersContract.getReserveConfigurationData(dai.address)).ltv; - expect(ltv).to.be.equal(0); - - // Borrow all the weth because of issue in collateral needed. - await expect( - pool - .connect(user1.signer) - .borrow(weth.address, borrowWethAmount, RateMode.Variable, 0, user1.address) - ).to.be.revertedWith(LTV_VALIDATION_FAILED); - - const userData = await pool.getUserAccountData(user1.address); - expect(userData.totalCollateralBase).to.be.eq(parseUnits('10', 8)); - expect(userData.totalDebtBase).to.be.eq(0); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/mint-to-treasury.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/mint-to-treasury.spec.ts deleted file mode 100644 index 23b7066..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/mint-to-treasury.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { expect } from 'chai'; -import { RateMode } from '../helpers/types'; -import { MAX_UINT_AMOUNT, ONE_YEAR } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; -import { advanceTimeAndBlock } from '@aave/deploy-v3'; - -makeSuite('Mint To Treasury', (testEnv: TestEnv) => { - it('User 0 deposits 1000 DAI. Borrower borrows 100 DAI. Clock moved forward one year. Calculates and verifies the amount accrued to the treasury', async () => { - const { users, pool, dai, helpersContract } = testEnv; - - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - const amountDAItoBorrow = await convertToCurrencyDecimals(dai.address, '100'); - - await expect(await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit)); - - // user 0 deposits 1000 DAI - await expect(await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT)); - await expect( - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ); - - await expect( - await pool - .connect(users[0].signer) - .borrow(dai.address, amountDAItoBorrow, RateMode.Variable, '0', users[0].address) - ); - - const { reserveFactor } = await helpersContract.getReserveConfigurationData(dai.address); - - await advanceTimeAndBlock(parseInt(ONE_YEAR)); - - await expect(await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit)); - - await expect( - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ); - - const { liquidityIndex, variableBorrowIndex } = await pool.getReserveData(dai.address); - - const expectedAccruedToTreasury = amountDAItoBorrow - .rayMul(variableBorrowIndex) - .sub(amountDAItoBorrow) - .percentMul(reserveFactor) - .rayDiv(liquidityIndex); - - const { accruedToTreasury } = await pool.getReserveData(dai.address); - - expect(accruedToTreasury).to.be.closeTo(expectedAccruedToTreasury, 2); - }); - - it('Mints the accrued to the treasury', async () => { - const { users, pool, dai, aDai } = testEnv; - - const treasuryAddress = await aDai.RESERVE_TREASURY_ADDRESS(); - const { accruedToTreasury } = await pool.getReserveData(dai.address); - - await expect(await pool.connect(users[0].signer).mintToTreasury([dai.address])); - - const normalizedIncome = await pool.getReserveNormalizedIncome(dai.address); - const treasuryBalance = await aDai.balanceOf(treasuryAddress); - - const expectedTreasuryBalance = accruedToTreasury.rayMul(normalizedIncome); - - expect(treasuryBalance).to.be.closeTo( - expectedTreasuryBalance, - 2, - 'Invalid treasury balance after minting' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/no-incentives-controller.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/no-incentives-controller.spec.ts deleted file mode 100644 index d3bc416..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/no-incentives-controller.spec.ts +++ /dev/null @@ -1,295 +0,0 @@ -import { expect } from 'chai'; -import { BigNumberish } from 'ethers'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { RateMode } from '../helpers/types'; -import { - AToken__factory, - ERC20, - ERC20__factory, - MintableERC20, - MintableERC20__factory, - StableDebtToken__factory, - VariableDebtToken__factory, -} from '../types'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { makeSuite } from './helpers/make-suite'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { setBlocktime, timeLatest } from '../helpers/misc-utils'; -import { config } from 'process'; - -makeSuite('Reserve Without Incentives Controller', (testEnv) => { - let mockToken: MintableERC20; - let aMockToken: ERC20; - let mockStableDebt: ERC20; - let mockVariableDebt: ERC20; - - before(async () => { - const { pool, poolAdmin, configurator, dai, helpersContract } = testEnv; - - mockToken = await new MintableERC20__factory(await getFirstSigner()).deploy( - 'MOCK', - 'MOCK', - '18' - ); - - const stableDebtTokenImplementation = await new StableDebtToken__factory( - await getFirstSigner() - ).deploy(pool.address); - const variableDebtTokenImplementation = await new VariableDebtToken__factory( - await getFirstSigner() - ).deploy(pool.address); - const aTokenImplementation = await new AToken__factory(await getFirstSigner()).deploy( - pool.address - ); - - const daiData = await pool.getReserveData(dai.address); - - const interestRateStrategyAddress = daiData.interestRateStrategyAddress; - - // Init the reserve - const initInputParams: { - aTokenImpl: string; - stableDebtTokenImpl: string; - variableDebtTokenImpl: string; - underlyingAssetDecimals: BigNumberish; - interestRateStrategyAddress: string; - underlyingAsset: string; - treasury: string; - incentivesController: string; - aTokenName: string; - aTokenSymbol: string; - variableDebtTokenName: string; - variableDebtTokenSymbol: string; - stableDebtTokenName: string; - stableDebtTokenSymbol: string; - params: string; - }[] = [ - { - aTokenImpl: aTokenImplementation.address, - stableDebtTokenImpl: stableDebtTokenImplementation.address, - variableDebtTokenImpl: variableDebtTokenImplementation.address, - underlyingAssetDecimals: 18, - interestRateStrategyAddress: interestRateStrategyAddress, - underlyingAsset: mockToken.address, - treasury: ZERO_ADDRESS, - incentivesController: ZERO_ADDRESS, - aTokenName: 'AMOCK', - aTokenSymbol: 'AMOCK', - variableDebtTokenName: 'VMOCK', - variableDebtTokenSymbol: 'VMOCK', - stableDebtTokenName: 'SMOCK', - stableDebtTokenSymbol: 'SMOCK', - params: '0x10', - }, - ]; - - // Add the mock reserve - await configurator.connect(poolAdmin.signer).initReserves(initInputParams); - - // Configuration - const daiReserveConfigurationData = await helpersContract.getReserveConfigurationData( - dai.address - ); - - const inputParams: { - asset: string; - baseLTV: BigNumberish; - liquidationThreshold: BigNumberish; - liquidationBonus: BigNumberish; - reserveFactor: BigNumberish; - borrowCap: BigNumberish; - supplyCap: BigNumberish; - stableBorrowingEnabled: boolean; - borrowingEnabled: boolean; - }[] = [ - { - asset: mockToken.address, - baseLTV: daiReserveConfigurationData.ltv, - liquidationThreshold: daiReserveConfigurationData.liquidationThreshold, - liquidationBonus: daiReserveConfigurationData.liquidationBonus, - reserveFactor: daiReserveConfigurationData.reserveFactor, - borrowCap: 68719476735, - supplyCap: 68719476735, - stableBorrowingEnabled: true, - borrowingEnabled: true, - }, - ]; - - const i = 0; - await configurator - .connect(poolAdmin.signer) - .configureReserveAsCollateral( - inputParams[i].asset, - inputParams[i].baseLTV, - inputParams[i].liquidationThreshold, - inputParams[i].liquidationBonus - ); - await configurator.connect(poolAdmin.signer).setReserveBorrowing(inputParams[i].asset, true); - - await configurator.setBorrowCap(inputParams[i].asset, inputParams[i].borrowCap); - await configurator.setReserveStableRateBorrowing( - inputParams[i].asset, - inputParams[i].stableBorrowingEnabled - ); - - await configurator - .connect(poolAdmin.signer) - .setSupplyCap(inputParams[i].asset, inputParams[i].supplyCap); - await configurator - .connect(poolAdmin.signer) - .setReserveFactor(inputParams[i].asset, inputParams[i].reserveFactor); - - const reserveData = await pool.getReserveData(mockToken.address); - aMockToken = ERC20__factory.connect(reserveData.aTokenAddress, await getFirstSigner()); - mockStableDebt = ERC20__factory.connect( - reserveData.stableDebtTokenAddress, - await getFirstSigner() - ); - mockVariableDebt = ERC20__factory.connect( - reserveData.variableDebtTokenAddress, - await getFirstSigner() - ); - }); - - it('Deposit mock tokens into aave', async () => { - const { - pool, - users: [user], - } = testEnv; - - expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - - await mockToken - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(mockToken.address, '10000')); - await mockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '1000'), - user.address, - 0 - ); - - expect(await aMockToken.balanceOf(user.address)).to.be.eq( - await convertToCurrencyDecimals(aMockToken.address, '1000') - ); - }); - - it('Transfer aMock tokens', async () => { - const { - users: [sender, receiver], - } = testEnv; - - expect(await aMockToken.balanceOf(sender.address)).to.be.eq( - await convertToCurrencyDecimals(aMockToken.address, '1000') - ); - expect(await aMockToken.balanceOf(receiver.address)).to.be.eq(0); - - await aMockToken - .connect(sender.signer) - .transfer(receiver.address, await convertToCurrencyDecimals(aMockToken.address, '1000')); - expect(await aMockToken.balanceOf(sender.address)).to.be.eq(0); - expect(await aMockToken.balanceOf(receiver.address)).to.be.eq( - await convertToCurrencyDecimals(aMockToken.address, '1000') - ); - }); - - it('Borrow mock tokens with stable rate', async () => { - const { - pool, - users: [, , user], - dai, - } = testEnv; - - expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockVariableDebt.balanceOf(user.address)).to.be.eq(0); - expect(await mockStableDebt.balanceOf(user.address)).to.be.eq(0); - - await dai - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '10000')); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit(dai.address, await convertToCurrencyDecimals(dai.address, '10000'), user.address, 0); - await pool - .connect(user.signer) - .borrow( - mockToken.address, - await convertToCurrencyDecimals(mockToken.address, '100'), - RateMode.Stable, - 0, - user.address - ); - - expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockToken.balanceOf(user.address)).to.be.eq( - await convertToCurrencyDecimals(mockToken.address, '100') - ); - expect(await mockVariableDebt.balanceOf(user.address)).to.be.eq(0); - expect(await mockStableDebt.balanceOf(user.address)).to.be.eq( - await convertToCurrencyDecimals(mockStableDebt.address, '100') - ); - }); - - it('Repay mock tokens', async () => { - const { - pool, - users: [, , user], - } = testEnv; - - const mintAmount = await convertToCurrencyDecimals(mockToken.address, '100'); - await mockToken.connect(user.signer)['mint(uint256)'](mintAmount); - - const expectedMockTokenBalance = mintAmount.add( - await convertToCurrencyDecimals(mockToken.address, '100') - ); - - expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockToken.balanceOf(user.address)).to.be.eq(expectedMockTokenBalance); - expect(await mockVariableDebt.balanceOf(user.address)).to.be.eq(0); - - await mockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const time = await timeLatest(); - - await setBlocktime(time.add(1).toNumber()); - - const stableDebtBefore = await mockStableDebt.balanceOf(user.address, { blockTag: 'pending' }); - - await pool - .connect(user.signer) - .repay(mockToken.address, stableDebtBefore, RateMode.Stable, user.address); - - expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockToken.balanceOf(user.address)).to.be.eq( - expectedMockTokenBalance.sub(stableDebtBefore) - ); - expect(await mockVariableDebt.balanceOf(user.address)).to.be.eq(0); - expect(await mockStableDebt.balanceOf(user.address)).to.be.eq(0); - }); - - it('Withdraw aMock tokens', async () => { - const { - pool, - users: [, user], - } = testEnv; - - expect(await mockToken.balanceOf(user.address)).to.be.eq(0); - - const aMockTokenBalanceBefore = await aMockToken.balanceOf(user.address, { - blockTag: 'pending', - }); - - await aMockToken.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .withdraw(mockToken.address, aMockTokenBalanceBefore, user.address); - - expect(await aMockToken.balanceOf(user.address)).to.be.eq(0); - expect(await mockToken.balanceOf(user.address)).to.be.eq(aMockTokenBalanceBefore); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pausable-pool.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pausable-pool.spec.ts deleted file mode 100644 index ed6b2ff..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pausable-pool.spec.ts +++ /dev/null @@ -1,402 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver'; -import { - getMockFlashLoanReceiver, - getMockPool, - getPoolConfiguratorProxy, -} from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { deployMockPool } from '@aave/deploy-v3/dist/helpers/contract-deployments'; -import { - ACLManager__factory, - ConfiguratorLogic__factory, - PoolAddressesProvider__factory, - PoolConfigurator__factory, -} from '../types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { evmSnapshot, evmRevert } from '@aave/deploy-v3'; - -makeSuite('PausablePool', (testEnv: TestEnv) => { - let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; - - const { RESERVE_PAUSED, INVALID_FROM_BALANCE_AFTER_TRANSFER, INVALID_TO_BALANCE_AFTER_TRANSFER } = - ProtocolErrors; - - before(async () => { - _mockFlashLoanReceiver = await getMockFlashLoanReceiver(); - }); - - it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succeeds', async () => { - const { users, pool, dai, aDai, configurator } = testEnv; - - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit); - - // user 0 deposits 1000 DAI - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0'); - - const user0Balance = await aDai.balanceOf(users[0].address); - const user1Balance = await aDai.balanceOf(users[1].address); - - // Configurator pauses the pool - await configurator.connect(users[1].signer).setPoolPause(true); - - // User 0 tries the transfer to User 1 - await expect( - aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit) - ).to.revertedWith(RESERVE_PAUSED); - - const pausedFromBalance = await aDai.balanceOf(users[0].address); - const pausedToBalance = await aDai.balanceOf(users[1].address); - - expect(pausedFromBalance).to.be.equal( - user0Balance.toString(), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - expect(pausedToBalance.toString()).to.be.equal( - user1Balance.toString(), - INVALID_FROM_BALANCE_AFTER_TRANSFER - ); - - // Configurator unpauses the pool - await configurator.connect(users[1].signer).setPoolPause(false); - - // User 0 succeeds transfer to User 1 - await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit); - - const fromBalance = await aDai.balanceOf(users[0].address); - const toBalance = await aDai.balanceOf(users[1].address); - - expect(fromBalance.toString()).to.be.equal( - user0Balance.sub(amountDAItoDeposit), - INVALID_FROM_BALANCE_AFTER_TRANSFER - ); - expect(toBalance.toString()).to.be.equal( - user1Balance.add(amountDAItoDeposit), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - }); - - it('Deposit', async () => { - const { users, pool, dai, aDai, configurator } = testEnv; - - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit); - - // user 0 deposits 1000 DAI - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - - // Configurator pauses the pool - await configurator.connect(users[1].signer).setPoolPause(true); - await expect( - pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ).to.revertedWith(RESERVE_PAUSED); - - // Configurator unpauses the pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('Withdraw', async () => { - const { users, pool, dai, aDai, configurator } = testEnv; - - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit); - - // user 0 deposits 1000 DAI - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0'); - - // Configurator pauses the pool - await configurator.connect(users[1].signer).setPoolPause(true); - - // user tries to burn - await expect( - pool.connect(users[0].signer).withdraw(dai.address, amountDAItoDeposit, users[0].address) - ).to.revertedWith(RESERVE_PAUSED); - - // Configurator unpauses the pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('Borrow', async () => { - const { pool, dai, users, configurator } = testEnv; - - const user = users[1]; - // Pause the pool - await configurator.connect(users[1].signer).setPoolPause(true); - - // Try to execute liquidation - await expect( - pool.connect(user.signer).borrow(dai.address, '1', '1', '0', user.address) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause the pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('Repay', async () => { - const { pool, dai, users, configurator } = testEnv; - - const user = users[1]; - // Pause the pool - await configurator.connect(users[1].signer).setPoolPause(true); - - // Try to execute liquidation - await expect( - pool.connect(user.signer).repay(dai.address, '1', '1', user.address) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause the pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('Flash loan', async () => { - const { dai, pool, weth, users, configurator } = testEnv; - - const caller = users[3]; - - const flashAmount = utils.parseEther('0.8'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - // Pause pool - await configurator.connect(users[1].signer).setPoolPause(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [1], - caller.address, - '0x10', - '0' - ) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('Liquidation call', async () => { - const { users, pool, usdc, oracle, weth, configurator, helpersContract } = testEnv; - const depositor = users[3]; - const borrower = users[4]; - - //mints USDC to depositor - await usdc - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access depositor wallet - await usdc.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 3 deposits 1000 USDC - const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000'); - - await pool - .connect(depositor.signer) - .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0'); - - //user 4 deposits ETH - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.06775'); - - //mints WETH to borrower - await weth.connect(borrower.signer)['mint(uint256)'](amountETHtoDeposit); - - //approve protocol to access borrower wallet - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); - - //user 4 borrows - const userGlobalData = await pool.getUserAccountData(borrower.address); - - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - const amountUSDCToBorrow = await convertToCurrencyDecimals( - usdc.address, - userGlobalData.availableBorrowsBase.div(usdcPrice).percentMul(9502).toString() - ); - - await pool - .connect(borrower.signer) - .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address); - - // Drops HF below 1 - await oracle.setAssetPrice(usdc.address, usdcPrice.percentMul(12000)); - - //mints dai to the liquidator - await usdc['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - await usdc.approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toString(); - - // Pause pool - await configurator.connect(users[1].signer).setPoolPause(true); - - // Do liquidation - await expect( - pool.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, true) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('SwapBorrowRateMode', async () => { - const { pool, weth, dai, usdc, users, configurator } = testEnv; - const user = users[1]; - const amountWETHToDeposit = utils.parseEther('10'); - const amountDAIToDeposit = utils.parseEther('120'); - const amountToBorrow = utils.parseUnits('65', 6); - - await weth.connect(user.signer)['mint(uint256)'](amountWETHToDeposit); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0'); - - await dai.connect(user.signer)['mint(uint256)'](amountDAIToDeposit); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).deposit(dai.address, amountDAIToDeposit, user.address, '0'); - - await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address); - - // Pause pool - await configurator.connect(users[1].signer).setPoolPause(true); - - // Try to repay - await expect( - pool.connect(user.signer).swapBorrowRateMode(usdc.address, RateMode.Stable) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('RebalanceStableBorrowRate', async () => { - const { pool, dai, users, configurator } = testEnv; - const user = users[1]; - // Pause pool - await configurator.connect(users[1].signer).setPoolPause(true); - - await expect( - pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('setUserUseReserveAsCollateral', async () => { - const { pool, weth, users, configurator } = testEnv; - const user = users[1]; - - const amountWETHToDeposit = utils.parseEther('1'); - await weth.connect(user.signer)['mint(uint256)'](amountWETHToDeposit); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0'); - - // Pause pool - await configurator.connect(users[1].signer).setPoolPause(true); - - await expect( - pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setPoolPause(false); - }); - - it('Configurator pauses Pool with a ZERO_ADDRESS reserve', async () => { - const { poolAdmin, emergencyAdmin, deployer } = testEnv; - - const snapId = await evmSnapshot(); - - // Deploy a mock Pool - const mockPool = await deployMockPool(); - - // Deploy a new PoolConfigurator - const configuratorLogic = await ( - await new ConfiguratorLogic__factory(await getFirstSigner()).deploy() - ).deployed(); - const poolConfigurator = await ( - await new PoolConfigurator__factory( - { - ['contracts/protocol/libraries/logic/ConfiguratorLogic.sol:ConfiguratorLogic']: - configuratorLogic.address, - }, - await getFirstSigner() - ).deploy() - ).deployed(); - - // Deploy a new PoolAddressesProvider - const MARKET_ID = '1'; - const poolAddressesProvider = await ( - await new PoolAddressesProvider__factory(await getFirstSigner()).deploy( - MARKET_ID, - deployer.address - ) - ).deployed(); - - // Set the ACL admin - expect(await poolAddressesProvider.setACLAdmin(poolAdmin.address)); - - // Update the ACLManager - const aclManager = await ( - await new ACLManager__factory(await getFirstSigner()).deploy(poolAddressesProvider.address) - ).deployed(); - expect(await poolAddressesProvider.setACLManager(aclManager.address)) - .to.emit(poolAddressesProvider, 'ACLManagerUpdated') - .withArgs(ZERO_ADDRESS, aclManager.address); - - // Set role of EmergencyAdmin - const emergencyAdminRole = await aclManager.EMERGENCY_ADMIN_ROLE(); - expect(await aclManager.addEmergencyAdmin(emergencyAdmin.address)) - .to.emit(aclManager, 'RoleGranted') - .withArgs(emergencyAdminRole, emergencyAdmin.address, poolAdmin.address); - - // Update the Pool impl with a MockPool - expect(await poolAddressesProvider.setPoolImpl(mockPool.address)) - .to.emit(poolAddressesProvider, 'PoolUpdated') - .withArgs(ZERO_ADDRESS, mockPool.address); - - // Add ZERO_ADDRESS as a reserve - const proxiedMockPoolAddress = await poolAddressesProvider.getPool(); - const proxiedMockPool = await getMockPool(proxiedMockPoolAddress); - expect(await proxiedMockPool.addReserveToReservesList(ZERO_ADDRESS)); - - // Update the PoolConfigurator impl with the PoolConfigurator - expect(await poolAddressesProvider.setPoolConfiguratorImpl(poolConfigurator.address)) - .to.emit(poolAddressesProvider, 'PoolConfiguratorUpdated') - .withArgs(ZERO_ADDRESS, poolConfigurator.address); - - const proxiedPoolConfiguratorAddress = await poolAddressesProvider.getPoolConfigurator(); - const proxiedPoolConfigurator = await getPoolConfiguratorProxy(proxiedPoolConfiguratorAddress); - - // Pause reserve - expect(await proxiedPoolConfigurator.connect(emergencyAdmin.signer).setPoolPause(true)); - - await evmRevert(snapId); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pausable-reserve.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pausable-reserve.spec.ts deleted file mode 100644 index 2be0b63..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pausable-reserve.spec.ts +++ /dev/null @@ -1,318 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver'; -import { getMockFlashLoanReceiver } from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; - -makeSuite('PausableReserve', (testEnv: TestEnv) => { - let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; - - const { RESERVE_PAUSED, INVALID_FROM_BALANCE_AFTER_TRANSFER, INVALID_TO_BALANCE_AFTER_TRANSFER } = - ProtocolErrors; - - before(async () => { - _mockFlashLoanReceiver = await getMockFlashLoanReceiver(); - }); - - it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succeeds', async () => { - const { users, pool, dai, aDai, configurator } = testEnv; - - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit); - - // user 0 deposits 1000 DAI - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0'); - - const user0Balance = await aDai.balanceOf(users[0].address); - const user1Balance = await aDai.balanceOf(users[1].address); - - // Configurator pauses the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, true); - - // User 0 tries the transfer to User 1 - await expect( - aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit) - ).to.revertedWith(RESERVE_PAUSED); - - const pausedFromBalance = await aDai.balanceOf(users[0].address); - const pausedToBalance = await aDai.balanceOf(users[1].address); - - expect(pausedFromBalance).to.be.equal( - user0Balance.toString(), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - expect(pausedToBalance.toString()).to.be.equal( - user1Balance.toString(), - INVALID_FROM_BALANCE_AFTER_TRANSFER - ); - - // Configurator unpauses the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, false); - - // User 0 succeeds transfer to User 1 - await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit); - - const fromBalance = await aDai.balanceOf(users[0].address); - const toBalance = await aDai.balanceOf(users[1].address); - - expect(fromBalance.toString()).to.be.equal( - user0Balance.sub(amountDAItoDeposit), - INVALID_FROM_BALANCE_AFTER_TRANSFER - ); - expect(toBalance.toString()).to.be.equal( - user1Balance.add(amountDAItoDeposit), - INVALID_TO_BALANCE_AFTER_TRANSFER - ); - }); - - it('Deposit', async () => { - const { users, pool, dai, aDai, configurator } = testEnv; - - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit); - - // user 0 deposits 1000 DAI - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - - // Configurator pauses the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, true); - await expect( - pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ).to.revertedWith(RESERVE_PAUSED); - - // Configurator unpauses the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, false); - }); - - it('Withdraw', async () => { - const { users, pool, dai, aDai, configurator } = testEnv; - - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await dai.connect(users[0].signer)['mint(uint256)'](amountDAItoDeposit); - - // user 0 deposits 1000 DAI - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[0].signer) - .deposit(dai.address, amountDAItoDeposit, users[0].address, '0'); - - // Configurator pauses the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, true); - - // user tries to burn - await expect( - pool.connect(users[0].signer).withdraw(dai.address, amountDAItoDeposit, users[0].address) - ).to.revertedWith(RESERVE_PAUSED); - - // Configurator unpauses the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, false); - }); - - it('Borrow', async () => { - const { pool, dai, users, configurator } = testEnv; - - const user = users[1]; - // Pause the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, true); - - // Try to execute liquidation - await expect( - pool.connect(user.signer).borrow(dai.address, '1', '1', '0', user.address) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, false); - }); - - it('Repay', async () => { - const { pool, dai, users, configurator } = testEnv; - - const user = users[1]; - // Pause the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, true); - - // Try to execute liquidation - await expect( - pool.connect(user.signer).repay(dai.address, '1', '1', user.address) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause the pool - await configurator.connect(users[1].signer).setReservePause(dai.address, false); - }); - - it('Flash loan', async () => { - const { dai, pool, weth, users, configurator } = testEnv; - - const caller = users[3]; - - const flashAmount = utils.parseEther('0.8'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - // Pause pool - await configurator.connect(users[1].signer).setReservePause(weth.address, true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [1], - caller.address, - '0x10', - '0' - ) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setReservePause(weth.address, false); - }); - - it('Liquidation call', async () => { - const { users, pool, usdc, oracle, weth, configurator, helpersContract } = testEnv; - const depositor = users[3]; - const borrower = users[4]; - - //mints USDC to depositor - await usdc - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - //approve protocol to access depositor wallet - await usdc.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 3 deposits 1000 USDC - const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000'); - - await pool - .connect(depositor.signer) - .deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0'); - - //user 4 deposits ETH - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.06775'); - - //mints WETH to borrower - await weth.connect(borrower.signer)['mint(uint256)'](amountETHtoDeposit); - - //approve protocol to access borrower wallet - await weth.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - await pool - .connect(borrower.signer) - .deposit(weth.address, amountETHtoDeposit, borrower.address, '0'); - - //user 4 borrows - const userGlobalData = await pool.getUserAccountData(borrower.address); - - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - const amountUSDCToBorrow = await convertToCurrencyDecimals( - usdc.address, - userGlobalData.availableBorrowsBase.div(usdcPrice).percentMul(9502).toString() - ); - - await pool - .connect(borrower.signer) - .borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address); - - // Drops HF below 1 - await oracle.setAssetPrice(usdc.address, usdcPrice.percentMul(12000)); - - //mints dai to the liquidator - await usdc['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - await usdc.approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - usdc.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - // Pause pool - await configurator.connect(users[1].signer).setReservePause(usdc.address, true); - - // Do liquidation - await expect( - pool.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, true) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setReservePause(usdc.address, false); - }); - - it('SwapBorrowRateMode', async () => { - const { pool, weth, dai, usdc, users, configurator } = testEnv; - const user = users[1]; - const amountWETHToDeposit = utils.parseEther('10'); - const amountDAIToDeposit = utils.parseEther('120'); - const amountToBorrow = await convertToCurrencyDecimals(usdc.address, '65'); - - await weth.connect(user.signer)['mint(uint256)'](amountWETHToDeposit); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0'); - - await dai.connect(user.signer)['mint(uint256)'](amountDAIToDeposit); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).deposit(dai.address, amountDAIToDeposit, user.address, '0'); - - await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address); - - // Pause pool - await configurator.connect(users[1].signer).setReservePause(usdc.address, true); - - // Try to repay - await expect( - pool.connect(user.signer).swapBorrowRateMode(usdc.address, RateMode.Stable) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setReservePause(usdc.address, false); - }); - - it('RebalanceStableBorrowRate', async () => { - const { pool, dai, users, configurator } = testEnv; - const user = users[1]; - // Pause pool - await configurator.connect(users[1].signer).setReservePause(dai.address, true); - - await expect( - pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setReservePause(dai.address, false); - }); - - it('setUserUseReserveAsCollateral', async () => { - const { pool, weth, users, configurator } = testEnv; - const user = users[1]; - - const amountWETHToDeposit = utils.parseEther('1'); - await weth.connect(user.signer)['mint(uint256)'](amountWETHToDeposit); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0'); - - // Pause pool - await configurator.connect(users[1].signer).setReservePause(weth.address, true); - - await expect( - pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false) - ).to.be.revertedWith(RESERVE_PAUSED); - - // Unpause pool - await configurator.connect(users[1].signer).setReservePause(weth.address, false); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-addresses-provider.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-addresses-provider.spec.ts deleted file mode 100644 index 08f557f..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-addresses-provider.spec.ts +++ /dev/null @@ -1,547 +0,0 @@ -import hre from 'hardhat'; -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { createRandomAddress } from '../helpers/misc-utils'; -import { ProtocolErrors } from '../helpers/types'; -import { ZERO_ADDRESS } from '../helpers/constants'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { deployPool, deployMockPool } from '@aave/deploy-v3/dist/helpers/contract-deployments'; -import { - evmSnapshot, - evmRevert, - getFirstSigner, - InitializableAdminUpgradeabilityProxy__factory, -} from '@aave/deploy-v3'; -import { MockPeripheryContractV1__factory, MockPeripheryContractV2__factory } from '../types'; -import { getProxyAdmin, getProxyImplementation } from '../helpers/contracts-helpers'; - -makeSuite('PoolAddressesProvider', (testEnv: TestEnv) => { - const { OWNABLE_ONLY_OWNER } = ProtocolErrors; - - it('Test the onlyOwner accessibility of the PoolAddressesProvider', async () => { - const { addressesProvider, users } = testEnv; - const mockAddress = createRandomAddress(); - - // Transfer ownership to user 1 - await addressesProvider.transferOwnership(users[1].address); - - // Test accessibility with user 0 - for (const contractFunction of [ - addressesProvider.setMarketId, - addressesProvider.setPoolImpl, - addressesProvider.setPoolConfiguratorImpl, - addressesProvider.setPriceOracle, - addressesProvider.setACLAdmin, - addressesProvider.setPriceOracleSentinel, - addressesProvider.setPoolDataProvider, - ]) { - await expect(contractFunction(mockAddress)).to.be.revertedWith(OWNABLE_ONLY_OWNER); - } - - await expect( - addressesProvider.setAddress(utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')), mockAddress) - ).to.be.revertedWith(OWNABLE_ONLY_OWNER); - - await expect( - addressesProvider.setAddressAsProxy( - utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')), - mockAddress - ) - ).to.be.revertedWith(OWNABLE_ONLY_OWNER); - }); - - it('Owner adds a new address as proxy', async () => { - const { addressesProvider, users } = testEnv; - - const currentAddressesProviderOwner = users[1]; - - const mockPool = await deployPool(); - const proxiedAddressId = utils.formatBytes32String('RANDOM_PROXIED'); - - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddressAsProxy(proxiedAddressId, mockPool.address) - ) - .to.emit(addressesProvider, 'AddressSetAsProxy') - .to.emit(addressesProvider, 'ProxyCreated'); - - const proxyAddress = await addressesProvider.getAddress(proxiedAddressId); - const implAddress = await getProxyImplementation(addressesProvider.address, proxyAddress); - expect(implAddress).to.be.eq(mockPool.address); - }); - - it('Owner adds a new address with no proxy', async () => { - const { addressesProvider, users } = testEnv; - - const currentAddressesProviderOwner = users[1]; - const mockNonProxiedAddress = createRandomAddress(); - const nonProxiedAddressId = utils.formatBytes32String('RANDOM_NON_PROXIED'); - - const oldAddress = await addressesProvider.getAddress(nonProxiedAddressId); - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddress(nonProxiedAddressId, mockNonProxiedAddress) - ) - .to.emit(addressesProvider, 'AddressSet') - .withArgs(nonProxiedAddressId, oldAddress, mockNonProxiedAddress); - - expect((await addressesProvider.getAddress(nonProxiedAddressId)).toLowerCase()).to.be.eq( - mockNonProxiedAddress.toLowerCase() - ); - - const proxyAddress = await addressesProvider.getAddress(nonProxiedAddressId); - await expect(getProxyImplementation(addressesProvider.address, proxyAddress)).to.be.reverted; - }); - - it('Owner adds a new address with no proxy and turns it into a proxy', async () => { - const { addressesProvider, users } = testEnv; - - const currentAddressesProviderOwner = users[1]; - const mockPool = await deployPool(); - const mockConvertibleAddress = mockPool.address; - const convertibleAddressId = utils.formatBytes32String('CONVERTIBLE_ADDRESS'); - - expect(await addressesProvider.getAddress(convertibleAddressId)).to.be.eq(ZERO_ADDRESS); - - const oldNonProxiedAddress = await addressesProvider.getAddress(convertibleAddressId); - - // Add address as non proxy - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddress(convertibleAddressId, mockConvertibleAddress) - ) - .to.emit(addressesProvider, 'AddressSet') - .withArgs(convertibleAddressId, oldNonProxiedAddress, mockConvertibleAddress); - - let registeredAddress = await addressesProvider.getAddress(convertibleAddressId); - expect(registeredAddress).to.be.eq(mockConvertibleAddress); - await expect(getProxyImplementation(addressesProvider.address, registeredAddress)).to.be - .reverted; - - // Unregister address as non proxy - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddress(convertibleAddressId, ZERO_ADDRESS) - ) - .to.emit(addressesProvider, 'AddressSet') - .withArgs(convertibleAddressId, mockConvertibleAddress, ZERO_ADDRESS); - - // Add address as proxy - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddressAsProxy(convertibleAddressId, mockConvertibleAddress) - ) - .to.emit(addressesProvider, 'AddressSetAsProxy') - .to.emit(addressesProvider, 'ProxyCreated'); - - const proxyAddress = await addressesProvider.getAddress(convertibleAddressId); - const implAddress = await getProxyImplementation(addressesProvider.address, proxyAddress); - expect(implAddress).to.be.eq(mockConvertibleAddress); - }); - - it('Unregister a proxy address', async () => { - const { addressesProvider, users } = testEnv; - - const currentAddressesProviderOwner = users[1]; - - const convertibleAddressId = utils.formatBytes32String('CONVERTIBLE_ADDRESS'); - - const proxyAddress = await addressesProvider.getAddress(convertibleAddressId); - - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddress(convertibleAddressId, ZERO_ADDRESS) - ) - .to.emit(addressesProvider, 'AddressSet') - .withArgs(convertibleAddressId, proxyAddress, ZERO_ADDRESS); - - const proxyAddressAfter = await addressesProvider.getAddress(convertibleAddressId); - expect(proxyAddressAfter).to.be.eq(ZERO_ADDRESS); - expect(proxyAddressAfter).to.be.not.eq(proxyAddress); - await expect(getProxyImplementation(addressesProvider.address, proxyAddressAfter)).to.be - .reverted; - }); - - it('Owner adds a new address with proxy and turns it into a no proxy', async () => { - const { addressesProvider, users } = testEnv; - - const currentAddressesProviderOwner = users[1]; - const mockPool = await deployPool(); - const mockConvertibleAddress = mockPool.address; - const convertibleAddressId = utils.formatBytes32String('CONVERTIBLE_ADDRESS2'); - - expect(await addressesProvider.getAddress(convertibleAddressId)).to.be.eq(ZERO_ADDRESS); - - // Add address as proxy - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddressAsProxy(convertibleAddressId, mockConvertibleAddress) - ) - .to.emit(addressesProvider, 'AddressSetAsProxy') - .to.emit(addressesProvider, 'ProxyCreated'); - - const proxyAddress = await addressesProvider.getAddress(convertibleAddressId); - const implAddress = await getProxyImplementation(addressesProvider.address, proxyAddress); - expect(implAddress).to.be.eq(mockConvertibleAddress); - - // Unregister address as proxy - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddress(convertibleAddressId, ZERO_ADDRESS) - ) - .to.emit(addressesProvider, 'AddressSet') - .withArgs(convertibleAddressId, proxyAddress, ZERO_ADDRESS); - - // Add address as non proxy - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddress(convertibleAddressId, mockConvertibleAddress) - ) - .to.emit(addressesProvider, 'AddressSet') - .withArgs(convertibleAddressId, ZERO_ADDRESS, mockConvertibleAddress); - - const registeredAddressAfter = await addressesProvider.getAddress(convertibleAddressId); - expect(registeredAddressAfter).to.be.not.eq(proxyAddress); - expect(registeredAddressAfter).to.be.eq(mockConvertibleAddress); - await expect(getProxyImplementation(addressesProvider.address, registeredAddressAfter)).to.be - .reverted; - }); - - it('Unregister a no proxy address', async () => { - const { addressesProvider, users } = testEnv; - - const currentAddressesProviderOwner = users[1]; - - const convertibleAddressId = utils.formatBytes32String('CONVERTIBLE_ADDRESS2'); - - const registeredAddress = await addressesProvider.getAddress(convertibleAddressId); - await expect(getProxyImplementation(addressesProvider.address, registeredAddress)).to.be - .reverted; - - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddress(convertibleAddressId, ZERO_ADDRESS) - ) - .to.emit(addressesProvider, 'AddressSet') - .withArgs(convertibleAddressId, registeredAddress, ZERO_ADDRESS); - - const registeredAddressAfter = await addressesProvider.getAddress(convertibleAddressId); - expect(registeredAddressAfter).to.be.eq(ZERO_ADDRESS); - expect(registeredAddressAfter).to.be.not.eq(registeredAddress); - await expect(getProxyImplementation(addressesProvider.address, registeredAddress)).to.be - .reverted; - }); - - it('Owner registers an existing contract (with proxy) and upgrade it', async () => { - const { addressesProvider, users, poolAdmin } = testEnv; - const proxyAdminOwner = users[0]; - - const currentAddressesProviderOwner = users[1]; - const initialManager = users[1]; - const initialProxyAdmin = users[2]; - - const newRegisteredContractId = hre.ethers.utils.keccak256( - hre.ethers.utils.toUtf8Bytes('NEW_REGISTERED_CONTRACT') - ); - - // Deploy the periphery contract that will be registered in the PoolAddressesProvider - const proxy = await ( - await new InitializableAdminUpgradeabilityProxy__factory(await getFirstSigner()).deploy() - ).deployed(); - - // Implementation - const impleV1 = await ( - await new MockPeripheryContractV1__factory(await getFirstSigner()).deploy() - ).deployed(); - await impleV1.initialize(initialManager.address, 123); - - // Initialize proxy - const incentivesInit = impleV1.interface.encodeFunctionData('initialize', [ - initialManager.address, - 123, - ]); - await ( - await proxy['initialize(address,address,bytes)']( - impleV1.address, // logic - initialProxyAdmin.address, // admin - incentivesInit // data - ) - ).wait(); - expect(await getProxyAdmin(proxy.address)).to.be.eq(initialProxyAdmin.address); - - const contractToRegister = MockPeripheryContractV1__factory.connect( - proxy.address, - proxyAdminOwner.signer - ); - expect(await contractToRegister.getManager()).to.be.eq(initialManager.address); - - // Register the periphery contract into the PoolAddressesProvider - expect(await proxy.connect(initialProxyAdmin.signer).changeAdmin(addressesProvider.address)); - expect(await getProxyAdmin(proxy.address)).to.be.eq(addressesProvider.address); - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddress(newRegisteredContractId, proxy.address) - ); - expect(await addressesProvider.getAddress(newRegisteredContractId)).to.be.eq(proxy.address); - - // Upgrade periphery contract to V2 from PoolAddressesProvider - // Note the new implementation contract should has a proper `initialize` function signature - - // New implementation - const impleV2 = await ( - await new MockPeripheryContractV2__factory(await getFirstSigner()).deploy() - ).deployed(); - await impleV2.initialize(addressesProvider.address); - - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setAddressAsProxy(newRegisteredContractId, impleV2.address) - ); - - const upgradedContract = MockPeripheryContractV2__factory.connect( - proxy.address, - proxyAdminOwner.signer - ); - expect(await upgradedContract.getManager()).to.be.eq(initialManager.address); - expect(await upgradedContract.getAddressesProvider()).to.be.eq(addressesProvider.address); - }); - - it('Owner updates the implementation of a proxy which is already initialized', async () => { - const snapId = await evmSnapshot(); - - const { addressesProvider, users } = testEnv; - const currentAddressesProviderOwner = users[1]; - - const mockPool = await deployMockPool(); - - // Pool has already a proxy - const poolAddress = await addressesProvider.getPool(); - expect(poolAddress).to.be.not.eq(ZERO_ADDRESS); - - const poolAddressId = utils.formatBytes32String('POOL'); - const proxyAddress = await addressesProvider.getAddress(poolAddressId); - const implementationAddress = await getProxyImplementation( - addressesProvider.address, - proxyAddress - ); - - // Update the Pool proxy - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setPoolImpl(mockPool.address) - ) - .to.emit(addressesProvider, 'PoolUpdated') - .withArgs(implementationAddress, mockPool.address); - - // Pool address should not change - expect(await addressesProvider.getPool()).to.be.eq(poolAddress); - - await evmRevert(snapId); - }); - - it('Owner updates the MarketId', async () => { - const snapId = await evmSnapshot(); - - const { addressesProvider, users } = testEnv; - const currentAddressesProviderOwner = users[1]; - - const NEW_MARKET_ID = 'NEW_MARKET'; - - // Current MarketId - const oldMarketId = await addressesProvider.getMarketId(); - - // Update the MarketId - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setMarketId(NEW_MARKET_ID) - ) - .to.emit(addressesProvider, 'MarketIdSet') - .withArgs(oldMarketId, NEW_MARKET_ID); - - expect(await addressesProvider.getMarketId()).to.be.not.eq(oldMarketId); - expect(await addressesProvider.getMarketId()).to.be.eq(NEW_MARKET_ID); - - await evmRevert(snapId); - }); - - it('Owner updates the PoolConfigurator', async () => { - const snapId = await evmSnapshot(); - - const { addressesProvider, configurator, users } = testEnv; - const currentAddressesProviderOwner = users[1]; - - const newPoolConfiguratorImpl = (await deployMockPool()).address; - - expect(await addressesProvider.getPoolConfigurator(), configurator.address); - - const poolConfiguratorAddressId = utils.formatBytes32String('POOL_CONFIGURATOR'); - const proxyAddress = await addressesProvider.getAddress(poolConfiguratorAddressId); - const implementationAddress = await getProxyImplementation( - addressesProvider.address, - proxyAddress - ); - - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setPoolConfiguratorImpl(newPoolConfiguratorImpl) - ) - .to.emit(addressesProvider, 'PoolConfiguratorUpdated') - .withArgs(implementationAddress, newPoolConfiguratorImpl); - - expect(await addressesProvider.getPoolConfigurator()).to.be.eq(configurator.address); - const implementationAddressAfter = await getProxyImplementation( - addressesProvider.address, - proxyAddress - ); - expect(implementationAddressAfter).to.be.not.eq(implementationAddress); - expect(implementationAddressAfter).to.be.eq(newPoolConfiguratorImpl); - - await evmRevert(snapId); - }); - - it('Owner updates the PriceOracle', async () => { - const snapId = await evmSnapshot(); - - const { addressesProvider, oracle, users } = testEnv; - const currentAddressesProviderOwner = users[1]; - - const newPriceOracleAddress = createRandomAddress(); - - expect(await addressesProvider.getPriceOracle(), oracle.address); - - const priceOracleAddressId = utils.formatBytes32String('PRICE_ORACLE'); - const registeredAddress = await addressesProvider.getAddress(priceOracleAddressId); - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setPriceOracle(newPriceOracleAddress) - ) - .to.emit(addressesProvider, 'PriceOracleUpdated') - .withArgs(registeredAddress, newPriceOracleAddress); - - expect(await addressesProvider.getPriceOracle()).to.be.not.eq(oracle.address); - expect(await addressesProvider.getPriceOracle()).to.be.eq(newPriceOracleAddress); - - await evmRevert(snapId); - }); - - it('Owner updates the ACLManager', async () => { - const snapId = await evmSnapshot(); - - const { addressesProvider, users, aclManager } = testEnv; - const currentAddressesProviderOwner = users[1]; - - const newACLManagerAddress = createRandomAddress(); - - expect(await addressesProvider.getACLManager(), aclManager.address); - - const aclManagerAddressId = utils.formatBytes32String('ACL_MANAGER'); - const registeredAddress = await addressesProvider.getAddress(aclManagerAddressId); - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setACLManager(newACLManagerAddress) - ) - .to.emit(addressesProvider, 'ACLManagerUpdated') - .withArgs(registeredAddress, newACLManagerAddress); - - expect(await addressesProvider.getACLManager()).to.be.not.eq(aclManager.address); - expect(await addressesProvider.getACLManager()).to.be.eq(newACLManagerAddress); - - await evmRevert(snapId); - }); - - it('Owner updates the ACLAdmin', async () => { - const snapId = await evmSnapshot(); - - const { addressesProvider, users } = testEnv; - const { aclAdmin: aclAdminAddress } = await hre.getNamedAccounts(); - const currentAddressesProviderOwner = users[1]; - - const newACLAdminAddress = createRandomAddress(); - - expect(await addressesProvider.getACLAdmin(), aclAdminAddress); - - const aclAdminAddressId = utils.formatBytes32String('ACL_ADMIN'); - const registeredAddress = await addressesProvider.getAddress(aclAdminAddressId); - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setACLAdmin(newACLAdminAddress) - ) - .to.emit(addressesProvider, 'ACLAdminUpdated') - .withArgs(registeredAddress, newACLAdminAddress); - - expect(await addressesProvider.getACLAdmin()).to.be.not.eq(aclAdminAddress); - expect(await addressesProvider.getACLAdmin()).to.be.eq(newACLAdminAddress); - - await evmRevert(snapId); - }); - - it('Owner updates the PriceOracleSentinel', async () => { - const snapId = await evmSnapshot(); - - const { addressesProvider, users } = testEnv; - const currentAddressesProviderOwner = users[1]; - - const newPriceOracleSentinelAddress = createRandomAddress(); - - const priceOracleSentinelAddressId = utils.formatBytes32String('PRICE_ORACLE_SENTINEL'); - const registeredAddress = await addressesProvider.getAddress(priceOracleSentinelAddressId); - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setPriceOracleSentinel(newPriceOracleSentinelAddress) - ) - .to.emit(addressesProvider, 'PriceOracleSentinelUpdated') - .withArgs(registeredAddress, newPriceOracleSentinelAddress); - - expect(await addressesProvider.getPriceOracleSentinel()).to.be.not.eq(registeredAddress); - expect(await addressesProvider.getPriceOracleSentinel()).to.be.eq( - newPriceOracleSentinelAddress - ); - - await evmRevert(snapId); - }); - - it('Owner updates the DataProvider', async () => { - const snapId = await evmSnapshot(); - - const { addressesProvider, helpersContract, users } = testEnv; - const currentAddressesProviderOwner = users[1]; - - expect(await addressesProvider.getPoolDataProvider(), helpersContract.address); - - const newDataProviderAddress = createRandomAddress(); - - const dataProviderAddressId = utils.formatBytes32String('DATA_PROVIDER'); - const registeredAddress = await addressesProvider.getAddress(dataProviderAddressId); - expect( - await addressesProvider - .connect(currentAddressesProviderOwner.signer) - .setPoolDataProvider(newDataProviderAddress) - ) - .to.emit(addressesProvider, 'PoolDataProviderUpdated') - .withArgs(registeredAddress, newDataProviderAddress); - - expect(await addressesProvider.getPoolDataProvider()).to.be.not.eq(helpersContract.address); - expect(await addressesProvider.getPoolDataProvider()).to.be.eq(newDataProviderAddress); - - await evmRevert(snapId); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-authorized-flashloan.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-authorized-flashloan.spec.ts deleted file mode 100644 index 3dfb147..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-authorized-flashloan.spec.ts +++ /dev/null @@ -1,519 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { - getMockFlashLoanReceiver, - getStableDebtToken, - getVariableDebtToken, -} from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { ProtocolErrors } from '../helpers/types'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; - -makeSuite('Pool: Authorized FlashLoan', (testEnv: TestEnv) => { - let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; - - const { - COLLATERAL_BALANCE_IS_ZERO, - ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE, - INVALID_FLASHLOAN_EXECUTOR_RETURN, - } = ProtocolErrors; - - before(async () => { - _mockFlashLoanReceiver = await getMockFlashLoanReceiver(); - }); - - it('Authorize a flash borrower', async () => { - const { deployer, aclManager } = testEnv; - const flashBorrowerRole = await aclManager.FLASH_BORROWER_ROLE(); - expect(await aclManager.addFlashBorrower(deployer.address)) - .to.emit(aclManager, 'RoleGranted') - .withArgs(flashBorrowerRole, deployer.address, deployer.address); - }); - - it('Deposits WETH into the reserve', async () => { - const { pool, weth } = testEnv; - const userAddress = await pool.signer.getAddress(); - const amountToDeposit = utils.parseEther('1'); - - expect(await weth['mint(uint256)'](amountToDeposit)); - - expect(await weth.approve(pool.address, MAX_UINT_AMOUNT)); - - expect(await pool.deposit(weth.address, amountToDeposit, userAddress, '0')); - }); - - it('Takes WETH flash loan with mode = 0, returns the funds correctly', async () => { - const { pool, helpersContract, weth } = testEnv; - - expect( - await pool.flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [utils.parseEther('0.8')], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ) - ); - - const reserveData = await helpersContract.getReserveData(weth.address); - - const currentLiquidityRate = reserveData.liquidityRate; - const currentLiquidityIndex = reserveData.liquidityIndex; - - const totalLiquidity = reserveData.totalAToken.add( - reserveData.accruedToTreasuryScaled.rayMul(reserveData.liquidityIndex) - ); - - expect(totalLiquidity).to.be.equal('1000000000000000000'); - expect(currentLiquidityRate).to.be.equal('0'); - expect(currentLiquidityIndex).to.be.equal('1000000000000000000000000000'); - }); - - it('Takes an ETH flash loan with mode = 0 as big as the available liquidity', async () => { - const { pool, helpersContract, weth } = testEnv; - - expect( - await pool.flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - ['1000000000000000000'], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ) - ); - - const reserveData = await helpersContract.getReserveData(weth.address); - - const currentLiquidityRate = reserveData.liquidityRate; - const currentLiquidityIndex = reserveData.liquidityIndex; - - const totalLiquidity = reserveData.totalAToken.add( - reserveData.accruedToTreasuryScaled.rayMul(reserveData.liquidityIndex) - ); - - expect(totalLiquidity).to.be.equal('1000000000000000000'); - expect(currentLiquidityRate).to.be.equal('0'); - expect(currentLiquidityIndex).to.be.equal('1000000000000000000000000000'); - }); - - it('Takes WETH flashloan, does not return the funds with mode = 0 (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [utils.parseEther('0.8')], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Takes WETH flash loan, simulating a receiver as EOA (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - expect(await _mockFlashLoanReceiver.setSimulateEOA(true)); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [utils.parseEther('0.8')], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.revertedWith(INVALID_FLASHLOAN_EXECUTOR_RETURN); - }); - - it('Takes a WETH flashloan with an invalid mode (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - expect(await _mockFlashLoanReceiver.setSimulateEOA(false)); - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [utils.parseEther('0.8')], - [4], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan with mode = 2, does not return the funds. A variable loan for caller is created', async () => { - const { dai, pool, weth, users, helpersContract } = testEnv; - - const caller = users[1]; - - const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - // Top up user - expect(await dai.connect(caller.signer)['mint(uint256)'](amountToDeposit)); - - expect(await dai.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect( - await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0') - ); - - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - - expect( - await pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [utils.parseEther('0.0571')], - [2], - caller.address, - '0x10', - '0' - ) - ); - const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - weth.address - ); - - const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress); - - const callerDebt = await wethDebtToken.balanceOf(caller.address); - - expect(callerDebt.toString()).to.be.equal('57100000000000000', 'Invalid user debt'); - }); - - it('Tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - - await expect( - pool.connect(caller.signer).flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - ['1000000000000000001'], //slightly higher than the available liquidity - [2], - caller.address, - '0x10', - '0' - ), - ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE - ).to.be.reverted; - }); - - it('Tries to take a flashloan using a non contract address as receiver (revert expected)', async () => { - const { pool, deployer, weth, users } = testEnv; - const caller = users[1]; - - await expect( - pool.flashLoan( - deployer.address, - [weth.address], - ['1000000000000000000'], - [2], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Deposits USDC into the reserve', async () => { - const { usdc, pool } = testEnv; - const userAddress = await pool.signer.getAddress(); - - const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000'); - - // Top up user - expect(await usdc['mint(uint256)'](amountToDeposit)); - - expect(await usdc.approve(pool.address, MAX_UINT_AMOUNT)); - - expect(await pool.deposit(usdc.address, amountToDeposit, userAddress, '0')); - }); - - it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => { - const { usdc, pool, helpersContract, deployer: depositor } = testEnv; - - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(false)); - - const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500'); - - expect( - await pool.flashLoan( - _mockFlashLoanReceiver.address, - [usdc.address], - [flashloanAmount], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ) - ); - - const reserveData = await helpersContract.getReserveData(usdc.address); - const userData = await helpersContract.getUserReserveData(usdc.address, depositor.address); - - const totalLiquidity = reserveData.totalAToken.add( - reserveData.accruedToTreasuryScaled.rayMul(reserveData.liquidityIndex) - ); - - const expectedLiquidity = await convertToCurrencyDecimals(usdc.address, '1000'); - - expect(totalLiquidity).to.be.equal(expectedLiquidity, 'Invalid total liquidity'); - expect(reserveData.liquidityRate).to.be.equal('0', 'Invalid liquidity rate'); - expect(reserveData.liquidityIndex).to.be.equal( - utils.parseUnits('1', 27), - 'Invalid liquidity index' - ); - expect(userData.currentATokenBalance).to.be.equal(expectedLiquidity, 'Invalid user balance'); - }); - - it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds (revert expected)', async () => { - const { usdc, pool, users } = testEnv; - const caller = users[2]; - - const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500'); - - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [usdc.address], - [flashloanAmount], - [2], - caller.address, - '0x10', - '0' - ) - ).to.be.revertedWith(COLLATERAL_BALANCE_IS_ZERO); - }); - - it('Caller deposits 5 WETH as collateral, Takes a USDC flashloan with mode = 2, does not return the funds. A loan for caller is created', async () => { - const { usdc, pool, weth, users, helpersContract } = testEnv; - - const caller = users[2]; - - const amountToDeposit = await convertToCurrencyDecimals(weth.address, '5'); - - // Top up user - expect(await weth.connect(caller.signer)['mint(uint256)'](amountToDeposit)); - - expect(await weth.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect( - await pool.connect(caller.signer).deposit(weth.address, amountToDeposit, caller.address, '0') - ); - - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - - const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500'); - - expect( - await pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [usdc.address], - [flashloanAmount], - [2], - caller.address, - '0x10', - '0' - ) - ); - const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - usdc.address - ); - - const usdcDebtToken = await getVariableDebtToken(variableDebtTokenAddress); - - const callerDebt = await usdcDebtToken.balanceOf(caller.address); - - expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt'); - }); - - it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds (revert expected)', async () => { - const { dai, pool, weth, users } = testEnv; - const caller = users[3]; - - const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - // Top up user - expect(await dai.connect(caller.signer)['mint(uint256)'](amountToDeposit)); - - expect(await dai.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect( - await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0') - ); - - const flashAmount = utils.parseEther('0.8'); - - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(false)); - expect(await _mockFlashLoanReceiver.setAmountToApprove(flashAmount.div(2))); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Caller takes a WETH flashloan with mode = 1', async () => { - const { pool, weth, users, helpersContract } = testEnv; - - const caller = users[3]; - - const flashAmount = utils.parseEther('0.0571'); - - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - - expect( - await pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [1], - caller.address, - '0x10', - '0' - ) - ); - - const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - weth.address - ); - - const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress); - - const callerDebt = await wethDebtToken.balanceOf(caller.address); - - expect(callerDebt.toString()).to.be.equal(flashAmount, 'Invalid user debt'); - }); - - it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user without allowance (revert expected)', async () => { - const { dai, pool, weth, users, helpersContract } = testEnv; - - const caller = users[5]; - const onBehalfOf = users[4]; - - const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - // Top up user - expect(await dai.connect(onBehalfOf.signer)['mint(uint256)'](amountToDeposit)); - - // Deposit 1000 dai for onBehalfOf user - expect(await dai.connect(onBehalfOf.signer).approve(pool.address, MAX_UINT_AMOUNT)); - - expect( - await pool - .connect(onBehalfOf.signer) - .deposit(dai.address, amountToDeposit, onBehalfOf.address, '0') - ); - - const flashAmount = utils.parseEther('0.0571'); - - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [1], - onBehalfOf.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user with allowance. A loan for onBehalfOf is creatd.', async () => { - const { pool, weth, users, helpersContract } = testEnv; - - const caller = users[5]; - const onBehalfOf = users[4]; - - const flashAmount = utils.parseEther('0.0571'); - - const reserveData = await pool.getReserveData(weth.address); - - const stableDebtToken = await getStableDebtToken(reserveData.stableDebtTokenAddress); - - // Deposited for onBehalfOf user already, delegate borrow allowance - expect( - await stableDebtToken - .connect(onBehalfOf.signer) - .approveDelegation(caller.address, flashAmount) - ); - - expect(await _mockFlashLoanReceiver.setFailExecutionTransfer(true)); - - expect( - await pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [1], - onBehalfOf.address, - '0x10', - '0' - ) - ); - - const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - weth.address - ); - - const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress); - - const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address); - - expect(onBehalfOfDebt.toString()).to.be.equal( - '57100000000000000', - 'Invalid onBehalfOf user debt' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-drop-reserve.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-drop-reserve.spec.ts deleted file mode 100644 index e14ffa9..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-drop-reserve.spec.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { ProtocolErrors } from '../helpers/types'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver'; -import { getMockFlashLoanReceiver } from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { makeSuite, TestEnv } from './helpers/make-suite'; - -makeSuite('Pool: Drop Reserve', (testEnv: TestEnv) => { - let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; - - const { - ATOKEN_SUPPLY_NOT_ZERO, - STABLE_DEBT_NOT_ZERO, - VARIABLE_DEBT_SUPPLY_NOT_ZERO, - ASSET_NOT_LISTED, - ZERO_ADDRESS_NOT_VALID, - } = ProtocolErrors; - - before(async () => { - _mockFlashLoanReceiver = await getMockFlashLoanReceiver(); - }); - - it('User 1 deposits DAI, User 2 borrow DAI stable and variable, should fail to drop DAI reserve', async () => { - const { - deployer, - users: [user1], - pool, - dai, - weth, - configurator, - } = testEnv; - - const depositedAmount = utils.parseEther('1000'); - const borrowedAmount = utils.parseEther('100'); - // setting reserve factor to 0 to ease tests, no aToken accrued in reserve - await configurator.setReserveFactor(dai.address, 0); - - await dai['mint(uint256)'](depositedAmount); - await dai.approve(pool.address, depositedAmount); - await dai.connect(user1.signer)['mint(uint256)'](depositedAmount); - await dai.connect(user1.signer).approve(pool.address, depositedAmount); - - await weth.connect(user1.signer)['mint(uint256)'](depositedAmount); - await weth.connect(user1.signer).approve(pool.address, depositedAmount); - - await pool.deposit(dai.address, depositedAmount, deployer.address, 0); - - await expect(configurator.dropReserve(dai.address)).to.be.revertedWith(ATOKEN_SUPPLY_NOT_ZERO); - - await pool.connect(user1.signer).deposit(weth.address, depositedAmount, user1.address, 0); - - await pool.connect(user1.signer).borrow(dai.address, borrowedAmount, 2, 0, user1.address); - await expect(configurator.dropReserve(dai.address)).to.be.revertedWith( - VARIABLE_DEBT_SUPPLY_NOT_ZERO - ); - await pool.connect(user1.signer).borrow(dai.address, borrowedAmount, 1, 0, user1.address); - await expect(configurator.dropReserve(dai.address)).to.be.revertedWith(STABLE_DEBT_NOT_ZERO); - }); - - it('User 2 repays debts, drop DAI reserve should fail', async () => { - const { - users: [user1], - pool, - dai, - configurator, - } = testEnv; - expect(await pool.connect(user1.signer).repay(dai.address, MAX_UINT_AMOUNT, 1, user1.address)); - await expect(configurator.dropReserve(dai.address)).to.be.revertedWith( - VARIABLE_DEBT_SUPPLY_NOT_ZERO - ); - - expect(await pool.connect(user1.signer).repay(dai.address, MAX_UINT_AMOUNT, 2, user1.address)); - await expect(configurator.dropReserve(dai.address)).to.be.revertedWith(ATOKEN_SUPPLY_NOT_ZERO); - }); - - it('User 1 withdraw DAI, drop DAI reserve should succeed', async () => { - const { deployer, pool, dai, configurator, helpersContract } = testEnv; - - await pool.withdraw(dai.address, MAX_UINT_AMOUNT, deployer.address); - const reserveCount = (await pool.getReservesList()).length; - expect(await configurator.dropReserve(dai.address)); - - const tokens = await pool.getReservesList(); - - expect(tokens.length).to.be.eq(reserveCount - 1); - expect(tokens.includes(dai.address)).to.be.false; - - const { isActive } = await helpersContract.getReserveConfigurationData(dai.address); - expect(isActive).to.be.false; - }); - - it('Drop an asset that is not a listed reserve should fail', async () => { - const { users, configurator } = testEnv; - await expect(configurator.dropReserve(users[5].address)).to.be.revertedWith(ASSET_NOT_LISTED); - }); - - it('Drop an asset that is not a listed reserve should fail', async () => { - const { users, configurator } = testEnv; - await expect(configurator.dropReserve(ZERO_ADDRESS)).to.be.revertedWith(ZERO_ADDRESS_NOT_VALID); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-edge.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-edge.spec.ts deleted file mode 100644 index d2c18be..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-edge.spec.ts +++ /dev/null @@ -1,796 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, BigNumberish, utils } from 'ethers'; -import { impersonateAccountsHardhat } from '../helpers/misc-utils'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { deployMintableERC20 } from '@aave/deploy-v3/dist/helpers/contract-deployments'; -import { ProtocolErrors } from '../helpers/types'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { topUpNonPayableWithEther } from './helpers/utils/funds'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { evmSnapshot, evmRevert, getPoolLibraries } from '@aave/deploy-v3'; -import { - MockPoolInherited__factory, - MockReserveInterestRateStrategy__factory, - StableDebtToken__factory, - VariableDebtToken__factory, - AToken__factory, - Pool__factory, - InitializableImmutableAdminUpgradeabilityProxy, - ERC20__factory, -} from '../types'; -import { getProxyImplementation } from '../helpers/contracts-helpers'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('Pool: Edge cases', (testEnv: TestEnv) => { - const { - NO_MORE_RESERVES_ALLOWED, - CALLER_NOT_ATOKEN, - NOT_CONTRACT, - CALLER_NOT_POOL_CONFIGURATOR, - RESERVE_ALREADY_INITIALIZED, - INVALID_ADDRESSES_PROVIDER, - RESERVE_ALREADY_ADDED, - DEBT_CEILING_NOT_ZERO, - ASSET_NOT_LISTED, - ZERO_ADDRESS_NOT_VALID, - } = ProtocolErrors; - - const MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 2500; - const MAX_NUMBER_RESERVES = 128; - - const POOL_ID = utils.formatBytes32String('POOL'); - - let snap: string; - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - - afterEach(async () => { - await evmRevert(snap); - }); - - it('Drop asset while user uses it as collateral, ensure that borrowing power is lowered', async () => { - const { - addressesProvider, - poolAdmin, - dai, - users: [user0], - } = testEnv; - const { deployer: deployerName } = await hre.getNamedAccounts(); - - // Deploy the mock Pool with a `dropReserve` skipping the checks - const NEW_POOL_IMPL_ARTIFACT = await hre.deployments.deploy('MockPoolInheritedDropper', { - contract: 'MockPoolInherited', - from: deployerName, - args: [addressesProvider.address], - libraries: { - SupplyLogic: (await hre.deployments.get('SupplyLogic')).address, - BorrowLogic: (await hre.deployments.get('BorrowLogic')).address, - LiquidationLogic: (await hre.deployments.get('LiquidationLogic')).address, - EModeLogic: (await hre.deployments.get('EModeLogic')).address, - BridgeLogic: (await hre.deployments.get('BridgeLogic')).address, - FlashLoanLogic: (await hre.deployments.get('FlashLoanLogic')).address, - PoolLogic: (await hre.deployments.get('PoolLogic')).address, - }, - log: false, - }); - - const poolProxyAddress = await addressesProvider.getPool(); - const oldPoolImpl = await getProxyImplementation(addressesProvider.address, poolProxyAddress); - - // Upgrade the Pool - expect( - await addressesProvider.connect(poolAdmin.signer).setPoolImpl(NEW_POOL_IMPL_ARTIFACT.address) - ) - .to.emit(addressesProvider, 'PoolUpdated') - .withArgs(oldPoolImpl, NEW_POOL_IMPL_ARTIFACT.address); - - // Get the Pool instance - const mockPoolAddress = await addressesProvider.getPool(); - const mockPool = await MockPoolInherited__factory.connect( - mockPoolAddress, - await getFirstSigner() - ); - - const amount = utils.parseUnits('10', 18); - const amountUSD = amount.div(BigNumber.from(10).pow(10)); - - await dai.connect(user0.signer)['mint(uint256)'](amount); - await dai.connect(user0.signer).approve(mockPool.address, MAX_UINT_AMOUNT); - - expect(await mockPool.connect(user0.signer).supply(dai.address, amount, user0.address, 0)); - - const userReserveDataBefore = await mockPool.getUserAccountData(user0.address); - - expect(userReserveDataBefore.totalCollateralBase).to.be.eq(amountUSD); - expect(userReserveDataBefore.totalDebtBase).to.be.eq(0); - expect(userReserveDataBefore.availableBorrowsBase).to.be.eq(amountUSD.mul(7500).div(10000)); - expect(userReserveDataBefore.currentLiquidationThreshold).to.be.eq(8000); - expect(userReserveDataBefore.ltv).to.be.eq(7500); - expect(userReserveDataBefore.healthFactor).to.be.eq(MAX_UINT_AMOUNT); - - expect(await mockPool.dropReserve(dai.address)); - - const userReserveDataAfter = await mockPool.getUserAccountData(user0.address); - - expect(userReserveDataAfter.totalCollateralBase).to.be.eq(0); - expect(userReserveDataAfter.totalDebtBase).to.be.eq(0); - expect(userReserveDataAfter.availableBorrowsBase).to.be.eq(0); - expect(userReserveDataAfter.currentLiquidationThreshold).to.be.eq(0); - expect(userReserveDataAfter.ltv).to.be.eq(0); - expect(userReserveDataAfter.healthFactor).to.be.eq(MAX_UINT_AMOUNT); - }); - - it('Initialize fresh deployment with incorrect addresses provider (revert expected)', async () => { - const { - addressesProvider, - users: [deployer], - } = testEnv; - const { deployer: deployerName } = await hre.getNamedAccounts(); - - const NEW_POOL_IMPL_ARTIFACT = await hre.deployments.deploy('Pool', { - contract: 'Pool', - from: deployerName, - args: [addressesProvider.address], - libraries: { - SupplyLogic: (await hre.deployments.get('SupplyLogic')).address, - BorrowLogic: (await hre.deployments.get('BorrowLogic')).address, - LiquidationLogic: (await hre.deployments.get('LiquidationLogic')).address, - EModeLogic: (await hre.deployments.get('EModeLogic')).address, - BridgeLogic: (await hre.deployments.get('BridgeLogic')).address, - FlashLoanLogic: (await hre.deployments.get('FlashLoanLogic')).address, - PoolLogic: (await hre.deployments.get('PoolLogic')).address, - }, - log: false, - }); - - const freshPool = Pool__factory.connect(NEW_POOL_IMPL_ARTIFACT.address, deployer.signer); - - await expect(freshPool.initialize(deployer.address)).to.be.revertedWith( - INVALID_ADDRESSES_PROVIDER - ); - }); - - it('Check initialization', async () => { - const { pool } = testEnv; - - expect(await pool.MAX_STABLE_RATE_BORROW_SIZE_PERCENT()).to.be.eq( - MAX_STABLE_RATE_BORROW_SIZE_PERCENT - ); - expect(await pool.MAX_NUMBER_RESERVES()).to.be.eq(MAX_NUMBER_RESERVES); - }); - - it('Tries to initialize a reserve as non PoolConfigurator (revert expected)', async () => { - const { pool, users, dai, helpersContract } = testEnv; - - const config = await helpersContract.getReserveTokensAddresses(dai.address); - - await expect( - pool - .connect(users[0].signer) - .initReserve( - dai.address, - config.aTokenAddress, - config.stableDebtTokenAddress, - config.variableDebtTokenAddress, - ZERO_ADDRESS - ) - ).to.be.revertedWith(CALLER_NOT_POOL_CONFIGURATOR); - }); - - it('Call `setUserUseReserveAsCollateral()` to use an asset as collateral when the asset is already set as collateral', async () => { - const { - pool, - helpersContract, - dai, - users: [user0], - } = testEnv; - - const amount = utils.parseUnits('10', 18); - await dai.connect(user0.signer)['mint(uint256)'](amount); - await dai.connect(user0.signer).approve(pool.address, MAX_UINT_AMOUNT); - - expect(await pool.connect(user0.signer).supply(dai.address, amount, user0.address, 0)); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - dai.address, - user0.address - ); - expect(userReserveDataBefore.usageAsCollateralEnabled).to.be.true; - - expect( - await pool.connect(user0.signer).setUserUseReserveAsCollateral(dai.address, true) - ).to.not.emit(pool, 'ReserveUsedAsCollateralEnabled'); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - dai.address, - user0.address - ); - expect(userReserveDataAfter.usageAsCollateralEnabled).to.be.true; - }); - - it('Call `setUserUseReserveAsCollateral()` to disable an asset as collateral when the asset is already disabled as collateral', async () => { - const { - pool, - helpersContract, - dai, - users: [user0], - } = testEnv; - - const amount = utils.parseUnits('10', 18); - await dai.connect(user0.signer)['mint(uint256)'](amount); - await dai.connect(user0.signer).approve(pool.address, MAX_UINT_AMOUNT); - - expect(await pool.connect(user0.signer).supply(dai.address, amount, user0.address, 0)); - - // Disable asset as collateral - expect(await pool.connect(user0.signer).setUserUseReserveAsCollateral(dai.address, false)) - .to.emit(pool, 'ReserveUsedAsCollateralDisabled') - .withArgs(dai.address, user0.address); - - const userReserveDataBefore = await helpersContract.getUserReserveData( - dai.address, - user0.address - ); - expect(userReserveDataBefore.usageAsCollateralEnabled).to.be.false; - - expect( - await pool.connect(user0.signer).setUserUseReserveAsCollateral(dai.address, false) - ).to.not.emit(pool, 'ReserveUsedAsCollateralDisabled'); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - dai.address, - user0.address - ); - expect(userReserveDataAfter.usageAsCollateralEnabled).to.be.false; - }); - - it('Call `mintToTreasury()` on a pool with an inactive reserve', async () => { - const { pool, poolAdmin, dai, users, configurator } = testEnv; - - // Deactivate reserve - expect(await configurator.connect(poolAdmin.signer).setReserveActive(dai.address, false)); - - // MintToTreasury - expect(await pool.connect(users[0].signer).mintToTreasury([dai.address])); - }); - - it('Tries to call `finalizeTransfer()` by a non-aToken address (revert expected)', async () => { - const { pool, dai, users } = testEnv; - - await expect( - pool - .connect(users[0].signer) - .finalizeTransfer(dai.address, users[0].address, users[1].address, 0, 0, 0) - ).to.be.revertedWith(CALLER_NOT_ATOKEN); - }); - - it('Tries to call `initReserve()` with an EOA as reserve (revert expected)', async () => { - const { pool, deployer, users, configurator } = testEnv; - - // Impersonate PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - await expect( - pool - .connect(configSigner) - .initReserve(users[0].address, ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS) - ).to.be.revertedWith(NOT_CONTRACT); - }); - - it('PoolConfigurator updates the ReserveInterestRateStrategy address', async () => { - const { pool, deployer, dai, configurator } = testEnv; - - // Impersonate PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - expect( - await pool - .connect(configSigner) - .setReserveInterestRateStrategyAddress(dai.address, ZERO_ADDRESS) - ); - - const config = await pool.getReserveData(dai.address); - expect(config.interestRateStrategyAddress).to.be.eq(ZERO_ADDRESS); - }); - - it('PoolConfigurator updates the ReserveInterestRateStrategy address for asset 0', async () => { - const { pool, deployer, dai, configurator } = testEnv; - - // Impersonate PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - await expect( - pool.connect(configSigner).setReserveInterestRateStrategyAddress(ZERO_ADDRESS, ZERO_ADDRESS) - ).to.be.revertedWith(ZERO_ADDRESS_NOT_VALID); - }); - - it('PoolConfigurator updates the ReserveInterestRateStrategy address for an unlisted asset (revert expected)', async () => { - const { pool, deployer, dai, configurator, users } = testEnv; - - // Impersonate PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - await expect( - pool - .connect(configSigner) - .setReserveInterestRateStrategyAddress(users[5].address, ZERO_ADDRESS) - ).to.be.revertedWith(ASSET_NOT_LISTED); - }); - - it('Activates the zero address reserve for borrowing via pool admin (expect revert)', async () => { - const { configurator } = testEnv; - await expect(configurator.setReserveBorrowing(ZERO_ADDRESS, true)).to.be.revertedWith( - ZERO_ADDRESS_NOT_VALID - ); - }); - - it('Initialize an already initialized reserve. ReserveLogic `init` where aTokenAddress != ZERO_ADDRESS (revert expected)', async () => { - const { pool, dai, deployer, configurator } = testEnv; - - // Impersonate PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - const config = await pool.getReserveData(dai.address); - - await expect( - pool.connect(configSigner).initReserve( - dai.address, - config.aTokenAddress, // just need a non-used reserve token - config.stableDebtTokenAddress, - config.variableDebtTokenAddress, - ZERO_ADDRESS - ) - ).to.be.revertedWith(RESERVE_ALREADY_INITIALIZED); - }); - - it('Init reserve with ZERO_ADDRESS as aToken twice, to enter `_addReserveToList()` already added (revert expected)', async () => { - /** - * To get into this case, we need to init a reserve with `aTokenAddress = address(0)` twice. - * `_addReserveToList()` is called from `initReserve`. However, in `initReserve` we run `init` before the `_addReserveToList()`, - * and in `init` we are checking if `aTokenAddress == address(0)`, so to bypass that we need this odd init. - */ - const { pool, dai, deployer, configurator } = testEnv; - - // Impersonate PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - const config = await pool.getReserveData(dai.address); - - const poolListBefore = await pool.getReservesList(); - - expect( - await pool - .connect(configSigner) - .initReserve( - config.aTokenAddress, - ZERO_ADDRESS, - config.stableDebtTokenAddress, - config.variableDebtTokenAddress, - ZERO_ADDRESS - ) - ); - const poolListMid = await pool.getReservesList(); - expect(poolListBefore.length + 1).to.be.eq(poolListMid.length); - - // Add it again. - await expect( - pool - .connect(configSigner) - .initReserve( - config.aTokenAddress, - ZERO_ADDRESS, - config.stableDebtTokenAddress, - config.variableDebtTokenAddress, - ZERO_ADDRESS - ) - ).to.be.revertedWith(RESERVE_ALREADY_ADDED); - const poolListAfter = await pool.getReservesList(); - expect(poolListAfter.length).to.be.eq(poolListMid.length); - }); - - it('Initialize reserves until max, then add one more (revert expected)', async () => { - // Upgrade the Pool to update the maximum number of reserves - const { addressesProvider, poolAdmin, pool, dai, deployer, configurator } = testEnv; - const { deployer: deployerName } = await hre.getNamedAccounts(); - - // Impersonate the PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - // Deploy the mock Pool with a setter of `maxNumberOfReserves` - const NEW_POOL_IMPL_ARTIFACT = await hre.deployments.deploy('MockPoolInherited', { - contract: 'MockPoolInherited', - from: deployerName, - args: [addressesProvider.address], - libraries: { - SupplyLogic: (await hre.deployments.get('SupplyLogic')).address, - BorrowLogic: (await hre.deployments.get('BorrowLogic')).address, - LiquidationLogic: (await hre.deployments.get('LiquidationLogic')).address, - EModeLogic: (await hre.deployments.get('EModeLogic')).address, - BridgeLogic: (await hre.deployments.get('BridgeLogic')).address, - FlashLoanLogic: (await hre.deployments.get('FlashLoanLogic')).address, - PoolLogic: (await hre.deployments.get('PoolLogic')).address, - }, - log: false, - }); - - const poolProxyAddress = await addressesProvider.getPool(); - const oldPoolImpl = await getProxyImplementation(addressesProvider.address, poolProxyAddress); - - // Upgrade the Pool - expect( - await addressesProvider.connect(poolAdmin.signer).setPoolImpl(NEW_POOL_IMPL_ARTIFACT.address) - ) - .to.emit(addressesProvider, 'PoolUpdated') - .withArgs(oldPoolImpl, NEW_POOL_IMPL_ARTIFACT.address); - - // Get the Pool instance - const mockPoolAddress = await addressesProvider.getPool(); - const mockPool = await MockPoolInherited__factory.connect( - mockPoolAddress, - await getFirstSigner() - ); - - // Get the current number of reserves - const numberOfReserves = (await mockPool.getReservesList()).length; - - // Set the limit - expect(await mockPool.setMaxNumberOfReserves(numberOfReserves)); - expect(await mockPool.MAX_NUMBER_RESERVES()).to.be.eq(numberOfReserves); - - const freshContract = await deployMintableERC20(['MOCK', 'MOCK', '18']); - const config = await pool.getReserveData(dai.address); - await expect( - pool.connect(configSigner).initReserve( - freshContract.address, // just need a non-used reserve token - ZERO_ADDRESS, - config.stableDebtTokenAddress, - config.variableDebtTokenAddress, - ZERO_ADDRESS - ) - ).to.be.revertedWith(NO_MORE_RESERVES_ALLOWED); - }); - - it('Add asset after multiple drops', async () => { - /** - * 1. Init assets (done through setup so get this for free) - * 2. Drop some reserves - * 3. Init a new asset. - * Intended behaviour new asset is inserted into one of the available spots in - */ - const { configurator, pool, poolAdmin, addressesProvider } = testEnv; - - const reservesListBefore = await pool.connect(configurator.signer).getReservesList(); - - // Remove first 2 assets that has no borrows - let dropped = 0; - for (let i = 0; i < reservesListBefore.length; i++) { - if (dropped == 2) { - break; - } - const reserveAsset = reservesListBefore[i]; - const assetData = await pool.getReserveData(reserveAsset); - - if ( - assetData.currentLiquidityRate.eq(0) && - assetData.currentStableBorrowRate.eq(0) && - assetData.currentVariableBorrowRate.eq(0) - ) { - await configurator.connect(poolAdmin.signer).dropReserve(reserveAsset); - dropped++; - } - } - - const reservesListAfterDrop = await pool.connect(configurator.signer).getReservesList(); - expect(reservesListAfterDrop.length).to.be.eq(reservesListBefore.length - 2); - - // Deploy new token and implementations - const mockToken = await deployMintableERC20(['MOCK', 'MOCK', '18']); - const stableDebtTokenImplementation = await new StableDebtToken__factory( - await getFirstSigner() - ).deploy(pool.address); - const variableDebtTokenImplementation = await new VariableDebtToken__factory( - await getFirstSigner() - ).deploy(pool.address); - const aTokenImplementation = await new AToken__factory(await getFirstSigner()).deploy( - pool.address - ); - const mockRateStrategy = await new MockReserveInterestRateStrategy__factory( - await getFirstSigner() - ).deploy(addressesProvider.address, 0, 0, 0, 0, 0, 0); - - // Init the reserve - const initInputParams: { - aTokenImpl: string; - stableDebtTokenImpl: string; - variableDebtTokenImpl: string; - underlyingAssetDecimals: BigNumberish; - interestRateStrategyAddress: string; - underlyingAsset: string; - treasury: string; - incentivesController: string; - aTokenName: string; - aTokenSymbol: string; - variableDebtTokenName: string; - variableDebtTokenSymbol: string; - stableDebtTokenName: string; - stableDebtTokenSymbol: string; - params: string; - }[] = [ - { - aTokenImpl: aTokenImplementation.address, - stableDebtTokenImpl: stableDebtTokenImplementation.address, - variableDebtTokenImpl: variableDebtTokenImplementation.address, - underlyingAssetDecimals: 18, - interestRateStrategyAddress: mockRateStrategy.address, - underlyingAsset: mockToken.address, - treasury: ZERO_ADDRESS, - incentivesController: ZERO_ADDRESS, - aTokenName: 'AMOCK', - aTokenSymbol: 'AMOCK', - variableDebtTokenName: 'VMOCK', - variableDebtTokenSymbol: 'VMOCK', - stableDebtTokenName: 'SMOCK', - stableDebtTokenSymbol: 'SMOCK', - params: '0x10', - }, - ]; - - expect(await configurator.connect(poolAdmin.signer).initReserves(initInputParams)); - const reservesListAfterInit = await pool.connect(configurator.signer).getReservesList(); - - let occurences = reservesListAfterInit.filter((v) => v == mockToken.address).length; - expect(occurences).to.be.eq(1, 'Asset has multiple occurrences in the reserves list'); - - expect(reservesListAfterInit.length).to.be.eq( - reservesListAfterDrop.length + 1, - 'Reserves list was increased by more than 1' - ); - }); - - it('Initialize reserves until max-1, then (drop one and add a new) x 2, finally add to hit max', async () => { - /** - * 1. Update max number of assets to current number og assets - * 2. Drop some reserves - * 3. Init a new asset. - * Intended behaviour: new asset is inserted into one of the available spots in `_reservesList` and `_reservesCount` kept the same - */ - - // Upgrade the Pool to update the maximum number of reserves - const { addressesProvider, poolAdmin, pool, dai, deployer, configurator } = testEnv; - const { deployer: deployerName } = await hre.getNamedAccounts(); - - // Impersonate the PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - // Deploy the mock Pool with a setter of `maxNumberOfReserves` - const NEW_POOL_IMPL_ARTIFACT = await hre.deployments.deploy('MockPoolInherited2', { - contract: 'MockPoolInherited', - from: deployerName, - args: [addressesProvider.address], - libraries: { - SupplyLogic: (await hre.deployments.get('SupplyLogic')).address, - BorrowLogic: (await hre.deployments.get('BorrowLogic')).address, - LiquidationLogic: (await hre.deployments.get('LiquidationLogic')).address, - EModeLogic: (await hre.deployments.get('EModeLogic')).address, - BridgeLogic: (await hre.deployments.get('BridgeLogic')).address, - FlashLoanLogic: (await hre.deployments.get('FlashLoanLogic')).address, - PoolLogic: (await hre.deployments.get('PoolLogic')).address, - }, - log: false, - }); - - const proxyAddress = await addressesProvider.getAddress(POOL_ID); - const implementationAddress = await getProxyImplementation( - addressesProvider.address, - proxyAddress - ); - - // Upgrade the Pool - expect( - await addressesProvider.connect(poolAdmin.signer).setPoolImpl(NEW_POOL_IMPL_ARTIFACT.address) - ) - .to.emit(addressesProvider, 'PoolUpdated') - .withArgs(implementationAddress, NEW_POOL_IMPL_ARTIFACT.address); - - // Get the Pool instance - const mockPoolAddress = await addressesProvider.getPool(); - const mockPool = await MockPoolInherited__factory.connect( - mockPoolAddress, - await getFirstSigner() - ); - - // Get the current number of reserves - let numberOfReserves = (await mockPool.getReservesList()).length; - - // Set the limit - expect(await mockPool.setMaxNumberOfReserves(numberOfReserves + 1)); - expect(await mockPool.MAX_NUMBER_RESERVES()).to.be.eq(numberOfReserves + 1); - - for (let dropped = 0; dropped < 2; dropped++) { - const reservesListBefore = await pool.connect(configurator.signer).getReservesList(); - for (let i = 0; i < reservesListBefore.length; i++) { - const reserveAsset = reservesListBefore[i]; - const assetData = await pool.getReserveData(reserveAsset); - - if (assetData.aTokenAddress == ZERO_ADDRESS) { - continue; - } - - if ( - assetData.currentLiquidityRate.eq(0) && - assetData.currentStableBorrowRate.eq(0) && - assetData.currentVariableBorrowRate.eq(0) - ) { - await configurator.connect(poolAdmin.signer).dropReserve(reserveAsset); - break; - } - } - - const reservesListLengthAfterDrop = (await pool.getReservesList()).length; - expect(reservesListLengthAfterDrop).to.be.eq(reservesListBefore.length - 1); - expect(reservesListLengthAfterDrop).to.be.lt(await mockPool.MAX_NUMBER_RESERVES()); - - const freshContract = await deployMintableERC20(['MOCK', 'MOCK', '18']); - const config = await pool.getReserveData(dai.address); - expect( - await pool.connect(configSigner).initReserve( - freshContract.address, // just need a non-used reserve token - ZERO_ADDRESS, - config.stableDebtTokenAddress, - config.variableDebtTokenAddress, - ZERO_ADDRESS - ) - ); - } - - const freshContract = await deployMintableERC20(['MOCK', 'MOCK', '18']); - const config = await pool.getReserveData(dai.address); - expect( - await pool.connect(configSigner).initReserve( - freshContract.address, // just need a non-used reserve token - ZERO_ADDRESS, - config.stableDebtTokenAddress, - config.variableDebtTokenAddress, - ZERO_ADDRESS - ) - ); - expect((await pool.getReservesList()).length).to.be.eq(await pool.MAX_NUMBER_RESERVES()); - }); - - it('Call `resetIsolationModeTotalDebt()` to reset isolationModeTotalDebt of an asset with non-zero debt ceiling', async () => { - const { - configurator, - pool, - helpersContract, - dai, - poolAdmin, - deployer, - users: [user0], - } = testEnv; - - const debtCeiling = utils.parseUnits('10', 2); - - expect(await helpersContract.getDebtCeiling(dai.address)).to.be.eq(0); - - await configurator.connect(poolAdmin.signer).setDebtCeiling(dai.address, debtCeiling); - - expect(await helpersContract.getDebtCeiling(dai.address)).to.be.eq(debtCeiling); - - // Impersonate PoolConfigurator - await topUpNonPayableWithEther(deployer.signer, [configurator.address], utils.parseEther('1')); - await impersonateAccountsHardhat([configurator.address]); - const configSigner = await hre.ethers.getSigner(configurator.address); - - await expect( - pool.connect(configSigner).resetIsolationModeTotalDebt(dai.address) - ).to.be.revertedWith(DEBT_CEILING_NOT_ZERO); - }); - - it('Tries to initialize a reserve with an AToken, StableDebtToken, and VariableDebt each deployed with the wrong pool address (revert expected)', async () => { - const { pool, deployer, configurator, addressesProvider } = testEnv; - - const NEW_POOL_IMPL_ARTIFACT = await hre.deployments.deploy('DummyPool', { - contract: 'Pool', - from: deployer.address, - args: [addressesProvider.address], - libraries: await getPoolLibraries(), - log: false, - }); - - const aTokenImp = await new AToken__factory(await getFirstSigner()).deploy(pool.address); - const stableDebtTokenImp = await new StableDebtToken__factory(deployer.signer).deploy( - pool.address - ); - const variableDebtTokenImp = await new VariableDebtToken__factory(deployer.signer).deploy( - pool.address - ); - - const aTokenWrongPool = await new AToken__factory(await getFirstSigner()).deploy( - NEW_POOL_IMPL_ARTIFACT.address - ); - const stableDebtTokenWrongPool = await new StableDebtToken__factory(deployer.signer).deploy( - NEW_POOL_IMPL_ARTIFACT.address - ); - const variableDebtTokenWrongPool = await new VariableDebtToken__factory(deployer.signer).deploy( - NEW_POOL_IMPL_ARTIFACT.address - ); - - const mockErc20 = await new ERC20__factory(deployer.signer).deploy('mock', 'MOCK'); - const mockRateStrategy = await new MockReserveInterestRateStrategy__factory( - await getFirstSigner() - ).deploy(addressesProvider.address, 0, 0, 0, 0, 0, 0); - - // Init the reserve - const initInputParams: { - aTokenImpl: string; - stableDebtTokenImpl: string; - variableDebtTokenImpl: string; - underlyingAssetDecimals: BigNumberish; - interestRateStrategyAddress: string; - underlyingAsset: string; - treasury: string; - incentivesController: string; - underlyingAssetName: string; - aTokenName: string; - aTokenSymbol: string; - variableDebtTokenName: string; - variableDebtTokenSymbol: string; - stableDebtTokenName: string; - stableDebtTokenSymbol: string; - params: string; - }[] = [ - { - aTokenImpl: aTokenImp.address, - stableDebtTokenImpl: stableDebtTokenImp.address, - variableDebtTokenImpl: variableDebtTokenImp.address, - underlyingAssetDecimals: 18, - interestRateStrategyAddress: mockRateStrategy.address, - underlyingAsset: mockErc20.address, - treasury: ZERO_ADDRESS, - incentivesController: ZERO_ADDRESS, - underlyingAssetName: 'MOCK', - aTokenName: 'AMOCK', - aTokenSymbol: 'AMOCK', - variableDebtTokenName: 'VMOCK', - variableDebtTokenSymbol: 'VMOCK', - stableDebtTokenName: 'SMOCK', - stableDebtTokenSymbol: 'SMOCK', - params: '0x10', - }, - ]; - - initInputParams[0].aTokenImpl = aTokenWrongPool.address; - await expect(configurator.initReserves(initInputParams)).to.be.reverted; - - initInputParams[0].aTokenImpl = aTokenImp.address; - initInputParams[0].stableDebtTokenImpl = stableDebtTokenWrongPool.address; - await expect(configurator.initReserves(initInputParams)).to.be.reverted; - - initInputParams[0].stableDebtTokenImpl = stableDebtTokenImp.address; - initInputParams[0].variableDebtTokenImpl = variableDebtTokenWrongPool.address; - await expect(configurator.initReserves(initInputParams)).to.be.reverted; - - initInputParams[0].variableDebtTokenImpl = variableDebtTokenImp.address; - expect(await configurator.initReserves(initInputParams)); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-flashloan.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-flashloan.spec.ts deleted file mode 100644 index a8154ae..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-flashloan.spec.ts +++ /dev/null @@ -1,695 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, ethers, Event, utils } from 'ethers'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver'; -import { ProtocolErrors } from '../helpers/types'; -import { - getMockFlashLoanReceiver, - getStableDebtToken, - getVariableDebtToken, -} from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; -import { waitForTx } from '@aave/deploy-v3'; - -makeSuite('Pool: FlashLoan', (testEnv: TestEnv) => { - let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; - - const { - COLLATERAL_BALANCE_IS_ZERO, - ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE, - INVALID_FLASHLOAN_EXECUTOR_RETURN, - } = ProtocolErrors; - - const TOTAL_PREMIUM = 9; - const PREMIUM_TO_PROTOCOL = 3000; - - before(async () => { - _mockFlashLoanReceiver = await getMockFlashLoanReceiver(); - }); - - it('Configurator sets total premium = 9 bps, premium to protocol = 30%', async () => { - const { configurator, pool } = testEnv; - await configurator.updateFlashloanPremiumTotal(TOTAL_PREMIUM); - await configurator.updateFlashloanPremiumToProtocol(PREMIUM_TO_PROTOCOL); - - expect(await pool.FLASHLOAN_PREMIUM_TOTAL()).to.be.equal(TOTAL_PREMIUM); - expect(await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()).to.be.equal(PREMIUM_TO_PROTOCOL); - }); - it('Deposits WETH into the reserve', async () => { - const { pool, weth, aave, dai } = testEnv; - const userAddress = await pool.signer.getAddress(); - const amountToDeposit = ethers.utils.parseEther('1'); - - await weth['mint(uint256)'](amountToDeposit); - - await weth.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(weth.address, amountToDeposit, userAddress, '0'); - - await aave['mint(uint256)'](amountToDeposit); - - await aave.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(aave.address, amountToDeposit, userAddress, '0'); - await dai['mint(uint256)'](amountToDeposit); - - await dai.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(dai.address, amountToDeposit, userAddress, '0'); - }); - - it('Takes WETH + Dai flash loan with mode = 0, returns the funds correctly', async () => { - const { pool, helpersContract, weth, aWETH, dai, aDai } = testEnv; - - const wethFlashBorrowedAmount = ethers.utils.parseEther('0.8'); - const daiFlashBorrowedAmount = ethers.utils.parseEther('0.3'); - const wethTotalFees = wethFlashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const wethFeesToProtocol = wethTotalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const wethFeesToLp = wethTotalFees.sub(wethFeesToProtocol); - const daiTotalFees = daiFlashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const daiFeesToProtocol = daiTotalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const daiFeesToLp = daiTotalFees.sub(daiFeesToProtocol); - - const wethLiquidityIndexAdded = wethFeesToLp - .mul(BigNumber.from(10).pow(27)) - .div(await aWETH.totalSupply()); - - const daiLiquidityIndexAdded = daiFeesToLp - .mul(ethers.BigNumber.from(10).pow(27)) - .div(await aDai.totalSupply()); - - let wethReserveData = await helpersContract.getReserveData(weth.address); - let daiReserveData = await helpersContract.getReserveData(dai.address); - - const wethLiquidityIndexBefore = wethReserveData.liquidityIndex; - const daiLiquidityIndexBefore = daiReserveData.liquidityIndex; - - const wethTotalLiquidityBefore = wethReserveData.totalAToken; - - const daiTotalLiquidityBefore = daiReserveData.totalAToken; - - const wethReservesBefore = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - const daiReservesBefore = await aDai.balanceOf(await aDai.RESERVE_TREASURY_ADDRESS()); - - const tx = await waitForTx( - await pool.flashLoan( - _mockFlashLoanReceiver.address, - [weth.address, dai.address], - [wethFlashBorrowedAmount, daiFlashBorrowedAmount], - [0, 0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ) - ); - - await pool.mintToTreasury([weth.address, dai.address]); - - wethReserveData = await helpersContract.getReserveData(weth.address); - daiReserveData = await helpersContract.getReserveData(dai.address); - - const wethCurrentLiquidityRate = wethReserveData.liquidityRate; - const wethCurrentLiquidityIndex = wethReserveData.liquidityIndex; - const daiCurrentLiquidityRate = daiReserveData.liquidityRate; - const daiCurrentLiquidityIndex = daiReserveData.liquidityIndex; - - const wethTotalLiquidityAfter = wethReserveData.totalAToken; - - const daiTotalLiquidityAfter = daiReserveData.totalAToken; - - const wethReservesAfter = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - const daiReservesAfter = await aDai.balanceOf(await aDai.RESERVE_TREASURY_ADDRESS()); - - expect(wethTotalLiquidityBefore.add(wethTotalFees)).to.be.closeTo(wethTotalLiquidityAfter, 2); - expect(wethCurrentLiquidityRate).to.be.equal(0); - expect(wethCurrentLiquidityIndex).to.be.equal( - wethLiquidityIndexBefore.add(wethLiquidityIndexAdded) - ); - expect(wethReservesAfter).to.be.equal(wethReservesBefore.add(wethFeesToProtocol)); - - expect(daiTotalLiquidityBefore.add(daiTotalFees)).to.be.closeTo(daiTotalLiquidityAfter, 2); - expect(daiCurrentLiquidityRate).to.be.equal(0); - expect(daiCurrentLiquidityIndex).to.be.equal( - daiLiquidityIndexBefore.add(daiLiquidityIndexAdded) - ); - expect(daiReservesAfter).to.be.equal(daiReservesBefore.add(daiFeesToProtocol)); - - // Check event values for `ReserveDataUpdated` - const reserveDataUpdatedEvents = tx.events?.filter( - ({ event }) => event === 'ReserveDataUpdated' - ) as Event[]; - for (const reserveDataUpdatedEvent of reserveDataUpdatedEvents) { - const reserveData = await helpersContract.getReserveData( - reserveDataUpdatedEvent.args?.reserve - ); - expect(reserveData.liquidityRate).to.be.eq(reserveDataUpdatedEvent.args?.liquidityRate); - expect(reserveData.stableBorrowRate).to.be.eq(reserveDataUpdatedEvent.args?.stableBorrowRate); - expect(reserveData.variableBorrowRate).to.be.eq( - reserveDataUpdatedEvent.args?.variableBorrowRate - ); - expect(reserveData.liquidityIndex).to.be.eq(reserveDataUpdatedEvent.args?.liquidityIndex); - expect(reserveData.variableBorrowIndex).to.be.eq( - reserveDataUpdatedEvent.args?.variableBorrowIndex - ); - } - }); - - it('Takes an authorized AAVE flash loan with mode = 0, returns the funds correctly', async () => { - const { - pool, - helpersContract, - aave, - aclManager, - users: [, , , authorizedUser], - } = testEnv; - - expect(await aclManager.addFlashBorrower(authorizedUser.address)); - - const flashBorrowedAmount = ethers.utils.parseEther('0.8'); - const totalFees = BigNumber.from(0); - - let reserveData = await helpersContract.getReserveData(aave.address); - - const totalLiquidityBefore = reserveData.totalAToken; - - await pool - .connect(authorizedUser.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [aave.address], - [flashBorrowedAmount], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ); - - await pool.mintToTreasury([aave.address]); - - reserveData = await helpersContract.getReserveData(aave.address); - - const totalLiquidityAfter = reserveData.totalAToken; - - expect(totalLiquidityBefore.add(totalFees)).to.be.closeTo(totalLiquidityAfter, 2); - }); - it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => { - const { pool, helpersContract, weth, aWETH, deployer } = testEnv; - - let reserveData = await helpersContract.getReserveData(weth.address); - - const totalLiquidityBefore = reserveData.totalAToken; - - const flashBorrowedAmount = totalLiquidityBefore; - - const totalFees = flashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const feesToProtocol = totalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const feesToLp = totalFees.sub(feesToProtocol); - const liquidityIndexBefore = reserveData.liquidityIndex; - const liquidityIndexAdded = feesToLp - .mul(BigNumber.from(10).pow(27)) - .div((await aWETH.totalSupply()).toString()) - .mul(liquidityIndexBefore) - .div(BigNumber.from(10).pow(27)); - - const reservesBefore = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - - expect( - await pool.flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashBorrowedAmount], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ) - ) - .to.emit(pool, 'FlashLoan') - .withArgs( - _mockFlashLoanReceiver.address, - deployer.address, - weth.address, - flashBorrowedAmount, - 0, - flashBorrowedAmount.mul(9).div(10000), - 0 - ); - await pool.mintToTreasury([weth.address]); - - reserveData = await helpersContract.getReserveData(weth.address); - - const currentLiquidityRate = reserveData.liquidityRate; - const currentLiquidityIndex = reserveData.liquidityIndex; - - const totalLiquidityAfter = reserveData.totalAToken; - - const reservesAfter = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - expect(totalLiquidityBefore.add(totalFees)).to.be.closeTo(totalLiquidityAfter, 2); - expect(currentLiquidityRate).to.be.equal(0); - expect(currentLiquidityIndex).to.be.equal(liquidityIndexBefore.add(liquidityIndexAdded)); - expect( - reservesAfter.sub(feesToProtocol).mul(liquidityIndexBefore).div(currentLiquidityIndex) - ).to.be.closeTo(reservesBefore, 2); - }); - it('Takes WETH flashloan, does not return the funds with mode = 0 (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [ethers.utils.parseEther('0.8')], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Takes WETH flashloan, simulating a receiver as EOA (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - await _mockFlashLoanReceiver.setSimulateEOA(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [ethers.utils.parseEther('0.8')], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.revertedWith(INVALID_FLASHLOAN_EXECUTOR_RETURN); - }); - - it('Takes a WETH flashloan with an invalid mode (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - await _mockFlashLoanReceiver.setSimulateEOA(false); - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [ethers.utils.parseEther('0.8')], - [4], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan with mode = 2, does not return the funds. A variable loan for caller is created', async () => { - const { dai, pool, weth, users, helpersContract } = testEnv; - - const caller = users[1]; - - await dai - .connect(caller.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - await dai.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - let reserveData = await helpersContract.getReserveData(weth.address); - - let totalLiquidityBefore = reserveData.totalAToken; - - const borrowAmount = ethers.utils.parseEther('0.0571'); - - expect( - await pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [borrowAmount], - [2], - caller.address, - '0x10', - '0' - ) - ) - .to.emit(pool, 'FlashLoan') - .withArgs( - _mockFlashLoanReceiver.address, - caller.address, - weth.address, - borrowAmount, - 2, - 0, - 0 - ); - - const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - weth.address - ); - reserveData = await helpersContract.getReserveData(weth.address); - - const totalLiquidityAfter = reserveData.totalAToken; - - expect(totalLiquidityAfter).to.be.closeTo(totalLiquidityBefore, 2); - - const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress); - const callerDebt = await wethDebtToken.balanceOf(caller.address); - - expect(callerDebt.toString()).to.be.equal('57100000000000000', 'Invalid user debt'); - // repays debt for later, so no interest accrue - await weth - .connect(caller.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(weth.address, '1000')); - await weth.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(caller.signer).repay(weth.address, MAX_UINT_AMOUNT, 2, caller.address); - }); - it('Tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - - await expect( - pool.connect(caller.signer).flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - ['1004415000000000000'], //slightly higher than the available liquidity - [2], - caller.address, - '0x10', - '0' - ), - ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE - ).to.be.reverted; - }); - - it('Tries to take a flashloan using a non contract address as receiver (revert expected)', async () => { - const { pool, deployer, weth, users } = testEnv; - const caller = users[1]; - - await expect( - pool.flashLoan( - deployer.address, - [weth.address], - ['1000000000000000000'], - [2], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Deposits USDC into the reserve', async () => { - const { usdc, pool } = testEnv; - const userAddress = await pool.signer.getAddress(); - - await usdc['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - await usdc.approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000'); - - await pool.deposit(usdc.address, amountToDeposit, userAddress, '0'); - }); - - it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => { - const { usdc, aUsdc, pool, helpersContract, deployer: depositor } = testEnv; - - await _mockFlashLoanReceiver.setFailExecutionTransfer(false); - - const flashBorrowedAmount = await convertToCurrencyDecimals(usdc.address, '500'); - const totalFees = flashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const feesToProtocol = totalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const feesToLp = totalFees.sub(feesToProtocol); - const liquidityIndexAdded = feesToLp - .mul(ethers.BigNumber.from(10).pow(27)) - .div(await aUsdc.totalSupply()); - - let reserveData = await helpersContract.getReserveData(usdc.address); - - const liquidityIndexBefore = reserveData.liquidityIndex; - - const totalLiquidityBefore = reserveData.totalAToken; - - const reservesBefore = await aUsdc.balanceOf(await aUsdc.RESERVE_TREASURY_ADDRESS()); - - await pool.flashLoan( - _mockFlashLoanReceiver.address, - [usdc.address], - [flashBorrowedAmount], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ); - - await pool.mintToTreasury([usdc.address]); - - reserveData = await helpersContract.getReserveData(usdc.address); - - const currentLiquidityRate = reserveData.liquidityRate; - const currentLiquidityIndex = reserveData.liquidityIndex; - - const totalLiquidityAfter = reserveData.totalAToken; - - const reservesAfter = await aUsdc.balanceOf(await aUsdc.RESERVE_TREASURY_ADDRESS()); - - expect(totalLiquidityBefore.add(totalFees)).to.be.closeTo(totalLiquidityAfter, 2); - expect(currentLiquidityRate).to.be.equal(0); - expect(currentLiquidityIndex).to.be.equal(liquidityIndexBefore.add(liquidityIndexAdded)); - expect(reservesAfter).to.be.equal(reservesBefore.add(feesToProtocol)); - }); - - it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds (revert expected)', async () => { - const { usdc, pool, users } = testEnv; - const caller = users[2]; - - const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [usdc.address], - [flashloanAmount], - [2], - caller.address, - '0x10', - '0' - ) - ).to.be.revertedWith(COLLATERAL_BALANCE_IS_ZERO); - }); - - it('Caller deposits 5 WETH as collateral, Takes a USDC flashloan with mode = 2, does not return the funds. A loan for caller is created', async () => { - const { usdc, pool, weth, users, helpersContract } = testEnv; - - const caller = users[2]; - - await weth - .connect(caller.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(weth.address, '5')); - - await weth.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(weth.address, '5'); - - await pool.connect(caller.signer).deposit(weth.address, amountToDeposit, caller.address, '0'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500'); - - await pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [usdc.address], - [flashloanAmount], - [2], - caller.address, - '0x10', - '0' - ); - const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - usdc.address - ); - - const usdcDebtToken = await getVariableDebtToken(variableDebtTokenAddress); - - const callerDebt = await usdcDebtToken.balanceOf(caller.address); - - expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt'); - }); - - it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => { - const { dai, pool, weth, users } = testEnv; - const caller = users[3]; - - await dai - .connect(caller.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - await dai.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0'); - - const flashAmount = ethers.utils.parseEther('0.8'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(false); - await _mockFlashLoanReceiver.setAmountToApprove(flashAmount.div(2)); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Caller takes a WETH flashloan with mode = 1', async () => { - const { pool, weth, users, helpersContract } = testEnv; - - const caller = users[3]; - - const flashAmount = ethers.utils.parseEther('0.0571'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - expect( - await pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [1], - caller.address, - '0x10', - '0' - ) - ) - .to.emit(pool, 'FlashLoan') - .withArgs(_mockFlashLoanReceiver.address, caller.address, weth.address, flashAmount, 1, 0, 0); - - const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - weth.address - ); - - const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress); - - const callerDebt = await wethDebtToken.balanceOf(caller.address); - - expect(callerDebt.toString()).to.be.equal('57100000000000000', 'Invalid user debt'); - }); - - it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user without allowance', async () => { - const { dai, pool, weth, users, helpersContract } = testEnv; - - const caller = users[5]; - const onBehalfOf = users[4]; - - // Deposit 1000 dai for onBehalfOf user - await dai - .connect(onBehalfOf.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - await dai.connect(onBehalfOf.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await pool - .connect(onBehalfOf.signer) - .deposit(dai.address, amountToDeposit, onBehalfOf.address, '0'); - - const flashAmount = ethers.utils.parseEther('0.0571'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [1], - onBehalfOf.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user with allowance. A loan for onBehalfOf is creatd.', async () => { - const { pool, weth, users, helpersContract } = testEnv; - - const caller = users[5]; - const onBehalfOf = users[4]; - - const flashAmount = ethers.utils.parseEther('0.0571'); - - const reserveData = await pool.getReserveData(weth.address); - - const stableDebtToken = await getStableDebtToken(reserveData.stableDebtTokenAddress); - - // Deposited for onBehalfOf user already, delegate borrow allowance - await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - await pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [1], - onBehalfOf.address, - '0x10', - '0' - ); - - const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - weth.address - ); - - const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress); - - const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address); - - expect(onBehalfOfDebt.toString()).to.be.equal( - '57100000000000000', - 'Invalid onBehalfOf user debt' - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-get-reserve-address-by-id.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-get-reserve-address-by-id.spec.ts deleted file mode 100644 index 9f918c1..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-get-reserve-address-by-id.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { expect } from 'chai'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { evmSnapshot, evmRevert, ZERO_ADDRESS } from '@aave/deploy-v3'; - -makeSuite('Pool: getReservesList', (testEnv: TestEnv) => { - let snap: string; - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - - afterEach(async () => { - await evmRevert(snap); - }); - - it('User gets address of reserve by id', async () => { - const { pool, usdc } = testEnv; - - const reserveData = await pool.getReserveData(usdc.address); - - const reserveAddress = await pool.getReserveAddressById(reserveData.id); - - await expect(reserveAddress).to.be.eq(usdc.address); - }); - - it('User calls `getReservesList` with a wrong id (id > reservesCount)', async () => { - const { pool } = testEnv; - - // MAX_NUMBER_RESERVES is always greater than reservesCount - const maxNumberOfReserves = await pool.MAX_NUMBER_RESERVES(); - const reserveAddress = await pool.getReserveAddressById(maxNumberOfReserves +1); - - await expect(reserveAddress).to.be.eq(ZERO_ADDRESS); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-l2.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-l2.spec.ts deleted file mode 100644 index 078f734..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-l2.spec.ts +++ /dev/null @@ -1,728 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, Signer, utils } from 'ethers'; -import { impersonateAccountsHardhat } from '../helpers/misc-utils'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { - evmSnapshot, - evmRevert, - DefaultReserveInterestRateStrategy__factory, - VariableDebtToken__factory, - increaseTime, - AaveDistributionManager, -} from '@aave/deploy-v3'; -import { - InitializableImmutableAdminUpgradeabilityProxy, - MockL2Pool__factory, - MockL2Pool, - L2Encoder, - L2Encoder__factory, -} from '../types'; -import { ethers, getChainId } from 'hardhat'; -import { - buildPermitParams, - getProxyImplementation, - getSignatureFromTypedData, -} from '../helpers/contracts-helpers'; -import { getTestWallets } from './helpers/utils/wallets'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { parseUnits } from 'ethers/lib/utils'; -import { getReserveData, getUserData } from './helpers/utils/helpers'; -import { calcExpectedStableDebtTokenBalance } from './helpers/utils/calculations'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('Pool: L2 functions', (testEnv: TestEnv) => { - const { - INVALID_HF, - NO_MORE_RESERVES_ALLOWED, - CALLER_NOT_ATOKEN, - NOT_CONTRACT, - CALLER_NOT_POOL_CONFIGURATOR, - RESERVE_ALREADY_INITIALIZED, - INVALID_ADDRESSES_PROVIDER, - RESERVE_ALREADY_ADDED, - DEBT_CEILING_NOT_ZERO, - ASSET_NOT_LISTED, - ZERO_ADDRESS_NOT_VALID, - } = ProtocolErrors; - - let l2Pool: MockL2Pool; - - const POOL_ID = utils.formatBytes32String('POOL'); - - let encoder: L2Encoder; - - before('Deploying L2Pool', async () => { - const { addressesProvider, poolAdmin, pool, deployer, oracle } = testEnv; - const { deployer: deployerName } = await hre.getNamedAccounts(); - - encoder = await (await new L2Encoder__factory(deployer.signer).deploy(pool.address)).deployed(); - - // Deploy the mock Pool with a `dropReserve` skipping the checks - const L2POOL_IMPL_ARTIFACT = await hre.deployments.deploy('MockL2Pool', { - contract: 'MockL2Pool', - from: deployerName, - args: [addressesProvider.address], - libraries: { - SupplyLogic: (await hre.deployments.get('SupplyLogic')).address, - BorrowLogic: (await hre.deployments.get('BorrowLogic')).address, - LiquidationLogic: (await hre.deployments.get('LiquidationLogic')).address, - EModeLogic: (await hre.deployments.get('EModeLogic')).address, - BridgeLogic: (await hre.deployments.get('BridgeLogic')).address, - FlashLoanLogic: (await hre.deployments.get('FlashLoanLogic')).address, - PoolLogic: (await hre.deployments.get('PoolLogic')).address, - }, - log: false, - }); - - const poolProxyAddress = await addressesProvider.getPool(); - const oldPoolImpl = await getProxyImplementation(addressesProvider.address, poolProxyAddress); - - // Upgrade the Pool - expect( - await addressesProvider.connect(poolAdmin.signer).setPoolImpl(L2POOL_IMPL_ARTIFACT.address) - ) - .to.emit(addressesProvider, 'PoolUpdated') - .withArgs(oldPoolImpl, L2POOL_IMPL_ARTIFACT.address); - - // Get the Pool instance - const poolAddress = await addressesProvider.getPool(); - l2Pool = await MockL2Pool__factory.connect(poolAddress, await getFirstSigner()); - expect(await addressesProvider.setPriceOracle(oracle.address)); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - expect(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - it('Supply', async () => { - const { - dai, - aDai, - users: [user0], - } = testEnv; - - const amount = utils.parseEther('100000'); - const referralCode = BigNumber.from(2); - - await dai.connect(user0.signer)['mint(uint256)'](amount); - await dai.connect(user0.signer).approve(l2Pool.address, amount); - - const encoded = await encoder.encodeSupplyParams(dai.address, amount, referralCode); - - expect(await l2Pool.connect(user0.signer)['supply(bytes32)'](encoded)) - .to.emit(l2Pool, 'Supply') - .withArgs(dai.address, user0.address, user0.address, amount, referralCode); - - const userBalance = await aDai.balanceOf(user0.address); - expect(userBalance).to.be.eq(amount, 'invalid amount deposited'); - }); - - it('Supply with permit test', async () => { - const { deployer, dai, aDai } = testEnv; - - const chainId = Number(await getChainId()); - const nonce = await dai.nonces(deployer.address); - const amount = utils.parseEther('10000'); - const highDeadline = '3000000000'; - const userPrivateKey = getTestWallets()[0].secretKey; - - const msgParams = buildPermitParams( - chainId, - dai.address, - '1', - await dai.symbol(), - deployer.address, - l2Pool.address, - nonce.toNumber(), - highDeadline, - amount.toString() - ); - const { v, r, s } = getSignatureFromTypedData(userPrivateKey, msgParams); - - await dai.connect(deployer.signer)['mint(uint256)'](amount); - const referralCode = BigNumber.from(2); - - const encoded = await encoder.encodeSupplyWithPermitParams( - dai.address, - amount, - referralCode, - highDeadline, - v, - r, - s - ); - - expect( - await l2Pool - .connect(deployer.signer) - ['supplyWithPermit(bytes32,bytes32,bytes32)'](encoded[0], r, s) - ) - .to.emit(l2Pool, 'Supply') - .withArgs(dai.address, deployer.address, deployer.address, amount, referralCode); - - const userBalance = await aDai.balanceOf(deployer.address); - expect(userBalance).to.be.eq(amount, 'invalid amount deposited'); - }); - - it('setUserUseReserveAsCollateral to false', async () => { - const { - dai, - aDai, - users: [user0], - helpersContract, - } = testEnv; - - const encoded = await encoder.encodeSetUserUseReserveAsCollateral(dai.address, false); - expect(await l2Pool.connect(user0.signer)['setUserUseReserveAsCollateral(bytes32)'](encoded)) - .to.emit(l2Pool, 'ReserveUsedAsCollateralDisabled') - .withArgs(dai.address, user0.address); - - const userData = await helpersContract.getUserReserveData(dai.address, user0.address); - expect(userData.usageAsCollateralEnabled).to.be.false; - }); - - it('setUserUseReserveAsCollateral to true', async () => { - const { - dai, - users: [user0], - helpersContract, - } = testEnv; - - const encoded = await encoder.encodeSetUserUseReserveAsCollateral(dai.address, true); - expect(await l2Pool.connect(user0.signer)['setUserUseReserveAsCollateral(bytes32)'](encoded)) - .to.emit(l2Pool, 'ReserveUsedAsCollateralEnabled') - .withArgs(dai.address, user0.address); - - const userData = await helpersContract.getUserReserveData(dai.address, user0.address); - expect(userData.usageAsCollateralEnabled).to.be.true; - }); - - it('Borrow', async () => { - const { - deployer, - usdc, - aUsdc, - users: [, user1], - helpersContract, - } = testEnv; - - const borrowAmount = parseUnits('100', 6); - const referralCode = BigNumber.from(16); - - expect(await usdc.balanceOf(deployer.address)).to.be.eq(0); - - await usdc.connect(user1.signer)['mint(uint256)'](borrowAmount.mul(10)); - await usdc.connect(user1.signer).approve(l2Pool.address, MAX_UINT_AMOUNT); - await l2Pool - .connect(user1.signer) - ['supply(address,uint256,address,uint16)']( - usdc.address, - borrowAmount.mul(10), - user1.address, - referralCode - ); - - const encoded = await encoder.encodeBorrowParams( - usdc.address, - borrowAmount, - RateMode.Variable, - referralCode - ); - - const data = await l2Pool.getReserveData(usdc.address); - const strat = await DefaultReserveInterestRateStrategy__factory.connect( - data.interestRateStrategyAddress, - deployer.signer - ); - - const { reserveFactor } = await helpersContract.getReserveConfigurationData(usdc.address); - - const [liqRate, sRate, varRate] = await strat.calculateInterestRates({ - unbacked: BigNumber.from(0), - liquidityAdded: BigNumber.from(0), - liquidityTaken: borrowAmount, - totalStableDebt: BigNumber.from(0), - totalVariableDebt: borrowAmount, - averageStableBorrowRate: BigNumber.from(0), - reserve: usdc.address, - aToken: aUsdc.address, - reserveFactor: reserveFactor, - }); - - expect(await l2Pool.connect(deployer.signer)['borrow(bytes32)'](encoded)) - .to.emit(l2Pool, 'Borrow') - .withArgs( - usdc.address, - deployer.address, - deployer.address, - borrowAmount, - Number(RateMode.Variable), - varRate, - referralCode - ); - - expect(await usdc.balanceOf(deployer.address)).to.be.eq(borrowAmount); - }); - - it('swapBorrowRateMode to stable', async () => { - const { deployer, dai, usdc, helpersContract } = testEnv; - const currentInterestRateMode = RateMode.Variable; - const encoded = await encoder.encodeSwapBorrowRateMode(usdc.address, currentInterestRateMode); - const userDataBefore = await helpersContract.getUserReserveData(usdc.address, deployer.address); - expect(userDataBefore.currentStableDebt).to.be.eq(0); - expect(userDataBefore.currentVariableDebt).to.be.gt(0); - - expect(await l2Pool.connect(deployer.signer)['swapBorrowRateMode(bytes32)'](encoded)) - .to.emit(l2Pool, 'SwapBorrowRateMode') - .withArgs(usdc.address, deployer.address, Number(currentInterestRateMode)); - - const userDataAfter = await helpersContract.getUserReserveData(usdc.address, deployer.address); - - expect(userDataAfter.currentStableDebt).to.be.gt(0); - expect(userDataAfter.currentVariableDebt).to.be.eq(0); - }); - - it('rebalanceStableBorrowRate (revert expected)', async () => { - // The test only checks that the value is translated properly, not that the underlying function is run correctly. - // see other rebalance tests for that - const { deployer, usdc } = testEnv; - const encoded = await encoder.encodeRebalanceStableBorrowRate(usdc.address, deployer.address); - await expect( - l2Pool.connect(deployer.signer)['rebalanceStableBorrowRate(bytes32)'](encoded) - ).to.be.revertedWith(ProtocolErrors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET); - }); - - it('swapBorrowRateMode to variable', async () => { - const { deployer, dai, usdc, helpersContract } = testEnv; - const currentInterestRateMode = RateMode.Stable; - const encoded = await encoder.encodeSwapBorrowRateMode(usdc.address, currentInterestRateMode); - const userDataBefore = await helpersContract.getUserReserveData(usdc.address, deployer.address); - expect(userDataBefore.currentStableDebt).to.be.gt(0); - expect(userDataBefore.currentVariableDebt).to.be.eq(0); - - expect(await l2Pool.connect(deployer.signer)['swapBorrowRateMode(bytes32)'](encoded)) - .to.emit(l2Pool, 'SwapBorrowRateMode') - .withArgs(usdc.address, deployer.address, Number(currentInterestRateMode)); - - const userDataAfter = await helpersContract.getUserReserveData(usdc.address, deployer.address); - expect(userDataAfter.currentStableDebt).to.be.eq(0); - expect(userDataAfter.currentVariableDebt).to.be.gt(0); - }); - - it('Repay some', async () => { - const { deployer, usdc } = testEnv; - - await usdc.connect(deployer.signer).approve(l2Pool.address, MAX_UINT_AMOUNT); - - const data = await l2Pool.getReserveData(usdc.address); - const vDebtToken = VariableDebtToken__factory.connect( - data.variableDebtTokenAddress, - deployer.signer - ); - - const debtBefore = await vDebtToken.balanceOf(deployer.address); - const balanceBefore = await usdc.balanceOf(deployer.address); - const repayAmount = parseUnits('50', 6); - - const encoded = await encoder.encodeRepayParams(usdc.address, repayAmount, RateMode.Variable); - - expect(await l2Pool.connect(deployer.signer)['repay(bytes32)'](encoded)) - .to.emit(l2Pool, 'Repay') - .withArgs(usdc.address, deployer.address, deployer.address, repayAmount, false); - - const userDebt = await vDebtToken.balanceOf(deployer.address); - expect(userDebt).to.be.eq(debtBefore.sub(repayAmount), 'invalid amount repaid'); - const userBalance = await usdc.balanceOf(deployer.address); - expect(userBalance).to.be.eq(balanceBefore.sub(repayAmount), 'invalid amount repaid'); - }); - - it('Repay some with aTokens', async () => { - const { - deployer, - usdc, - aUsdc, - users: [, user1], - } = testEnv; - - await usdc.connect(deployer.signer).approve(l2Pool.address, MAX_UINT_AMOUNT); - - const data = await l2Pool.getReserveData(usdc.address); - const vDebtToken = VariableDebtToken__factory.connect( - data.variableDebtTokenAddress, - deployer.signer - ); - - const repayAmount = parseUnits('10', 6); - expect(await aUsdc.connect(user1.signer).transfer(deployer.address, repayAmount)); - - const balanceBefore = await usdc.balanceOf(deployer.address); - const debtBefore = await vDebtToken.balanceOf(deployer.address); - - const encoded = await encoder.encodeRepayWithATokensParams( - usdc.address, - repayAmount, - RateMode.Variable - ); - - expect(await l2Pool.connect(deployer.signer)['repayWithATokens(bytes32)'](encoded)) - .to.emit(l2Pool, 'Repay') - .withArgs(usdc.address, deployer.address, deployer.address, repayAmount, true); - - const userDebt = await vDebtToken.balanceOf(deployer.address); - const userBalance = await usdc.balanceOf(deployer.address); - const userABalance = await aUsdc.balanceOf(deployer.address); - expect(userDebt).to.be.eq(debtBefore.sub(repayAmount), 'invalid amount repaid'); - expect(userBalance).to.be.eq(balanceBefore, 'user balance changed'); - expect(userABalance).to.be.eq(0, 'invalid amount repaid'); - }); - - it('Repay remainder with permit', async () => { - const { deployer, usdc } = testEnv; - - const data = await l2Pool.getReserveData(usdc.address); - const vDebtToken = VariableDebtToken__factory.connect( - data.variableDebtTokenAddress, - deployer.signer - ); - - const debtBefore = await vDebtToken.balanceOf(deployer.address); - - const chainId = Number(await getChainId()); - const nonce = await usdc.nonces(deployer.address); - const amount = MAX_UINT_AMOUNT; - const highDeadline = '3000000000'; - const userPrivateKey = getTestWallets()[0].secretKey; - - const msgParams = buildPermitParams( - chainId, - usdc.address, - '1', - await usdc.symbol(), - deployer.address, - l2Pool.address, - nonce.toNumber(), - highDeadline, - amount.toString() - ); - const { v, r, s } = getSignatureFromTypedData(userPrivateKey, msgParams); - - await usdc.connect(deployer.signer)['mint(uint256)'](debtBefore.mul(10)); - await usdc.connect(deployer.signer).approve(l2Pool.address, MAX_UINT_AMOUNT); - - const encoded = await encoder.encodeRepayWithPermitParams( - usdc.address, - amount, - RateMode.Variable, - highDeadline, - v, - r, - s - ); - - expect( - await l2Pool - .connect(deployer.signer) - ['repayWithPermit(bytes32,bytes32,bytes32)'](encoded[0], r, s) - ) - .to.emit(l2Pool, 'Repay') - .withArgs(usdc.address, deployer.address, deployer.address, debtBefore, false); - - const userBalance = await vDebtToken.balanceOf(deployer.address); - expect(userBalance).to.be.eq(0, 'invalid amount repaid'); - }); - - it('Withdraw some', async () => { - const { - dai, - aDai, - users: [user0], - } = testEnv; - - const amount = utils.parseEther('0.5'); - const encoded = await encoder.encodeWithdrawParams(dai.address, amount); - const balanceBefore = await aDai.balanceOf(user0.address); - - expect(await l2Pool.connect(user0.signer)['withdraw(bytes32)'](encoded)) - .to.emit(l2Pool, 'Withdraw') - .withArgs(dai.address, user0.address, user0.address, amount); - - const userBalance = await aDai.balanceOf(user0.address); - expect(userBalance).to.be.eq(balanceBefore.sub(amount), 'invalid amount withdrawn'); - }); - - it('Withdraw remainder', async () => { - const { - dai, - aDai, - users: [user0], - } = testEnv; - - const amount = MAX_UINT_AMOUNT; - const encoded = await encoder.encodeWithdrawParams(dai.address, amount); - const balanceBefore = await aDai.balanceOf(user0.address); - - expect(await l2Pool.connect(user0.signer)['withdraw(bytes32)'](encoded)) - .to.emit(l2Pool, 'Withdraw') - .withArgs(dai.address, user0.address, user0.address, balanceBefore); - - const userBalance = await aDai.balanceOf(user0.address); - expect(userBalance).to.be.eq(0, 'invalid amount withdrawn'); - }); - - it('liquidationCall', async () => { - const { - dai, - usdc, - users: [depositor, borrower, liquidator], - oracle, - pool, - helpersContract, - } = testEnv; - - //mints DAI to depositor - const amountDAItoDeposit = parseUnits('5000', 18); - await dai.connect(depositor.signer)['mint(uint256)'](amountDAItoDeposit); - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(depositor.signer) - .deposit(dai.address, amountDAItoDeposit, depositor.address, '0'); - - //user 2 deposits usdc - const amountUSDCtoDeposit = parseUnits('1000', 6); - await usdc.connect(borrower.signer)['mint(uint256)'](parseUnits('1000', 6)); - await usdc.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(borrower.signer) - .deposit(usdc.address, amountUSDCtoDeposit, borrower.address, '0'); - - const userGlobalData = await pool.getUserAccountData(borrower.address); - const daiPrice = await oracle.getAssetPrice(dai.address); - - const amountDAIToBorrow = userGlobalData.availableBorrowsBase - .mul(9500) - .div(10000) - .div(daiPrice) - .mul(BigNumber.from(10).pow(18)); - - await pool - .connect(borrower.signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - expect(userGlobalDataAfter.currentLiquidationThreshold).to.be.equal(8500, INVALID_HF); - - // Increases price - await oracle.setAssetPrice(dai.address, daiPrice.mul(2)); - const userGlobalDataPriceChange = await pool.getUserAccountData(borrower.address); - expect(userGlobalDataPriceChange.healthFactor).to.be.lt(parseUnits('1', 18), INVALID_HF); - - //mints dai to the liquidator - await dai.connect(liquidator.signer)['mint(uint256)'](parseUnits('1000', 18)); - - //approve protocol to access the liquidator wallet - await dai.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); - const usdcReserveDataBefore = await getReserveData(helpersContract, usdc.address); - - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2); - - await increaseTime(100); - - const encoded = await encoder.encodeLiquidationCall( - usdc.address, - dai.address, - borrower.address, - amountToLiquidate, - false - ); - - const tx = await l2Pool - .connect(liquidator.signer) - ['liquidationCall(bytes32,bytes32)'](encoded[0], encoded[1]); - - const userReserveDataAfter = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const daiReserveDataAfter = await getReserveData(helpersContract, dai.address); - const usdcReserveDataAfter = await getReserveData(helpersContract, usdc.address); - - const collateralPrice = await oracle.getAssetPrice(usdc.address); - const principalPrice = await oracle.getAssetPrice(dai.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(usdc.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(dai.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(amountToLiquidate) - .percentMul(10500) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - if (!tx.blockNumber) { - expect(false, 'Invalid block number'); - return; - } - const txTimestamp = BigNumber.from( - (await hre.ethers.provider.getBlock(tx.blockNumber)).timestamp - ); - - const stableDebtBeforeTx = calcExpectedStableDebtTokenBalance( - userReserveDataBefore.principalStableDebt, - userReserveDataBefore.stableBorrowRate, - userReserveDataBefore.stableRateLastUpdated, - txTimestamp - ); - - expect(userReserveDataAfter.currentStableDebt).to.be.closeTo( - stableDebtBeforeTx.sub(amountToLiquidate), - 2, - 'Invalid user debt after liquidation' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(daiReserveDataAfter.liquidityIndex).to.be.gte( - daiReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(daiReserveDataAfter.liquidityRate).to.be.lt( - daiReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(daiReserveDataAfter.totalLiquidity).to.be.closeTo( - daiReserveDataBefore.totalLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal total liquidity' - ); - - expect(usdcReserveDataAfter.totalLiquidity).to.be.closeTo( - usdcReserveDataBefore.totalLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral total liquidity' - ); - - expect(daiReserveDataAfter.availableLiquidity).to.be.closeTo( - daiReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - expect(usdcReserveDataAfter.availableLiquidity).to.be.closeTo( - usdcReserveDataBefore.availableLiquidity.sub(expectedCollateralLiquidated), - 2, - 'Invalid collateral available liquidity' - ); - await oracle.setAssetPrice(dai.address, daiPrice); - }); - - it('liquidationCall max value', async () => { - const { - dai, - aUsdc, - usdc, - users: [depositor, borrower, liquidator], - oracle, - pool, - helpersContract, - } = testEnv; - - //mints DAI to depositor - const amountDAItoDeposit = parseUnits('5000', 18); - await dai.connect(depositor.signer)['mint(uint256)'](amountDAItoDeposit); - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(depositor.signer) - .deposit(dai.address, amountDAItoDeposit, depositor.address, '0'); - - //user 2 deposits usdc - const amountUSDCtoDeposit = parseUnits('1000', 6); - await usdc.connect(borrower.signer)['mint(uint256)'](parseUnits('1000', 6)); - await usdc.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(borrower.signer) - .deposit(usdc.address, amountUSDCtoDeposit, borrower.address, '0'); - - const userGlobalData = await pool.getUserAccountData(borrower.address); - const daiPrice = await oracle.getAssetPrice(dai.address); - - const amountDAIToBorrow = userGlobalData.availableBorrowsBase - .mul(9500) - .div(10000) - .div(daiPrice) - .mul(BigNumber.from(10).pow(18)); - - await pool - .connect(borrower.signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Stable, '0', borrower.address); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - expect(userGlobalDataAfter.currentLiquidationThreshold).to.be.equal(8500, INVALID_HF); - - // Increase price - await oracle.setAssetPrice(dai.address, daiPrice.mul(2)); - const userGlobalDataPriceChange = await pool.getUserAccountData(borrower.address); - expect(userGlobalDataPriceChange.healthFactor).to.be.lt(parseUnits('1', 18), INVALID_HF); - - //mints dai to the liquidator - await dai.connect(liquidator.signer)['mint(uint256)'](parseUnits('1000', 18)); - - //approve protocol to access the liquidator wallet - await dai.connect(liquidator.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const encoded = await encoder.encodeLiquidationCall( - usdc.address, - dai.address, - borrower.address, - MAX_UINT_AMOUNT, - true - ); - - const liquidatorAUSDCBefore = await aUsdc.balanceOf(liquidator.address); - - const tx = await l2Pool - .connect(liquidator.signer) - ['liquidationCall(bytes32,bytes32)'](encoded[0], encoded[1]); - - const userReserveDataAfter = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - expect(await aUsdc.balanceOf(liquidator.address)).to.be.gt(liquidatorAUSDCBefore); - expect( - userReserveDataAfter.currentStableDebt.add(userReserveDataAfter.currentVariableDebt) - ).to.be.lt( - userReserveDataBefore.currentStableDebt.add(userReserveDataBefore.currentVariableDebt) - ); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-normal-flashloan.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-normal-flashloan.spec.ts deleted file mode 100644 index e054058..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-normal-flashloan.spec.ts +++ /dev/null @@ -1,349 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, ethers } from 'ethers'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { MockFlashLoanReceiver } from '../types/MockFlashLoanReceiver'; -import { ProtocolErrors } from '../helpers/types'; -import { - getMockFlashLoanReceiver, - getStableDebtToken, - getVariableDebtToken, -} from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; - -makeSuite('Pool: FlashLoan for gas comparison', (testEnv: TestEnv) => { - let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; - - const { ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE, INVALID_FLASHLOAN_EXECUTOR_RETURN } = - ProtocolErrors; - - const TOTAL_PREMIUM = 9; - const PREMIUM_TO_PROTOCOL = 3000; - - before(async () => { - _mockFlashLoanReceiver = await getMockFlashLoanReceiver(); - }); - - it('Configurator sets total premium = 9 bps, premium to protocol = 30%', async () => { - const { configurator, pool } = testEnv; - await configurator.updateFlashloanPremiumTotal(TOTAL_PREMIUM); - await configurator.updateFlashloanPremiumToProtocol(PREMIUM_TO_PROTOCOL); - - expect(await pool.FLASHLOAN_PREMIUM_TOTAL()).to.be.equal(TOTAL_PREMIUM); - expect(await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()).to.be.equal(PREMIUM_TO_PROTOCOL); - }); - it('Deposits WETH into the reserve', async () => { - const { pool, weth, aave, dai } = testEnv; - const userAddress = await pool.signer.getAddress(); - const amountToDeposit = ethers.utils.parseEther('1'); - - await weth['mint(uint256)'](amountToDeposit); - - await weth.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(weth.address, amountToDeposit, userAddress, '0'); - - await aave['mint(uint256)'](amountToDeposit); - - await aave.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(aave.address, amountToDeposit, userAddress, '0'); - await dai['mint(uint256)'](amountToDeposit); - - await dai.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(dai.address, amountToDeposit, userAddress, '0'); - }); - - it('Takes WETH flash loan with mode = 0, returns the funds correctly', async () => { - const { pool, helpersContract, weth, aWETH, dai, aDai } = testEnv; - - const wethFlashBorrowedAmount = ethers.utils.parseEther('0.8'); - const wethTotalFees = wethFlashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const wethFeesToProtocol = wethTotalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const wethFeesToLp = wethTotalFees.sub(wethFeesToProtocol); - - const wethLiquidityIndexAdded = wethFeesToLp - .mul(BigNumber.from(10).pow(27)) - .div(await aWETH.totalSupply()); - - let wethReserveData = await helpersContract.getReserveData(weth.address); - - const wethLiquidityIndexBefore = wethReserveData.liquidityIndex; - - const wethTotalLiquidityBefore = wethReserveData.totalAToken; - - const wethReservesBefore = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - - await pool.flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [wethFlashBorrowedAmount], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ); - - await pool.mintToTreasury([weth.address, dai.address]); - - wethReserveData = await helpersContract.getReserveData(weth.address); - - const wethCurrentLiquidityRate = wethReserveData.liquidityRate; - const wethCurrentLiquidityIndex = wethReserveData.liquidityIndex; - - const wethTotalLiquidityAfter = wethReserveData.totalAToken; - - const wethReservesAfter = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - - expect(wethTotalLiquidityBefore.add(wethTotalFees)).to.be.closeTo(wethTotalLiquidityAfter, 2); - expect(wethCurrentLiquidityRate).to.be.equal(0); - expect(wethCurrentLiquidityIndex).to.be.equal( - wethLiquidityIndexBefore.add(wethLiquidityIndexAdded) - ); - expect(wethReservesAfter).to.be.equal(wethReservesBefore.add(wethFeesToProtocol)); - }); - - it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => { - const { pool, helpersContract, weth, aWETH } = testEnv; - - let reserveData = await helpersContract.getReserveData(weth.address); - - const totalLiquidityBefore = reserveData.totalAToken; - - const flashBorrowedAmount = totalLiquidityBefore; - - const totalFees = flashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const feesToProtocol = totalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const feesToLp = totalFees.sub(feesToProtocol); - const liquidityIndexBefore = reserveData.liquidityIndex; - const liquidityIndexAdded = feesToLp - .mul(BigNumber.from(10).pow(27)) - .div((await aWETH.totalSupply()).toString()) - .mul(liquidityIndexBefore) - .div(BigNumber.from(10).pow(27)); - - const reservesBefore = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - - const txResult = await pool.flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashBorrowedAmount], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ); - - await pool.mintToTreasury([weth.address]); - - reserveData = await helpersContract.getReserveData(weth.address); - - const currentLiquidityRate = reserveData.liquidityRate; - const currentLiquidityIndex = reserveData.liquidityIndex; - - const totalLiquidityAfter = reserveData.totalAToken; - - const reservesAfter = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - expect(totalLiquidityBefore.add(totalFees)).to.be.closeTo(totalLiquidityAfter, 2); - expect(currentLiquidityRate).to.be.equal(0); - expect(currentLiquidityIndex).to.be.equal(liquidityIndexBefore.add(liquidityIndexAdded)); - expect( - reservesAfter.sub(feesToProtocol).mul(liquidityIndexBefore).div(currentLiquidityIndex) - ).to.be.closeTo(reservesBefore, 2); - }); - it('Takes WETH flashloan, does not return the funds with mode = 0 (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [ethers.utils.parseEther('0.8')], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Takes WETH flashloan, simulating a receiver as EOA (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - await _mockFlashLoanReceiver.setSimulateEOA(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [ethers.utils.parseEther('0.8')], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.revertedWith(INVALID_FLASHLOAN_EXECUTOR_RETURN); - }); - - it('Tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - - await expect( - pool.connect(caller.signer).flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - ['1004415000000000000'], //slightly higher than the available liquidity - [2], - caller.address, - '0x10', - '0' - ), - ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE - ).to.be.reverted; - }); - - it('Tries to take a flashloan using a non contract address as receiver (revert expected)', async () => { - const { pool, deployer, weth, users } = testEnv; - const caller = users[1]; - - await expect( - pool.flashLoan( - deployer.address, - [weth.address], - ['1000000000000000000'], - [2], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Deposits USDC into the reserve', async () => { - const { usdc, pool } = testEnv; - const userAddress = await pool.signer.getAddress(); - - await usdc['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - await usdc.approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000'); - - await pool.deposit(usdc.address, amountToDeposit, userAddress, '0'); - }); - - it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => { - const { usdc, aUsdc, pool, helpersContract, deployer: depositor } = testEnv; - - await _mockFlashLoanReceiver.setFailExecutionTransfer(false); - - const flashBorrowedAmount = await convertToCurrencyDecimals(usdc.address, '500'); - const totalFees = flashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const feesToProtocol = totalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const feesToLp = totalFees.sub(feesToProtocol); - const liquidityIndexAdded = feesToLp - .mul(ethers.BigNumber.from(10).pow(27)) - .div(await aUsdc.totalSupply()); - - let reserveData = await helpersContract.getReserveData(usdc.address); - - const liquidityIndexBefore = reserveData.liquidityIndex; - - const totalLiquidityBefore = reserveData.totalAToken; - - const reservesBefore = await aUsdc.balanceOf(await aUsdc.RESERVE_TREASURY_ADDRESS()); - - await pool.flashLoan( - _mockFlashLoanReceiver.address, - [usdc.address], - [flashBorrowedAmount], - [0], - _mockFlashLoanReceiver.address, - '0x10', - '0' - ); - - await pool.mintToTreasury([usdc.address]); - - reserveData = await helpersContract.getReserveData(usdc.address); - - const currentLiquidityRate = reserveData.liquidityRate; - const currentLiquidityIndex = reserveData.liquidityIndex; - - const totalLiquidityAfter = reserveData.totalAToken; - - const reservesAfter = await aUsdc.balanceOf(await aUsdc.RESERVE_TREASURY_ADDRESS()); - - expect(totalLiquidityBefore.add(totalFees)).to.be.closeTo(totalLiquidityAfter, 2); - expect(currentLiquidityRate).to.be.equal(0); - expect(currentLiquidityIndex).to.be.equal(liquidityIndexBefore.add(liquidityIndexAdded)); - expect(reservesAfter).to.be.equal(reservesBefore.add(feesToProtocol)); - }); - - it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds (revert expected)', async () => { - const { usdc, pool, users } = testEnv; - const caller = users[2]; - - const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(true); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [usdc.address], - [flashloanAmount], - [2], - caller.address, - '0x10', - '0' - ) - ).to.be.revertedWith(INVALID_FLASHLOAN_EXECUTOR_RETURN); - }); - - it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => { - const { dai, pool, weth, users } = testEnv; - const caller = users[3]; - - await dai - .connect(caller.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - await dai.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0'); - - const flashAmount = ethers.utils.parseEther('0.8'); - - await _mockFlashLoanReceiver.setFailExecutionTransfer(false); - await _mockFlashLoanReceiver.setAmountToApprove(flashAmount.div(2)); - - await expect( - pool - .connect(caller.signer) - .flashLoan( - _mockFlashLoanReceiver.address, - [weth.address], - [flashAmount], - [0], - caller.address, - '0x10', - '0' - ) - ).to.be.reverted; - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-simple-flashloan.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-simple-flashloan.spec.ts deleted file mode 100644 index a198d8e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/pool-simple-flashloan.spec.ts +++ /dev/null @@ -1,406 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, ethers, Event } from 'ethers'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { ProtocolErrors } from '../helpers/types'; -import { TestEnv, makeSuite } from './helpers/make-suite'; - -import './helpers/utils/wadraymath'; -import { - MockFlashLoanSimpleReceiver, - MockFlashLoanSimpleReceiver__factory, - FlashloanAttacker__factory, - IERC20Detailed__factory, -} from '../types'; -import { parseEther, parseUnits } from '@ethersproject/units'; -import { waitForTx } from '@aave/deploy-v3'; - -makeSuite('Pool: Simple FlashLoan', (testEnv: TestEnv) => { - let _mockFlashLoanSimpleReceiver = {} as MockFlashLoanSimpleReceiver; - - const { ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE, INVALID_FLASHLOAN_EXECUTOR_RETURN } = - ProtocolErrors; - const TOTAL_PREMIUM = 9; - const PREMIUM_TO_PROTOCOL = 3000; - - before(async () => { - const { addressesProvider, deployer } = testEnv; - - _mockFlashLoanSimpleReceiver = await new MockFlashLoanSimpleReceiver__factory( - deployer.signer - ).deploy(addressesProvider.address); - }); - - it('Configurator sets total premium = 9 bps, premium to protocol = 30%', async () => { - const { configurator, pool } = testEnv; - await configurator.updateFlashloanPremiumTotal(TOTAL_PREMIUM); - await configurator.updateFlashloanPremiumToProtocol(PREMIUM_TO_PROTOCOL); - - expect(await pool.FLASHLOAN_PREMIUM_TOTAL()).to.be.equal(TOTAL_PREMIUM); - expect(await pool.FLASHLOAN_PREMIUM_TO_PROTOCOL()).to.be.equal(PREMIUM_TO_PROTOCOL); - }); - - it('Deposits WETH into the reserve', async () => { - const { pool, weth, aave, dai } = testEnv; - const userAddress = await pool.signer.getAddress(); - const amountToDeposit = ethers.utils.parseEther('1'); - - await weth['mint(uint256)'](amountToDeposit); - - await weth.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(weth.address, amountToDeposit, userAddress, '0'); - - await aave['mint(uint256)'](amountToDeposit); - - await aave.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(aave.address, amountToDeposit, userAddress, '0'); - await dai['mint(uint256)'](amountToDeposit); - - await dai.approve(pool.address, MAX_UINT_AMOUNT); - - await pool.deposit(dai.address, amountToDeposit, userAddress, '0'); - }); - - it('Takes simple WETH flash loan and returns the funds correctly', async () => { - const { pool, helpersContract, weth, aWETH } = testEnv; - - const wethFlashBorrowedAmount = ethers.utils.parseEther('0.8'); - const wethTotalFees = wethFlashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const wethFeesToProtocol = wethTotalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const wethFeesToLp = wethTotalFees.sub(wethFeesToProtocol); - - const wethLiquidityIndexAdded = wethFeesToLp - .mul(BigNumber.from(10).pow(27)) - .div(await aWETH.totalSupply()); - - let wethReserveData = await helpersContract.getReserveData(weth.address); - - const wethLiquidityIndexBefore = wethReserveData.liquidityIndex; - - const wethTotalLiquidityBefore = wethReserveData.totalAToken; - - const wethReservesBefore = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - - const tx = await waitForTx( - await pool.flashLoanSimple( - _mockFlashLoanSimpleReceiver.address, - weth.address, - wethFlashBorrowedAmount, - '0x10', - '0' - ) - ); - - await pool.mintToTreasury([weth.address]); - - wethReserveData = await helpersContract.getReserveData(weth.address); - - const wethCurrentLiquidityRate = wethReserveData.liquidityRate; - const wethCurrentLiquidityIndex = wethReserveData.liquidityIndex; - - const wethTotalLiquidityAfter = wethReserveData.totalAToken; - - const wethReservesAfter = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - - expect(wethTotalLiquidityBefore.add(wethTotalFees)).to.be.closeTo(wethTotalLiquidityAfter, 2); - expect(wethCurrentLiquidityRate).to.be.equal(0); - expect(wethCurrentLiquidityIndex).to.be.equal( - wethLiquidityIndexBefore.add(wethLiquidityIndexAdded) - ); - expect(wethReservesAfter).to.be.equal(wethReservesBefore.add(wethFeesToProtocol)); - - // Check event values for `ReserveDataUpdated` - const reserveDataUpdatedEvents = tx.events?.filter( - ({ event }) => event === 'ReserveDataUpdated' - ) as Event[]; - for (const reserveDataUpdatedEvent of reserveDataUpdatedEvents) { - const reserveData = await helpersContract.getReserveData( - reserveDataUpdatedEvent.args?.reserve - ); - expect(reserveData.liquidityRate).to.be.eq(reserveDataUpdatedEvent.args?.liquidityRate); - expect(reserveData.stableBorrowRate).to.be.eq(reserveDataUpdatedEvent.args?.stableBorrowRate); - expect(reserveData.variableBorrowRate).to.be.eq( - reserveDataUpdatedEvent.args?.variableBorrowRate - ); - expect(reserveData.liquidityIndex).to.be.eq(reserveDataUpdatedEvent.args?.liquidityIndex); - expect(reserveData.variableBorrowIndex).to.be.eq( - reserveDataUpdatedEvent.args?.variableBorrowIndex - ); - } - }); - - it('Takes a simple ETH flashloan as big as the available liquidity', async () => { - const { pool, helpersContract, weth, aWETH } = testEnv; - - let reserveData = await helpersContract.getReserveData(weth.address); - - const totalLiquidityBefore = reserveData.totalAToken; - - const flashBorrowedAmount = totalLiquidityBefore; - - const totalFees = flashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const feesToProtocol = totalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const feesToLp = totalFees.sub(feesToProtocol); - const liquidityIndexBefore = reserveData.liquidityIndex; - const liquidityIndexAdded = feesToLp - .mul(BigNumber.from(10).pow(27)) - .div((await aWETH.totalSupply()).toString()) - .mul(liquidityIndexBefore) - .div(BigNumber.from(10).pow(27)); - - const reservesBefore = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - - const txResult = await pool.flashLoanSimple( - _mockFlashLoanSimpleReceiver.address, - weth.address, - flashBorrowedAmount, - '0x10', - '0' - ); - - await pool.mintToTreasury([weth.address]); - - reserveData = await helpersContract.getReserveData(weth.address); - - const currentLiquidityRate = reserveData.liquidityRate; - const currentLiquidityIndex = reserveData.liquidityIndex; - - const totalLiquidityAfter = reserveData.totalAToken; - - const reservesAfter = await aWETH.balanceOf(await aWETH.RESERVE_TREASURY_ADDRESS()); - expect(totalLiquidityBefore.add(totalFees)).to.be.closeTo(totalLiquidityAfter, 2); - expect(currentLiquidityRate).to.be.equal(0); - expect(currentLiquidityIndex).to.be.equal(liquidityIndexBefore.add(liquidityIndexAdded)); - expect( - reservesAfter.sub(feesToProtocol).mul(liquidityIndexBefore).div(currentLiquidityIndex) - ).to.be.equal(reservesBefore); - }); - - it('Takes WETH flashloan, does not return the funds (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - await _mockFlashLoanSimpleReceiver.setFailExecutionTransfer(true); - - await expect( - pool - .connect(caller.signer) - .flashLoanSimple( - _mockFlashLoanSimpleReceiver.address, - weth.address, - ethers.utils.parseEther('0.8'), - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Takes WETH flashloan, simulating a receiver as EOA (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - await _mockFlashLoanSimpleReceiver.setFailExecutionTransfer(true); - await _mockFlashLoanSimpleReceiver.setSimulateEOA(true); - - await expect( - pool - .connect(caller.signer) - .flashLoanSimple( - _mockFlashLoanSimpleReceiver.address, - weth.address, - ethers.utils.parseEther('0.8'), - '0x10', - '0' - ) - ).to.be.revertedWith(INVALID_FLASHLOAN_EXECUTOR_RETURN); - }); - - it('Tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => { - const { pool, weth, users } = testEnv; - const caller = users[1]; - - await expect( - pool.connect(caller.signer).flashLoanSimple( - _mockFlashLoanSimpleReceiver.address, - weth.address, - '1004415000000000000', //slightly higher than the available liquidity - '0x10', - '0' - ), - ERC20_TRANSFER_AMOUNT_EXCEEDS_BALANCE - ).to.be.reverted; - }); - - it('Tries to take a flashloan using a non contract address as receiver (revert expected)', async () => { - const { pool, deployer, weth, users } = testEnv; - const caller = users[1]; - - await expect( - pool.flashLoanSimple(deployer.address, weth.address, '1000000000000000000', '0x10', '0') - ).to.be.reverted; - }); - - it('Deposits USDC into the reserve', async () => { - const { usdc, pool } = testEnv; - const userAddress = await pool.signer.getAddress(); - - await usdc['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '1000')); - - await usdc.approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000'); - - await pool.deposit(usdc.address, amountToDeposit, userAddress, '0'); - }); - - it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => { - const { usdc, aUsdc, pool, helpersContract, deployer: depositor } = testEnv; - - await _mockFlashLoanSimpleReceiver.setFailExecutionTransfer(false); - - const flashBorrowedAmount = await convertToCurrencyDecimals(usdc.address, '500'); - const totalFees = flashBorrowedAmount.mul(TOTAL_PREMIUM).div(10000); - const feesToProtocol = totalFees.mul(PREMIUM_TO_PROTOCOL).div(10000); - const feesToLp = totalFees.sub(feesToProtocol); - const liquidityIndexAdded = feesToLp - .mul(ethers.BigNumber.from(10).pow(27)) - .div(await aUsdc.totalSupply()); - - let reserveData = await helpersContract.getReserveData(usdc.address); - - const liquidityIndexBefore = reserveData.liquidityIndex; - - const totalLiquidityBefore = reserveData.totalAToken; - - const reservesBefore = await aUsdc.balanceOf(await aUsdc.RESERVE_TREASURY_ADDRESS()); - - await pool.flashLoanSimple( - _mockFlashLoanSimpleReceiver.address, - usdc.address, - flashBorrowedAmount, - '0x10', - '0' - ); - - await pool.mintToTreasury([usdc.address]); - - reserveData = await helpersContract.getReserveData(usdc.address); - - const currentLiquidityRate = reserveData.liquidityRate; - const currentLiquidityIndex = reserveData.liquidityIndex; - - const totalLiquidityAfter = reserveData.totalAToken; - - const reservesAfter = await aUsdc.balanceOf(await aUsdc.RESERVE_TREASURY_ADDRESS()); - - expect(totalLiquidityBefore.add(totalFees)).to.be.closeTo(totalLiquidityAfter, 2); - expect(currentLiquidityRate).to.be.equal(0); - expect(currentLiquidityIndex).to.be.equal(liquidityIndexBefore.add(liquidityIndexAdded)); - expect(reservesAfter).to.be.equal(reservesBefore.add(feesToProtocol)); - }); - - it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds (revert expected)', async () => { - const { usdc, pool, users } = testEnv; - const caller = users[2]; - - const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500'); - - await _mockFlashLoanSimpleReceiver.setFailExecutionTransfer(true); - - await expect( - pool - .connect(caller.signer) - .flashLoanSimple( - _mockFlashLoanSimpleReceiver.address, - usdc.address, - flashloanAmount, - '0x10', - '0' - ) - ).to.be.revertedWith(INVALID_FLASHLOAN_EXECUTOR_RETURN); - }); - - it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => { - const { dai, pool, weth, users } = testEnv; - const caller = users[3]; - - await dai - .connect(caller.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - - await dai.connect(caller.signer).approve(pool.address, MAX_UINT_AMOUNT); - - const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000'); - - await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0'); - - const flashAmount = ethers.utils.parseEther('0.8'); - - await _mockFlashLoanSimpleReceiver.setFailExecutionTransfer(false); - await _mockFlashLoanSimpleReceiver.setAmountToApprove(flashAmount.div(2)); - - await expect( - pool - .connect(caller.signer) - .flashLoanSimple( - _mockFlashLoanSimpleReceiver.address, - weth.address, - flashAmount, - '0x10', - '0' - ) - ).to.be.reverted; - }); - - it('Check that reentrance borrow within flashloanSimple impacts rates', async () => { - /** - * 1. FlashBorrow a tiny bit of DAI - * 2. As the action in the middle. Borrow ALL the DAI using eth collateral - * 3. Repay the tiny bit - * The result should be that the interest rate increase due to higher utilisation. - */ - - const { - deployer, - pool, - dai, - aDai, - weth, - addressesProvider, - users: [user], - } = testEnv; - - const flashAttacker = await new FlashloanAttacker__factory(deployer.signer).deploy( - addressesProvider.address - ); - - await flashAttacker.connect(user.signer).supplyAsset(weth.address, parseEther('100')); - - const dataBefore = await pool.getReserveData(dai.address); - const debtToken = IERC20Detailed__factory.connect( - dataBefore.variableDebtTokenAddress, - deployer.signer - ); - const debtBefore = await debtToken.totalSupply(); - const availableBefore = await dai.balanceOf(aDai.address); - - await pool - .connect(user.signer) - .flashLoanSimple(flashAttacker.address, dai.address, parseUnits('1', 18), '0x10', 0); - - const dataAfter = await pool.getReserveData(dai.address); - const debtAfter = await debtToken.totalSupply(); - const availableAfter = await dai.balanceOf(aDai.address); - - // More debt and less available -> higher usage-> rates will increase - expect(debtAfter).to.be.gt(debtBefore); - expect(availableAfter).to.be.lt(availableBefore); - - // Premium is added - expect(dataAfter.liquidityIndex).to.be.gt(dataBefore.liquidityIndex); - - // Rates should have increased - expect(dataAfter.currentLiquidityRate).to.be.gt(dataBefore.currentLiquidityRate); - expect(dataAfter.currentVariableBorrowRate).to.be.gt(dataBefore.currentVariableBorrowRate); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/price-oracle-sentinel.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/price-oracle-sentinel.spec.ts deleted file mode 100644 index 93c3bf6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/price-oracle-sentinel.spec.ts +++ /dev/null @@ -1,630 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { timeLatest } from '../helpers/misc-utils'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { - PriceOracleSentinel, - PriceOracleSentinel__factory, - SequencerOracle, - SequencerOracle__factory, -} from '../types'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { calcExpectedVariableDebtTokenBalance } from './helpers/utils/calculations'; -import { getReserveData, getUserData } from './helpers/utils/helpers'; -import './helpers/utils/wadraymath'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { waitForTx, increaseTime } from '@aave/deploy-v3'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('PriceOracleSentinel', (testEnv: TestEnv) => { - const { - PRICE_ORACLE_SENTINEL_CHECK_FAILED, - INVALID_HF, - CALLER_NOT_POOL_ADMIN, - CALLER_NOT_RISK_OR_POOL_ADMIN, - } = ProtocolErrors; - - let sequencerOracle: SequencerOracle; - let priceOracleSentinel: PriceOracleSentinel; - - const GRACE_PERIOD = BigNumber.from(60 * 60); - - before(async () => { - const { addressesProvider, deployer, oracle } = testEnv; - - // Deploy SequencerOracle - sequencerOracle = await ( - await new SequencerOracle__factory(deployer.signer).deploy(deployer.address) - ).deployed(); - - priceOracleSentinel = await ( - await new PriceOracleSentinel__factory(await getFirstSigner()).deploy( - addressesProvider.address, - sequencerOracle.address, - GRACE_PERIOD - ) - ).deployed(); - - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - it('Admin sets a PriceOracleSentinel and activate it for DAI and WETH', async () => { - const { addressesProvider, poolAdmin } = testEnv; - - expect( - await addressesProvider - .connect(poolAdmin.signer) - .setPriceOracleSentinel(priceOracleSentinel.address) - ) - .to.emit(addressesProvider, 'PriceOracleSentinelUpdated') - .withArgs(ZERO_ADDRESS, priceOracleSentinel.address); - - expect(await addressesProvider.getPriceOracleSentinel()).to.be.eq(priceOracleSentinel.address); - - const answer = await sequencerOracle.latestRoundData(); - expect(answer[1]).to.be.eq(0); - expect(answer[3]).to.be.eq(0); - }); - - it('Pooladmin updates grace period for sentinel', async () => { - const { poolAdmin } = testEnv; - - const newGracePeriod = 0; - - expect(await priceOracleSentinel.getGracePeriod()).to.be.eq(GRACE_PERIOD); - expect(await priceOracleSentinel.connect(poolAdmin.signer).setGracePeriod(0)) - .to.emit(priceOracleSentinel, 'GracePeriodUpdated') - .withArgs(0); - expect(await priceOracleSentinel.getGracePeriod()).to.be.eq(newGracePeriod); - }); - - it('Risk admin updates grace period for sentinel', async () => { - const { riskAdmin } = testEnv; - - expect(await priceOracleSentinel.getGracePeriod()).to.be.eq(0); - expect(await priceOracleSentinel.connect(riskAdmin.signer).setGracePeriod(GRACE_PERIOD)) - .to.emit(priceOracleSentinel, 'GracePeriodUpdated') - .withArgs(GRACE_PERIOD); - expect(await priceOracleSentinel.getGracePeriod()).to.be.eq(GRACE_PERIOD); - }); - - it('User tries to set grace period for sentinel', async () => { - const { - users: [user], - } = testEnv; - - expect(await priceOracleSentinel.getGracePeriod()).to.be.eq(GRACE_PERIOD); - await expect(priceOracleSentinel.connect(user.signer).setGracePeriod(0)).to.be.revertedWith( - CALLER_NOT_RISK_OR_POOL_ADMIN - ); - expect(await priceOracleSentinel.getGracePeriod()).to.not.be.eq(0); - }); - - it('Pooladmin update the sequencer oracle', async () => { - const { poolAdmin } = testEnv; - - const newSequencerOracle = ZERO_ADDRESS; - - expect(await priceOracleSentinel.getSequencerOracle()).to.be.eq(sequencerOracle.address); - expect( - await priceOracleSentinel.connect(poolAdmin.signer).setSequencerOracle(newSequencerOracle) - ) - .to.emit(priceOracleSentinel, 'SequencerOracleUpdated') - .withArgs(newSequencerOracle); - expect(await priceOracleSentinel.getSequencerOracle()).to.be.eq(newSequencerOracle); - - expect( - await priceOracleSentinel - .connect(poolAdmin.signer) - .setSequencerOracle(sequencerOracle.address) - ) - .to.emit(priceOracleSentinel, 'SequencerOracleUpdated') - .withArgs(sequencerOracle.address); - expect(await priceOracleSentinel.getSequencerOracle()).to.be.eq(sequencerOracle.address); - }); - - it('User tries to update sequencer oracle', async () => { - const { - users: [user], - } = testEnv; - const newSequencerOracle = ZERO_ADDRESS; - - expect(await priceOracleSentinel.getSequencerOracle()).to.be.eq(sequencerOracle.address); - await expect( - priceOracleSentinel.connect(user.signer).setSequencerOracle(newSequencerOracle) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - expect(await priceOracleSentinel.getSequencerOracle()).to.be.eq(sequencerOracle.address); - }); - - it('Borrow DAI', async () => { - const { - dai, - weth, - users: [depositor, borrower, borrower2], - pool, - oracle, - } = testEnv; - - //mints DAI to depositor - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '2000')); - - //approve protocol to access depositor wallet - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 1 deposits 1000 DAI - const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '2000'); - await pool - .connect(depositor.signer) - .deposit(dai.address, amountDAItoDeposit, depositor.address, '0'); - - const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '0.06775'); - - for (let i = 0; i < 2; i++) { - const borrowers = [borrower, borrower2]; - const currBorrower = borrowers[i]; - //mints WETH to borrower - await weth.connect(currBorrower.signer)['mint(uint256)'](amountETHtoDeposit); - - //approve protocol to access borrower wallet - await weth.connect(currBorrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - - //user 2 deposits 1 WETH - await pool - .connect(currBorrower.signer) - .deposit(weth.address, amountETHtoDeposit, currBorrower.address, '0'); - - //user 2 borrows - const userGlobalData = await pool.getUserAccountData(currBorrower.address); - const daiPrice = await oracle.getAssetPrice(dai.address); - - const amountDAIToBorrow = await convertToCurrencyDecimals( - dai.address, - userGlobalData.availableBorrowsBase.div(daiPrice.toString()).percentMul(9500).toString() - ); - - await pool - .connect(currBorrower.signer) - .borrow(dai.address, amountDAIToBorrow, RateMode.Variable, '0', currBorrower.address); - } - }); - - it('Kill sequencer and drop health factor below 1', async () => { - const { - dai, - users: [, borrower], - pool, - oracle, - } = testEnv; - - const daiPrice = await oracle.getAssetPrice(dai.address); - await oracle.setAssetPrice(dai.address, daiPrice.percentMul(11000)); - const userGlobalData = await pool.getUserAccountData(borrower.address); - - expect(userGlobalData.healthFactor).to.be.lt(utils.parseUnits('1', 18), INVALID_HF); - const currAnswer = await sequencerOracle.latestRoundData(); - waitForTx(await sequencerOracle.setAnswer(true, currAnswer[3])); - }); - - it('Tries to liquidate borrower when sequencer is down (HF > 0.95) (revert expected)', async () => { - const { - pool, - dai, - weth, - users: [, borrower], - helpersContract, - } = testEnv; - - await dai['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - await dai.approve(pool.address, MAX_UINT_AMOUNT); - - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2); - await expect( - pool.liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, true) - ).to.be.revertedWith(PRICE_ORACLE_SENTINEL_CHECK_FAILED); - }); - - it('Drop health factor lower', async () => { - const { - dai, - users: [, borrower], - pool, - oracle, - } = testEnv; - - const daiPrice = await oracle.getAssetPrice(dai.address); - await oracle.setAssetPrice(dai.address, daiPrice.percentMul(11000)); - const userGlobalData = await pool.getUserAccountData(borrower.address); - - expect(userGlobalData.healthFactor).to.be.lt(utils.parseUnits('1', 18), INVALID_HF); - }); - - it('Liquidates borrower when sequencer is down (HF < 0.95)', async () => { - const { - pool, - dai, - weth, - users: [, borrower], - oracle, - helpersContract, - deployer, - } = testEnv; - - await dai['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - await dai.approve(pool.address, MAX_UINT_AMOUNT); - - const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); - const ethReserveDataBefore = await getReserveData(helpersContract, weth.address); - - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const userWethReserveDataBefore = await getUserData( - pool, - helpersContract, - weth.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2); - - const tx = await pool.liquidationCall( - weth.address, - dai.address, - borrower.address, - amountToLiquidate, - true - ); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - dai.address, - borrower.address - ); - - const userWethReserveDataAfter = await helpersContract.getUserReserveData( - weth.address, - borrower.address - ); - - const daiReserveDataAfter = await getReserveData(helpersContract, dai.address); - const ethReserveDataAfter = await getReserveData(helpersContract, weth.address); - - const collateralPrice = await oracle.getAssetPrice(weth.address); - const principalPrice = await oracle.getAssetPrice(dai.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(weth.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(dai.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(amountToLiquidate) - .percentMul(10500) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - expect(expectedCollateralLiquidated).to.be.closeTo( - userWethReserveDataBefore.currentATokenBalance.sub( - userWethReserveDataAfter.currentATokenBalance - ), - 2, - 'Invalid collateral amount liquidated' - ); - - if (!tx.blockNumber) { - expect(false, 'Invalid block number'); - return; - } - - const txTimestamp = BigNumber.from( - (await hre.ethers.provider.getBlock(tx.blockNumber)).timestamp - ); - - const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance( - daiReserveDataBefore, - userReserveDataBefore, - txTimestamp - ); - - expect(userReserveDataAfter.currentVariableDebt).to.be.closeTo( - variableDebtBeforeTx.sub(amountToLiquidate), - 2, - 'Invalid user borrow balance after liquidation' - ); - - expect(daiReserveDataAfter.availableLiquidity).to.be.closeTo( - daiReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(daiReserveDataAfter.liquidityIndex).to.be.gte( - daiReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(daiReserveDataAfter.liquidityRate).to.be.lt( - daiReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(ethReserveDataAfter.availableLiquidity).to.be.closeTo( - ethReserveDataBefore.availableLiquidity, - 2, - 'Invalid collateral available liquidity' - ); - - expect( - (await helpersContract.getUserReserveData(weth.address, deployer.address)) - .usageAsCollateralEnabled - ).to.be.true; - }); - - it('User tries to borrow (revert expected)', async () => { - const { - dai, - weth, - users: [, , , user], - pool, - oracle, - } = testEnv; - - await weth.connect(user.signer)['mint(uint256)'](utils.parseUnits('0.06775', 18)); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .supply(weth.address, utils.parseUnits('0.06775', 18), user.address, 0); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseUnits('100', 18), RateMode.Variable, 0, user.address) - ).to.be.revertedWith(PRICE_ORACLE_SENTINEL_CHECK_FAILED); - }); - - it('Turn on sequencer', async () => { - await waitForTx(await sequencerOracle.setAnswer(false, await timeLatest())); - }); - - it('User tries to borrow (revert expected)', async () => { - const { - dai, - weth, - users: [, , , user], - pool, - } = testEnv; - - await weth.connect(user.signer)['mint(uint256)'](utils.parseUnits('0.06775', 18)); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .supply(weth.address, utils.parseUnits('0.06775', 18), user.address, 0); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseUnits('100', 18), RateMode.Variable, 0, user.address) - ).to.be.revertedWith(PRICE_ORACLE_SENTINEL_CHECK_FAILED); - }); - - it('Turn off sequencer + increase time more than grace period', async () => { - const currAnswer = await sequencerOracle.latestRoundData(); - await waitForTx(await sequencerOracle.setAnswer(true, currAnswer[3])); - await increaseTime(GRACE_PERIOD.mul(2).toNumber()); - }); - - it('User tries to borrow (revert expected)', async () => { - const { - dai, - weth, - users: [, , , user], - pool, - } = testEnv; - - await weth.connect(user.signer)['mint(uint256)'](utils.parseUnits('0.06775', 18)); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .supply(weth.address, utils.parseUnits('0.06775', 18), user.address, 0); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseUnits('100', 18), RateMode.Variable, 0, user.address) - ).to.be.revertedWith(PRICE_ORACLE_SENTINEL_CHECK_FAILED); - }); - - it('Turn on sequencer + increase time past grace period', async () => { - await waitForTx(await sequencerOracle.setAnswer(false, await timeLatest())); - await increaseTime(GRACE_PERIOD.mul(2).toNumber()); - }); - - it('User tries to borrow', async () => { - const { - dai, - weth, - users: [, , , user], - pool, - } = testEnv; - - await weth.connect(user.signer)['mint(uint256)'](utils.parseUnits('0.06775', 18)); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .supply(weth.address, utils.parseUnits('0.06775', 18), user.address, 0); - - await waitForTx( - await pool - .connect(user.signer) - .borrow(dai.address, utils.parseUnits('100', 18), RateMode.Variable, 0, user.address) - ); - }); - - it('Increase health factor', async () => { - const { - dai, - users: [, borrower], - pool, - oracle, - } = testEnv; - const daiPrice = await oracle.getAssetPrice(dai.address); - await oracle.setAssetPrice(dai.address, daiPrice.percentMul(9500)); - const userGlobalData = await pool.getUserAccountData(borrower.address); - - expect(userGlobalData.healthFactor).to.be.lt(utils.parseUnits('1', 18), INVALID_HF); - expect(userGlobalData.healthFactor).to.be.gt(utils.parseUnits('0.95', 18), INVALID_HF); - }); - - it('Liquidates borrower when sequencer is up again', async () => { - const { - pool, - dai, - weth, - users: [, , borrower], - oracle, - helpersContract, - deployer, - } = testEnv; - - await dai['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - await dai.approve(pool.address, MAX_UINT_AMOUNT); - - const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); - const ethReserveDataBefore = await getReserveData(helpersContract, weth.address); - - const userReserveDataBefore = await getUserData( - pool, - helpersContract, - dai.address, - borrower.address - ); - - const userWethReserveDataBefore = await getUserData( - pool, - helpersContract, - weth.address, - borrower.address - ); - - const amountToLiquidate = userReserveDataBefore.currentVariableDebt.div(2); - - // The supply is the same, but there should be a change in who has what. The liquidator should have received what the borrower lost. - const tx = await pool.liquidationCall( - weth.address, - dai.address, - borrower.address, - amountToLiquidate, - true - ); - - const userReserveDataAfter = await helpersContract.getUserReserveData( - dai.address, - borrower.address - ); - - const userWethReserveDataAfter = await helpersContract.getUserReserveData( - weth.address, - borrower.address - ); - - const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - - const daiReserveDataAfter = await getReserveData(helpersContract, dai.address); - const ethReserveDataAfter = await getReserveData(helpersContract, weth.address); - - const collateralPrice = await oracle.getAssetPrice(weth.address); - const principalPrice = await oracle.getAssetPrice(dai.address); - - const collateralDecimals = (await helpersContract.getReserveConfigurationData(weth.address)) - .decimals; - const principalDecimals = (await helpersContract.getReserveConfigurationData(dai.address)) - .decimals; - - const expectedCollateralLiquidated = principalPrice - .mul(amountToLiquidate) - .percentMul(10500) - .mul(BigNumber.from(10).pow(collateralDecimals)) - .div(collateralPrice.mul(BigNumber.from(10).pow(principalDecimals))); - - expect(expectedCollateralLiquidated).to.be.closeTo( - userWethReserveDataBefore.currentATokenBalance.sub( - userWethReserveDataAfter.currentATokenBalance - ), - 2, - 'Invalid collateral amount liquidated' - ); - - if (!tx.blockNumber) { - expect(false, 'Invalid block number'); - return; - } - - const txTimestamp = BigNumber.from( - (await hre.ethers.provider.getBlock(tx.blockNumber)).timestamp - ); - - const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance( - daiReserveDataBefore, - userReserveDataBefore, - txTimestamp - ); - - expect(userReserveDataAfter.currentVariableDebt).to.be.closeTo( - variableDebtBeforeTx.sub(amountToLiquidate), - 2, - 'Invalid user borrow balance after liquidation' - ); - - expect(daiReserveDataAfter.availableLiquidity).to.be.closeTo( - daiReserveDataBefore.availableLiquidity.add(amountToLiquidate), - 2, - 'Invalid principal available liquidity' - ); - - //the liquidity index of the principal reserve needs to be bigger than the index before - expect(daiReserveDataAfter.liquidityIndex).to.be.gte( - daiReserveDataBefore.liquidityIndex, - 'Invalid liquidity index' - ); - - //the principal APY after a liquidation needs to be lower than the APY before - expect(daiReserveDataAfter.liquidityRate).to.be.lt( - daiReserveDataBefore.liquidityRate, - 'Invalid liquidity APY' - ); - - expect(ethReserveDataAfter.availableLiquidity).to.be.closeTo( - ethReserveDataBefore.availableLiquidity, - 2, - 'Invalid collateral available liquidity' - ); - - expect( - (await helpersContract.getUserReserveData(weth.address, deployer.address)) - .usageAsCollateralEnabled - ).to.be.true; - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/rate-strategy.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/rate-strategy.spec.ts deleted file mode 100644 index a8ea05f..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/rate-strategy.spec.ts +++ /dev/null @@ -1,426 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, BigNumberish, utils } from 'ethers'; -import { deployDefaultReserveInterestRateStrategy } from '@aave/deploy-v3/dist/helpers/contract-deployments'; -import { PERCENTAGE_FACTOR } from '../helpers/constants'; -import { AToken, DefaultReserveInterestRateStrategy, MintableERC20 } from '../types'; -import { strategyDAI } from '@aave/deploy-v3/dist/markets/aave/reservesConfigs'; -import { rateStrategyStableTwo } from '@aave/deploy-v3/dist/markets/aave/rateStrategies'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { formatUnits } from '@ethersproject/units'; -import './helpers/utils/wadraymath'; - -const DEBUG = false; - -type CalculateInterestRatesParams = { - unbacked: BigNumberish; - liquidityAdded: BigNumberish; - liquidityTaken: BigNumberish; - totalStableDebt: BigNumberish; - totalVariableDebt: BigNumberish; - averageStableBorrowRate: BigNumberish; - reserveFactor: BigNumberish; - reserve: string; - aToken: string; -}; - -makeSuite('InterestRateStrategy', (testEnv: TestEnv) => { - let strategyInstance: DefaultReserveInterestRateStrategy; - let dai: MintableERC20; - let aDai: AToken; - const baseStableRate = BigNumber.from(rateStrategyStableTwo.variableRateSlope1).add( - rateStrategyStableTwo.baseStableRateOffset - ); - - const { INVALID_OPTIMAL_USAGE_RATIO, INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO } = - ProtocolErrors; - - before(async () => { - dai = testEnv.dai; - aDai = testEnv.aDai; - - const { addressesProvider } = testEnv; - - strategyInstance = await deployDefaultReserveInterestRateStrategy([ - addressesProvider.address, - rateStrategyStableTwo.optimalUsageRatio, - rateStrategyStableTwo.baseVariableBorrowRate, - rateStrategyStableTwo.variableRateSlope1, - rateStrategyStableTwo.variableRateSlope2, - rateStrategyStableTwo.stableRateSlope1, - rateStrategyStableTwo.stableRateSlope2, - rateStrategyStableTwo.baseStableRateOffset, - rateStrategyStableTwo.stableRateExcessOffset, - rateStrategyStableTwo.optimalStableToTotalDebtRatio, - ]); - }); - - it('Checks rates at 0% usage ratio, empty reserve', async () => { - let params: CalculateInterestRatesParams = { - unbacked: 0, - liquidityAdded: 0, - liquidityTaken: 0, - totalStableDebt: 0, - totalVariableDebt: 0, - averageStableBorrowRate: 0, - reserveFactor: strategyDAI.reserveFactor, - reserve: dai.address, - aToken: aDai.address, - }; - - const { - 0: currentLiquidityRate, - 1: currentStableBorrowRate, - 2: currentVariableBorrowRate, - } = await strategyInstance.calculateInterestRates(params); - - expect(currentLiquidityRate).to.be.equal(0, 'Invalid liquidity rate'); - expect(currentStableBorrowRate).to.be.equal(baseStableRate, 'Invalid stable rate'); - expect(currentVariableBorrowRate).to.be.equal( - rateStrategyStableTwo.baseVariableBorrowRate, - 'Invalid variable rate' - ); - }); - - it('Checks rates at 80% usage ratio', async () => { - let params: CalculateInterestRatesParams = { - unbacked: 0, - liquidityAdded: '200000000000000000', - liquidityTaken: 0, - totalStableDebt: 0, - totalVariableDebt: '800000000000000000', - averageStableBorrowRate: 0, - reserveFactor: strategyDAI.reserveFactor, - reserve: dai.address, - aToken: aDai.address, - }; - - const { - 0: currentLiquidityRate, - 1: currentStableBorrowRate, - 2: currentVariableBorrowRate, - } = await strategyInstance.calculateInterestRates(params); - - const expectedVariableRate = BigNumber.from(rateStrategyStableTwo.baseVariableBorrowRate).add( - rateStrategyStableTwo.variableRateSlope1 - ); - - expect(currentLiquidityRate).to.be.equal( - expectedVariableRate - .percentMul(8000) - .percentMul(BigNumber.from(PERCENTAGE_FACTOR).sub(strategyDAI.reserveFactor)), - 'Invalid liquidity rate' - ); - - expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); - - expect(currentStableBorrowRate).to.be.equal( - baseStableRate.add(rateStrategyStableTwo.stableRateSlope1), - 'Invalid stable rate' - ); - - if (DEBUG) { - console.log(`Current Liquidity Rate: ${formatUnits(currentLiquidityRate, 27)}`); - console.log(`Current Borrow Rate V : ${formatUnits(currentVariableBorrowRate, 27)}`); - console.log(`Current Borrow Rate S : ${formatUnits(currentStableBorrowRate, 27)}`); - } - }); - - it('Checks rates at 100% usage ratio', async () => { - let params: CalculateInterestRatesParams = { - unbacked: 0, - liquidityAdded: '0', - liquidityTaken: 0, - totalStableDebt: 0, - totalVariableDebt: '1000000000000000000', - averageStableBorrowRate: 0, - reserveFactor: strategyDAI.reserveFactor, - reserve: dai.address, - aToken: aDai.address, - }; - - const { - 0: currentLiquidityRate, - 1: currentStableBorrowRate, - 2: currentVariableBorrowRate, - } = await strategyInstance.calculateInterestRates(params); - - const expectedVariableRate = BigNumber.from(rateStrategyStableTwo.baseVariableBorrowRate) - .add(rateStrategyStableTwo.variableRateSlope1) - .add(rateStrategyStableTwo.variableRateSlope2); - - expect(currentLiquidityRate).to.be.equal( - expectedVariableRate.percentMul( - BigNumber.from(PERCENTAGE_FACTOR).sub(strategyDAI.reserveFactor) - ), - 'Invalid liquidity rate' - ); - - expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); - - expect(currentStableBorrowRate).to.be.equal( - baseStableRate - .add(rateStrategyStableTwo.stableRateSlope1) - .add(rateStrategyStableTwo.stableRateSlope2), - 'Invalid stable rate' - ); - - if (DEBUG) { - console.log(`Current Liquidity Rate: ${formatUnits(currentLiquidityRate, 27)}`); - console.log(`Current Borrow Rate V : ${formatUnits(currentVariableBorrowRate, 27)}`); - console.log(`Current Borrow Rate S : ${formatUnits(currentStableBorrowRate, 27)}`); - } - }); - - it('Checks rates at 100% usage ratio, 50% stable debt and 50% variable debt, with a 10% avg stable rate', async () => { - let params: CalculateInterestRatesParams = { - unbacked: 0, - liquidityAdded: '0', - liquidityTaken: 0, - totalStableDebt: '400000000000000000', - totalVariableDebt: '400000000000000000', - averageStableBorrowRate: '100000000000000000000000000', - reserveFactor: strategyDAI.reserveFactor, - reserve: dai.address, - aToken: aDai.address, - }; - - const { - 0: currentLiquidityRate, - 1: currentStableBorrowRate, - 2: currentVariableBorrowRate, - } = await strategyInstance.calculateInterestRates(params); - - const expectedVariableRate = BigNumber.from(rateStrategyStableTwo.baseVariableBorrowRate) - .add(rateStrategyStableTwo.variableRateSlope1) - .add(rateStrategyStableTwo.variableRateSlope2); - - const expectedLiquidityRate = BigNumber.from(currentVariableBorrowRate) - .add(utils.parseUnits('0.1', 27)) - .div('2') - .percentMul(BigNumber.from(PERCENTAGE_FACTOR).sub(strategyDAI.reserveFactor)); - - expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); - expect(currentLiquidityRate).to.be.equal(expectedLiquidityRate, 'Invalid liquidity rate'); - expect(currentStableBorrowRate).to.be.equal( - baseStableRate - .add(rateStrategyStableTwo.stableRateSlope1) - .add(rateStrategyStableTwo.stableRateSlope2) - .add( - BigNumber.from(rateStrategyStableTwo.stableRateExcessOffset).rayMul( - BigNumber.from(utils.parseUnits('0.375', 27)) - ) - ), - 'Invalid stable rate' - ); - }); - - it('Checks rates at 80% borrow usage ratio and 50% supply usage due to minted tokens', async () => { - let params: CalculateInterestRatesParams = { - unbacked: '600000000000000000', - liquidityAdded: '200000000000000000', - liquidityTaken: 0, - totalStableDebt: '0', - totalVariableDebt: '800000000000000000', - averageStableBorrowRate: '0', - reserveFactor: strategyDAI.reserveFactor, - reserve: dai.address, - aToken: aDai.address, - }; - - const { - 0: currentLiquidityRate, - 1: currentStableBorrowRate, - 2: currentVariableBorrowRate, - } = await strategyInstance.calculateInterestRates(params); - - const expectedVariableRate = BigNumber.from(rateStrategyStableTwo.baseVariableBorrowRate).add( - rateStrategyStableTwo.variableRateSlope1 - ); - - expect(currentLiquidityRate).to.be.equal( - expectedVariableRate - .percentMul(5000) - .percentMul(BigNumber.from(PERCENTAGE_FACTOR).sub(strategyDAI.reserveFactor)), - 'Invalid liquidity rate' - ); - - expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); - - expect(currentStableBorrowRate).to.be.equal( - baseStableRate.add(rateStrategyStableTwo.stableRateSlope1), - 'Invalid stable rate' - ); - }); - - it('Checks rates at 80% borrow usage ratio and 0.8% supply usage due to minted tokens', async () => { - const availableLiquidity = BigNumber.from('200000000000000000'); - const totalVariableDebt = BigNumber.from('800000000000000000'); - - let params: CalculateInterestRatesParams = { - unbacked: totalVariableDebt.mul('124').sub(availableLiquidity), - liquidityAdded: availableLiquidity, - liquidityTaken: 0, - totalStableDebt: '0', - totalVariableDebt: totalVariableDebt, - averageStableBorrowRate: '0', - reserveFactor: strategyDAI.reserveFactor, - reserve: dai.address, - aToken: aDai.address, - }; - - const { - 0: currentLiquidityRate, - 1: currentStableBorrowRate, - 2: currentVariableBorrowRate, - } = await strategyInstance.calculateInterestRates(params); - - const expectedVariableRate = BigNumber.from(rateStrategyStableTwo.baseVariableBorrowRate).add( - rateStrategyStableTwo.variableRateSlope1 - ); - - expect(currentLiquidityRate).to.be.equal( - expectedVariableRate - .percentMul(80) - .percentMul(BigNumber.from(PERCENTAGE_FACTOR).sub(strategyDAI.reserveFactor)), - 'Invalid liquidity rate' - ); - expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); - - expect(currentStableBorrowRate).to.be.equal( - baseStableRate.add(rateStrategyStableTwo.stableRateSlope1), - 'Invalid stable rate' - ); - - if (DEBUG) { - console.log(`Current Liquidity Rate: ${formatUnits(currentLiquidityRate, 27)}`); - console.log(`Current Borrow Rate V : ${formatUnits(currentVariableBorrowRate, 27)}`); - console.log(`Current Borrow Rate S : ${formatUnits(currentStableBorrowRate, 27)}`); - } - }); - - it('Checks rates at 0.8% usage', async () => { - let params: CalculateInterestRatesParams = { - unbacked: 0, - liquidityAdded: '9920000000000000000000', - liquidityTaken: 0, - totalStableDebt: '0', - totalVariableDebt: '80000000000000000000', - averageStableBorrowRate: '0', - reserveFactor: strategyDAI.reserveFactor, - reserve: dai.address, - aToken: aDai.address, - }; - - const { - 0: currentLiquidityRate, - 1: currentStableBorrowRate, - 2: currentVariableBorrowRate, - } = await strategyInstance.calculateInterestRates(params); - - const usageRatio = BigNumber.from(1).ray().percentMul(80); - const OPTIMAL_USAGE_RATIO = BigNumber.from(rateStrategyStableTwo.optimalUsageRatio); - - const expectedVariableRate = BigNumber.from(rateStrategyStableTwo.baseVariableBorrowRate).add( - BigNumber.from(rateStrategyStableTwo.variableRateSlope1).rayMul( - usageRatio.rayDiv(OPTIMAL_USAGE_RATIO) - ) - ); - - expect(currentLiquidityRate).to.be.equal( - expectedVariableRate - .percentMul(80) - .percentMul(BigNumber.from(PERCENTAGE_FACTOR).sub(strategyDAI.reserveFactor)), - 'Invalid liquidity rate' - ); - - expect(currentVariableBorrowRate).to.be.equal(expectedVariableRate, 'Invalid variable rate'); - - expect(currentStableBorrowRate).to.be.equal( - baseStableRate.add( - BigNumber.from(rateStrategyStableTwo.stableRateSlope1).rayMul( - usageRatio.rayDiv(OPTIMAL_USAGE_RATIO) - ) - ), - 'Invalid stable rate' - ); - - if (DEBUG) { - console.log(`Current Liquidity Rate: ${formatUnits(currentLiquidityRate, 27)}`); - console.log(`Current Borrow Rate V : ${formatUnits(currentVariableBorrowRate, 27)}`); - console.log(`Current Borrow Rate S : ${formatUnits(currentStableBorrowRate, 27)}`); - } - }); - - it('Checks getters', async () => { - expect(await strategyInstance.OPTIMAL_USAGE_RATIO()).to.be.eq( - rateStrategyStableTwo.optimalUsageRatio - ); - expect(await strategyInstance.getBaseVariableBorrowRate()).to.be.eq( - rateStrategyStableTwo.baseVariableBorrowRate - ); - expect(await strategyInstance.getVariableRateSlope1()).to.be.eq( - rateStrategyStableTwo.variableRateSlope1 - ); - expect(await strategyInstance.getVariableRateSlope2()).to.be.eq( - rateStrategyStableTwo.variableRateSlope2 - ); - expect(await strategyInstance.getStableRateSlope1()).to.be.eq( - rateStrategyStableTwo.stableRateSlope1 - ); - expect(await strategyInstance.getStableRateSlope2()).to.be.eq( - rateStrategyStableTwo.stableRateSlope2 - ); - expect(await strategyInstance.getMaxVariableBorrowRate()).to.be.eq( - BigNumber.from(rateStrategyStableTwo.baseVariableBorrowRate) - .add(BigNumber.from(rateStrategyStableTwo.variableRateSlope1)) - .add(BigNumber.from(rateStrategyStableTwo.variableRateSlope2)) - ); - expect(await strategyInstance.MAX_EXCESS_USAGE_RATIO()).to.be.eq( - BigNumber.from(1).ray().sub(rateStrategyStableTwo.optimalUsageRatio) - ); - expect(await strategyInstance.MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO()).to.be.eq( - BigNumber.from(1).ray().sub(rateStrategyStableTwo.optimalStableToTotalDebtRatio) - ); - expect(await strategyInstance.getStableRateExcessOffset()).to.be.eq( - rateStrategyStableTwo.stableRateExcessOffset - ); - }); - - it('Deploy an interest rate strategy with optimalUsageRatio out of range (expect revert)', async () => { - const { addressesProvider } = testEnv; - - await expect( - deployDefaultReserveInterestRateStrategy([ - addressesProvider.address, - utils.parseUnits('1.0', 28), - rateStrategyStableTwo.baseVariableBorrowRate, - rateStrategyStableTwo.variableRateSlope1, - rateStrategyStableTwo.variableRateSlope2, - rateStrategyStableTwo.stableRateSlope1, - rateStrategyStableTwo.stableRateSlope2, - rateStrategyStableTwo.baseStableRateOffset, - rateStrategyStableTwo.stableRateExcessOffset, - rateStrategyStableTwo.optimalStableToTotalDebtRatio, - ]) - ).to.be.revertedWith(INVALID_OPTIMAL_USAGE_RATIO); - }); - - it('Deploy an interest rate strategy with optimalStableToTotalDebtRatio out of range (expect revert)', async () => { - const { addressesProvider } = testEnv; - await expect( - deployDefaultReserveInterestRateStrategy([ - addressesProvider.address, - rateStrategyStableTwo.optimalUsageRatio, - rateStrategyStableTwo.baseVariableBorrowRate, - rateStrategyStableTwo.variableRateSlope1, - rateStrategyStableTwo.variableRateSlope2, - rateStrategyStableTwo.stableRateSlope1, - rateStrategyStableTwo.stableRateSlope2, - rateStrategyStableTwo.baseStableRateOffset, - rateStrategyStableTwo.stableRateExcessOffset, - utils.parseUnits('1.0', 28), - ]) - ).to.be.revertedWith(INVALID_OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/rescue-tokens.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/rescue-tokens.spec.ts deleted file mode 100644 index e0843a7..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/rescue-tokens.spec.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { ProtocolErrors } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { evmSnapshot, evmRevert, ONE_ADDRESS } from '@aave/deploy-v3'; -import { deployMintableERC20 } from '@aave/deploy-v3/dist/helpers/contract-deployments'; -import { MintableERC20 } from '../types'; - -makeSuite('Rescue tokens', (testEnv: TestEnv) => { - const { CALLER_NOT_POOL_ADMIN, CALLER_MUST_BE_POOL, UNDERLYING_CANNOT_BE_RESCUED } = - ProtocolErrors; - - let snap: string; - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - - afterEach(async () => { - await evmRevert(snap); - }); - - it('User tries to rescue tokens from Pool (revert expected)', async () => { - const { - pool, - usdc, - users: [rescuer], - } = testEnv; - - const amount = 1; - await expect( - pool.connect(rescuer.signer).rescueTokens(usdc.address, rescuer.address, amount) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); - - it('PoolAdmin rescue tokens from Pool', async () => { - const { - poolAdmin, - pool, - usdc, - users: [locker], - } = testEnv; - - const amountToLock = utils.parseUnits('10', 18); - - // Lock - await usdc['mint(address,uint256)'](locker.address, amountToLock); - await usdc.connect(locker.signer).transfer(pool.address, amountToLock); - - const lockerBalanceBefore = await usdc.balanceOf(locker.address); - const poolBalanceBefore = await usdc.balanceOf(pool.address); - - expect( - await pool.connect(poolAdmin.signer).rescueTokens(usdc.address, locker.address, amountToLock) - ); - - const poolBalanceAfter = await usdc.balanceOf(pool.address); - expect(poolBalanceBefore).to.be.eq(poolBalanceAfter.add(amountToLock)); - const lockerBalanceAfter = await usdc.balanceOf(locker.address); - expect(lockerBalanceBefore).to.be.eq(lockerBalanceAfter.sub(amountToLock)); - }); - - it('User tries to rescue tokens from AToken (revert expected)', async () => { - const { - usdc, - aDai, - users: [rescuer], - } = testEnv; - - const amount = 1; - await expect( - aDai.connect(rescuer.signer).rescueTokens(usdc.address, rescuer.address, amount) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); - - it('User tries to rescue tokens of underlying from AToken (revert expected)', async () => { - const { - aDai, - dai, - users: [rescuer], - } = testEnv; - - const amount = 1; - await expect( - aDai.connect(rescuer.signer).rescueTokens(dai.address, rescuer.address, amount) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); - - it('PoolAdmin tries to rescue tokens of underlying from AToken (revert expected)', async () => { - const { - poolAdmin, - aDai, - dai, - users: [rescuer], - } = testEnv; - - const amount = 1; - await expect( - aDai.connect(poolAdmin.signer).rescueTokens(dai.address, rescuer.address, amount) - ).to.be.revertedWith(UNDERLYING_CANNOT_BE_RESCUED); - }); - - it('PoolAdmin rescue tokens from AToken', async () => { - const { - poolAdmin, - dai, - usdc, - aDai, - users: [locker], - } = testEnv; - - const amountToLock = utils.parseUnits('10', 18); - - // Lock - await usdc['mint(address,uint256)'](locker.address, amountToLock); - await usdc.connect(locker.signer).transfer(aDai.address, amountToLock); - - const lockerBalanceBefore = await usdc.balanceOf(locker.address); - const aTokenBalanceBefore = await usdc.balanceOf(aDai.address); - - expect( - await aDai.connect(poolAdmin.signer).rescueTokens(usdc.address, locker.address, amountToLock) - ); - - const aTokenBalanceAfter = await usdc.balanceOf(aDai.address); - expect(aTokenBalanceBefore).to.be.eq(aTokenBalanceAfter.add(amountToLock)); - const lockerBalanceAfter = await usdc.balanceOf(locker.address); - expect(lockerBalanceBefore).to.be.eq(lockerBalanceAfter.sub(amountToLock)); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/reserve-configuration.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/reserve-configuration.spec.ts deleted file mode 100644 index bdce2c4..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/reserve-configuration.spec.ts +++ /dev/null @@ -1,357 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber } from 'ethers'; -import { deployMockReserveConfiguration } from '@aave/deploy-v3/dist/helpers/contract-deployments'; -import { ProtocolErrors } from '../helpers/types'; -import { evmSnapshot, evmRevert } from '@aave/deploy-v3'; -import { MockReserveConfiguration } from '../types'; - -describe('ReserveConfiguration', async () => { - let snap: string; - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - afterEach(async () => { - await evmRevert(snap); - }); - - let configMock: MockReserveConfiguration; - - const ZERO = BigNumber.from(0); - const LTV = BigNumber.from(8000); - const LB = BigNumber.from(500); - const RESERVE_FACTOR = BigNumber.from(1000); - const DECIMALS = BigNumber.from(18); - const BORROW_CAP = BigNumber.from(100); - const SUPPLY_CAP = BigNumber.from(200); - const UNBACKED_MINT_CAP = BigNumber.from(300); - const EMODE_CATEGORY = BigNumber.from(1); - - const MAX_VALID_LTV = BigNumber.from(65535); - const MAX_VALID_LIQUIDATION_THRESHOLD = BigNumber.from(65535); - const MAX_VALID_DECIMALS = BigNumber.from(255); - const MAX_VALID_EMODE_CATEGORY = BigNumber.from(255); - const MAX_VALID_RESERVE_FACTOR = BigNumber.from(65535); - const MAX_VALID_LIQUIDATION_PROTOCOL_FEE = BigNumber.from(65535); - - before(async () => { - configMock = await deployMockReserveConfiguration(); - }); - - const bigNumbersToArrayString = (arr: BigNumber[]): string[] => arr.map((x) => x.toString()); - - it('getLtv()', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLtv()).to.be.eq(ZERO); - expect(await configMock.setLtv(LTV)); - // LTV is the 1st param - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([LTV, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLtv()).to.be.eq(LTV); - expect(await configMock.setLtv(0)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLtv()).to.be.eq(ZERO); - }); - - it('getLiquidationBonus()', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLiquidationBonus()).to.be.eq(ZERO); - expect(await configMock.setLiquidationBonus(LB)); - // LB is the 3rd param - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, LB, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLiquidationBonus()).to.be.eq(LB); - expect(await configMock.setLiquidationBonus(0)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLiquidationBonus()).to.be.eq(ZERO); - }); - - it('getDecimals()', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getDecimals()).to.be.eq(ZERO); - expect(await configMock.setDecimals(DECIMALS)); - // decimals is the 4th param - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, DECIMALS, ZERO, ZERO]) - ); - expect(await configMock.getDecimals()).to.be.eq(DECIMALS); - expect(await configMock.setDecimals(0)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getDecimals()).to.be.eq(ZERO); - }); - - it('getEModeCategory()', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getEModeCategory()).to.be.eq(ZERO); - expect(await configMock.setEModeCategory(EMODE_CATEGORY)); - // eMode category is the 6th param - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, EMODE_CATEGORY]) - ); - expect(await configMock.getEModeCategory()).to.be.eq(EMODE_CATEGORY); - expect(await configMock.setEModeCategory(0)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getEModeCategory()).to.be.eq(ZERO); - }); - - it('getFrozen()', async () => { - expect(await configMock.getFlags()).to.be.eql([false, false, false, false, false]); - expect(await configMock.getFrozen()).to.be.false; - expect(await configMock.setFrozen(true)); - // frozen is the 2nd flag - expect(await configMock.getFlags()).to.be.eql([false, true, false, false, false]); - expect(await configMock.getFrozen()).to.be.true; - expect(await configMock.setFrozen(false)); - expect(await configMock.getFlags()).to.be.eql([false, false, false, false, false]); - expect(await configMock.getFrozen()).to.be.false; - }); - - it('getBorrowingEnabled()', async () => { - expect(await configMock.getFlags()).to.be.eql([false, false, false, false, false]); - expect(await configMock.getBorrowingEnabled()).to.be.false; - expect(await configMock.setBorrowingEnabled(true)); - // borrowing is the 3rd flag - expect(await configMock.getFlags()).to.be.eql([false, false, true, false, false]); - expect(await configMock.getBorrowingEnabled()).to.be.true; - expect(await configMock.setBorrowingEnabled(false)); - expect(await configMock.getFlags()).to.be.eql([false, false, false, false, false]); - expect(await configMock.getBorrowingEnabled()).to.be.false; - }); - - it('getStableRateBorrowingEnabled()', async () => { - expect(await configMock.getFlags()).to.be.eql([false, false, false, false, false]); - expect(await configMock.getStableRateBorrowingEnabled()).to.be.false; - expect(await configMock.setStableRateBorrowingEnabled(true)); - // stable borrowing is the 4th flag - expect(await configMock.getFlags()).to.be.eql([false, false, false, true, false]); - expect(await configMock.getStableRateBorrowingEnabled()).to.be.true; - expect(await configMock.setStableRateBorrowingEnabled(false)); - expect(await configMock.getFlags()).to.be.eql([false, false, false, false, false]); - expect(await configMock.getStableRateBorrowingEnabled()).to.be.false; - }); - - it('getReserveFactor()', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getReserveFactor()).to.be.eq(ZERO); - expect(await configMock.setReserveFactor(RESERVE_FACTOR)); - // reserve factor is the 5th param - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, RESERVE_FACTOR, ZERO]) - ); - expect(await configMock.getReserveFactor()).to.be.eq(RESERVE_FACTOR); - expect(await configMock.setReserveFactor(ZERO)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getReserveFactor()).to.be.eq(ZERO); - }); - - it('setReserveFactor() with reserveFactor == MAX_VALID_RESERVE_FACTOR', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.setReserveFactor(MAX_VALID_RESERVE_FACTOR)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, MAX_VALID_RESERVE_FACTOR, ZERO]) - ); - }); - - it('setReserveFactor() with reserveFactor > MAX_VALID_RESERVE_FACTOR', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - await expect(configMock.setReserveFactor(MAX_VALID_RESERVE_FACTOR.add(1))).to.be.revertedWith( - ProtocolErrors.INVALID_RESERVE_FACTOR - ); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - }); - - it('getBorrowCap()', async () => { - expect(bigNumbersToArrayString(await configMock.getCaps())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO]) - ); - expect(await configMock.getBorrowCap()).to.be.eq(ZERO); - expect(await configMock.setBorrowCap(BORROW_CAP)); - // borrow cap is the 1st cap - expect(bigNumbersToArrayString(await configMock.getCaps())).to.be.eql( - bigNumbersToArrayString([BORROW_CAP, ZERO]) - ); - expect(await configMock.getBorrowCap()).to.be.eq(BORROW_CAP); - expect(await configMock.setBorrowCap(ZERO)); - expect(bigNumbersToArrayString(await configMock.getCaps())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO]) - ); - expect(await configMock.getBorrowCap()).to.be.eq(ZERO); - }); - - it('getSupplyCap()', async () => { - expect(bigNumbersToArrayString(await configMock.getCaps())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO]) - ); - expect(await configMock.getSupplyCap()).to.be.eq(ZERO); - expect(await configMock.setSupplyCap(SUPPLY_CAP)); - // supply cap is the 2nd cap - expect(bigNumbersToArrayString(await configMock.getCaps())).to.be.eql( - bigNumbersToArrayString([ZERO, SUPPLY_CAP]) - ); - expect(await configMock.getSupplyCap()).to.be.eq(SUPPLY_CAP); - expect(await configMock.setSupplyCap(ZERO)); - expect(bigNumbersToArrayString(await configMock.getCaps())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO]) - ); - expect(await configMock.getSupplyCap()).to.be.eq(ZERO); - }); - - it('getUnbackedMintCap()', async () => { - expect(await configMock.getUnbackedMintCap()).to.be.eq(ZERO); - expect(await configMock.setUnbackedMintCap(UNBACKED_MINT_CAP)); - expect(await configMock.getUnbackedMintCap()).to.be.eq(UNBACKED_MINT_CAP); - expect(await configMock.setUnbackedMintCap(ZERO)); - expect(await configMock.getUnbackedMintCap()).to.be.eq(ZERO); - }); - - it('setLtv() with ltv = MAX_VALID_LTV', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLtv()).to.be.eq(ZERO); - expect(await configMock.setLtv(MAX_VALID_LTV)); - // LTV is the 1st param - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([MAX_VALID_LTV, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLtv()).to.be.eq(MAX_VALID_LTV); - expect(await configMock.setLtv(0)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLtv()).to.be.eq(ZERO); - }); - - it('setLtv() with ltv > MAX_VALID_LTV (revert expected)', async () => { - expect(await configMock.getLtv()).to.be.eq(ZERO); - - const { INVALID_LTV } = ProtocolErrors; - - // setLTV to MAX_VALID_LTV + 1 - await expect(configMock.setLtv(MAX_VALID_LTV.add(1))).to.be.revertedWith(INVALID_LTV); - expect(await configMock.getLtv()).to.be.eq(ZERO); - }); - - it('setLiquidationThreshold() with threshold = MAX_VALID_LIQUIDATION_THRESHOLD', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLiquidationThreshold()).to.be.eq(ZERO); - expect(await configMock.setLiquidationThreshold(MAX_VALID_LIQUIDATION_THRESHOLD)); - // LIQ_THRESHOLD is the 2nd param - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, MAX_VALID_LIQUIDATION_THRESHOLD, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLiquidationThreshold()).to.be.eq(MAX_VALID_LIQUIDATION_THRESHOLD); - expect(await configMock.setLiquidationThreshold(0)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getLiquidationThreshold()).to.be.eq(ZERO); - }); - - it('setLiquidationThreshold() with threshold > MAX_VALID_LIQUIDATION_THRESHOLD (revert expected)', async () => { - expect(await configMock.getLiquidationThreshold()).to.be.eq(ZERO); - - const { INVALID_LIQ_THRESHOLD } = ProtocolErrors; - - // setLiquidationThreshold to MAX_VALID_LIQUIDATION_THRESHOLD + 1 - await expect( - configMock.setLiquidationThreshold(MAX_VALID_LIQUIDATION_THRESHOLD.add(1)) - ).to.be.revertedWith(INVALID_LIQ_THRESHOLD); - expect(await configMock.getLiquidationThreshold()).to.be.eq(ZERO); - }); - - it('setDecimals() with decimals = MAX_VALID_DECIMALS', async () => { - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getDecimals()).to.be.eq(ZERO); - expect(await configMock.setDecimals(MAX_VALID_DECIMALS)); - // Decimals is the 4th param - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, MAX_VALID_DECIMALS, ZERO, ZERO]) - ); - expect(await configMock.getDecimals()).to.be.eq(MAX_VALID_DECIMALS); - expect(await configMock.setDecimals(0)); - expect(bigNumbersToArrayString(await configMock.getParams())).to.be.eql( - bigNumbersToArrayString([ZERO, ZERO, ZERO, ZERO, ZERO, ZERO]) - ); - expect(await configMock.getDecimals()).to.be.eq(ZERO); - }); - - it('setDecimals() with decimals > MAX_VALID_DECIMALS (revert expected)', async () => { - expect(await configMock.getDecimals()).to.be.eq(ZERO); - - const { INVALID_DECIMALS } = ProtocolErrors; - - // setDecimals to MAX_VALID_DECIMALS + 1 - await expect(configMock.setDecimals(MAX_VALID_DECIMALS.add(1))).to.be.revertedWith( - INVALID_DECIMALS - ); - expect(await configMock.getDecimals()).to.be.eq(ZERO); - }); - - it('setEModeCategory() with categoryID = MAX_VALID_EMODE_CATEGORY', async () => { - expect(await configMock.getEModeCategory()).to.be.eq(ZERO); - expect(await configMock.setEModeCategory(MAX_VALID_EMODE_CATEGORY)); - expect(await configMock.getEModeCategory()).to.be.eq(MAX_VALID_EMODE_CATEGORY); - expect(await configMock.setEModeCategory(0)); - expect(await configMock.getEModeCategory()).to.be.eq(ZERO); - }); - - it('setEModeCategory() with categoryID > MAX_VALID_EMODE_CATEGORY (revert expected)', async () => { - expect(await configMock.getEModeCategory()).to.be.eq(ZERO); - - const { INVALID_EMODE_CATEGORY } = ProtocolErrors; - - await expect(configMock.setEModeCategory(MAX_VALID_EMODE_CATEGORY.add(1))).to.be.revertedWith( - INVALID_EMODE_CATEGORY - ); - expect(await configMock.getEModeCategory()).to.be.eq(ZERO); - }); - - it('setLiquidationProtocolFee() with liquidationProtocolFee == MAX_VALID_LIQUIDATION_PROTOCOL_FEE', async () => { - expect(await configMock.getLiquidationProtocolFee()).to.be.eq(ZERO); - expect(await configMock.setLiquidationProtocolFee(MAX_VALID_LIQUIDATION_PROTOCOL_FEE)); - expect(await configMock.getLiquidationProtocolFee()).to.be.eq( - MAX_VALID_LIQUIDATION_PROTOCOL_FEE - ); - }); - - it('setLiquidationProtocolFee() with liquidationProtocolFee > MAX_VALID_LIQUIDATION_PROTOCOL_FEE', async () => { - expect(await configMock.getLiquidationProtocolFee()).to.be.eq(ZERO); - await expect( - configMock.setLiquidationProtocolFee(MAX_VALID_LIQUIDATION_PROTOCOL_FEE.add(1)) - ).to.be.revertedWith(ProtocolErrors.INVALID_LIQUIDATION_PROTOCOL_FEE); - expect(await configMock.getLiquidationProtocolFee()).to.be.eq(ZERO); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/scenario.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/scenario.spec.ts deleted file mode 100644 index 7347ad6..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/scenario.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import fs from 'fs'; -import AaveConfig from '@aave/deploy-v3/dist/markets/aave'; -import { configuration as actionsConfiguration } from './helpers/actions'; -import { configuration as calculationsConfiguration } from './helpers/utils/calculations'; -import { makeSuite } from './helpers/make-suite'; -import { executeStory } from './helpers/scenario-engine'; - -const scenarioFolder = './test-suites/helpers/scenarios/'; - -const selectedScenarios: string[] = []; //"borrow-repay-stable-edge.json", "borrow-repay-stable.json"]; - -fs.readdirSync(scenarioFolder).forEach((file) => { - if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; - - const scenario = require(`./helpers/scenarios/${file}`); - - makeSuite(scenario.title, async (testEnv) => { - before('Initializing configuration', async () => { - actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage - - calculationsConfiguration.reservesParams = AaveConfig.ReservesConfig; - }); - - for (const story of scenario.stories) { - it(story.description, async function () { - // Retry the test scenarios up to 4 times in case random HEVM network errors happen - //this.retries(4); - await executeStory(story, testEnv); - }); - } - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/siloed-borrowing.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/siloed-borrowing.spec.ts deleted file mode 100644 index 3c97f0a..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/siloed-borrowing.spec.ts +++ /dev/null @@ -1,188 +0,0 @@ -const { expect } = require('chai'); -import { utils, BigNumber } from 'ethers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { AAVE_REFERRAL, MAX_UINT_AMOUNT, MAX_UNBACKED_MINT_CAP } from '../helpers/constants'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { TestEnv, makeSuite } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; -import { evmSnapshot } from '@aave/deploy-v3'; - -makeSuite('Siloed borrowing', (testEnv: TestEnv) => { - const { SILOED_BORROWING_VIOLATION } = ProtocolErrors; - - let snapshot; - - before(async () => { - snapshot = await evmSnapshot(); - }); - - it('Configure DAI as siloed borrowing asset', async () => { - const { configurator, helpersContract, dai } = testEnv; - - await configurator.setSiloedBorrowing(dai.address, true); - const siloed = await helpersContract.getSiloedBorrowing(dai.address); - - expect(siloed).to.be.equal(true, 'Invalid siloed state for DAI'); - }); - - it('User 0 supplies DAI, User 1 supplies ETH and USDC, borrows DAI', async () => { - const { users, pool, dai, weth, usdc, variableDebtDai } = testEnv; - - const wethSupplyAmount = utils.parseEther('1'); - const daiBorrowAmount = utils.parseEther('10'); - const daiSupplyAmount = utils.parseEther('1000'); - const usdcSupplyAmount = utils.parseUnits('1000', 6); - - await dai.connect(users[0].signer)['mint(address,uint256)'](users[0].address, daiSupplyAmount); - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[0].signer).supply(dai.address, daiSupplyAmount, users[0].address, '0'); - - await usdc - .connect(users[1].signer) - ['mint(address,uint256)'](users[1].address, usdcSupplyAmount); - await usdc.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .supply(usdc.address, usdcSupplyAmount, users[1].address, '0'); - - await weth - .connect(users[1].signer) - ['mint(address,uint256)'](users[1].address, wethSupplyAmount); - await weth.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .supply(weth.address, wethSupplyAmount, users[1].address, '0'); - await pool - .connect(users[1].signer) - .borrow(dai.address, daiBorrowAmount, RateMode.Variable, '0', users[1].address); - - const debtBalance = await variableDebtDai.balanceOf(users[1].address); - - expect(debtBalance).to.be.closeTo(daiBorrowAmount, 2); - }); - - it('User 0 supplies USDC, User 1 tries to borrow USDC (revert expected)', async () => { - const { users, pool, usdc } = testEnv; - - const usdcBorrowAmount = utils.parseUnits('1', '6'); - const usdcSupplyAmount = utils.parseUnits('1000', '6'); - - await usdc - .connect(users[0].signer) - ['mint(address,uint256)'](users[0].address, usdcSupplyAmount); - await usdc.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[0].signer) - .supply(usdc.address, usdcSupplyAmount, users[0].address, '0'); - - await expect( - pool - .connect(users[1].signer) - .borrow(usdc.address, usdcBorrowAmount, RateMode.Variable, '0', users[1].address) - ).to.be.revertedWith(SILOED_BORROWING_VIOLATION); - }); - - it('User 1 repays DAI, borrows USDC', async () => { - const { users, pool, usdc, dai } = testEnv; - - const usdcBorrowAmount = utils.parseUnits('100', '6'); - const daiMintAmount = utils.parseEther('1000'); - - await dai.connect(users[1].signer)['mint(address,uint256)'](users[1].address, daiMintAmount); - await dai.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .repay(dai.address, MAX_UINT_AMOUNT, RateMode.Variable, users[1].address); - - await pool - .connect(users[1].signer) - .borrow(usdc.address, usdcBorrowAmount, RateMode.Variable, '0', users[1].address); - }); - - it('User 1 tries to borrow DAI (revert expected)', async () => { - const { users, pool, dai } = testEnv; - - const daiBorrowAmount = utils.parseEther('1'); - - await expect( - pool - .connect(users[1].signer) - .borrow(dai.address, daiBorrowAmount, RateMode.Variable, '0', users[1].address) - ).to.be.revertedWith(SILOED_BORROWING_VIOLATION); - }); - - it('User 1 borrows ETH, tries to borrow DAI (revert expected)', async () => { - const { users, pool, dai, weth } = testEnv; - - const wethBorrowAmount = utils.parseEther('0.01'); - const daiBorrowAmount = utils.parseEther('1'); - - await pool - .connect(users[1].signer) - .borrow(weth.address, wethBorrowAmount, RateMode.Variable, '0', users[1].address); - - await expect( - pool - .connect(users[1].signer) - .borrow(dai.address, daiBorrowAmount, RateMode.Variable, '0', users[1].address) - ).to.be.revertedWith(SILOED_BORROWING_VIOLATION); - }); - - it('User 1 Repays USDC and WETH debt, set USDC as siloed', async () => { - const { users, pool, usdc, weth, configurator, helpersContract } = testEnv; - - const wethMintAmount = utils.parseEther('1'); - - const usdcMintAmount = utils.parseEther('1000'); - - await usdc.connect(users[1].signer)['mint(address,uint256)'](users[1].address, usdcMintAmount); - await usdc.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .repay(usdc.address, MAX_UINT_AMOUNT, RateMode.Variable, users[1].address); - - await weth.connect(users[1].signer)['mint(address,uint256)'](users[1].address, wethMintAmount); - await pool - .connect(users[1].signer) - .repay(weth.address, MAX_UINT_AMOUNT, RateMode.Variable, users[1].address); - - await configurator.setSiloedBorrowing(usdc.address, true); - const siloed = await helpersContract.getSiloedBorrowing(usdc.address); - - expect(siloed).to.be.equal(true, 'Invalid siloed state for USDC'); - }); - - it('User 1 borrows DAI, tries to borrow USDC (revert expected)', async () => { - const { users, pool, usdc, dai } = testEnv; - - const daiBorrowAmount = utils.parseEther('1'); - const usdcBorrowAmount = utils.parseUnits('1', '6'); - - await pool - .connect(users[1].signer) - .borrow(dai.address, daiBorrowAmount, RateMode.Variable, '0', users[1].address); - - await expect( - pool - .connect(users[1].signer) - .borrow(usdc.address, usdcBorrowAmount, RateMode.Variable, '0', users[1].address) - ).to.be.revertedWith(SILOED_BORROWING_VIOLATION); - }); - - it('User 1 borrows more DAI', async () => { - const { users, pool, dai, variableDebtDai } = testEnv; - - const daiBorrowAmount = utils.parseEther('1'); - - const debtBefore = await variableDebtDai.balanceOf(users[1].address); - - await pool - .connect(users[1].signer) - .borrow(dai.address, daiBorrowAmount, RateMode.Variable, '0', users[1].address); - - const debtAfter = await variableDebtDai.balanceOf(users[1].address); - - //large interval to account for interest generated - expect(debtAfter).to.be.closeTo(debtBefore.add(daiBorrowAmount), 10000000); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/stable-debt-token.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/stable-debt-token.spec.ts deleted file mode 100644 index 4546e63..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/stable-debt-token.spec.ts +++ /dev/null @@ -1,351 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber, utils } from 'ethers'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { MAX_UINT_AMOUNT, RAY, ZERO_ADDRESS } from '../helpers/constants'; -import { impersonateAccountsHardhat, setAutomine } from '../helpers/misc-utils'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { topUpNonPayableWithEther } from './helpers/utils/funds'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { evmRevert, evmSnapshot, increaseTime, waitForTx } from '@aave/deploy-v3'; -import { StableDebtToken__factory } from '../types'; -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('StableDebtToken', (testEnv: TestEnv) => { - const { CALLER_MUST_BE_POOL, CALLER_NOT_POOL_ADMIN } = ProtocolErrors; - let snap: string; - - before(async () => { - snap = await evmSnapshot(); - }); - - it('Check initialization', async () => { - const { pool, weth, dai, helpersContract, users } = testEnv; - const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) - .stableDebtTokenAddress; - const stableDebtContract = StableDebtToken__factory.connect( - daiStableDebtTokenAddress, - users[0].signer - ); - - expect(await stableDebtContract.UNDERLYING_ASSET_ADDRESS()).to.be.eq(dai.address); - expect(await stableDebtContract.POOL()).to.be.eq(pool.address); - expect(await stableDebtContract.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - - const totSupplyAndRateBefore = await stableDebtContract.getTotalSupplyAndAvgRate(); - expect(totSupplyAndRateBefore[0].toString()).to.be.eq('0'); - expect(totSupplyAndRateBefore[1].toString()).to.be.eq('0'); - - // Need to create some debt to do this good - await dai - .connect(users[0].signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[0].signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, '1000'), - users[0].address, - 0 - ); - await weth.connect(users[1].signer)['mint(uint256)'](utils.parseEther('10')); - await weth.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .deposit(weth.address, utils.parseEther('10'), users[1].address, 0); - await pool - .connect(users[1].signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '200'), - RateMode.Stable, - 0, - users[1].address - ); - - const totSupplyAndRateAfter = await stableDebtContract.getTotalSupplyAndAvgRate(); - expect(totSupplyAndRateAfter[0]).to.be.gt(0); - expect(totSupplyAndRateAfter[1]).to.be.gt(0); - }); - - it('Tries to mint not being the Pool (revert expected)', async () => { - const { deployer, dai, helpersContract } = testEnv; - - const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) - .stableDebtTokenAddress; - - const stableDebtContract = StableDebtToken__factory.connect( - daiStableDebtTokenAddress, - deployer.signer - ); - - await expect( - stableDebtContract.mint(deployer.address, deployer.address, '1', '1') - ).to.be.revertedWith(CALLER_MUST_BE_POOL); - }); - - it('Tries to burn not being the Pool (revert expected)', async () => { - const { deployer, dai, helpersContract } = testEnv; - - const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) - .stableDebtTokenAddress; - - const stableDebtContract = StableDebtToken__factory.connect( - daiStableDebtTokenAddress, - deployer.signer - ); - - const name = await stableDebtContract.name(); - - expect(name).to.be.equal('Aave Testnet stable debt bearing DAI'); - await expect(stableDebtContract.burn(deployer.address, '1')).to.be.revertedWith( - CALLER_MUST_BE_POOL - ); - }); - - it('Tries to transfer debt tokens (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) - .stableDebtTokenAddress; - const stableDebtContract = StableDebtToken__factory.connect( - daiStableDebtTokenAddress, - users[0].signer - ); - - await expect( - stableDebtContract.connect(users[0].signer).transfer(users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Check Mint and Transfer events when borrowing on behalf', async () => { - const snapId = await evmSnapshot(); - const { - pool, - weth, - dai, - usdc, - users: [user1, user2, user3], - } = testEnv; - - // Add USDC liquidity - await usdc.connect(user3.signer)['mint(uint256)'](utils.parseUnits('1000', 6)); - await usdc.connect(user3.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user3.signer) - .supply(usdc.address, utils.parseUnits('1000', 6), user3.address, 0); - - // User1 supplies 10 WETH - await weth.connect(user1.signer)['mint(uint256)'](utils.parseUnits('10', 18)); - await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user1.signer) - .supply(weth.address, utils.parseUnits('10', 18), user1.address, 0); - - const usdcData = await pool.getReserveData(usdc.address); - const stableDebtToken = StableDebtToken__factory.connect( - usdcData.stableDebtTokenAddress, - user1.signer - ); - const beforeDebtBalanceUser2 = await stableDebtToken.balanceOf(user2.address); - - // User1 borrows 100 USDC - const borrowAmount = utils.parseUnits('100', 6); - expect( - await pool - .connect(user1.signer) - .borrow(usdc.address, borrowAmount, RateMode.Stable, 0, user1.address) - ); - - // User1 approves user2 to borrow 1000 USDC - expect( - await stableDebtToken - .connect(user1.signer) - .approveDelegation(user2.address, utils.parseUnits('1000', 6)) - ); - - // Increase time so interests accrue - await increaseTime(24 * 3600); - - // User2 borrows 1000 USDC on behalf of user1 - const borrowOnBehalfAmount = utils.parseUnits('100', 6); - const tx = await waitForTx( - await pool - .connect(user2.signer) - .borrow(usdc.address, borrowOnBehalfAmount, RateMode.Stable, 0, user1.address) - ); - - const afterDebtBalanceUser1 = await stableDebtToken.balanceOf(user1.address); - const afterDebtBalanceUser2 = await stableDebtToken.balanceOf(user2.address); - - // Calculate interests - const expectedDebtIncreaseUser1 = afterDebtBalanceUser1.sub( - borrowOnBehalfAmount.add(borrowAmount) - ); - - const transferEventSig = utils.keccak256( - utils.toUtf8Bytes('Transfer(address,address,uint256)') - ); - const mintEventSig = utils.keccak256( - utils.toUtf8Bytes('Mint(address,address,uint256,uint256,uint256,uint256,uint256,uint256)') - ); - - const rawTransferEvents = tx.logs.filter( - ({ topics, address }) => topics[0] === transferEventSig && address == stableDebtToken.address - ); - const transferAmount = stableDebtToken.interface.parseLog(rawTransferEvents[0]).args.value; - - const rawMintEvents = tx.logs.filter( - ({ topics, address }) => topics[0] === mintEventSig && address == stableDebtToken.address - ); - const { amount: mintAmount, balanceIncrease } = stableDebtToken.interface.parseLog( - rawMintEvents[0] - ).args; - - expect(expectedDebtIncreaseUser1.add(borrowOnBehalfAmount)).to.be.eq(transferAmount); - expect(borrowOnBehalfAmount.add(balanceIncrease)).to.be.eq(mintAmount); - expect(expectedDebtIncreaseUser1).to.be.eq(balanceIncrease); - expect(afterDebtBalanceUser2).to.be.eq(beforeDebtBalanceUser2); - - await evmRevert(snapId); - }); - - it('Tries to approve debt tokens (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) - .stableDebtTokenAddress; - const stableDebtContract = StableDebtToken__factory.connect( - daiStableDebtTokenAddress, - users[0].signer - ); - - await expect( - stableDebtContract.connect(users[0].signer).approve(users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - await expect( - stableDebtContract.allowance(users[0].address, users[1].address) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Tries to increase allowance of debt tokens (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) - .stableDebtTokenAddress; - const stableDebtContract = StableDebtToken__factory.connect( - daiStableDebtTokenAddress, - users[0].signer - ); - - await expect( - stableDebtContract.connect(users[0].signer).increaseAllowance(users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Tries to decrease allowance of debt tokens (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) - .stableDebtTokenAddress; - const stableDebtContract = StableDebtToken__factory.connect( - daiStableDebtTokenAddress, - users[0].signer - ); - - await expect( - stableDebtContract.connect(users[0].signer).decreaseAllowance(users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Tries to transferFrom (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) - .stableDebtTokenAddress; - const stableDebtContract = StableDebtToken__factory.connect( - daiStableDebtTokenAddress, - users[0].signer - ); - - await expect( - stableDebtContract - .connect(users[0].signer) - .transferFrom(users[0].address, users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Burn stable debt tokens such that `secondTerm >= firstTerm`', async () => { - // To enter the case where secondTerm >= firstTerm, we also need previousSupply <= amount. - // The easiest way is to use two users, such that for user 2 his stableRate > average stableRate. - // In practice to enter the case we can perform the following actions - // user 1 borrow 2 wei at rate = 10**27 - // user 2 borrow 1 wei rate = 10**30 - // progress time by a year, to accrue significant debt. - // then let user 2 withdraw sufficient funds such that secondTerm (userStableRate * burnAmount) >= averageRate * supply - // if we do not have user 1 deposit as well, we will have issues getting past previousSupply <= amount, as amount > supply for secondTerm to be > firstTerm. - await evmRevert(snap); - const rateGuess1 = BigNumber.from(RAY); - const rateGuess2 = BigNumber.from(10).pow(30); - const amount1 = BigNumber.from(2); - const amount2 = BigNumber.from(1); - - const { deployer, pool, dai, helpersContract, users } = testEnv; - - // Impersonate the Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - const config = await helpersContract.getReserveTokensAddresses(dai.address); - const stableDebt = StableDebtToken__factory.connect( - config.stableDebtTokenAddress, - deployer.signer - ); - - // Next two txs should be mined in the same block - await setAutomine(false); - await stableDebt - .connect(poolSigner) - .mint(users[0].address, users[0].address, amount1, rateGuess1); - - await stableDebt - .connect(poolSigner) - .mint(users[1].address, users[1].address, amount2, rateGuess2); - await setAutomine(true); - - await increaseTime(60 * 60 * 24 * 365); - const totalSupplyAfterTime = BigNumber.from(18798191); - await stableDebt.connect(poolSigner).burn(users[1].address, totalSupplyAfterTime.sub(1)); - }); - - it('setIncentivesController() ', async () => { - const snapshot = await evmSnapshot(); - const { dai, helpersContract, poolAdmin, aclManager, deployer } = testEnv; - const config = await helpersContract.getReserveTokensAddresses(dai.address); - const stableDebt = StableDebtToken__factory.connect( - config.stableDebtTokenAddress, - deployer.signer - ); - - expect(await aclManager.connect(deployer.signer).addPoolAdmin(poolAdmin.address)); - - expect(await stableDebt.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - expect(await stableDebt.connect(poolAdmin.signer).setIncentivesController(ZERO_ADDRESS)); - expect(await stableDebt.getIncentivesController()).to.be.eq(ZERO_ADDRESS); - - await evmRevert(snapshot); - }); - - it('setIncentivesController() from not pool admin (revert expected)', async () => { - const { - dai, - helpersContract, - users: [user], - } = testEnv; - const config = await helpersContract.getReserveTokensAddresses(dai.address); - const stableDebt = StableDebtToken__factory.connect(config.stableDebtTokenAddress, user.signer); - - expect(await stableDebt.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - - await expect( - stableDebt.connect(user.signer).setIncentivesController(ZERO_ADDRESS) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/subgraph-scenarios.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/subgraph-scenarios.spec.ts deleted file mode 100644 index 4035e7f..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/subgraph-scenarios.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { configuration as actionsConfiguration } from './helpers/actions'; -import { configuration as calculationsConfiguration } from './helpers/utils/calculations'; -import { makeSuite } from './helpers/make-suite'; -import { executeStory } from './helpers/scenario-engine'; -import AaveConfig from '@aave/deploy-v3/dist/markets/aave'; - -makeSuite('Subgraph scenario tests', async (testEnv) => { - let story: any; - - before('Initializing configuration', async () => { - const scenario = require(`./helpers/scenarios/borrow-repay-stable`); - story = scenario.stories[0]; - - actionsConfiguration.skipIntegrityCheck = false; //set this to true to execute solidity-coverage - - calculationsConfiguration.reservesParams = AaveConfig.ReservesConfig; - }); - it('deposit-borrow', async () => { - await executeStory(story, testEnv); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/upgradeability.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/upgradeability.spec.ts deleted file mode 100644 index 9f2f711..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/upgradeability.spec.ts +++ /dev/null @@ -1,561 +0,0 @@ -import { expect } from 'chai'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { ProtocolErrors } from '../helpers/types'; -import { ONE_ADDRESS, ZERO_ADDRESS } from '../helpers/constants'; -import { - getAToken, - getMockInitializableImple, - getMockInitializableImpleV2, - getMockStableDebtToken, - getMockVariableDebtToken, - getStableDebtToken, - getVariableDebtToken, -} from '@aave/deploy-v3/dist/helpers/contract-getters'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { - deployInitializableImmutableAdminUpgradeabilityProxy, - deployMockAToken, - deployMockInitializableFromConstructorImple, - deployMockInitializableImple, - deployMockInitializableImpleV2, - deployMockReentrantInitializableImple, - deployMockStableDebtToken, - deployMockVariableDebtToken, -} from '@aave/deploy-v3/dist/helpers/contract-deployments'; -import { - InitializableImmutableAdminUpgradeabilityProxy, - InitializableImmutableAdminUpgradeabilityProxy__factory, -} from '../types'; -import { evmSnapshot, evmRevert, getEthersSigners } from '@aave/deploy-v3'; - -makeSuite('Upgradeability', (testEnv: TestEnv) => { - context('VersionedInitializable', async () => { - it('Call initialize from the constructor function', async () => { - const initValue = '1'; - const implementation = await deployMockInitializableFromConstructorImple([initValue]); - expect(await implementation.value()).to.be.eq(initValue); - }); - - it('Call initialize from the initialize function (reentrant)', async () => { - const initValue = 1; - const finalValue = 2; - const implementation = await deployMockReentrantInitializableImple(); - expect(await implementation.initialize(initValue)); - expect(await implementation.value()).to.be.eq(finalValue, `value is not ${finalValue}`); - }); - - it('Tries to initialize once it is already initialized (revert expected)', async () => { - const implementation = await deployMockInitializableImple(); - expect( - await implementation.initialize( - 10, // value - 'some text', // text - [10, 20, 30] - ) - ); - await expect( - implementation.initialize( - 100, // value - 'some text', // text - [100, 200, 300] - ) - ).to.be.revertedWith('Contract instance has already been initialized'); - }); - }); - - context('InitializableImmutableAdminUpgradeabilityProxy', async () => { - let snap: string; - - let proxyAdminOwner, newAdmin, nonAdmin; - let implementationV1, implementationV2, proxiedImpl; - let proxy: InitializableImmutableAdminUpgradeabilityProxy; - - beforeEach(async () => { - snap = await evmSnapshot(); - - implementationV1 = await deployMockInitializableImple(); - implementationV2 = await deployMockInitializableImpleV2(); - const encodedInitialize = implementationV1.interface.encodeFunctionData('initialize', [ - 0, // value - 'text', // text - [1, 2, 3], // values - ]); - proxy = await deployInitializableImmutableAdminUpgradeabilityProxy([proxyAdminOwner.address]); - expect(await proxy.initialize(implementationV1.address, encodedInitialize)); - proxiedImpl = await getMockInitializableImple(proxy.address); - }); - afterEach(async () => { - await evmRevert(snap); - }); - - before(async () => { - const { users } = testEnv; - [proxyAdminOwner, newAdmin, nonAdmin] = users; - [proxyAdminOwner, newAdmin, nonAdmin] = await getEthersSigners(); - }); - - it('initialize() implementation version is correct', async () => { - expect(await proxiedImpl.connect(nonAdmin).REVISION()).to.be.eq(1, 'impl revision is not 1'); - }); - - it('initialize() implementation initialization is correct', async () => { - expect(await proxiedImpl.connect(nonAdmin).value()).to.be.eq(0, 'impl value is not 0'); - expect(await proxiedImpl.connect(nonAdmin).text()).to.be.eq( - 'text', - 'impl text is not correct' - ); - expect(await proxiedImpl.connect(nonAdmin).values(0)).to.be.eq(1, 'impl values[0] is not 1'); - expect(await proxiedImpl.connect(nonAdmin).values(1)).to.be.eq(2, 'impl values[1] is not 2'); - expect(await proxiedImpl.connect(nonAdmin).values(2)).to.be.eq(3, 'impl values[2] is not 3'); - }); - - it('initialize() when initializing the proxy once it is already initialized (revert expected)', async () => { - const encodedInitialize = proxiedImpl.interface.encodeFunctionData('initialize', [ - 10, // value - 'some text', // text - [10, 20, 30], - ]); - await expect(proxy.initialize(implementationV1.address, encodedInitialize)).to.be.reverted; - }); - - it('initialize() when initializing the impl from non-admin address once it is already initialized (revert expected)', async () => { - await expect( - proxiedImpl.connect(nonAdmin).initialize( - 10, // value - 'some text', // text - [10, 20, 30] - ) - ).to.be.revertedWith('Contract instance has already been initialized'); - }); - - it('initialize() when initializing the impl from admin address once it is already initialized (revert expected)', async () => { - await expect( - proxiedImpl.connect(proxyAdminOwner).initialize( - 10, // value - 'some text', // text - [10, 20, 30] - ) - ).to.be.revertedWith('Cannot call fallback function from the proxy admin'); - }); - - it('initialize() deploy a proxy and call to initialize() with no initialization data', async () => { - proxy = await ( - await new InitializableImmutableAdminUpgradeabilityProxy__factory( - await getFirstSigner() - ).deploy(proxyAdminOwner.address) - ).deployed(); - expect(await proxy.initialize(implementationV1.address, Buffer.from(''))); - }); - - it('initialize() while calling initialize() with wrong initialization data (revert expected)', async () => { - proxy = await ( - await new InitializableImmutableAdminUpgradeabilityProxy__factory( - await getFirstSigner() - ).deploy(proxyAdminOwner.address) - ).deployed(); - // Initialize with wrong initialization data - await expect(proxy.initialize(implementationV1.address, Buffer.from('wrongInitialize'))).to.be - .reverted; - }); - - it('admin() non-view function from admin address', async () => { - expect(await proxy.connect(proxyAdminOwner).admin()); - }); - - it('admin() non-view function from non-admin address', async () => { - await expect(proxy.connect(nonAdmin).admin()).to.be.reverted; - }); - - it('admin() callStatic from admin address', async () => { - expect(await proxy.connect(proxyAdminOwner).callStatic.admin()).to.be.eq( - proxyAdminOwner.address, - 'proxy admin address not correct' - ); - }); - - it('implementation() non-view function from admin address', async () => { - expect(await proxy.connect(proxyAdminOwner).implementation()); - }); - - it('implementation() non-view function from non-admin address', async () => { - await expect(proxy.connect(nonAdmin).implementation()).to.be.reverted; - }); - - it('implementation() callStatic from admin address', async () => { - expect(await proxy.connect(proxyAdminOwner).callStatic.implementation()).to.be.eq( - implementationV1.address, - 'proxy implementation address not correct' - ); - }); - - it('upgradeTo() to a new imple from non-admin address (revert expected)', async () => { - await expect(proxy.connect(nonAdmin).upgradeTo(implementationV2.address)).to.be.reverted; - }); - - it('upgradeTo() to a non-contract imple from admin address (revert expected)', async () => { - await expect(proxy.connect(proxyAdminOwner).upgradeTo(ONE_ADDRESS)).to.be.revertedWith( - 'Cannot set a proxy implementation to a non-contract address' - ); - }); - - it('upgradeTo() to a new imple from admin address', async () => { - expect(await proxiedImpl.connect(nonAdmin).REVISION()).to.be.eq(1, 'impl revision is not 1'); - - await expect(proxy.connect(proxyAdminOwner).upgradeTo(implementationV2.address)) - .to.emit(proxy, 'Upgraded') - .withArgs(implementationV2.address); - - proxiedImpl = await getMockInitializableImpleV2(proxy.address); - expect(await proxiedImpl.connect(nonAdmin).REVISION()).to.be.eq(2, 'impl revision is not 2'); - - // Check proxy storage layout keeps the same - expect(await proxiedImpl.connect(nonAdmin).value()).to.be.eq(0, 'impl value is not 0'); - expect(await proxiedImpl.connect(nonAdmin).text()).to.be.eq( - 'text', - 'impl text is not correct' - ); - expect(await proxiedImpl.connect(nonAdmin).values(0)).to.be.eq(1, 'impl values[0] is not 1'); - expect(await proxiedImpl.connect(nonAdmin).values(1)).to.be.eq(2, 'impl values[1] is not 2'); - expect(await proxiedImpl.connect(nonAdmin).values(2)).to.be.eq(3, 'impl values[2] is not 3'); - - // Initialize - await proxiedImpl.connect(nonAdmin).initialize( - 10, // value - 'some text', // text - [10, 20, 30] - ); - expect(await proxiedImpl.connect(nonAdmin).value()).to.be.eq(10, 'impl value is not 0'); - expect(await proxiedImpl.connect(nonAdmin).text()).to.be.eq( - 'some text', - 'impl text not correct' - ); - expect(await proxiedImpl.connect(nonAdmin).values(0)).to.be.eq(10, 'impl values[0] not 10'); - expect(await proxiedImpl.connect(nonAdmin).values(1)).to.be.eq(20, 'impl values[1] not 20'); - expect(await proxiedImpl.connect(nonAdmin).values(2)).to.be.eq(30, 'impl values[2] not 30'); - }); - - it('upgradeTo() when initializing the new imple from admin address (revert expected)', async () => { - await expect(proxy.connect(proxyAdminOwner).upgradeTo(implementationV2.address)) - .to.emit(proxy, 'Upgraded') - .withArgs(implementationV2.address); - // Initialize - await proxiedImpl.connect(nonAdmin).initialize( - 10, // value - 'some text', // text - [10, 20, 30] - ); - await expect( - proxiedImpl.connect(nonAdmin).initialize( - 10, // value - 'some text', // text - [10, 20, 30] - ) - ).to.be.revertedWith('Contract instance has already been initialized'); - }); - - it('upgradeToAndCall() to a new impl from non-admin address (revert expected)', async () => { - await expect( - proxy.connect(nonAdmin).upgradeToAndCall(implementationV2.address, Buffer.from('')) - ).to.be.reverted; - }); - - it('upgradeToAndCall() to a non-contract impl from admin address (revert expected)', async () => { - await expect( - proxy.connect(proxyAdminOwner).upgradeToAndCall(ONE_ADDRESS, Buffer.from('')) - ).to.be.revertedWith('Cannot set a proxy implementation to a non-contract address'); - }); - - it('upgradeToAndCall() to a new impl from admin address', async () => { - expect(await proxiedImpl.connect(nonAdmin).REVISION()).to.be.eq(1, 'impl revision is not 1'); - - const encodedInitialize = implementationV1.interface.encodeFunctionData('initialize', [ - 10, // value - 'some text', // text - [10, 20, 30], - ]); - await expect( - proxy.connect(proxyAdminOwner).upgradeToAndCall(implementationV2.address, encodedInitialize) - ) - .to.emit(proxy, 'Upgraded') - .withArgs(implementationV2.address); - - proxiedImpl = await getMockInitializableImpleV2(proxy.address); - - // Check initialization - expect(await proxiedImpl.connect(nonAdmin).REVISION()).to.be.eq(2, 'impl revision is not 2'); - expect(await proxiedImpl.connect(nonAdmin).value()).to.be.eq(10, 'impl value is not 0'); - expect(await proxiedImpl.connect(nonAdmin).text()).to.be.eq( - 'some text', - 'impl text not correct' - ); - expect(await proxiedImpl.connect(nonAdmin).values(0)).to.be.eq(10, 'impl values[0] not 10'); - expect(await proxiedImpl.connect(nonAdmin).values(1)).to.be.eq(20, 'impl values[1] not 20'); - expect(await proxiedImpl.connect(nonAdmin).values(2)).to.be.eq(30, 'impl values[2] not 30'); - }); - - it('upgradeToAndCall() for a new proxied contract with no initialize function (revert expected)', async () => { - const impl = await deployMockInitializableImple(); - const encodedInitialize = Buffer.from(''); - await expect(proxy.connect(proxyAdminOwner).upgradeToAndCall(impl.address, encodedInitialize)) - .reverted; - }); - - it('upgradeToAndCall() when initializing the new impl from admin address once it is already initialized (revert expected)', async () => { - const encodedInitialize = implementationV1.interface.encodeFunctionData('initialize', [ - 10, // value - 'some text', // text - [10, 20, 30], - ]); - await expect( - proxy.connect(proxyAdminOwner).upgradeToAndCall(implementationV2.address, encodedInitialize) - ) - .to.emit(proxy, 'Upgraded') - .withArgs(implementationV2.address); - await expect( - proxiedImpl.connect(nonAdmin).initialize( - 10, // value - 'some text', // text - [10, 20, 30] - ) - ).to.be.revertedWith('Contract instance has already been initialized'); - }); - - it('implementation.setValue() call through the proxy', async () => { - const newValue = 123; - expect(await proxiedImpl.connect(nonAdmin).value()).to.be.eq(0, 'value not correct'); - expect(await proxiedImpl.connect(nonAdmin).setValueViaProxy(newValue)); - expect(await proxiedImpl.connect(nonAdmin).value()).to.be.eq(123, 'value not correct'); - }); - - it('implementation.setValue() direct call to the implementation', async () => { - const newValue = 123; - expect(await implementationV1.value()).to.be.eq(0, 'value not correct'); - expect(await implementationV1.setValue(newValue)); - expect(await implementationV1.value()).to.be.eq(123, 'value not correct'); - }); - }); - - context('PoolConfigurator upgrade ability', () => { - const { CALLER_NOT_POOL_ADMIN } = ProtocolErrors; - let newATokenAddress: string; - let newStableTokenAddress: string; - let newVariableTokenAddress: string; - - before('deploying instances', async () => { - const { dai, pool } = testEnv; - const aTokenInstance = await deployMockAToken([ - pool.address, - dai.address, - ZERO_ADDRESS, - ZERO_ADDRESS, - 'Aave Interest bearing DAI updated', - 'aDAI', - '0x10', - ]); - - const stableDebtTokenInstance = await deployMockStableDebtToken([ - pool.address, - dai.address, - ZERO_ADDRESS, - 'Aave stable debt bearing DAI updated', - 'stableDebtDAI', - '0x10', - ]); - - const variableDebtTokenInstance = await deployMockVariableDebtToken([ - pool.address, - dai.address, - ZERO_ADDRESS, - 'Aave variable debt bearing DAI updated', - 'variableDebtDAI', - '0x10', - ]); - - newATokenAddress = aTokenInstance.address; - newVariableTokenAddress = variableDebtTokenInstance.address; - newStableTokenAddress = stableDebtTokenInstance.address; - }); - - it('Tries to update the DAI Atoken implementation with a different address than the poolManager', async () => { - const { dai, configurator, users } = testEnv; - - const name = await (await getAToken(newATokenAddress)).name(); - const symbol = await (await getAToken(newATokenAddress)).symbol(); - - const updateATokenInputParams: { - asset: string; - treasury: string; - incentivesController: string; - name: string; - symbol: string; - implementation: string; - params: string; - } = { - asset: dai.address, - treasury: ZERO_ADDRESS, - incentivesController: ZERO_ADDRESS, - name: name, - symbol: symbol, - implementation: newATokenAddress, - params: '0x10', - }; - await expect( - configurator.connect(users[1].signer).updateAToken(updateATokenInputParams) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); - - it('Upgrades the DAI Atoken implementation ', async () => { - const { dai, configurator, aDai } = testEnv; - - const name = await (await getAToken(newATokenAddress)).name(); - const symbol = await (await getAToken(newATokenAddress)).symbol(); - - const updateATokenInputParams: { - asset: string; - treasury: string; - incentivesController: string; - name: string; - symbol: string; - implementation: string; - params: string; - } = { - asset: dai.address, - treasury: ZERO_ADDRESS, - incentivesController: ZERO_ADDRESS, - name: name, - symbol: symbol, - implementation: newATokenAddress, - params: '0x10', - }; - await configurator.updateAToken(updateATokenInputParams); - - const tokenName = await aDai.name(); - - expect(tokenName).to.be.eq('Aave Interest bearing DAI updated', 'Invalid token name'); - }); - - it('Tries to update the DAI Stable debt token implementation with a different address than the poolManager', async () => { - const { dai, configurator, users } = testEnv; - - const name = await (await getStableDebtToken(newStableTokenAddress)).name(); - const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol(); - - const updateDebtTokenInput: { - asset: string; - incentivesController: string; - name: string; - symbol: string; - implementation: string; - params: string; - } = { - asset: dai.address, - incentivesController: ZERO_ADDRESS, - name: name, - symbol: symbol, - implementation: newStableTokenAddress, - params: '0x10', - }; - - await expect( - configurator.connect(users[1].signer).updateStableDebtToken(updateDebtTokenInput) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); - - it('Upgrades the DAI stable debt token implementation ', async () => { - const { dai, configurator, helpersContract } = testEnv; - - const name = await (await getStableDebtToken(newStableTokenAddress)).name(); - const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol(); - - const updateDebtTokenInput: { - asset: string; - incentivesController: string; - name: string; - symbol: string; - implementation: string; - params: string; - } = { - asset: dai.address, - incentivesController: ZERO_ADDRESS, - name: name, - symbol: symbol, - implementation: newStableTokenAddress, - params: '0x10', - }; - - await configurator.updateStableDebtToken(updateDebtTokenInput); - - const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - dai.address - ); - - const debtToken = await getMockStableDebtToken(stableDebtTokenAddress); - - const tokenName = await debtToken.name(); - - expect(tokenName).to.be.eq('Aave stable debt bearing DAI updated', 'Invalid token name'); - }); - - it('Tries to update the DAI variable debt token implementation with a different address than the poolManager', async () => { - const { dai, configurator, users } = testEnv; - - const name = await (await getVariableDebtToken(newVariableTokenAddress)).name(); - const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol(); - - const updateDebtTokenInput: { - asset: string; - incentivesController: string; - name: string; - symbol: string; - implementation: string; - params: string; - } = { - asset: dai.address, - incentivesController: ZERO_ADDRESS, - name: name, - symbol: symbol, - implementation: newVariableTokenAddress, - params: '0x10', - }; - - await expect( - configurator.connect(users[1].signer).updateVariableDebtToken(updateDebtTokenInput) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); - - it('Upgrades the DAI variable debt token implementation ', async () => { - const { dai, configurator, helpersContract } = testEnv; - - const name = await (await getVariableDebtToken(newVariableTokenAddress)).name(); - const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol(); - - const updateDebtTokenInput: { - asset: string; - incentivesController: string; - name: string; - symbol: string; - implementation: string; - params: string; - } = { - asset: dai.address, - incentivesController: ZERO_ADDRESS, - name: name, - symbol: symbol, - implementation: newVariableTokenAddress, - params: '0x10', - }; - - expect(await configurator.updateVariableDebtToken(updateDebtTokenInput)); - - const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses( - dai.address - ); - - const debtToken = await getMockVariableDebtToken(variableDebtTokenAddress); - - const tokenName = await debtToken.name(); - - expect(tokenName).to.be.eq('Aave variable debt bearing DAI updated', 'Invalid token name'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/validation-logic.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/validation-logic.spec.ts deleted file mode 100644 index 3bcbffc..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/validation-logic.spec.ts +++ /dev/null @@ -1,1023 +0,0 @@ -import { expect } from 'chai'; -import { utils, constants } from 'ethers'; -import { parseUnits } from '@ethersproject/units'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { MAX_UINT_AMOUNT } from '../helpers/constants'; -import { RateMode, ProtocolErrors } from '../helpers/types'; -import { impersonateAccountsHardhat, setAutomine, setAutomineEvm } from '../helpers/misc-utils'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { waitForTx, evmSnapshot, evmRevert, getVariableDebtToken } from '@aave/deploy-v3'; -import { topUpNonPayableWithEther } from './helpers/utils/funds'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('ValidationLogic: Edge cases', (testEnv: TestEnv) => { - const { - RESERVE_INACTIVE, - RESERVE_FROZEN, - RESERVE_PAUSED, - INVALID_AMOUNT, - BORROWING_NOT_ENABLED, - STABLE_BORROWING_NOT_ENABLED, - COLLATERAL_SAME_AS_BORROWING_CURRENCY, - AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE, - NO_DEBT_OF_SELECTED_TYPE, - SAME_BLOCK_BORROW_REPAY, - HEALTH_FACTOR_NOT_BELOW_THRESHOLD, - INVALID_INTEREST_RATE_MODE_SELECTED, - UNDERLYING_BALANCE_ZERO, - INCONSISTENT_FLASHLOAN_PARAMS, - HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD, - INCONSISTENT_EMODE_CATEGORY, - } = ProtocolErrors; - - let snap: string; - - before(async () => { - const { addressesProvider, oracle } = testEnv; - - await waitForTx(await addressesProvider.setPriceOracle(oracle.address)); - }); - - after(async () => { - const { aaveOracle, addressesProvider } = testEnv; - await waitForTx(await addressesProvider.setPriceOracle(aaveOracle.address)); - }); - - beforeEach(async () => { - snap = await evmSnapshot(); - }); - afterEach(async () => { - await evmRevert(snap); - }); - - it('validateDeposit() when reserve is not active (revert expected)', async () => { - const { pool, poolAdmin, configurator, helpersContract, users, dai } = testEnv; - const user = users[0]; - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveActive(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(false); - expect(configAfter.isFrozen).to.be.eq(false); - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('1000')); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await expect( - pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0) - ).to.be.revertedWith(RESERVE_INACTIVE); - }); - - it('validateDeposit() when reserve is frozen (revert expected)', async () => { - const { pool, poolAdmin, configurator, helpersContract, users, dai } = testEnv; - const user = users[0]; - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveFreeze(dai.address, true); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(true); - expect(configAfter.isFrozen).to.be.eq(true); - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('1000')); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await expect( - pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0) - ).to.be.revertedWith(RESERVE_FROZEN); - }); - - it('validateBorrow() when reserve is not active (revert expected)', async () => { - /** - * Unclear how we should enter this stage with normal usage. - * Can be done by sending dai directly to aDai contract after it have been deactivated. - * If deposited normally it is not possible for us deactivate. - */ - - const { pool, poolAdmin, configurator, helpersContract, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('10000')); - await usdc.connect(user.signer).approve(pool.address, utils.parseEther('10000')); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('10000'), user.address, 0); - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveActive(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(false); - expect(configAfter.isFrozen).to.be.eq(false); - - // Transferring directly into aDai such that we can borrow - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('1000')); - await dai.connect(user.signer).transfer(aDai.address, utils.parseEther('1000')); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('1000'), RateMode.Variable, 0, user.address) - ).to.be.revertedWith(RESERVE_INACTIVE); - }); - - it('validateBorrow() when reserve is frozen (revert expected)', async () => { - const { pool, poolAdmin, configurator, helpersContract, users, dai, usdc } = testEnv; - const user = users[0]; - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('1000')); - await dai.connect(user.signer).approve(pool.address, utils.parseEther('1000')); - await pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0); - - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('10000')); - await usdc.connect(user.signer).approve(pool.address, utils.parseEther('10000')); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('10000'), user.address, 0); - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveFreeze(dai.address, true); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(true); - expect(configAfter.isFrozen).to.be.eq(true); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('1000'), RateMode.Variable, 0, user.address) - ).to.be.revertedWith(RESERVE_FROZEN); - }); - - it('validateBorrow() when amount == 0 (revert expected)', async () => { - const { pool, users, dai } = testEnv; - const user = users[0]; - - await expect( - pool.connect(user.signer).borrow(dai.address, 0, RateMode.Variable, 0, user.address) - ).to.be.revertedWith(INVALID_AMOUNT); - }); - - it('validateBorrow() when borrowing is not enabled (revert expected)', async () => { - const { pool, poolAdmin, configurator, helpersContract, users, dai, usdc } = testEnv; - const user = users[0]; - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('1000')); - await dai.connect(user.signer).approve(pool.address, utils.parseEther('1000')); - await pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0); - - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('10000')); - await usdc.connect(user.signer).approve(pool.address, utils.parseEther('10000')); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('10000'), user.address, 0); - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.borrowingEnabled).to.be.eq(true); - - // Disable borrowing - await configurator.connect(poolAdmin.signer).setReserveStableRateBorrowing(dai.address, false); - await configurator.connect(poolAdmin.signer).setReserveBorrowing(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.borrowingEnabled).to.be.eq(false); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('1000'), RateMode.Variable, 0, user.address) - ).to.be.revertedWith(BORROWING_NOT_ENABLED); - }); - - it('validateBorrow() when stableRateBorrowing is not enabled', async () => { - const { pool, poolAdmin, configurator, helpersContract, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('1000')); - await dai.connect(user.signer).approve(pool.address, utils.parseEther('1000')); - await pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0); - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.stableBorrowRateEnabled).to.be.eq(true); - - // Disable stable rate borrowing - await configurator.connect(poolAdmin.signer).setReserveStableRateBorrowing(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.stableBorrowRateEnabled).to.be.eq(false); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('500'), RateMode.Stable, 0, user.address) - ).to.be.revertedWith(STABLE_BORROWING_NOT_ENABLED); - }); - - it('validateBorrow() borrowing when user has already a HF < threshold', async () => { - const { pool, users, dai, usdc, oracle } = testEnv; - const user = users[0]; - const depositor = users[1]; - - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '2000')); - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(depositor.signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, '2000'), - depositor.address, - 0 - ); - - await usdc - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '2000')); - await usdc.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '2000'), - user.address, - 0 - ); - - await pool - .connect(user.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '1000'), - RateMode.Variable, - 0, - user.address - ); - - const daiPrice = await oracle.getAssetPrice(dai.address); - - await oracle.setAssetPrice(dai.address, daiPrice.mul(2)); - - await expect( - pool - .connect(user.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '200'), - RateMode.Variable, - 0, - user.address - ) - ).to.be.revertedWith(HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD); - }); - - it('validateBorrow() stable borrowing where collateral is mostly the same currency is borrowing (revert expected)', async () => { - // Stable borrowing - // isUsingAsCollateral == true - // ltv != 0 - // amount < aToken Balance - - const { pool, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await dai.connect(user.signer).approve(pool.address, utils.parseEther('1000')); - await pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0); - await dai.connect(user.signer).transfer(aDai.address, utils.parseEther('1000')); - - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('10000')); - await usdc.connect(user.signer).approve(pool.address, utils.parseEther('10000')); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('10000'), user.address, 0); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('500'), RateMode.Stable, 0, user.address) - ).to.be.revertedWith(COLLATERAL_SAME_AS_BORROWING_CURRENCY); - }); - - it('validateBorrow() stable borrowing when amount > maxLoanSizeStable (revert expected)', async () => { - const { pool, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await dai.connect(user.signer).approve(pool.address, utils.parseEther('1000')); - await pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0); - await dai.connect(user.signer).transfer(aDai.address, utils.parseEther('1000')); - - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('10000')); - await usdc.connect(user.signer).approve(pool.address, utils.parseEther('10000')); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('10000'), user.address, 0); - - await expect( - pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('1500'), RateMode.Stable, 0, user.address) - ).to.be.revertedWith(AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE); - }); - - it('validateLiquidationCall() when healthFactor > threshold (revert expected)', async () => { - // Liquidation something that is not liquidatable - const { pool, users, dai, usdc } = testEnv; - const depositor = users[0]; - const borrower = users[1]; - - await dai - .connect(depositor.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '500')); - await dai.connect(depositor.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(depositor.signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, '500'), - depositor.address, - 0 - ); - await usdc - .connect(borrower.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(usdc.address, '500')); - await usdc.connect(borrower.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(borrower.signer) - .deposit( - usdc.address, - await convertToCurrencyDecimals(usdc.address, '500'), - borrower.address, - 0 - ); - - await pool - .connect(borrower.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '250'), - RateMode.Variable, - 0, - borrower.address - ); - - // Try to liquidate the borrower - await expect( - pool - .connect(depositor.signer) - .liquidationCall(usdc.address, dai.address, borrower.address, 0, false) - ).to.be.revertedWith(HEALTH_FACTOR_NOT_BELOW_THRESHOLD); - }); - - it('validateRepay() when reserve is not active (revert expected)', async () => { - // Unsure how we can end in this scenario. Would require that it could be deactivated after someone have borrowed - const { pool, users, dai, helpersContract, configurator, poolAdmin } = testEnv; - const user = users[0]; - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveActive(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(false); - expect(configAfter.isFrozen).to.be.eq(false); - - await expect( - pool - .connect(user.signer) - .repay(dai.address, utils.parseEther('1'), RateMode.Variable, user.address) - ).to.be.revertedWith(RESERVE_INACTIVE); - }); - - it('validateRepay() when variable borrowing and repaying in same block (revert expected)', async () => { - // Same block repay - - const { pool, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - // We need some debt. - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await usdc.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('2000'), user.address, 0); - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await dai.connect(user.signer).transfer(aDai.address, utils.parseEther('2000')); - - // Turn off automining - pretty sure that coverage is getting messed up here. - await setAutomine(false); - - // Borrow 500 dai - await pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('500'), RateMode.Variable, 0, user.address); - - // Turn on automining, but not mine a new block until next tx - await setAutomineEvm(true); - - await expect( - pool - .connect(user.signer) - .repay(dai.address, utils.parseEther('500'), RateMode.Variable, user.address) - ).to.be.revertedWith(SAME_BLOCK_BORROW_REPAY); - }); - - it('validateRepay() when variable borrowing and repaying in same block using credit delegation (revert expected)', async () => { - const { - pool, - dai, - weth, - users: [user1, user2, user3], - } = testEnv; - - // Add liquidity - await dai.connect(user3.signer)['mint(uint256)'](utils.parseUnits('1000', 18)); - await dai.connect(user3.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user3.signer) - .supply(dai.address, utils.parseUnits('1000', 18), user3.address, 0); - - // User1 supplies 10 WETH - await dai.connect(user1.signer)['mint(uint256)'](utils.parseUnits('100', 18)); - await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await weth.connect(user1.signer)['mint(uint256)'](utils.parseUnits('10', 18)); - await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user1.signer) - .supply(weth.address, utils.parseUnits('10', 18), user1.address, 0); - - const daiData = await pool.getReserveData(dai.address); - const variableDebtToken = await getVariableDebtToken(daiData.variableDebtTokenAddress); - - // User1 approves User2 to borrow 1000 DAI - expect( - await variableDebtToken - .connect(user1.signer) - .approveDelegation(user2.address, utils.parseUnits('1000', 18)) - ); - - // User2 borrows on behalf of User1 - const borrowOnBehalfAmount = utils.parseUnits('100', 18); - expect( - await pool - .connect(user2.signer) - .borrow(dai.address, borrowOnBehalfAmount, RateMode.Variable, 0, user1.address) - ); - - // Turn off automining to simulate actions in same block - await setAutomine(false); - - // User2 borrows 2 DAI on behalf of User1 - await pool - .connect(user2.signer) - .borrow(dai.address, utils.parseEther('2'), RateMode.Variable, 0, user1.address); - - // Turn on automining, but not mine a new block until next tx - await setAutomineEvm(true); - - await expect( - pool - .connect(user1.signer) - .repay(dai.address, utils.parseEther('2'), RateMode.Variable, user1.address) - ).to.be.revertedWith(SAME_BLOCK_BORROW_REPAY); - }); - - it('validateRepay() when stable borrowing and repaying in same block (revert expected)', async () => { - // Same block repay - - const { pool, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - // We need some debt. - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await usdc.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('2000'), user.address, 0); - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await dai.connect(user.signer).transfer(aDai.address, utils.parseEther('2000')); - - // Turn off automining - pretty sure that coverage is getting messed up here. - await setAutomine(false); - - // Borrow 500 dai - await pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('500'), RateMode.Stable, 0, user.address); - - // Turn on automining, but not mine a new block until next tx - await setAutomineEvm(true); - - await expect( - pool - .connect(user.signer) - .repay(dai.address, utils.parseEther('500'), RateMode.Stable, user.address) - ).to.be.revertedWith(SAME_BLOCK_BORROW_REPAY); - }); - - it('validateRepay() the variable debt when is 0 (stableDebt > 0) (revert expected)', async () => { - // (stableDebt > 0 && DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE) || - // (variableDebt > 0 && DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.VARIABLE), - - const { pool, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - // We need some debt - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await usdc.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('2000'), user.address, 0); - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await dai.connect(user.signer).transfer(aDai.address, utils.parseEther('2000')); - - await pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('250'), RateMode.Stable, 0, user.address); - - await expect( - pool - .connect(user.signer) - .repay(dai.address, utils.parseEther('250'), RateMode.Variable, user.address) - ).to.be.revertedWith(NO_DEBT_OF_SELECTED_TYPE); - }); - - it('validateRepay() the stable debt when is 0 (variableDebt > 0) (revert expected)', async () => { - // (stableDebt > 0 && DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE) || - // (variableDebt > 0 && DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.VARIABLE), - - const { pool, users, dai } = testEnv; - const user = users[0]; - - // We need some debt - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).deposit(dai.address, utils.parseEther('2000'), user.address, 0); - - await pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('250'), RateMode.Variable, 0, user.address); - - await expect( - pool - .connect(user.signer) - .repay(dai.address, utils.parseEther('250'), RateMode.Stable, user.address) - ).to.be.revertedWith(NO_DEBT_OF_SELECTED_TYPE); - }); - - it('validateSwapRateMode() when reserve is not active', async () => { - // Not clear when this would be useful in practice, as you should not be able to have debt if it is deactivated - const { pool, poolAdmin, configurator, helpersContract, users, dai, aDai } = testEnv; - const user = users[0]; - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveActive(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(false); - expect(configAfter.isFrozen).to.be.eq(false); - - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.Stable) - ).to.be.revertedWith(RESERVE_INACTIVE); - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.Variable) - ).to.be.revertedWith(RESERVE_INACTIVE); - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.None) - ).to.be.revertedWith(RESERVE_INACTIVE); - }); - - it('validateSwapRateMode() when reserve is frozen', async () => { - // Not clear when this would be useful in practice, as you should not be able to have debt if it is deactivated - const { pool, poolAdmin, configurator, helpersContract, users, dai } = testEnv; - const user = users[0]; - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveFreeze(dai.address, true); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(true); - expect(configAfter.isFrozen).to.be.eq(true); - - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.Stable) - ).to.be.revertedWith(RESERVE_FROZEN); - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.Variable) - ).to.be.revertedWith(RESERVE_FROZEN); - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.None) - ).to.be.revertedWith(RESERVE_FROZEN); - }); - - it('validateSwapRateMode() with currentRateMode not equal to stable or variable, (revert expected)', async () => { - const { pool, helpersContract, users, dai } = testEnv; - const user = users[0]; - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.None) - ).to.be.revertedWith(INVALID_INTEREST_RATE_MODE_SELECTED); - }); - - it('validateSwapRateMode() from variable to stable with stableBorrowing disabled (revert expected)', async () => { - const { pool, poolAdmin, configurator, helpersContract, users, dai } = testEnv; - const user = users[0]; - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('1000')); - await dai.connect(user.signer).approve(pool.address, utils.parseEther('1000')); - await pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0); - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.stableBorrowRateEnabled).to.be.eq(true); - - // Disable stable rate borrowing - await configurator.connect(poolAdmin.signer).setReserveStableRateBorrowing(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.stableBorrowRateEnabled).to.be.eq(false); - - // We need some variable debt, and then flip it - - await dai - .connect(user.signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '5000')); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user.signer) - .deposit(dai.address, await convertToCurrencyDecimals(dai.address, '5000'), user.address, 0); - - await pool - .connect(user.signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '500'), - RateMode.Variable, - 0, - user.address - ); - - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.Variable) - ).to.be.revertedWith(STABLE_BORROWING_NOT_ENABLED); - }); - - it('validateSwapRateMode() where collateral is mostly the same currency is borrowing (revert expected)', async () => { - // SwapRate from variable to stable - // isUsingAsCollateral == true - // ltv != 0 - // stableDebt + variableDebt < aToken - - const { pool, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - await dai.connect(user.signer)['mint(uint256)'](utils.parseEther('2000')); - await dai.connect(user.signer).approve(pool.address, utils.parseEther('1000')); - await pool.connect(user.signer).deposit(dai.address, utils.parseEther('1000'), user.address, 0); - await dai.connect(user.signer).transfer(aDai.address, utils.parseEther('1000')); - - await usdc.connect(user.signer)['mint(uint256)'](utils.parseEther('10000')); - await usdc.connect(user.signer).approve(pool.address, utils.parseEther('10000')); - await pool - .connect(user.signer) - .deposit(usdc.address, utils.parseEther('10000'), user.address, 0); - - await pool - .connect(user.signer) - .borrow(dai.address, utils.parseEther('500'), RateMode.Variable, 0, user.address); - - await expect( - pool.connect(user.signer).swapBorrowRateMode(dai.address, RateMode.Variable) - ).to.be.revertedWith(COLLATERAL_SAME_AS_BORROWING_CURRENCY); - }); - - it('validateRebalanceStableBorrowRate() when reserve is not active (revert expected)', async () => { - const { pool, configurator, helpersContract, poolAdmin, users, dai } = testEnv; - const user = users[0]; - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveActive(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(false); - expect(configAfter.isFrozen).to.be.eq(false); - - await expect( - pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address) - ).to.be.revertedWith(RESERVE_INACTIVE); - }); - - it('validateSetUseReserveAsCollateral() when reserve is not active (revert expected)', async () => { - /** - * Since its not possible to deactivate a reserve with existing suppliers, making the user have - * aToken balance (aDAI) its not technically possible to end up in this situation. - * However, we impersonate the Pool to get some aDAI and make the test possible - */ - const { pool, configurator, helpersContract, poolAdmin, users, dai, aDai } = testEnv; - const user = users[0]; - - const configBefore = await helpersContract.getReserveConfigurationData(dai.address); - expect(configBefore.isActive).to.be.eq(true); - expect(configBefore.isFrozen).to.be.eq(false); - - await configurator.connect(poolAdmin.signer).setReserveActive(dai.address, false); - - const configAfter = await helpersContract.getReserveConfigurationData(dai.address); - expect(configAfter.isActive).to.be.eq(false); - expect(configAfter.isFrozen).to.be.eq(false); - - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - await topUpNonPayableWithEther(user.signer, [pool.address], utils.parseEther('1')); - expect(await aDai.connect(poolSigner).mint(user.address, user.address, 1, 1)); - - await expect( - pool.connect(user.signer).setUserUseReserveAsCollateral(dai.address, true) - ).to.be.revertedWith(RESERVE_INACTIVE); - - await expect( - pool.connect(user.signer).setUserUseReserveAsCollateral(dai.address, false) - ).to.be.revertedWith(RESERVE_INACTIVE); - }); - - it('validateSetUseReserveAsCollateral() with userBalance == 0 (revert expected)', async () => { - const { pool, users, dai } = testEnv; - const user = users[0]; - - await expect( - pool.connect(user.signer).setUserUseReserveAsCollateral(dai.address, true) - ).to.be.revertedWith(UNDERLYING_BALANCE_ZERO); - - await expect( - pool.connect(user.signer).setUserUseReserveAsCollateral(dai.address, false) - ).to.be.revertedWith(UNDERLYING_BALANCE_ZERO); - }); - - it('validateFlashloan() with inconsistent params (revert expected)', async () => { - const { pool, users, dai, aDai, usdc } = testEnv; - const user = users[0]; - - await expect( - pool - .connect(user.signer) - .flashLoan( - aDai.address, - [dai.address, usdc.address], - [0], - [RateMode.Variable, RateMode.Variable], - user.address, - '0x00', - 0 - ) - ).to.be.revertedWith(INCONSISTENT_FLASHLOAN_PARAMS); - }); - - it('validateFlashloan() with inactive reserve (revert expected)', async () => { - const { - configurator, - poolAdmin, - pool, - dai, - aDai, - usdc, - users: [user], - } = testEnv; - - expect(await configurator.connect(poolAdmin.signer).setReserveActive(dai.address, false)); - - await expect( - pool - .connect(user.signer) - .flashLoan( - aDai.address, - [dai.address, usdc.address], - [0, 0], - [RateMode.Variable, RateMode.Variable], - user.address, - '0x00', - 0 - ) - ).to.be.revertedWith(RESERVE_INACTIVE); - }); - - it('validateFlashLoanSimple() with paused reserve (revert expected)', async () => { - const { - configurator, - poolAdmin, - pool, - weth, - users: [user], - } = testEnv; - - expect(await configurator.connect(poolAdmin.signer).setReservePause(weth.address, true)); - - await expect( - pool.connect(user.signer).flashLoanSimple(user.address, weth.address, 0, '0x10', 0) - ).to.be.revertedWith(RESERVE_PAUSED); - }); - - it('validateFlashLoanSimple() with inactive reserve (revert expected)', async () => { - const { - configurator, - poolAdmin, - pool, - weth, - users: [user], - } = testEnv; - - expect(await configurator.connect(poolAdmin.signer).setReserveActive(weth.address, false)); - - await expect( - pool.connect(user.signer).flashLoanSimple(user.address, weth.address, 0, '0x10', 0) - ).to.be.revertedWith(RESERVE_INACTIVE); - }); - - it('validateSetUserEMode() to undefined emode category (revert expected)', async () => { - const { - pool, - users: [user], - } = testEnv; - - await expect(pool.connect(user.signer).setUserEMode(101)).to.be.revertedWith( - INCONSISTENT_EMODE_CATEGORY - ); - }); - - it('validateSetUserEMode() with empty config', async () => { - const { - configurator, - poolAdmin, - pool, - users: [user], - } = testEnv; - - expect( - await configurator - .connect(poolAdmin.signer) - .setEModeCategory('101', '9800', '9900', '10100', constants.AddressZero, 'INCONSISTENT') - ); - - await pool.connect(user.signer).setUserEMode(101); - }); - - it('validateSetUserEMode() with categoryId == 0', async () => { - const { - dai, - pool, - users: [user], - } = testEnv; - - // Deposit to make sure config is not empty - await dai.connect(user.signer)['mint(uint256)'](parseUnits('1000', 18)); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).supply(dai.address, parseUnits('1000', 18), user.address, 0); - - await pool.connect(user.signer).setUserEMode(0); - - expect(await pool.getUserEMode(user.address)).to.be.eq(0); - }); - - it('validateBorrow() with eMode > 0, borrowing asset not in category (revert expected)', async () => { - const { - configurator, - poolAdmin, - usdc, - dai, - pool, - users: [user, usdcProvider], - } = testEnv; - - await usdc.connect(usdcProvider.signer)['mint(uint256)'](parseUnits('1000', 6)); - await usdc.connect(usdcProvider.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(usdcProvider.signer) - .supply(usdc.address, parseUnits('1000', 6), usdcProvider.address, 0); - - await dai.connect(user.signer)['mint(uint256)'](parseUnits('1000', 18)); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).supply(dai.address, parseUnits('1000', 18), user.address, 0); - - await configurator - .connect(poolAdmin.signer) - .setEModeCategory('101', '9800', '9900', '10100', constants.AddressZero, 'NO-ASSETS'); - - await pool.connect(user.signer).setUserEMode(101); - - await expect( - pool - .connect(user.signer) - .borrow(usdc.address, parseUnits('100', 6), RateMode.Variable, 0, user.address) - ).to.be.revertedWith(INCONSISTENT_EMODE_CATEGORY); - }); - - it('validateHFAndLtv() with HF < 1 (revert expected)', async () => { - const { - usdc, - dai, - pool, - oracle, - users: [user, usdcProvider], - } = testEnv; - - await usdc.connect(usdcProvider.signer)['mint(uint256)'](parseUnits('1000', 6)); - await usdc.connect(usdcProvider.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(usdcProvider.signer) - .supply(usdc.address, parseUnits('1000', 6), usdcProvider.address, 0); - - await dai.connect(user.signer)['mint(uint256)'](parseUnits('1000', 18)); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).supply(dai.address, parseUnits('1000', 18), user.address, 0); - - const userGlobalData = await pool.getUserAccountData(user.address); - const usdcPrice = await oracle.getAssetPrice(usdc.address); - - const amountUSDCToBorrow = await convertToCurrencyDecimals( - usdc.address, - userGlobalData.availableBorrowsBase.div(usdcPrice).toString() - ); - - await pool - .connect(user.signer) - .borrow(usdc.address, amountUSDCToBorrow, RateMode.Variable, 0, user.address); - - await expect( - pool.connect(user.signer).withdraw(dai.address, parseUnits('500', 18), user.address) - ).to.be.revertedWith(HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD); - }); - - it('validateHFAndLtv() with HF < 1 for 0 LTV asset (revert expected)', async () => { - const { - usdc, - dai, - pool, - oracle, - poolAdmin, - configurator, - helpersContract, - users: [user, usdcProvider], - } = testEnv; - - // Supply usdc - await usdc.connect(usdcProvider.signer)['mint(uint256)'](parseUnits('1000', 6)); - await usdc.connect(usdcProvider.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(usdcProvider.signer) - .supply(usdc.address, parseUnits('1000', 6), usdcProvider.address, 0); - - // Supply dai - await dai.connect(user.signer)['mint(uint256)'](parseUnits('1000', 18)); - await dai.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).supply(dai.address, parseUnits('1000', 18), user.address, 0); - - // Borrow usdc - await pool - .connect(user.signer) - .borrow(usdc.address, parseUnits('500', 6), RateMode.Variable, 0, user.address); - - // Drop LTV - const daiData = await helpersContract.getReserveConfigurationData(dai.address); - - await configurator - .connect(poolAdmin.signer) - .configureReserveAsCollateral( - dai.address, - 0, - daiData.liquidationThreshold, - daiData.liquidationBonus - ); - - // Withdraw all my dai - await expect( - pool.connect(user.signer).withdraw(dai.address, parseUnits('500', 18), user.address) - ).to.be.revertedWith(HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/variable-debt-token.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/variable-debt-token.spec.ts deleted file mode 100644 index 444a0de..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/variable-debt-token.spec.ts +++ /dev/null @@ -1,380 +0,0 @@ -import { expect } from 'chai'; -import { utils } from 'ethers'; -import { impersonateAccountsHardhat } from '../helpers/misc-utils'; -import { MAX_UINT_AMOUNT, ZERO_ADDRESS } from '../helpers/constants'; -import { ProtocolErrors, RateMode } from '../helpers/types'; -import { makeSuite, TestEnv } from './helpers/make-suite'; -import { topUpNonPayableWithEther } from './helpers/utils/funds'; -import { convertToCurrencyDecimals } from '../helpers/contracts-helpers'; -import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { evmRevert, evmSnapshot, increaseTime, waitForTx } from '@aave/deploy-v3'; -import { VariableDebtToken__factory } from '../types'; -import './helpers/utils/wadraymath'; - -declare var hre: HardhatRuntimeEnvironment; - -makeSuite('VariableDebtToken', (testEnv: TestEnv) => { - const { CALLER_MUST_BE_POOL, INVALID_MINT_AMOUNT, INVALID_BURN_AMOUNT, CALLER_NOT_POOL_ADMIN } = - ProtocolErrors; - - it('Check initialization', async () => { - const { pool, weth, dai, helpersContract, users } = testEnv; - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - - const variableDebtContract = await VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - users[0].signer - ); - - expect(await variableDebtContract.UNDERLYING_ASSET_ADDRESS()).to.be.eq(dai.address); - expect(await variableDebtContract.POOL()).to.be.eq(pool.address); - expect(await variableDebtContract.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - - const scaledUserBalanceAndSupplyUser0Before = - await variableDebtContract.getScaledUserBalanceAndSupply(users[0].address); - expect(scaledUserBalanceAndSupplyUser0Before[0]).to.be.eq(0); - expect(scaledUserBalanceAndSupplyUser0Before[1]).to.be.eq(0); - - // Need to create some debt to do this good - await dai - .connect(users[0].signer) - ['mint(uint256)'](await convertToCurrencyDecimals(dai.address, '1000')); - await dai.connect(users[0].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[0].signer) - .deposit( - dai.address, - await convertToCurrencyDecimals(dai.address, '1000'), - users[0].address, - 0 - ); - await weth.connect(users[1].signer)['mint(uint256)'](utils.parseEther('10')); - await weth.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(users[1].signer) - .deposit(weth.address, utils.parseEther('10'), users[1].address, 0); - await pool - .connect(users[1].signer) - .borrow( - dai.address, - await convertToCurrencyDecimals(dai.address, '200'), - RateMode.Variable, - 0, - users[1].address - ); - - const scaledUserBalanceAndSupplyUser0After = - await variableDebtContract.getScaledUserBalanceAndSupply(users[0].address); - expect(scaledUserBalanceAndSupplyUser0After[0]).to.be.eq(0); - expect(scaledUserBalanceAndSupplyUser0After[1]).to.be.gt(0); - - const scaledUserBalanceAndSupplyUser1After = - await variableDebtContract.getScaledUserBalanceAndSupply(users[1].address); - expect(scaledUserBalanceAndSupplyUser1After[1]).to.be.gt(0); - expect(scaledUserBalanceAndSupplyUser1After[1]).to.be.gt(0); - - expect(scaledUserBalanceAndSupplyUser0After[1]).to.be.eq( - scaledUserBalanceAndSupplyUser1After[1] - ); - }); - - it('Tries to mint not being the Pool (revert expected)', async () => { - const { deployer, dai, helpersContract } = testEnv; - - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - deployer.signer - ); - - await expect( - variableDebtContract.mint(deployer.address, deployer.address, '1', '1') - ).to.be.revertedWith(CALLER_MUST_BE_POOL); - }); - - it('Tries to burn not being the Pool (revert expected)', async () => { - const { deployer, dai, helpersContract } = testEnv; - - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - deployer.signer - ); - - await expect(variableDebtContract.burn(deployer.address, '1', '1')).to.be.revertedWith( - CALLER_MUST_BE_POOL - ); - }); - - it('Tries to mint with amountScaled == 0 (revert expected)', async () => { - const { deployer, pool, dai, helpersContract, users } = testEnv; - - // Impersonate the Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - deployer.signer - ); - - await expect( - variableDebtContract - .connect(poolSigner) - .mint(users[0].address, users[0].address, 0, utils.parseUnits('1', 27)) - ).to.be.revertedWith(INVALID_MINT_AMOUNT); - }); - - it('Tries to burn with amountScaled == 0 (revert expected)', async () => { - const { deployer, pool, dai, helpersContract, users } = testEnv; - - // Impersonate the Pool - await topUpNonPayableWithEther(deployer.signer, [pool.address], utils.parseEther('1')); - await impersonateAccountsHardhat([pool.address]); - const poolSigner = await hre.ethers.getSigner(pool.address); - - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - deployer.signer - ); - - await expect( - variableDebtContract.connect(poolSigner).burn(users[0].address, 0, utils.parseUnits('1', 27)) - ).to.be.revertedWith(INVALID_BURN_AMOUNT); - }); - - it('Tries to transfer debt tokens (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - users[0].signer - ); - - await expect( - variableDebtContract.connect(users[0].signer).transfer(users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Tries to approve debt tokens (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - users[0].signer - ); - - await expect( - variableDebtContract.connect(users[0].signer).approve(users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - await expect( - variableDebtContract.allowance(users[0].address, users[1].address) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Tries to increaseAllowance (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - users[0].signer - ); - - await expect( - variableDebtContract.connect(users[0].signer).increaseAllowance(users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Tries to decreaseAllowance (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - users[0].signer - ); - - await expect( - variableDebtContract.connect(users[0].signer).decreaseAllowance(users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('Tries to transferFrom debt tokens (revert expected)', async () => { - const { users, dai, helpersContract } = testEnv; - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - users[0].signer - ); - - await expect( - variableDebtContract - .connect(users[0].signer) - .transferFrom(users[0].address, users[1].address, 500) - ).to.be.revertedWith(ProtocolErrors.OPERATION_NOT_SUPPORTED); - }); - - it('setIncentivesController() ', async () => { - const snapshot = await evmSnapshot(); - const { dai, helpersContract, poolAdmin, aclManager, deployer } = testEnv; - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - deployer.signer - ); - - expect(await aclManager.connect(deployer.signer).addPoolAdmin(poolAdmin.address)); - - expect(await variableDebtContract.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - expect( - await variableDebtContract.connect(poolAdmin.signer).setIncentivesController(ZERO_ADDRESS) - ); - expect(await variableDebtContract.getIncentivesController()).to.be.eq(ZERO_ADDRESS); - - await evmRevert(snapshot); - }); - - it('setIncentivesController() from not pool admin (revert expected)', async () => { - const { - dai, - helpersContract, - users: [user], - } = testEnv; - const daiVariableDebtTokenAddress = ( - await helpersContract.getReserveTokensAddresses(dai.address) - ).variableDebtTokenAddress; - const variableDebtContract = VariableDebtToken__factory.connect( - daiVariableDebtTokenAddress, - user.signer - ); - - expect(await variableDebtContract.getIncentivesController()).to.not.be.eq(ZERO_ADDRESS); - - await expect( - variableDebtContract.connect(user.signer).setIncentivesController(ZERO_ADDRESS) - ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); - }); - - it('Check Mint and Transfer events when borrowing on behalf', async () => { - const { - pool, - weth, - dai, - users: [user1, user2, user3], - } = testEnv; - - // Add liquidity - await dai.connect(user3.signer)['mint(uint256)'](utils.parseUnits('1000', 18)); - await dai.connect(user3.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user3.signer) - .supply(dai.address, utils.parseUnits('1000', 18), user3.address, 0); - - // User1 supplies 10 WETH - await weth.connect(user1.signer)['mint(uint256)'](utils.parseUnits('10', 18)); - await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(user1.signer) - .supply(weth.address, utils.parseUnits('10', 18), user1.address, 0); - - const daiData = await pool.getReserveData(dai.address); - const variableDebtToken = VariableDebtToken__factory.connect( - daiData.variableDebtTokenAddress, - user1.signer - ); - const beforeDebtBalanceUser2 = await variableDebtToken.balanceOf(user2.address); - - // User1 borrows 100 DAI - const borrowAmount = utils.parseUnits('100', 18); - expect( - await pool - .connect(user1.signer) - .borrow(dai.address, borrowAmount, RateMode.Variable, 0, user1.address) - ); - - // User1 approves user2 to borrow 1000 DAI - expect( - await variableDebtToken - .connect(user1.signer) - .approveDelegation(user2.address, utils.parseUnits('1000', 18)) - ); - - // Increase time so interests accrue - await increaseTime(24 * 3600); - - const previousIndexUser1Before = await variableDebtToken.getPreviousIndex(user1.address); - const previousIndexUser2Before = await variableDebtToken.getPreviousIndex(user2.address); - - // User2 borrows 100 DAI on behalf of user1 - const borrowOnBehalfAmount = utils.parseUnits('100', 18); - const tx = await waitForTx( - await pool - .connect(user2.signer) - .borrow(dai.address, borrowOnBehalfAmount, RateMode.Variable, 0, user1.address) - ); - - const previousIndexUser1After = await variableDebtToken.getPreviousIndex(user1.address); - const previousIndexUser2After = await variableDebtToken.getPreviousIndex(user2.address); - - // User2 index should be the same - expect(previousIndexUser1Before).to.be.not.eq(previousIndexUser1After); - expect(previousIndexUser2Before).to.be.eq(previousIndexUser2After); - - const afterDebtBalanceUser1 = await variableDebtToken.balanceOf(user1.address); - - const interest = afterDebtBalanceUser1.sub(borrowAmount).sub(borrowOnBehalfAmount); - - const transferEventSig = utils.keccak256( - utils.toUtf8Bytes('Transfer(address,address,uint256)') - ); - - const rawTransferEvents = tx.logs.filter( - ({ topics, address }) => - topics[0] === transferEventSig && address == variableDebtToken.address - ); - const parsedTransferEvent = variableDebtToken.interface.parseLog(rawTransferEvents[0]); - const transferAmount = parsedTransferEvent.args.value; - - expect(transferAmount).to.be.closeTo(borrowOnBehalfAmount.add(interest), 2); - - const mintEventSig = utils.keccak256( - utils.toUtf8Bytes('Mint(address,address,uint256,uint256,uint256)') - ); - const rawMintEvents = tx.logs.filter( - ({ topics, address }) => topics[0] === mintEventSig && address == variableDebtToken.address - ); - - const parsedMintEvent = variableDebtToken.interface.parseLog(rawMintEvents[0]); - - expect(parsedMintEvent.args.value).to.be.closeTo(borrowOnBehalfAmount.add(interest), 2); - expect(parsedMintEvent.args.balanceIncrease).to.be.closeTo(interest, 2); - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-suites/wadraymath.spec.ts b/lib/morpho-utils/lib/aave-v3-core/test-suites/wadraymath.spec.ts deleted file mode 100644 index 640a005..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-suites/wadraymath.spec.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { expect } from 'chai'; -import { BigNumber } from 'ethers'; -import { MAX_UINT_AMOUNT, RAY, WAD, HALF_RAY, HALF_WAD } from '../helpers/constants'; -import { WadRayMathWrapper, WadRayMathWrapper__factory } from '../types'; -import { getFirstSigner } from '@aave/deploy-v3/dist/helpers/utilities/signer'; -import { makeSuite } from './helpers/make-suite'; -import './helpers/utils/wadraymath'; - -makeSuite('WadRayMath', () => { - let wrapper: WadRayMathWrapper; - - before('setup', async () => { - const factory = new WadRayMathWrapper__factory(await getFirstSigner()); - wrapper = await ((await factory.deploy()) as WadRayMathWrapper).deployed(); - }); - - it('Plain getters', async () => { - expect((await wrapper.wad()).toString()).to.be.eq(WAD); - expect((await wrapper.halfWad()).toString()).to.be.eq(HALF_WAD); - expect((await wrapper.ray()).toString()).to.be.eq(RAY); - expect((await wrapper.halfRay()).toString()).to.be.eq(HALF_RAY); - }); - - it('wadMul()', async () => { - const a = BigNumber.from('134534543232342353231234'); - const b = BigNumber.from('13265462389132757665657'); - - expect(await wrapper.wadMul(a, b)).to.be.eq(a.wadMul(b)); - expect(await wrapper.wadMul(0, b)).to.be.eq('0'); - expect(await wrapper.wadMul(a, 0)).to.be.eq('0'); - - const tooLargeA = BigNumber.from(MAX_UINT_AMOUNT).sub(HALF_WAD).div(b).add(1); - await expect(wrapper.wadMul(tooLargeA, b)).to.be.reverted; - }); - - it('wadDiv()', async () => { - const a = BigNumber.from('134534543232342353231234'); - const b = BigNumber.from('13265462389132757665657'); - - expect(await wrapper.wadDiv(a, b)).to.be.eq(a.wadDiv(b)); - - const halfB = b.div(2); - const tooLargeA = BigNumber.from(MAX_UINT_AMOUNT).sub(halfB).div(WAD).add(1); - - await expect(wrapper.wadDiv(tooLargeA, b)).to.be.reverted; - - await expect(wrapper.wadDiv(a, 0)).to.be.reverted; - }); - - it('rayMul()', async () => { - const a = BigNumber.from('134534543232342353231234'); - const b = BigNumber.from('13265462389132757665657'); - - expect(await wrapper.rayMul(a, b)).to.be.eq(a.rayMul(b)); - expect(await wrapper.rayMul(0, b)).to.be.eq('0'); - expect(await wrapper.rayMul(a, 0)).to.be.eq('0'); - - const tooLargeA = BigNumber.from(MAX_UINT_AMOUNT).sub(HALF_RAY).div(b).add(1); - await expect(wrapper.rayMul(tooLargeA, b)).to.be.reverted; - }); - - it('rayDiv()', async () => { - const a = BigNumber.from('134534543232342353231234'); - const b = BigNumber.from('13265462389132757665657'); - - expect(await wrapper.rayDiv(a, b)).to.be.eq(a.rayDiv(b)); - - const halfB = b.div(2); - const tooLargeA = BigNumber.from(MAX_UINT_AMOUNT).sub(halfB).div(RAY).add(1); - - await expect(wrapper.rayDiv(tooLargeA, b)).to.be.reverted; - await expect(wrapper.rayDiv(a, 0)).to.be.reverted; - }); - - it('rayToWad()', async () => { - const half = BigNumber.from(10).pow(9).div(2); - - const a = BigNumber.from('10').pow(27); - expect(await wrapper.rayToWad(a)).to.be.eq(a.rayToWad()); - - const roundDown = BigNumber.from('10').pow(27).add(half.sub(1)); - expect(await wrapper.rayToWad(roundDown)).to.be.eq(roundDown.rayToWad()); - - const roundUp = BigNumber.from('10').pow(27).add(half); - expect(await wrapper.rayToWad(roundUp)).to.be.eq(roundUp.rayToWad()); - - const tooLarge = BigNumber.from(MAX_UINT_AMOUNT).sub(half).add(1); - expect(await wrapper.rayToWad(tooLarge)).to.be.eq(tooLarge.rayToWad()); - }); - - it('wadToRay()', async () => { - const a = BigNumber.from('10').pow(18); - expect(await wrapper.wadToRay(a)).to.be.eq(a.wadToRay()); - - const ratio = BigNumber.from(10).pow(9); - const tooLarge = BigNumber.from(MAX_UINT_AMOUNT).div(ratio).add(1); - await expect(wrapper.wadToRay(tooLarge)).to.be.reverted; - }); -}); diff --git a/lib/morpho-utils/lib/aave-v3-core/test-wallets.js b/lib/morpho-utils/lib/aave-v3-core/test-wallets.js deleted file mode 100644 index 65da7d4..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/test-wallets.js +++ /dev/null @@ -1,38 +0,0 @@ -const balance = '1000000000000000000000000'; - -module.exports = { - accounts: [ - { - secretKey: '0xc5e8f61d1ab959b397eecc0a37a6517b8e67a0e7cf1f4bce5591f3ed80199122', - balance, - }, - { - secretKey: '0xd49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb', - balance, - }, - { - secretKey: '0x23c601ae397441f3ef6f1075dcb0031ff17fb079837beadaf3c84d96c6f3e569', - balance, - }, - { - secretKey: '0xee9d129c1997549ee09c0757af5939b2483d80ad649a0eda68e8b0357ad11131', - balance, - }, - { - secretKey: '0x87630b2d1de0fbd5044eb6891b3d9d98c34c8d310c852f98550ba774480e47cc', - balance, - }, - { - secretKey: '0x275cc4a2bfd4f612625204a20a2280ab53a6da2d14860c47a9f5affe58ad86d4', - balance, - }, - { - secretKey: '0xaee25d55ce586148a853ca83fdfacaf7bc42d5762c6e7187e6f8e822d8e6a650', - balance, - }, - { - secretKey: '0xa2e0097c961c67ec197b6865d7ecea6caffc68ebeb00e6050368c8f67fc9c588', - balance, - }, - ], -}; diff --git a/lib/morpho-utils/lib/aave-v3-core/tsconfig.json b/lib/morpho-utils/lib/aave-v3-core/tsconfig.json deleted file mode 100644 index 294757e..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "target": "es2019", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "outDir": "dist", - "noImplicitAny": false, - "resolveJsonModule": true, - "declaration": true, - "declarationDir": "./types" - }, - "include": ["./scripts", "./test-suites", "./tasks", "./helpers"], - "files": [ - "./hardhat.config.ts", - "node_modules/hardhat-typechain/src/type-extensions.ts", - "node_modules/@nomiclabs/hardhat-waffle/src/type-extensions.ts", - "node_modules/@nomiclabs/hardhat-etherscan/src/type-extensions.ts", - "node_modules/hardhat-gas-reporter/src/type-extensions.ts" - ] -} diff --git a/lib/morpho-utils/lib/aave-v3-core/tslint.json b/lib/morpho-utils/lib/aave-v3-core/tslint.json deleted file mode 100644 index 0e579d4..0000000 --- a/lib/morpho-utils/lib/aave-v3-core/tslint.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": ["tslint-config-prettier"], - "rulesDirectory": ["tslint-plugin-prettier"], - "rules": { - "prettier": true, - "max-line-length": [true, 100], - "import-name": false - }, - "linterOptions": { - "exclude": ["src/migration/**", "src/contracts/ABI/**"] - } -} diff --git a/lib/morpho-utils/lib/forge-std/.github/workflows/ci.yml b/lib/morpho-utils/lib/forge-std/.github/workflows/ci.yml deleted file mode 100644 index 9971ff9..0000000 --- a/lib/morpho-utils/lib/forge-std/.github/workflows/ci.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: CI - -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dependencies - run: forge install - - - name: Check backward compatibility - run: | - forge build --skip test --use solc:0.8.0 - forge build --skip test --use solc:0.7.6 - forge build --skip test --use solc:0.7.0 - forge build --skip test --use solc:0.6.2 - - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dependencies - run: forge install - - - name: Run tests - run: forge test -vvv - - fmt: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Check formatting - run: forge fmt --check diff --git a/lib/morpho-utils/lib/forge-std/.gitignore b/lib/morpho-utils/lib/forge-std/.gitignore deleted file mode 100644 index 756106d..0000000 --- a/lib/morpho-utils/lib/forge-std/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -cache/ -out/ -.vscode -.idea diff --git a/lib/morpho-utils/lib/forge-std/.gitmodules b/lib/morpho-utils/lib/forge-std/.gitmodules deleted file mode 100644 index e124719..0000000 --- a/lib/morpho-utils/lib/forge-std/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/ds-test"] - path = lib/ds-test - url = https://github.com/dapphub/ds-test diff --git a/lib/morpho-utils/lib/forge-std/LICENSE-APACHE b/lib/morpho-utils/lib/forge-std/LICENSE-APACHE deleted file mode 100644 index cf01a49..0000000 --- a/lib/morpho-utils/lib/forge-std/LICENSE-APACHE +++ /dev/null @@ -1,203 +0,0 @@ -Copyright Contributors to Forge Standard Library - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/lib/morpho-utils/lib/forge-std/LICENSE-MIT b/lib/morpho-utils/lib/forge-std/LICENSE-MIT deleted file mode 100644 index 28f9830..0000000 --- a/lib/morpho-utils/lib/forge-std/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright Contributors to Forge Standard Library - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE O THE USE OR OTHER -DEALINGS IN THE SOFTWARE.R diff --git a/lib/morpho-utils/lib/forge-std/README.md b/lib/morpho-utils/lib/forge-std/README.md deleted file mode 100644 index cddbd82..0000000 --- a/lib/morpho-utils/lib/forge-std/README.md +++ /dev/null @@ -1,250 +0,0 @@ -# Forge Standard Library • [![tests](https://github.com/brockelmore/forge-std/actions/workflows/tests.yml/badge.svg)](https://github.com/brockelmore/forge-std/actions/workflows/tests.yml) - -Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. - -**Learn how to use Forge-Std with the [📖 Foundry Book (Forge-Std Guide)](https://book.getfoundry.sh/forge/forge-std.html).** - -## Install - -```bash -forge install foundry-rs/forge-std -``` - -## Contracts -### stdError - -This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler builtin errors. - -See the contract itself for all error codes. - -#### Example usage - -```solidity - -import "forge-std/Test.sol"; - -contract TestContract is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } -} - -contract ErrorsTest { - function arithmeticError(uint256 a) public { - uint256 a = a - 100; - } -} -``` - -### stdStorage - -This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can *always* find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The one _major_ caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (`bytes32(0)`). - -This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth. - -I.e.: -```solidity -struct T { - // depth 0 - uint256 a; - // depth 1 - uint256 b; -} -``` - -#### Example usage - -```solidity -import "forge-std/Test.sol"; - -contract TestContract is Test { - using stdStorage for StdStorage; - - Storage test; - - function setUp() public { - test = new Storage(); - } - - function testFindExists() public { - // Lets say we want to find the slot for the public - // variable `exists`. We just pass in the function selector - // to the `find` command - uint256 slot = stdstore.target(address(test)).sig("exists()").find(); - assertEq(slot, 0); - } - - function testWriteExists() public { - // Lets say we want to write to the slot for the public - // variable `exists`. We just pass in the function selector - // to the `checked_write` command - stdstore.target(address(test)).sig("exists()").checked_write(100); - assertEq(test.exists(), 100); - } - - // It supports arbitrary storage layouts, like assembly based storage locations - function testFindHidden() public { - // `hidden` is a random hash of a bytes, iteration through slots would - // not find it. Our mechanism does - // Also, you can use the selector instead of a string - uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find(); - assertEq(slot, uint256(keccak256("my.random.var"))); - } - - // If targeting a mapping, you have to pass in the keys necessary to perform the find - // i.e.: - function testFindMapping() public { - uint256 slot = stdstore - .target(address(test)) - .sig(test.map_addr.selector) - .with_key(address(this)) - .find(); - // in the `Storage` constructor, we wrote that this address' value was 1 in the map - // so when we load the slot, we expect it to be 1 - assertEq(uint(vm.load(address(test), bytes32(slot))), 1); - } - - // If the target is a struct, you can specify the field depth: - function testFindStruct() public { - // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. - uint256 slot_for_a_field = stdstore - .target(address(test)) - .sig(test.basicStruct.selector) - .depth(0) - .find(); - - uint256 slot_for_b_field = stdstore - .target(address(test)) - .sig(test.basicStruct.selector) - .depth(1) - .find(); - - assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1); - assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2); - } -} - -// A complex storage contract -contract Storage { - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - constructor() { - map_addr[msg.sender] = 1; - } - - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - // mapping(address => Packed) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basicStruct = UnpackedStruct({ - a: 1, - b: 2 - }); - - function hidden() public view returns (bytes32 t) { - // an extremely hidden storage slot - bytes32 slot = keccak256("my.random.var"); - assembly { - t := sload(slot) - } - } -} -``` - -### stdCheats - -This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for address that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. - - -#### Example usage: -```solidity - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; - -// Inherit the stdCheats -contract StdCheatsTest is Test { - Bar test; - function setUp() public { - test = new Bar(); - } - - function testHoax() public { - // we call `hoax`, which gives the target address - // eth and then calls `prank` - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - - // overloaded to allow you to specify how much eth to - // initialize the address with - hoax(address(1337), 1); - test.bar{value: 1}(address(1337)); - } - - function testStartHoax() public { - // we call `startHoax`, which gives the target address - // eth and then calls `startPrank` - // - // it is also overloaded so that you can specify an eth amount - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } -} - -contract Bar { - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } -} -``` - -### Std Assertions - -Expand upon the assertion functions from the `DSTest` library. - -### `console.log` - -Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). -It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console2.sol"; -... -console2.log(someValue); -``` - -If you need compatibility with Hardhat, you must use the standard `console.sol` instead. -Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console.sol"; -... -console.log(someValue); -``` - -## License - -Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. \ No newline at end of file diff --git a/lib/morpho-utils/lib/forge-std/foundry.toml b/lib/morpho-utils/lib/forge-std/foundry.toml deleted file mode 100644 index 4f93dbf..0000000 --- a/lib/morpho-utils/lib/forge-std/foundry.toml +++ /dev/null @@ -1,21 +0,0 @@ -[profile.default] -fs_permissions = [{ access = "read-write", path = "./"}] - -[rpc_endpoints] -# We intentionally use both dashes and underscores in the key names to ensure both are supported. -# The RPC URLs below match the StdChains URLs but append a trailing slash for testing. -mainnet = "https://api.mycryptoapi.com/eth/" -optimism_goerli = "https://goerli.optimism.io/" -arbitrum-one-goerli = "https://goerli-rollup.arbitrum.io/rpc/" - -[fmt] -# These are all the `forge fmt` defaults. -line_length = 120 -tab_width = 4 -bracket_spacing = false -int_types = 'long' -multiline_func_header = 'attributes_first' -quote_style = 'double' -number_underscore = 'preserve' -single_line_statement_blocks = 'preserve' -ignore = ["src/console.sol", "src/console2.sol"] \ No newline at end of file diff --git a/lib/morpho-utils/lib/forge-std/lib/ds-test/.gitignore b/lib/morpho-utils/lib/forge-std/lib/ds-test/.gitignore deleted file mode 100644 index 63f0b2c..0000000 --- a/lib/morpho-utils/lib/forge-std/lib/ds-test/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.dapple -/build -/out diff --git a/lib/morpho-utils/lib/forge-std/lib/ds-test/LICENSE b/lib/morpho-utils/lib/forge-std/lib/ds-test/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/lib/morpho-utils/lib/forge-std/lib/ds-test/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/lib/morpho-utils/lib/forge-std/lib/ds-test/Makefile b/lib/morpho-utils/lib/forge-std/lib/ds-test/Makefile deleted file mode 100644 index 661dac4..0000000 --- a/lib/morpho-utils/lib/forge-std/lib/ds-test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all:; dapp build - -test: - -dapp --use solc:0.4.23 build - -dapp --use solc:0.4.26 build - -dapp --use solc:0.5.17 build - -dapp --use solc:0.6.12 build - -dapp --use solc:0.7.5 build - -demo: - DAPP_SRC=demo dapp --use solc:0.7.5 build - -hevm dapp-test --verbose 3 - -.PHONY: test demo diff --git a/lib/morpho-utils/lib/forge-std/lib/ds-test/default.nix b/lib/morpho-utils/lib/forge-std/lib/ds-test/default.nix deleted file mode 100644 index cf65419..0000000 --- a/lib/morpho-utils/lib/forge-std/lib/ds-test/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ solidityPackage, dappsys }: solidityPackage { - name = "ds-test"; - src = ./src; -} diff --git a/lib/morpho-utils/lib/forge-std/lib/ds-test/demo/demo.sol b/lib/morpho-utils/lib/forge-std/lib/ds-test/demo/demo.sol deleted file mode 100644 index f3bb48e..0000000 --- a/lib/morpho-utils/lib/forge-std/lib/ds-test/demo/demo.sol +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.5.0; - -import "../src/test.sol"; - -contract DemoTest is DSTest { - function test_this() public pure { - require(true); - } - function test_logs() public { - emit log("-- log(string)"); - emit log("a string"); - - emit log("-- log_named_uint(string, uint)"); - emit log_named_uint("uint", 512); - - emit log("-- log_named_int(string, int)"); - emit log_named_int("int", -512); - - emit log("-- log_named_address(string, address)"); - emit log_named_address("address", address(this)); - - emit log("-- log_named_bytes32(string, bytes32)"); - emit log_named_bytes32("bytes32", "a string"); - - emit log("-- log_named_bytes(string, bytes)"); - emit log_named_bytes("bytes", hex"cafefe"); - - emit log("-- log_named_string(string, string)"); - emit log_named_string("string", "a string"); - - emit log("-- log_named_decimal_uint(string, uint, uint)"); - emit log_named_decimal_uint("decimal uint", 1.0e18, 18); - - emit log("-- log_named_decimal_int(string, int, uint)"); - emit log_named_decimal_int("decimal int", -1.0e18, 18); - } - event log_old_named_uint(bytes32,uint); - function test_old_logs() public { - emit log_old_named_uint("key", 500); - emit log_named_bytes32("bkey", "val"); - } - function test_trace() public view { - this.echo("string 1", "string 2"); - } - function test_multiline() public { - emit log("a multiline\\nstring"); - emit log("a multiline string"); - emit log_bytes("a string"); - emit log_bytes("a multiline\nstring"); - emit log_bytes("a multiline\\nstring"); - emit logs(hex"0000"); - emit log_named_bytes("0x0000", hex"0000"); - emit logs(hex"ff"); - } - function echo(string memory s1, string memory s2) public pure - returns (string memory, string memory) - { - return (s1, s2); - } - - function prove_this(uint x) public { - emit log_named_uint("sym x", x); - assertGt(x + 1, 0); - } - - function test_logn() public { - assembly { - log0(0x01, 0x02) - log1(0x01, 0x02, 0x03) - log2(0x01, 0x02, 0x03, 0x04) - log3(0x01, 0x02, 0x03, 0x04, 0x05) - } - } - - event MyEvent(uint, uint indexed, uint, uint indexed); - function test_events() public { - emit MyEvent(1, 2, 3, 4); - } - - function test_asserts() public { - string memory err = "this test has failed!"; - emit log("## assertTrue(bool)\n"); - assertTrue(false); - emit log("\n"); - assertTrue(false, err); - - emit log("\n## assertEq(address,address)\n"); - assertEq(address(this), msg.sender); - emit log("\n"); - assertEq(address(this), msg.sender, err); - - emit log("\n## assertEq32(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(uint,uint)\n"); - assertEq(uint(0), 1); - emit log("\n"); - assertEq(uint(0), 1, err); - - emit log("\n## assertEq(int,int)\n"); - assertEq(-1, -2); - emit log("\n"); - assertEq(-1, -2, err); - - emit log("\n## assertEqDecimal(int,int,uint)\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertEqDecimal(uint,uint,uint)\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGt(uint,uint)\n"); - assertGt(uint(0), 0); - emit log("\n"); - assertGt(uint(0), 0, err); - - emit log("\n## assertGt(int,int)\n"); - assertGt(-1, -1); - emit log("\n"); - assertGt(-1, -1, err); - - emit log("\n## assertGtDecimal(int,int,uint)\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGtDecimal(uint,uint,uint)\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGe(uint,uint)\n"); - assertGe(uint(0), 1); - emit log("\n"); - assertGe(uint(0), 1, err); - - emit log("\n## assertGe(int,int)\n"); - assertGe(-1, 0); - emit log("\n"); - assertGe(-1, 0, err); - - emit log("\n## assertGeDecimal(int,int,uint)\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGeDecimal(uint,uint,uint)\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertLt(uint,uint)\n"); - assertLt(uint(0), 0); - emit log("\n"); - assertLt(uint(0), 0, err); - - emit log("\n## assertLt(int,int)\n"); - assertLt(-1, -1); - emit log("\n"); - assertLt(-1, -1, err); - - emit log("\n## assertLtDecimal(int,int,uint)\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLtDecimal(uint,uint,uint)\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertLe(uint,uint)\n"); - assertLe(uint(1), 0); - emit log("\n"); - assertLe(uint(1), 0, err); - - emit log("\n## assertLe(int,int)\n"); - assertLe(0, -1); - emit log("\n"); - assertLe(0, -1, err); - - emit log("\n## assertLeDecimal(int,int,uint)\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLeDecimal(uint,uint,uint)\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertEq(string,string)\n"); - string memory s1 = "string 1"; - string memory s2 = "string 2"; - assertEq(s1, s2); - emit log("\n"); - assertEq(s1, s2, err); - - emit log("\n## assertEq0(bytes,bytes)\n"); - assertEq0(hex"abcdef01", hex"abcdef02"); - emit log("\n"); - assertEq0(hex"abcdef01", hex"abcdef02", err); - } -} - -contract DemoTestWithSetUp { - function setUp() public { - } - function test_pass() public pure { - } -} diff --git a/lib/morpho-utils/lib/forge-std/lib/ds-test/package.json b/lib/morpho-utils/lib/forge-std/lib/ds-test/package.json deleted file mode 100644 index 4802ada..0000000 --- a/lib/morpho-utils/lib/forge-std/lib/ds-test/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ds-test", - "version": "1.0.0", - "description": "Assertions, equality checks and other test helpers ", - "bugs": "https://github.com/dapphub/ds-test/issues", - "license": "GPL-3.0", - "author": "Contributors to ds-test", - "files": [ - "src/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/dapphub/ds-test.git" - } -} diff --git a/lib/morpho-utils/lib/forge-std/lib/ds-test/src/test.sol b/lib/morpho-utils/lib/forge-std/lib/ds-test/src/test.sol deleted file mode 100644 index 515a3bd..0000000 --- a/lib/morpho-utils/lib/forge-std/lib/ds-test/src/test.sol +++ /dev/null @@ -1,469 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pragma solidity >=0.5.0; - -contract DSTest { - event log (string); - event logs (bytes); - - event log_address (address); - event log_bytes32 (bytes32); - event log_int (int); - event log_uint (uint); - event log_bytes (bytes); - event log_string (string); - - event log_named_address (string key, address val); - event log_named_bytes32 (string key, bytes32 val); - event log_named_decimal_int (string key, int val, uint decimals); - event log_named_decimal_uint (string key, uint val, uint decimals); - event log_named_int (string key, int val); - event log_named_uint (string key, uint val); - event log_named_bytes (string key, bytes val); - event log_named_string (string key, string val); - - bool public IS_TEST = true; - bool private _failed; - - address constant HEVM_ADDRESS = - address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); - - modifier mayRevert() { _; } - modifier testopts(string memory) { _; } - - function failed() public returns (bool) { - if (_failed) { - return _failed; - } else { - bool globalFailed = false; - if (hasHEVMContext()) { - (, bytes memory retdata) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("load(address,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed")) - ) - ); - globalFailed = abi.decode(retdata, (bool)); - } - return globalFailed; - } - } - - function fail() internal { - if (hasHEVMContext()) { - (bool status, ) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("store(address,bytes32,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x01))) - ) - ); - status; // Silence compiler warnings - } - _failed = true; - } - - function hasHEVMContext() internal view returns (bool) { - uint256 hevmCodeSize = 0; - assembly { - hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) - } - return hevmCodeSize > 0; - } - - modifier logs_gas() { - uint startGas = gasleft(); - _; - uint endGas = gasleft(); - emit log_named_uint("gas", startGas - endGas); - } - - function assertTrue(bool condition) internal { - if (!condition) { - emit log("Error: Assertion Failed"); - fail(); - } - } - - function assertTrue(bool condition, string memory err) internal { - if (!condition) { - emit log_named_string("Error", err); - assertTrue(condition); - } - } - - function assertEq(address a, address b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [address]"); - emit log_named_address(" Expected", b); - emit log_named_address(" Actual", a); - fail(); - } - } - function assertEq(address a, address b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes32 a, bytes32 b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [bytes32]"); - emit log_named_bytes32(" Expected", b); - emit log_named_bytes32(" Actual", a); - fail(); - } - } - function assertEq(bytes32 a, bytes32 b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - function assertEq32(bytes32 a, bytes32 b) internal { - assertEq(a, b); - } - function assertEq32(bytes32 a, bytes32 b, string memory err) internal { - assertEq(a, b, err); - } - - function assertEq(int a, int b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [int]"); - emit log_named_int(" Expected", b); - emit log_named_int(" Actual", a); - fail(); - } - } - function assertEq(int a, int b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEq(uint a, uint b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [uint]"); - emit log_named_uint(" Expected", b); - emit log_named_uint(" Actual", a); - fail(); - } - } - function assertEq(uint a, uint b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEqDecimal(int a, int b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal int]"); - emit log_named_decimal_int(" Expected", b, decimals); - emit log_named_decimal_int(" Actual", a, decimals); - fail(); - } - } - function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - function assertEqDecimal(uint a, uint b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Expected", b, decimals); - emit log_named_decimal_uint(" Actual", a, decimals); - fail(); - } - } - function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - - function assertGt(uint a, uint b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGt(uint a, uint b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGt(int a, int b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGt(int a, int b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGtDecimal(int a, int b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - function assertGtDecimal(uint a, uint b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - - function assertGe(uint a, uint b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGe(uint a, uint b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGe(int a, int b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGe(int a, int b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGeDecimal(int a, int b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - function assertGeDecimal(uint a, uint b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertLt(uint a, uint b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLt(uint a, uint b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLt(int a, int b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLt(int a, int b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLtDecimal(int a, int b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - function assertLtDecimal(uint a, uint b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - - function assertLe(uint a, uint b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLe(uint a, uint b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLe(int a, int b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLe(int a, int b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLeDecimal(int a, int b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - function assertLeDecimal(uint a, uint b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertEq(string memory a, string memory b) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log("Error: a == b not satisfied [string]"); - emit log_named_string(" Expected", b); - emit log_named_string(" Actual", a); - fail(); - } - } - function assertEq(string memory a, string memory b, string memory err) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { - ok = true; - if (a.length == b.length) { - for (uint i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - ok = false; - } - } - } else { - ok = false; - } - } - function assertEq0(bytes memory a, bytes memory b) internal { - if (!checkEq0(a, b)) { - emit log("Error: a == b not satisfied [bytes]"); - emit log_named_bytes(" Expected", b); - emit log_named_bytes(" Actual", a); - fail(); - } - } - function assertEq0(bytes memory a, bytes memory b, string memory err) internal { - if (!checkEq0(a, b)) { - emit log_named_string("Error", err); - assertEq0(a, b); - } - } -} diff --git a/lib/morpho-utils/lib/forge-std/package.json b/lib/morpho-utils/lib/forge-std/package.json deleted file mode 100644 index 656de98..0000000 --- a/lib/morpho-utils/lib/forge-std/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "forge-std", - "version": "1.0.0", - "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", - "homepage": "https://book.getfoundry.sh/forge/forge-std", - "bugs": "https://github.com/foundry-rs/forge-std/issues", - "license": "(Apache-2.0 OR MIT)", - "author": "Contributors to Forge Standard Library", - "files": [ - "src/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/foundry-rs/forge-std.git" - } -} diff --git a/lib/morpho-utils/lib/forge-std/src/Common.sol b/lib/morpho-utils/lib/forge-std/src/Common.sol deleted file mode 100644 index a29b484..0000000 --- a/lib/morpho-utils/lib/forge-std/src/Common.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {StdStorage, Vm} from "./Components.sol"; - -abstract contract CommonBase { - address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); - uint256 internal constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - StdStorage internal stdstore; - Vm internal constant vm = Vm(VM_ADDRESS); -} diff --git a/lib/morpho-utils/lib/forge-std/src/Components.sol b/lib/morpho-utils/lib/forge-std/src/Components.sol deleted file mode 100644 index 6c20fff..0000000 --- a/lib/morpho-utils/lib/forge-std/src/Components.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import "./console.sol"; -import "./console2.sol"; -import "./StdAssertions.sol"; -import "./StdCheats.sol"; -import "./StdError.sol"; -import "./StdJson.sol"; -import "./StdMath.sol"; -import "./StdStorage.sol"; -import "./StdUtils.sol"; -import "./Vm.sol"; diff --git a/lib/morpho-utils/lib/forge-std/src/Script.sol b/lib/morpho-utils/lib/forge-std/src/Script.sol deleted file mode 100644 index d051169..0000000 --- a/lib/morpho-utils/lib/forge-std/src/Script.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {CommonBase} from "./Common.sol"; -// forgefmt: disable-next-line -import {console, console2, StdCheatsSafe, stdJson, stdMath, StdStorage, stdStorageSafe, StdUtils, VmSafe} from "./Components.sol"; - -abstract contract ScriptBase is CommonBase { - VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); -} - -abstract contract Script is ScriptBase, StdCheatsSafe, StdUtils { - bool public IS_SCRIPT = true; -} diff --git a/lib/morpho-utils/lib/forge-std/src/StdAssertions.sol b/lib/morpho-utils/lib/forge-std/src/StdAssertions.sol deleted file mode 100644 index 6926809..0000000 --- a/lib/morpho-utils/lib/forge-std/src/StdAssertions.sol +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import "../lib/ds-test/src/test.sol"; -import "./StdMath.sol"; - -abstract contract StdAssertions is DSTest { - event log_array(uint256[] val); - event log_array(int256[] val); - event log_array(address[] val); - event log_named_array(string key, uint256[] val); - event log_named_array(string key, int256[] val); - event log_named_array(string key, address[] val); - - function fail(string memory err) internal virtual { - emit log_named_string("Error", err); - fail(); - } - - function assertFalse(bool data) internal virtual { - assertTrue(!data); - } - - function assertFalse(bool data, string memory err) internal virtual { - assertTrue(!data, err); - } - - function assertEq(bool a, bool b) internal virtual { - if (a != b) { - emit log("Error: a == b not satisfied [bool]"); - emit log_named_string(" Expected", b ? "true" : "false"); - emit log_named_string(" Actual", a ? "true" : "false"); - fail(); - } - } - - function assertEq(bool a, bool b, string memory err) internal virtual { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes memory a, bytes memory b) internal virtual { - assertEq0(a, b); - } - - function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual { - assertEq0(a, b, err); - } - - function assertEq(uint256[] memory a, uint256[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [uint[]]"); - emit log_named_array(" Expected", b); - emit log_named_array(" Actual", a); - fail(); - } - } - - function assertEq(int256[] memory a, int256[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [int[]]"); - emit log_named_array(" Expected", b); - emit log_named_array(" Actual", a); - fail(); - } - } - - function assertEq(address[] memory a, address[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [address[]]"); - emit log_named_array(" Expected", b); - emit log_named_array(" Actual", a); - fail(); - } - } - - function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - // Legacy helper - function assertEqUint(uint256 a, uint256 b) internal virtual { - assertEq(uint256(a), uint256(b)); - } - - function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Expected", b); - emit log_named_uint(" Actual", a); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbs(a, b, maxDelta); - } - } - - function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_int(" Expected", b); - emit log_named_int(" Actual", a); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbs(a, b, maxDelta); - } - } - - function assertApproxEqRel( - uint256 a, - uint256 b, - uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% - ) internal virtual { - if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Expected", b); - emit log_named_uint(" Actual", a); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta, 18); - emit log_named_decimal_uint(" % Delta", percentDelta, 18); - fail(); - } - } - - function assertApproxEqRel( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the expected is 0, actual must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRel(a, b, maxPercentDelta); - } - } - - function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual { - if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_int(" Expected", b); - emit log_named_int(" Actual", a); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta, 18); - emit log_named_decimal_uint(" % Delta", percentDelta, 18); - fail(); - } - } - - function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the expected is 0, actual must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRel(a, b, maxPercentDelta); - } - } -} diff --git a/lib/morpho-utils/lib/forge-std/src/StdCheats.sol b/lib/morpho-utils/lib/forge-std/src/StdCheats.sol deleted file mode 100644 index 240db21..0000000 --- a/lib/morpho-utils/lib/forge-std/src/StdCheats.sol +++ /dev/null @@ -1,619 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "./StdStorage.sol"; -import "./Vm.sol"; - -abstract contract StdCheatsSafe { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and - /// syntaxes, we put the constructor in a private method and assign an unused return value to a variable. This - /// forces the method to run during construction, but without declaring an explicit constructor. - uint256 private CONSTRUCTOR = _constructor(); - - struct Chain { - // The chain name, using underscores as the separator to match `foundry.toml` conventions. - string name; - // The chain's Chain ID. - uint256 chainId; - // A default RPC endpoint for this chain. - // NOTE: This default RPC URL is included for convenience to facilitate quick tests and - // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy - // usage as you will be throttled and this is a disservice to others who need this endpoint. - string rpcUrl; - } - - struct Chains { - Chain Anvil; - Chain Hardhat; - Chain Mainnet; - Chain Goerli; - Chain Sepolia; - Chain Optimism; - Chain OptimismGoerli; - Chain ArbitrumOne; - Chain ArbitrumOneGoerli; - Chain ArbitrumNova; - Chain Polygon; - Chain PolygonMumbai; - Chain Avalanche; - Chain AvalancheFuji; - Chain BnbSmartChain; - Chain BnbSmartChainTestnet; - Chain GnosisChain; - } - - Chains stdChains; - - // Data structures to parse Transaction objects from the broadcast artifact - // that conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawTx1559 { - string[] arguments; - address contractAddress; - string contractName; - // json value name = function - string functionSig; - bytes32 hash; - // json value name = tx - RawTx1559Detail txDetail; - // json value name = type - string opcode; - } - - struct RawTx1559Detail { - AccessList[] accessList; - bytes data; - address from; - bytes gas; - bytes nonce; - address to; - bytes txType; - bytes value; - } - - struct Tx1559 { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - bytes32 hash; - Tx1559Detail txDetail; - string opcode; - } - - struct Tx1559Detail { - AccessList[] accessList; - bytes data; - address from; - uint256 gas; - uint256 nonce; - address to; - uint256 txType; - uint256 value; - } - - // Data structures to parse Transaction objects from the broadcast artifact - // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct TxLegacy { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - string hash; - string opcode; - TxDetailLegacy transaction; - } - - struct TxDetailLegacy { - AccessList[] accessList; - uint256 chainId; - bytes data; - address from; - uint256 gas; - uint256 gasPrice; - bytes32 hash; - uint256 nonce; - bytes1 opcode; - bytes32 r; - bytes32 s; - uint256 txType; - address to; - uint8 v; - uint256 value; - } - - struct AccessList { - address accessAddress; - bytes32[] storageKeys; - } - - // Data structures to parse Receipt objects from the broadcast artifact. - // The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawReceipt { - bytes32 blockHash; - bytes blockNumber; - address contractAddress; - bytes cumulativeGasUsed; - bytes effectiveGasPrice; - address from; - bytes gasUsed; - RawReceiptLog[] logs; - bytes logsBloom; - bytes status; - address to; - bytes32 transactionHash; - bytes transactionIndex; - } - - struct Receipt { - bytes32 blockHash; - uint256 blockNumber; - address contractAddress; - uint256 cumulativeGasUsed; - uint256 effectiveGasPrice; - address from; - uint256 gasUsed; - ReceiptLog[] logs; - bytes logsBloom; - uint256 status; - address to; - bytes32 transactionHash; - uint256 transactionIndex; - } - - // Data structures to parse the entire broadcast artifact, assuming the - // transactions conform to EIP1559. - - struct EIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - Receipt[] receipts; - uint256 timestamp; - Tx1559[] transactions; - TxReturn[] txReturns; - } - - struct RawEIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - RawReceipt[] receipts; - TxReturn[] txReturns; - uint256 timestamp; - RawTx1559[] transactions; - } - - struct RawReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - bytes blockNumber; - bytes data; - bytes logIndex; - bool removed; - bytes32[] topics; - bytes32 transactionHash; - bytes transactionIndex; - bytes transactionLogIndex; - } - - struct ReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - uint256 blockNumber; - bytes data; - uint256 logIndex; - bytes32[] topics; - uint256 transactionIndex; - uint256 transactionLogIndex; - bool removed; - } - - struct TxReturn { - string internalType; - string value; - } - - function _constructor() private returns (uint256) { - // Initialize `stdChains` with the defaults. - stdChains = Chains({ - Anvil: Chain("Anvil", 31337, "http://127.0.0.1:8545"), - Hardhat: Chain("Hardhat", 31337, "http://127.0.0.1:8545"), - Mainnet: Chain("Mainnet", 1, "https://api.mycryptoapi.com/eth"), - Goerli: Chain("Goerli", 5, "https://goerli.infura.io/v3/84842078b09946638c03157f83405213"), // Default Infura key from ethers.js: https://github.com/ethers-io/ethers.js/blob/c80fcddf50a9023486e9f9acb1848aba4c19f7b6/packages/providers/src.ts/infura-provider.ts - Sepolia: Chain("Sepolia", 11155111, "https://rpc.sepolia.dev"), - Optimism: Chain("Optimism", 10, "https://mainnet.optimism.io"), - OptimismGoerli: Chain("OptimismGoerli", 420, "https://goerli.optimism.io"), - ArbitrumOne: Chain("ArbitrumOne", 42161, "https://arb1.arbitrum.io/rpc"), - ArbitrumOneGoerli: Chain("ArbitrumOneGoerli", 421613, "https://goerli-rollup.arbitrum.io/rpc"), - ArbitrumNova: Chain("ArbitrumNova", 42170, "https://nova.arbitrum.io/rpc"), - Polygon: Chain("Polygon", 137, "https://polygon-rpc.com"), - PolygonMumbai: Chain("PolygonMumbai", 80001, "https://rpc-mumbai.matic.today"), - Avalanche: Chain("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc"), - AvalancheFuji: Chain("AvalancheFuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc"), - BnbSmartChain: Chain("BnbSmartChain", 56, "https://bsc-dataseed1.binance.org"), - BnbSmartChainTestnet: Chain("BnbSmartChainTestnet", 97, "https://data-seed-prebsc-1-s1.binance.org:8545"), - GnosisChain: Chain("GnosisChain", 100, "https://rpc.gnosischain.com") - }); - - // Loop over RPC URLs in the config file to replace the default RPC URLs - (string[2][] memory rpcs) = vm.rpcUrls(); - for (uint256 i = 0; i < rpcs.length; i++) { - (string memory name, string memory rpcUrl) = (rpcs[i][0], rpcs[i][1]); - // forgefmt: disable-start - if (isEqual(name, "anvil")) stdChains.Anvil.rpcUrl = rpcUrl; - else if (isEqual(name, "hardhat")) stdChains.Hardhat.rpcUrl = rpcUrl; - else if (isEqual(name, "mainnet")) stdChains.Mainnet.rpcUrl = rpcUrl; - else if (isEqual(name, "goerli")) stdChains.Goerli.rpcUrl = rpcUrl; - else if (isEqual(name, "sepolia")) stdChains.Sepolia.rpcUrl = rpcUrl; - else if (isEqual(name, "optimism")) stdChains.Optimism.rpcUrl = rpcUrl; - else if (isEqual(name, "optimism_goerli", "optimism-goerli")) stdChains.OptimismGoerli.rpcUrl = rpcUrl; - else if (isEqual(name, "arbitrum_one", "arbitrum-one")) stdChains.ArbitrumOne.rpcUrl = rpcUrl; - else if (isEqual(name, "arbitrum_one_goerli", "arbitrum-one-goerli")) stdChains.ArbitrumOneGoerli.rpcUrl = rpcUrl; - else if (isEqual(name, "arbitrum_nova", "arbitrum-nova")) stdChains.ArbitrumNova.rpcUrl = rpcUrl; - else if (isEqual(name, "polygon")) stdChains.Polygon.rpcUrl = rpcUrl; - else if (isEqual(name, "polygon_mumbai", "polygon-mumbai")) stdChains.PolygonMumbai.rpcUrl = rpcUrl; - else if (isEqual(name, "avalanche")) stdChains.Avalanche.rpcUrl = rpcUrl; - else if (isEqual(name, "avalanche_fuji", "avalanche-fuji")) stdChains.AvalancheFuji.rpcUrl = rpcUrl; - else if (isEqual(name, "bnb_smart_chain", "bnb-smart-chain")) stdChains.BnbSmartChain.rpcUrl = rpcUrl; - else if (isEqual(name, "bnb_smart_chain_testnet", "bnb-smart-chain-testnet")) stdChains.BnbSmartChainTestnet.rpcUrl = rpcUrl; - else if (isEqual(name, "gnosis_chain", "gnosis-chain")) stdChains.GnosisChain.rpcUrl = rpcUrl; - // forgefmt: disable-end - } - return 0; - } - - function isEqual(string memory a, string memory b) private pure returns (bool) { - return keccak256(abi.encode(a)) == keccak256(abi.encode(b)); - } - - function isEqual(string memory a, string memory b, string memory c) private pure returns (bool) { - return keccak256(abi.encode(a)) == keccak256(abi.encode(b)) - || keccak256(abi.encode(a)) == keccak256(abi.encode(c)); - } - - function assumeNoPrecompiles(address addr) internal virtual { - // Assembly required since `block.chainid` was introduced in 0.8.0. - uint256 chainId; - assembly { - chainId := chainid() - } - assumeNoPrecompiles(addr, chainId); - } - - function assumeNoPrecompiles(address addr, uint256 chainId) internal virtual { - // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific - // address), but the same rationale for excluding them applies so we include those too. - - // These should be present on all EVM-compatible chains. - vm.assume(addr < address(0x1) || addr > address(0x9)); - - // forgefmt: disable-start - if (chainId == stdChains.Optimism.chainId || chainId == stdChains.OptimismGoerli.chainId) { - // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 - vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); - } else if (chainId == stdChains.ArbitrumOne.chainId || chainId == stdChains.ArbitrumOneGoerli.chainId) { - // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains - vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); - } else if (chainId == stdChains.Avalanche.chainId || chainId == stdChains.AvalancheFuji.chainId) { - // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 - vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); - vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); - vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); - } - // forgefmt: disable-end - } - - function readEIP1559ScriptArtifact(string memory path) internal virtual returns (EIP1559ScriptArtifact memory) { - string memory data = vm.readFile(path); - bytes memory parsedData = vm.parseJson(data); - RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); - EIP1559ScriptArtifact memory artifact; - artifact.libraries = rawArtifact.libraries; - artifact.path = rawArtifact.path; - artifact.timestamp = rawArtifact.timestamp; - artifact.pending = rawArtifact.pending; - artifact.txReturns = rawArtifact.txReturns; - artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); - artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); - return artifact; - } - - function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { - Tx1559[] memory txs = new Tx1559[](rawTxs.length); - for (uint256 i; i < rawTxs.length; i++) { - txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); - } - return txs; - } - - function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { - Tx1559 memory transaction; - transaction.arguments = rawTx.arguments; - transaction.contractName = rawTx.contractName; - transaction.functionSig = rawTx.functionSig; - transaction.hash = rawTx.hash; - transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); - transaction.opcode = rawTx.opcode; - return transaction; - } - - function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) - internal - pure - virtual - returns (Tx1559Detail memory) - { - Tx1559Detail memory txDetail; - txDetail.data = rawDetail.data; - txDetail.from = rawDetail.from; - txDetail.to = rawDetail.to; - txDetail.nonce = bytesToUint(rawDetail.nonce); - txDetail.txType = bytesToUint(rawDetail.txType); - txDetail.value = bytesToUint(rawDetail.value); - txDetail.gas = bytesToUint(rawDetail.gas); - txDetail.accessList = rawDetail.accessList; - return txDetail; - } - - function readTx1559s(string memory path) internal virtual returns (Tx1559[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); - RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); - return rawToConvertedEIPTx1559s(rawTxs); - } - - function readTx1559(string memory path, uint256 index) internal virtual returns (Tx1559 memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); - return rawToConvertedEIPTx1559(rawTx); - } - - // Analogous to readTransactions, but for receipts. - function readReceipts(string memory path) internal virtual returns (Receipt[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); - RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); - return rawToConvertedReceipts(rawReceipts); - } - - function readReceipt(string memory path, uint256 index) internal virtual returns (Receipt memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); - return rawToConvertedReceipt(rawReceipt); - } - - function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { - Receipt[] memory receipts = new Receipt[](rawReceipts.length); - for (uint256 i; i < rawReceipts.length; i++) { - receipts[i] = rawToConvertedReceipt(rawReceipts[i]); - } - return receipts; - } - - function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { - Receipt memory receipt; - receipt.blockHash = rawReceipt.blockHash; - receipt.to = rawReceipt.to; - receipt.from = rawReceipt.from; - receipt.contractAddress = rawReceipt.contractAddress; - receipt.effectiveGasPrice = bytesToUint(rawReceipt.effectiveGasPrice); - receipt.cumulativeGasUsed = bytesToUint(rawReceipt.cumulativeGasUsed); - receipt.gasUsed = bytesToUint(rawReceipt.gasUsed); - receipt.status = bytesToUint(rawReceipt.status); - receipt.transactionIndex = bytesToUint(rawReceipt.transactionIndex); - receipt.blockNumber = bytesToUint(rawReceipt.blockNumber); - receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); - receipt.logsBloom = rawReceipt.logsBloom; - receipt.transactionHash = rawReceipt.transactionHash; - return receipt; - } - - function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) - internal - pure - virtual - returns (ReceiptLog[] memory) - { - ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); - for (uint256 i; i < rawLogs.length; i++) { - logs[i].logAddress = rawLogs[i].logAddress; - logs[i].blockHash = rawLogs[i].blockHash; - logs[i].blockNumber = bytesToUint(rawLogs[i].blockNumber); - logs[i].data = rawLogs[i].data; - logs[i].logIndex = bytesToUint(rawLogs[i].logIndex); - logs[i].topics = rawLogs[i].topics; - logs[i].transactionIndex = bytesToUint(rawLogs[i].transactionIndex); - logs[i].transactionLogIndex = bytesToUint(rawLogs[i].transactionLogIndex); - logs[i].removed = rawLogs[i].removed; - } - return logs; - } - - // Deploy a contract by fetching the contract bytecode from - // the artifacts directory - // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` - function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); - } - - function deployCode(string memory what) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); - } - - /// @dev deploy contract with value on construction - function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); - } - - function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); - } - - // creates a labeled address and the corresponding private key - function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { - privateKey = uint256(keccak256(abi.encodePacked(name))); - addr = vm.addr(privateKey); - vm.label(addr, name); - } - - // creates a labeled address - function makeAddr(string memory name) internal virtual returns (address addr) { - (addr,) = makeAddrAndKey(name); - } - - function deriveRememberKey(string memory mnemonic, uint32 index) - internal - virtual - returns (address who, uint256 privateKey) - { - privateKey = vm.deriveKey(mnemonic, index); - who = vm.rememberKey(privateKey); - } - - function bytesToUint(bytes memory b) private pure returns (uint256) { - uint256 number; - for (uint256 i = 0; i < b.length; i++) { - number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); - } - return number; - } -} - -// Wrappers around cheatcodes to avoid footguns -abstract contract StdCheats is StdCheatsSafe { - using stdStorage for StdStorage; - - StdStorage private stdstore; - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - // Skip forward or rewind time by the specified number of seconds - function skip(uint256 time) internal virtual { - vm.warp(block.timestamp + time); - } - - function rewind(uint256 time) internal virtual { - vm.warp(block.timestamp - time); - } - - // Setup a prank from an address that has some ether - function hoax(address who) internal virtual { - vm.deal(who, 1 << 128); - vm.prank(who); - } - - function hoax(address who, uint256 give) internal virtual { - vm.deal(who, give); - vm.prank(who); - } - - function hoax(address who, address origin) internal virtual { - vm.deal(who, 1 << 128); - vm.prank(who, origin); - } - - function hoax(address who, address origin, uint256 give) internal virtual { - vm.deal(who, give); - vm.prank(who, origin); - } - - // Start perpetual prank from an address that has some ether - function startHoax(address who) internal virtual { - vm.deal(who, 1 << 128); - vm.startPrank(who); - } - - function startHoax(address who, uint256 give) internal virtual { - vm.deal(who, give); - vm.startPrank(who); - } - - // Start perpetual prank from an address that has some ether - // tx.origin is set to the origin parameter - function startHoax(address who, address origin) internal virtual { - vm.deal(who, 1 << 128); - vm.startPrank(who, origin); - } - - function startHoax(address who, address origin, uint256 give) internal virtual { - vm.deal(who, give); - vm.startPrank(who, origin); - } - - function changePrank(address who) internal virtual { - vm.stopPrank(); - vm.startPrank(who); - } - - // The same as Vm's `deal` - // Use the alternative signature for ERC20 tokens - function deal(address to, uint256 give) internal virtual { - vm.deal(to, give); - } - - // Set the balance of an account for any ERC20 token - // Use the alternative signature to update `totalSupply` - function deal(address token, address to, uint256 give) internal virtual { - deal(token, to, give, false); - } - - function deal(address token, address to, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd)); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0x18160ddd).checked_write(totSup); - } - } -} diff --git a/lib/morpho-utils/lib/forge-std/src/StdError.sol b/lib/morpho-utils/lib/forge-std/src/StdError.sol deleted file mode 100644 index a302191..0000000 --- a/lib/morpho-utils/lib/forge-std/src/StdError.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test -pragma solidity >=0.6.2 <0.9.0; - -library stdError { - bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); - bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); - bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); - bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); - bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); - bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); - bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); - bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); - bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); -} diff --git a/lib/morpho-utils/lib/forge-std/src/StdJson.sol b/lib/morpho-utils/lib/forge-std/src/StdJson.sol deleted file mode 100644 index f5fd707..0000000 --- a/lib/morpho-utils/lib/forge-std/src/StdJson.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.0 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "./Vm.sol"; - -// Helpers for parsing keys into types. -library stdJson { - VmSafe private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function parseRaw(string memory json, string memory key) internal returns (bytes memory) { - return vm.parseJson(json, key); - } - - function readUint(string memory json, string memory key) internal returns (uint256) { - return abi.decode(vm.parseJson(json, key), (uint256)); - } - - function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) { - return abi.decode(vm.parseJson(json, key), (uint256[])); - } - - function readInt(string memory json, string memory key) internal returns (int256) { - return abi.decode(vm.parseJson(json, key), (int256)); - } - - function readIntArray(string memory json, string memory key) internal returns (int256[] memory) { - return abi.decode(vm.parseJson(json, key), (int256[])); - } - - function readBytes32(string memory json, string memory key) internal returns (bytes32) { - return abi.decode(vm.parseJson(json, key), (bytes32)); - } - - function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) { - return abi.decode(vm.parseJson(json, key), (bytes32[])); - } - - function readString(string memory json, string memory key) internal returns (string memory) { - return abi.decode(vm.parseJson(json, key), (string)); - } - - function readStringArray(string memory json, string memory key) internal returns (string[] memory) { - return abi.decode(vm.parseJson(json, key), (string[])); - } - - function readAddress(string memory json, string memory key) internal returns (address) { - return abi.decode(vm.parseJson(json, key), (address)); - } - - function readAddressArray(string memory json, string memory key) internal returns (address[] memory) { - return abi.decode(vm.parseJson(json, key), (address[])); - } - - function readBool(string memory json, string memory key) internal returns (bool) { - return abi.decode(vm.parseJson(json, key), (bool)); - } - - function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) { - return abi.decode(vm.parseJson(json, key), (bool[])); - } - - function readBytes(string memory json, string memory key) internal returns (bytes memory) { - return abi.decode(vm.parseJson(json, key), (bytes)); - } - - function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) { - return abi.decode(vm.parseJson(json, key), (bytes[])); - } -} diff --git a/lib/morpho-utils/lib/forge-std/src/StdMath.sol b/lib/morpho-utils/lib/forge-std/src/StdMath.sol deleted file mode 100644 index 459523b..0000000 --- a/lib/morpho-utils/lib/forge-std/src/StdMath.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -library stdMath { - int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; - - function abs(int256 a) internal pure returns (uint256) { - // Required or it will fail when `a = type(int256).min` - if (a == INT256_MIN) { - return 57896044618658097711785492504343953926634992332820282019728792003956564819968; - } - - return uint256(a > 0 ? a : -a); - } - - function delta(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? a - b : b - a; - } - - function delta(int256 a, int256 b) internal pure returns (uint256) { - // a and b are of the same sign - // this works thanks to two's complement, the left-most bit is the sign bit - if ((a ^ b) > -1) { - return delta(abs(a), abs(b)); - } - - // a and b are of opposite signs - return abs(a) + abs(b); - } - - function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - - return absDelta * 1e18 / b; - } - - function percentDelta(int256 a, int256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - uint256 absB = abs(b); - - return absDelta * 1e18 / absB; - } -} diff --git a/lib/morpho-utils/lib/forge-std/src/StdStorage.sol b/lib/morpho-utils/lib/forge-std/src/StdStorage.sol deleted file mode 100644 index 89710e8..0000000 --- a/lib/morpho-utils/lib/forge-std/src/StdStorage.sol +++ /dev/null @@ -1,327 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import "./Vm.sol"; - -struct StdStorage { - mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; - mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds; - bytes32[] _keys; - bytes4 _sig; - uint256 _depth; - address _target; - bytes32 _set; -} - -library stdStorageSafe { - event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); - event WARNING_UninitedSlot(address who, uint256 slot); - - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return bytes4(keccak256(bytes(sigStr))); - } - - /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against - // slot complexity: - // if flat, will be bytes32(uint256(uint)); - // if map, will be keccak256(abi.encode(key, uint(slot))); - // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); - // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); - function find(StdStorage storage self) internal returns (uint256) { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - // calldata to test against - if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - vm.record(); - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - (bytes32[] memory reads,) = vm.accesses(address(who)); - if (reads.length == 1) { - bytes32 curr = vm.load(who, reads[0]); - if (curr == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[0])); - } - if (fdat != curr) { - require( - false, - "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." - ); - } - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - } else if (reads.length > 1) { - for (uint256 i = 0; i < reads.length; i++) { - bytes32 prev = vm.load(who, reads[i]); - if (prev == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[i])); - } - // store - vm.store(who, reads[i], bytes32(hex"1337")); - bool success; - bytes memory rdat; - { - (success, rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - if (success && fdat == bytes32(hex"1337")) { - // we found which of the slots is the actual one - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - vm.store(who, reads[i], prev); - break; - } - vm.store(who, reads[i], prev); - } - } else { - require(false, "stdStorage find(StdStorage): No storage use detected for target."); - } - - require( - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], - "stdStorage find(StdStorage): Slot(s) not found." - ); - - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - self._target = _target; - return self; - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - self._sig = _sig; - return self; - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - self._sig = sigs(_sig); - return self; - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - self._keys.push(bytes32(uint256(uint160(who)))); - return self; - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - self._keys.push(bytes32(amt)); - return self; - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - self._keys.push(key); - return self; - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - self._depth = _depth; - return self; - } - - function read(StdStorage storage self) private returns (bytes memory) { - address t = self._target; - uint256 s = find(self); - return abi.encode(vm.load(t, bytes32(s))); - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return abi.decode(read(self), (bytes32)); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - int256 v = read_int(self); - if (v == 0) return false; - if (v == 1) return true; - revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - } - - function read_address(StdStorage storage self) internal returns (address) { - return abi.decode(read(self), (address)); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return abi.decode(read(self), (uint256)); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return abi.decode(read(self), (int256)); - } - - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} - -library stdStorage { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return stdStorageSafe.sigs(sigStr); - } - - function find(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.find(self); - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - return stdStorageSafe.target(self, _target); - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, who); - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, amt); - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, key); - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - return stdStorageSafe.depth(self, _depth); - } - - function checked_write(StdStorage storage self, address who) internal { - checked_write(self, bytes32(uint256(uint160(who)))); - } - - function checked_write(StdStorage storage self, uint256 amt) internal { - checked_write(self, bytes32(amt)); - } - - function checked_write(StdStorage storage self, bool write) internal { - bytes32 t; - /// @solidity memory-safe-assembly - assembly { - t := write - } - checked_write(self, t); - } - - function checked_write(StdStorage storage self, bytes32 set) internal { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - find(self); - } - bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]); - - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - bytes32 curr = vm.load(who, slot); - - if (fdat != curr) { - require( - false, - "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." - ); - } - vm.store(who, slot, set); - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return stdStorageSafe.read_bytes32(self); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - return stdStorageSafe.read_bool(self); - } - - function read_address(StdStorage storage self) internal returns (address) { - return stdStorageSafe.read_address(self); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.read_uint(self); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return stdStorageSafe.read_int(self); - } - - // Private function so needs to be copied over - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - // Private function so needs to be copied over - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} diff --git a/lib/morpho-utils/lib/forge-std/src/StdUtils.sol b/lib/morpho-utils/lib/forge-std/src/StdUtils.sol deleted file mode 100644 index b52fa23..0000000 --- a/lib/morpho-utils/lib/forge-std/src/StdUtils.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import "./console2.sol"; - -abstract contract StdUtils { - uint256 private constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { - require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); - - // If x is between min and max, return x directly. This is to ensure that dictionary values - // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 - if (x >= min && x <= max) return x; - - uint256 size = max - min + 1; - - // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. - // This helps ensure coverage of the min/max values. - if (x <= 3 && size > x) return min + x; - if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); - - // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. - if (x > max) { - uint256 diff = x - max; - uint256 rem = diff % size; - if (rem == 0) return max; - result = min + rem - 1; - } else if (x < max) { - uint256 diff = min - x; - uint256 rem = diff % size; - if (rem == 0) return min; - result = max - rem + 1; - } - } - - function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) { - result = _bound(x, min, max); - console2.log("Bound Result", result); - } - - /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce - /// @notice adapated from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol) - function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { - // forgefmt: disable-start - // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0. - // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it. - if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))); - if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))); - - // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length. - if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))); - if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))); - if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)))); - // forgefmt: disable-end - - // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp - // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) - // We assume nobody can have a nonce large enough to require more than 32 bytes. - return addressFromLast20Bytes( - keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) - ); - } - - function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) - internal - pure - virtual - returns (address) - { - return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash))); - } - - function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { - return address(uint160(uint256(bytesValue))); - } -} diff --git a/lib/morpho-utils/lib/forge-std/src/Test.sol b/lib/morpho-utils/lib/forge-std/src/Test.sol deleted file mode 100644 index 09eca87..0000000 --- a/lib/morpho-utils/lib/forge-std/src/Test.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {CommonBase} from "./Common.sol"; -import "../lib/ds-test/src/test.sol"; -// forgefmt: disable-next-line -import {console, console2, StdAssertions, StdCheats, stdError, stdJson, stdMath, StdStorage, stdStorage, StdUtils, Vm} from "./Components.sol"; - -abstract contract TestBase is CommonBase {} - -abstract contract Test is TestBase, DSTest, StdAssertions, StdCheats, StdUtils {} diff --git a/lib/morpho-utils/lib/forge-std/src/Vm.sol b/lib/morpho-utils/lib/forge-std/src/Vm.sol deleted file mode 100644 index 5a24d1c..0000000 --- a/lib/morpho-utils/lib/forge-std/src/Vm.sol +++ /dev/null @@ -1,252 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -interface VmSafe { - struct Log { - bytes32[] topics; - bytes data; - } - - // Loads a storage slot from an address (who, slot) - function load(address, bytes32) external returns (bytes32); - // Signs data, (privateKey, digest) => (v, r, s) - function sign(uint256, bytes32) external returns (uint8, bytes32, bytes32); - // Gets the address for a given private key, (privateKey) => (address) - function addr(uint256) external returns (address); - // Gets the nonce of an account - function getNonce(address) external returns (uint64); - // Performs a foreign function call via the terminal, (stringInputs) => (result) - function ffi(string[] calldata) external returns (bytes memory); - // Sets environment variables, (name, value) - function setEnv(string calldata, string calldata) external; - // Reads environment variables, (name) => (value) - function envBool(string calldata) external returns (bool); - function envUint(string calldata) external returns (uint256); - function envInt(string calldata) external returns (int256); - function envAddress(string calldata) external returns (address); - function envBytes32(string calldata) external returns (bytes32); - function envString(string calldata) external returns (string memory); - function envBytes(string calldata) external returns (bytes memory); - // Reads environment variables as arrays, (name, delim) => (value[]) - function envBool(string calldata, string calldata) external returns (bool[] memory); - function envUint(string calldata, string calldata) external returns (uint256[] memory); - function envInt(string calldata, string calldata) external returns (int256[] memory); - function envAddress(string calldata, string calldata) external returns (address[] memory); - function envBytes32(string calldata, string calldata) external returns (bytes32[] memory); - function envString(string calldata, string calldata) external returns (string[] memory); - function envBytes(string calldata, string calldata) external returns (bytes[] memory); - // Records all storage reads and writes - function record() external; - // Gets all accessed reads and write slot from a recording session, for a given address - function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes); - // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file - function getCode(string calldata) external returns (bytes memory); - // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file - function getDeployedCode(string calldata) external returns (bytes memory); - // Labels an address in call traces - function label(address, string calldata) external; - // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain - function broadcast() external; - // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain - function broadcast(address) external; - // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain - function broadcast(uint256) external; - // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain - function startBroadcast() external; - // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain - function startBroadcast(address) external; - // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain - function startBroadcast(uint256) external; - // Stops collecting onchain transactions - function stopBroadcast() external; - // Reads the entire content of file to string, (path) => (data) - function readFile(string calldata) external returns (string memory); - // Reads the entire content of file as binary. Path is relative to the project root. (path) => (data) - function readFileBinary(string calldata) external returns (bytes memory); - // Get the path of the current project root - function projectRoot() external returns (string memory); - // Reads next line of file to string, (path) => (line) - function readLine(string calldata) external returns (string memory); - // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. - // (path, data) => () - function writeFile(string calldata, string calldata) external; - // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. - // Path is relative to the project root. (path, data) => () - function writeFileBinary(string calldata, bytes calldata) external; - // Writes line to file, creating a file if it does not exist. - // (path, data) => () - function writeLine(string calldata, string calldata) external; - // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. - // (path) => () - function closeFile(string calldata) external; - // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases: - // - Path points to a directory. - // - The file doesn't exist. - // - The user lacks permissions to remove the file. - // (path) => () - function removeFile(string calldata) external; - // Convert values to a string, (value) => (stringified value) - function toString(address) external returns (string memory); - function toString(bytes calldata) external returns (string memory); - function toString(bytes32) external returns (string memory); - function toString(bool) external returns (string memory); - function toString(uint256) external returns (string memory); - function toString(int256) external returns (string memory); - // Convert values from a string, (string) => (parsed value) - function parseBytes(string calldata) external returns (bytes memory); - function parseAddress(string calldata) external returns (address); - function parseUint(string calldata) external returns (uint256); - function parseInt(string calldata) external returns (int256); - function parseBytes32(string calldata) external returns (bytes32); - function parseBool(string calldata) external returns (bool); - // Record all the transaction logs - function recordLogs() external; - // Gets all the recorded logs, () => (logs) - function getRecordedLogs() external returns (Log[] memory); - // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index} - function deriveKey(string calldata, uint32) external returns (uint256); - // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path {path}{index} - function deriveKey(string calldata, string calldata, uint32) external returns (uint256); - // Adds a private key to the local forge wallet and returns the address - function rememberKey(uint256) external returns (address); - // Given a string of JSON, return the ABI-encoded value of provided key - // (stringified json, key) => (ABI-encoded data) - // Read the note below! - function parseJson(string calldata, string calldata) external returns (bytes memory); - // Given a string of JSON, return it as ABI-encoded, (stringified json, key) => (ABI-encoded data) - // Read the note below! - function parseJson(string calldata) external returns (bytes memory); - // Note: - // ---- - // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects - // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in - // ALPHABETICAL ordser. That means that in order to succesfully decode the tuple, we need to define a tuple that - // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded - // as tuples, with the attributes in the order in which they are defined. - // For example: json = { 'a': 1, 'b': 0xa4tb......3xs} - // a: uint256 - // b: address - // To decode that json, we need to define a struct or a tuple as follows: - // struct json = { uint256 a; address b; } - // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to - // decode the tuple in that order, and thus fail. - - // Returns the RPC url for the given alias - function rpcUrl(string calldata) external returns (string memory); - // Returns all rpc urls and their aliases `[alias, url][]` - function rpcUrls() external returns (string[2][] memory); - - // If the condition is false, discard this run's fuzz inputs and generate new ones. - function assume(bool) external; -} - -interface Vm is VmSafe { - // Sets block.timestamp (newTimestamp) - function warp(uint256) external; - // Sets block.height (newHeight) - function roll(uint256) external; - // Sets block.basefee (newBasefee) - function fee(uint256) external; - // Sets block.difficulty (newDifficulty) - function difficulty(uint256) external; - // Sets block.chainid - function chainId(uint256) external; - // Stores a value to an address' storage slot, (who, slot, value) - function store(address, bytes32, bytes32) external; - // Sets the nonce of an account; must be higher than the current nonce of the account - function setNonce(address, uint64) external; - // Sets the *next* call's msg.sender to be the input address - function prank(address) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called - function startPrank(address) external; - // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input - function prank(address, address) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input - function startPrank(address, address) external; - // Resets subsequent calls' msg.sender to be `address(this)` - function stopPrank() external; - // Sets an address' balance, (who, newBalance) - function deal(address, uint256) external; - // Sets an address' code, (who, newCode) - function etch(address, bytes calldata) external; - // Expects an error on next call - function expectRevert(bytes calldata) external; - function expectRevert(bytes4) external; - function expectRevert() external; - // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). - // Call this function, then emit an event, then call a function. Internally after the call, we check if - // logs were emitted in the expected order with the expected topics and data (as specified by the booleans) - function expectEmit(bool, bool, bool, bool) external; - function expectEmit(bool, bool, bool, bool, address) external; - // Mocks a call to an address, returning specified data. - // Calldata can either be strict or a partial match, e.g. if you only - // pass a Solidity selector to the expected calldata, then the entire Solidity - // function will be mocked. - function mockCall(address, bytes calldata, bytes calldata) external; - // Mocks a call to an address with a specific msg.value, returning specified data. - // Calldata match takes precedence over msg.value in case of ambiguity. - function mockCall(address, uint256, bytes calldata, bytes calldata) external; - // Clears all mocked calls - function clearMockedCalls() external; - // Expects a call to an address with the specified calldata. - // Calldata can either be a strict or a partial match - function expectCall(address, bytes calldata) external; - // Expects a call to an address with the specified msg.value and calldata - function expectCall(address, uint256, bytes calldata) external; - // Sets block.coinbase (who) - function coinbase(address) external; - // Snapshot the current state of the evm. - // Returns the id of the snapshot that was created. - // To revert a snapshot use `revertTo` - function snapshot() external returns (uint256); - // Revert the state of the evm to a previous snapshot - // Takes the snapshot id to revert to. - // This deletes the snapshot and all snapshots taken after the given snapshot id. - function revertTo(uint256) external returns (bool); - // Creates a new fork with the given endpoint and block and returns the identifier of the fork - function createFork(string calldata, uint256) external returns (uint256); - // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork - function createFork(string calldata) external returns (uint256); - // Creates a new fork with the given endpoint and at the block the given transaction was mined in, and replays all transaction mined in the block before the transaction - function createFork(string calldata, bytes32) external returns (uint256); - // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork - function createSelectFork(string calldata, uint256) external returns (uint256); - // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, and replays all transaction mined in the block before the transaction - function createSelectFork(string calldata, bytes32) external returns (uint256); - // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork - function createSelectFork(string calldata) external returns (uint256); - // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. - function selectFork(uint256) external; - /// Returns the currently active fork - /// Reverts if no fork is currently active - function activeFork() external returns (uint256); - // Updates the currently active fork to given block number - // This is similar to `roll` but for the currently active fork - function rollFork(uint256) external; - // Updates the currently active fork to given transaction - // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block - function rollFork(bytes32) external; - // Updates the given fork to given block number - function rollFork(uint256 forkId, uint256 blockNumber) external; - // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block - function rollFork(uint256 forkId, bytes32 transaction) external; - // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup - // Meaning, changes made to the state of this account will be kept when switching forks - function makePersistent(address) external; - function makePersistent(address, address) external; - function makePersistent(address, address, address) external; - function makePersistent(address[] calldata) external; - // Revokes persistent status from the address, previously added via `makePersistent` - function revokePersistent(address) external; - function revokePersistent(address[] calldata) external; - // Returns true if the account is marked as persistent - function isPersistent(address) external returns (bool); - // In forking mode, explicitly grant the given address cheatcode access - function allowCheatcodes(address) external; - // Fetches the given transaction from the active fork and executes it on the current state - function transact(bytes32 txHash) external; - // Fetches the given transaction from the given fork and executes it on the current state - function transact(uint256 forkId, bytes32 txHash) external; -} diff --git a/lib/morpho-utils/lib/forge-std/src/console.sol b/lib/morpho-utils/lib/forge-std/src/console.sol deleted file mode 100644 index ad57e53..0000000 --- a/lib/morpho-utils/lib/forge-std/src/console.sol +++ /dev/null @@ -1,1533 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -library console { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _sendLogPayload(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal view { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); - } - - function logUint(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function logString(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function log(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); - } - - function log(uint p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); - } - - function log(uint p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); - } - - function log(uint p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); - } - - function log(string memory p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); - } - - function log(bool p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); - } - - function log(address p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); - } - - function log(uint p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); - } - - function log(uint p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); - } - - function log(uint p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); - } - - function log(uint p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); - } - - function log(uint p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); - } - - function log(uint p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); - } - - function log(uint p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); - } - - function log(uint p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); - } - - function log(uint p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); - } - - function log(uint p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); - } - - function log(uint p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); - } - - function log(bool p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); - } - - function log(bool p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); - } - - function log(bool p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); - } - - function log(address p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); - } - - function log(address p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); - } - - function log(address p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/forge-std/src/console2.sol b/lib/morpho-utils/lib/forge-std/src/console2.sol deleted file mode 100644 index 8cd6e21..0000000 --- a/lib/morpho-utils/lib/forge-std/src/console2.sol +++ /dev/null @@ -1,1538 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should -/// use `int256` and `uint256`. This modified version fixes that. This version is recommended -/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in -/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`. -/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178 -library console2 { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _sendLogPayload(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal view { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int256 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function logUint(uint256 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function logString(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint256 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function log(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint256 p0, uint256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); - } - - function log(uint256 p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); - } - - function log(uint256 p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); - } - - function log(uint256 p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); - } - - function log(string memory p0, uint256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); - } - - function log(bool p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); - } - - function log(address p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint256 p0, uint256 p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC1155.sol b/lib/morpho-utils/lib/forge-std/src/interfaces/IERC1155.sol deleted file mode 100644 index 692b744..0000000 --- a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC1155.sol +++ /dev/null @@ -1,104 +0,0 @@ -pragma solidity >=0.6.2; - -import "src/interfaces/IERC165.sol"; - -/// @title ERC-1155 Multi Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-1155 -/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. -interface ERC1155 is IERC165 { - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_id` argument MUST be the token type being transferred. - /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferSingle( - address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value - ); - - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_ids` argument MUST be the list of tokens being transferred. - /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferBatch( - address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values - ); - - /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. - /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". - event URI(string _value, uint256 indexed _id); - - /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. - /// - MUST revert on any other error. - /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). - /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _id ID of the token type - /// @param _value Transfer amount - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` - function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; - - /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if length of `_ids` is not the same as length of `_values`. - /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. - /// - MUST revert on any other error. - /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). - /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). - /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _ids IDs of each token type (order and length must match _values array) - /// @param _values Transfer amounts per token type (order and length must match _ids array) - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` - function safeBatchTransferFrom( - address _from, - address _to, - uint256[] calldata _ids, - uint256[] calldata _values, - bytes calldata _data - ) external; - - /// @notice Get the balance of an account's tokens. - /// @param _owner The address of the token holder - /// @param _id ID of the token - /// @return The _owner's balance of the token type requested - function balanceOf(address _owner, uint256 _id) external view returns (uint256); - - /// @notice Get the balance of multiple account/token pairs - /// @param _owners The addresses of the token holders - /// @param _ids ID of the tokens - /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) - function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) - external - view - returns (uint256[] memory); - - /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. - /// @dev MUST emit the ApprovalForAll event on success. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Queries the approval status of an operator for a given owner. - /// @param _owner The owner of the tokens - /// @param _operator Address of authorized operator - /// @return True if the operator is approved, false if not - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC165.sol b/lib/morpho-utils/lib/forge-std/src/interfaces/IERC165.sol deleted file mode 100644 index 05e8d8d..0000000 --- a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC165.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity >=0.6.2; - -interface IERC165 { - /// @notice Query if a contract implements an interface - /// @param interfaceID The interface identifier, as specified in ERC-165 - /// @dev Interface identification is specified in ERC-165. This function - /// uses less than 30,000 gas. - /// @return `true` if the contract implements `interfaceID` and - /// `interfaceID` is not 0xffffffff, `false` otherwise - function supportsInterface(bytes4 interfaceID) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC20.sol b/lib/morpho-utils/lib/forge-std/src/interfaces/IERC20.sol deleted file mode 100644 index 95b279e..0000000 --- a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC20.sol +++ /dev/null @@ -1,42 +0,0 @@ -pragma solidity >=0.6.2; - -/// @dev Interface of the ERC20 standard as defined in the EIP. -/// @dev This includes the optional name, symbol, and decimals metadata. -interface IERC20 { - /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). - event Transfer(address indexed from, address indexed to, uint256 value); - - /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` - /// is the new allowance. - event Approval(address indexed owner, address indexed spender, uint256 value); - - /// @notice Returns the amount of tokens in existence. - function totalSupply() external view returns (uint256); - - /// @notice Returns the amount of tokens owned by `account`. - function balanceOf(address account) external view returns (uint256); - - /// @notice Moves `amount` tokens from the caller's account to `to`. - function transfer(address to, uint256 amount) external returns (bool); - - /// @notice Returns the remaining number of tokens that `spender` is allowed - /// to spend on behalf of `owner` - function allowance(address owner, address spender) external view returns (uint256); - - /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. - /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - function approve(address spender, uint256 amount) external returns (bool); - - /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. - /// `amount` is then deducted from the caller's allowance. - function transferFrom(address from, address to, uint256 amount) external returns (bool); - - /// @notice Returns the name of the token. - function name() external view returns (string memory); - - /// @notice Returns the symbol of the token. - function symbol() external view returns (string memory); - - /// @notice Returns the decimals places of the token. - function decimals() external view returns (uint8); -} diff --git a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC4626.sol b/lib/morpho-utils/lib/forge-std/src/interfaces/IERC4626.sol deleted file mode 100644 index 07afb52..0000000 --- a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC4626.sol +++ /dev/null @@ -1,189 +0,0 @@ -pragma solidity >=0.6.2; - -import "src/interfaces/IERC20.sol"; - -/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in -/// https://eips.ethereum.org/EIPS/eip-4626 -interface IERC4626 is IERC20 { - event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares - ); - - /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. - /// @dev - /// - MUST be an ERC-20 token contract. - /// - MUST NOT revert. - function asset() external view returns (address assetTokenAddress); - - /// @notice Returns the total amount of the underlying asset that is “managed” by Vault. - /// @dev - /// - SHOULD include any compounding that occurs from yield. - /// - MUST be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT revert. - function totalAssets() external view returns (uint256 totalManagedAssets); - - /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToShares(uint256 assets) external view returns (uint256 shares); - - /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToAssets(uint256 shares) external view returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, - /// through a deposit call. - /// @dev - /// - MUST return a limited value if receiver is subject to some deposit limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. - /// - MUST NOT revert. - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit - /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called - /// in the same transaction. - /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the - /// deposit would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewDeposit(uint256 assets) external view returns (uint256 shares); - - /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// deposit execution, and are accounted for during deposit. - /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - - /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. - /// @dev - /// - MUST return a limited value if receiver is subject to some mint limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. - /// - MUST NOT revert. - function maxMint(address receiver) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call - /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the - /// same transaction. - /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint - /// would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by minting. - function previewMint(uint256 shares) external view returns (uint256 assets); - - /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint - /// execution, and are accounted for during mint. - /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function mint(uint256 shares, address receiver) external returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the - /// Vault, through a withdraw call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST NOT revert. - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw - /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if - /// called - /// in the same transaction. - /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though - /// the withdrawal would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - - /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// withdraw execution, and are accounted for during withdraw. - /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); - - /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, - /// through a redeem call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. - /// - MUST NOT revert. - function maxRedeem(address owner) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call - /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the - /// same transaction. - /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the - /// redemption would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. - function previewRedeem(uint256 shares) external view returns (uint256 assets); - - /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// redeem execution, and are accounted for during redeem. - /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); -} diff --git a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC721.sol b/lib/morpho-utils/lib/forge-std/src/interfaces/IERC721.sol deleted file mode 100644 index 954468c..0000000 --- a/lib/morpho-utils/lib/forge-std/src/interfaces/IERC721.sol +++ /dev/null @@ -1,163 +0,0 @@ -pragma solidity >=0.6.2; - -import "src/interfaces/IERC165.sol"; - -/// @title ERC-721 Non-Fungible Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. -interface IERC721 is IERC165 { - /// @dev This emits when ownership of any NFT changes by any mechanism. - /// This event emits when NFTs are created (`from` == 0) and destroyed - /// (`to` == 0). Exception: during contract creation, any number of NFTs - /// may be created and assigned without emitting Transfer. At the time of - /// any transfer, the approved address for that NFT (if any) is reset to none. - event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); - - /// @dev This emits when the approved address for an NFT is changed or - /// reaffirmed. The zero address indicates there is no approved address. - /// When a Transfer event emits, this also indicates that the approved - /// address for that NFT (if any) is reset to none. - event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); - - /// @dev This emits when an operator is enabled or disabled for an owner. - /// The operator can manage all NFTs of the owner. - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @notice Count all NFTs assigned to an owner - /// @dev NFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. - /// @param _owner An address for whom to query the balance - /// @return The number of NFTs owned by `_owner`, possibly zero - function balanceOf(address _owner) external view returns (uint256); - - /// @notice Find the owner of an NFT - /// @dev NFTs assigned to zero address are considered invalid, and queries - /// about them do throw. - /// @param _tokenId The identifier for an NFT - /// @return The address of the owner of the NFT - function ownerOf(uint256 _tokenId) external view returns (address); - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. When transfer is complete, this function - /// checks if `_to` is a smart contract (code size > 0). If so, it calls - /// `onERC721Received` on `_to` and throws if the return value is not - /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - /// @param data Additional data with no specified format, sent in call to `_to` - function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev This works identically to the other function with an extra data parameter, - /// except this function just sets data to "". - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE - /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE - /// THEY MAY BE PERMANENTLY LOST - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function transferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Change or reaffirm the approved address for an NFT - /// @dev The zero address indicates there is no approved address. - /// Throws unless `msg.sender` is the current NFT owner, or an authorized - /// operator of the current owner. - /// @param _approved The new approved NFT controller - /// @param _tokenId The NFT to approve - function approve(address _approved, uint256 _tokenId) external payable; - - /// @notice Enable or disable approval for a third party ("operator") to manage - /// all of `msg.sender`'s assets - /// @dev Emits the ApprovalForAll event. The contract MUST allow - /// multiple operators per owner. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Get the approved address for a single NFT - /// @dev Throws if `_tokenId` is not a valid NFT. - /// @param _tokenId The NFT to find the approved address for - /// @return The approved address for this NFT, or the zero address if there is none - function getApproved(uint256 _tokenId) external view returns (address); - - /// @notice Query if an address is an authorized operator for another address - /// @param _owner The address that owns the NFTs - /// @param _operator The address that acts on behalf of the owner - /// @return True if `_operator` is an approved operator for `_owner`, false otherwise - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} - -/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. -interface IERC721TokenReceiver { - /// @notice Handle the receipt of an NFT - /// @dev The ERC721 smart contract calls this function on the recipient - /// after a `transfer`. This function MAY throw to revert and reject the - /// transfer. Return of other than the magic value MUST result in the - /// transaction being reverted. - /// Note: the contract address is always the message sender. - /// @param _operator The address which called `safeTransferFrom` function - /// @param _from The address which previously owned the token - /// @param _tokenId The NFT identifier which is being transferred - /// @param _data Additional data with no specified format - /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - /// unless throwing - function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) - external - returns (bytes4); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. -interface IERC721Metadata is IERC721 { - /// @notice A descriptive name for a collection of NFTs in this contract - function name() external view returns (string memory _name); - - /// @notice An abbreviated name for NFTs in this contract - function symbol() external view returns (string memory _symbol); - - /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. - /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC - /// 3986. The URI may point to a JSON file that conforms to the "ERC721 - /// Metadata JSON Schema". - function tokenURI(uint256 _tokenId) external view returns (string memory); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x780e9d63. -interface IERC721Enumerable is IERC721 { - /// @notice Count NFTs tracked by this contract - /// @return A count of valid NFTs tracked by this contract, where each one of - /// them has an assigned and queryable owner not equal to the zero address - function totalSupply() external view returns (uint256); - - /// @notice Enumerate valid NFTs - /// @dev Throws if `_index` >= `totalSupply()`. - /// @param _index A counter less than `totalSupply()` - /// @return The token identifier for the `_index`th NFT, - /// (sort order not specified) - function tokenByIndex(uint256 _index) external view returns (uint256); - - /// @notice Enumerate NFTs assigned to an owner - /// @dev Throws if `_index` >= `balanceOf(_owner)` or if - /// `_owner` is the zero address, representing invalid NFTs. - /// @param _owner An address where we are interested in NFTs owned by them - /// @param _index A counter less than `balanceOf(_owner)` - /// @return The token identifier for the `_index`th NFT assigned to `_owner`, - /// (sort order not specified) - function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/forge-std/test/StdAssertions.t.sol b/lib/morpho-utils/lib/forge-std/test/StdAssertions.t.sol deleted file mode 100644 index 4d5827d..0000000 --- a/lib/morpho-utils/lib/forge-std/test/StdAssertions.t.sol +++ /dev/null @@ -1,587 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdAssertionsTest is Test { - string constant CUSTOM_ERROR = "guh!"; - - bool constant EXPECT_PASS = false; - bool constant EXPECT_FAIL = true; - - TestTest t = new TestTest(); - - /*////////////////////////////////////////////////////////////////////////// - FAIL(STRING) - //////////////////////////////////////////////////////////////////////////*/ - - function testShouldFail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._fail(CUSTOM_ERROR); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_FALSE - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertFalse_Pass() external { - t._assertFalse(false, EXPECT_PASS); - } - - function testAssertFalse_Fail() external { - vm.expectEmit(false, false, false, true); - emit log("Error: Assertion Failed"); - t._assertFalse(true, EXPECT_FAIL); - } - - function testAssertFalse_Err_Pass() external { - t._assertFalse(false, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertFalse_Err_Fail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertFalse(true, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(BOOL) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_Bool_Pass(bool a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testAssertEq_Bool_Fail(bool a, bool b) external { - vm.assume(a != b); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [bool]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_BoolErr_Pass(bool a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertEq_BoolErr_Fail(bool a, bool b) external { - vm.assume(a != b); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(BYTES) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_Bytes_Pass(bytes calldata a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testAssertEq_Bytes_Fail(bytes calldata a, bytes calldata b) external { - vm.assume(keccak256(a) != keccak256(b)); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [bytes]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_BytesErr_Pass(bytes calldata a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertEq_BytesErr_Fail(bytes calldata a, bytes calldata b) external { - vm.assume(keccak256(a) != keccak256(b)); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(ARRAY) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_UintArr_Pass(uint256 e0, uint256 e1, uint256 e2) public { - uint256[] memory a = new uint256[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - uint256[] memory b = new uint256[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_IntArr_Pass(int256 e0, int256 e1, int256 e2) public { - int256[] memory a = new int256[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - int256[] memory b = new int256[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_AddressArr_Pass(address e0, address e1, address e2) public { - address[] memory a = new address[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - address[] memory b = new address[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_UintArr_FailEl(uint256 e1) public { - vm.assume(e1 != 0); - uint256[] memory a = new uint256[](3); - uint256[] memory b = new uint256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_IntArr_FailEl(int256 e1) public { - vm.assume(e1 != 0); - int256[] memory a = new int256[](3); - int256[] memory b = new int256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_AddressArr_FailEl(address e1) public { - vm.assume(e1 != address(0)); - address[] memory a = new address[](3); - address[] memory b = new address[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_UintArrErr_FailEl(uint256 e1) public { - vm.assume(e1 != 0); - uint256[] memory a = new uint256[](3); - uint256[] memory b = new uint256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_IntArrErr_FailEl(int256 e1) public { - vm.assume(e1 != 0); - int256[] memory a = new int256[](3); - int256[] memory b = new int256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_AddressArrErr_FailEl(address e1) public { - vm.assume(e1 != address(0)); - address[] memory a = new address[](3); - address[] memory b = new address[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_UintArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - uint256[] memory a = new uint256[](lenA); - uint256[] memory b = new uint256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_IntArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - int256[] memory a = new int256[](lenA); - int256[] memory b = new int256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_AddressArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - address[] memory a = new address[](lenA); - address[] memory b = new address[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_UintArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - uint256[] memory a = new uint256[](lenA); - uint256[] memory b = new uint256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_IntArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - int256[] memory a = new int256[](lenA); - int256[] memory b = new int256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_AddressArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - address[] memory a = new address[](lenA); - address[] memory b = new address[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEqUint() public { - assertEqUint(uint8(1), uint128(1)); - assertEqUint(uint64(2), uint64(2)); - } - - function testFailAssertEqUint() public { - assertEqUint(uint64(1), uint96(2)); - assertEqUint(uint160(3), uint160(4)); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbs_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testAssertApproxEqAbs_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); - } - - function testAssertApproxEqAbs_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbs_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbs_Int_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testAssertApproxEqAbs_Int_Fail(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); - } - - function testAssertApproxEqAbs_IntErr_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbs_IntErr_Fail(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRel_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); - } - - function testAssertApproxEqRel_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); - } - - function testAssertApproxEqRel_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRel_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRel_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); - } - - function testAssertApproxEqRel_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); - } - - function testAssertApproxEqRel_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRel_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); - } -} - -contract TestTest is Test { - modifier expectFailure(bool expectFail) { - bool preState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); - _; - bool postState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); - - if (preState == true) { - return; - } - - if (expectFail) { - require(postState == true, "expected failure not triggered"); - - // unwind the expected failure - vm.store(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x00))); - } else { - require(postState == false, "unexpected failure was triggered"); - } - } - - function _fail(string memory err) external expectFailure(true) { - fail(err); - } - - function _assertFalse(bool data, bool expectFail) external expectFailure(expectFail) { - assertFalse(data); - } - - function _assertFalse(bool data, string memory err, bool expectFail) external expectFailure(expectFail) { - assertFalse(data, err); - } - - function _assertEq(bool a, bool b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(bool a, bool b, string memory err, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b, err); - } - - function _assertEq(bytes memory a, bytes memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(bytes memory a, bytes memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(uint256[] memory a, uint256[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(int256[] memory a, int256[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(address[] memory a, address[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(uint256[] memory a, uint256[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(int256[] memory a, int256[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(address[] memory a, address[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta); - } - - function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta, err); - } - - function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta); - } - - function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta, err); - } - - function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta); - } - - function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta, err); - } - - function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta); - } - - function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta, err); - } -} diff --git a/lib/morpho-utils/lib/forge-std/test/StdCheats.t.sol b/lib/morpho-utils/lib/forge-std/test/StdCheats.t.sol deleted file mode 100644 index 0580c2d..0000000 --- a/lib/morpho-utils/lib/forge-std/test/StdCheats.t.sol +++ /dev/null @@ -1,283 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdCheats.sol"; -import "../src/Test.sol"; -import "../src/StdJson.sol"; - -contract StdCheatsTest is Test { - Bar test; - - using stdJson for string; - - function setUp() public { - test = new Bar(); - } - - function testSkip() public { - vm.warp(100); - skip(25); - assertEq(block.timestamp, 125); - } - - function testRewind() public { - vm.warp(100); - rewind(25); - assertEq(block.timestamp, 75); - } - - function testHoax() public { - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - } - - function testHoaxOrigin() public { - hoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - } - - function testHoaxDifferentAddresses() public { - hoax(address(1337), address(7331)); - test.origin{value: 100}(address(1337), address(7331)); - } - - function testStartHoax() public { - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testStartHoaxOrigin() public { - startHoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - test.origin{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testChangePrank() public { - vm.startPrank(address(1337)); - test.bar(address(1337)); - changePrank(address(0xdead)); - test.bar(address(0xdead)); - changePrank(address(1337)); - test.bar(address(1337)); - vm.stopPrank(); - } - - function testMakeAddrEquivalence() public { - (address addr,) = makeAddrAndKey("1337"); - assertEq(makeAddr("1337"), addr); - } - - function testMakeAddrSigning() public { - (address addr, uint256 key) = makeAddrAndKey("1337"); - bytes32 hash = keccak256("some_message"); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); - assertEq(ecrecover(hash, v, r, s), addr); - } - - function testDeal() public { - deal(address(this), 1 ether); - assertEq(address(this).balance, 1 ether); - } - - function testDealToken() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18); - assertEq(barToken.balanceOf(address(this)), 10000e18); - } - - function testDealTokenAdjustTS() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18, true); - assertEq(barToken.balanceOf(address(this)), 10000e18); - assertEq(barToken.totalSupply(), 20000e18); - deal(bar, address(this), 0, true); - assertEq(barToken.balanceOf(address(this)), 0); - assertEq(barToken.totalSupply(), 10000e18); - } - - function testDeployCode() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function testDeployCodeNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar"); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function testDeployCodeVal() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - function testDeployCodeValNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - // We need this so we can call "this.deployCode" rather than "deployCode" directly - function deployCodeHelper(string memory what) external { - deployCode(what); - } - - function testDeployCodeFail() public { - vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); - this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); - } - - function getCode(address who) internal view returns (bytes memory o_code) { - /// @solidity memory-safe-assembly - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(who) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(who, add(o_code, 0x20), 0, size) - } - } - - function testDeriveRememberKey() public { - string memory mnemonic = "test test test test test test test test test test test junk"; - - (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); - assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); - } - - function testBytesToUint() public { - assertEq(3, bytesToUint_test(hex"03")); - assertEq(2, bytesToUint_test(hex"02")); - assertEq(255, bytesToUint_test(hex"ff")); - assertEq(29625, bytesToUint_test(hex"73b9")); - } - - function testParseJsonTxDetail() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - string memory json = vm.readFile(path); - bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); - RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); - Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); - assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); - assertEq( - txDetail.data, - hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" - ); - assertEq(txDetail.nonce, 3); - assertEq(txDetail.txType, 2); - assertEq(txDetail.gas, 29625); - assertEq(txDetail.value, 0); - } - - function testReadEIP1559Transaction() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 0; - Tx1559 memory transaction = readTx1559(path, index); - transaction; - } - - function testReadEIP1559Transactions() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Tx1559[] memory transactions = readTx1559s(path); - transactions; - } - - function testReadReceipt() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 5; - Receipt memory receipt = readReceipt(path, index); - assertEq( - receipt.logsBloom, - hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" - ); - } - - function testReadReceipts() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Receipt[] memory receipts = readReceipts(path); - receipts; - } - - function bytesToUint_test(bytes memory b) private pure returns (uint256) { - uint256 number; - for (uint256 i = 0; i < b.length; i++) { - number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); - } - return number; - } - - function testChainRpcInitialization() public { - // RPCs specified in `foundry.toml` should be updated. - assertEq(stdChains.Mainnet.rpcUrl, "https://api.mycryptoapi.com/eth/"); - assertEq(stdChains.OptimismGoerli.rpcUrl, "https://goerli.optimism.io/"); - assertEq(stdChains.ArbitrumOneGoerli.rpcUrl, "https://goerli-rollup.arbitrum.io/rpc/"); - - // Other RPCs should remain unchanged. - assertEq(stdChains.Anvil.rpcUrl, "http://127.0.0.1:8545"); - assertEq(stdChains.Hardhat.rpcUrl, "http://127.0.0.1:8545"); - assertEq(stdChains.Sepolia.rpcUrl, "https://rpc.sepolia.dev"); - } - - // Ensure we can connect to the default RPC URL for each chain. - function testRpcs() public { - (string[2][] memory rpcs) = vm.rpcUrls(); - for (uint256 i = 0; i < rpcs.length; i++) { - ( /* string memory name */ , string memory rpcUrl) = (rpcs[i][0], rpcs[i][1]); - vm.createSelectFork(rpcUrl); - } - } -} - -contract Bar { - constructor() payable { - /// `DEAL` STDCHEAT - totalSupply = 10000e18; - balanceOf[address(this)] = totalSupply; - } - - /// `HOAX` STDCHEATS - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } - - function origin(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedSender, "!prank"); - } - - function origin(address expectedSender, address expectedOrigin) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedOrigin, "!prank"); - } - - /// `DEAL` STDCHEAT - mapping(address => uint256) public balanceOf; - uint256 public totalSupply; -} - -contract RevertingContract { - constructor() { - revert(); - } -} diff --git a/lib/morpho-utils/lib/forge-std/test/StdError.t.sol b/lib/morpho-utils/lib/forge-std/test/StdError.t.sol deleted file mode 100644 index ccd3efa..0000000 --- a/lib/morpho-utils/lib/forge-std/test/StdError.t.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import "../src/StdError.sol"; -import "../src/Test.sol"; - -contract StdErrorsTest is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectAssertion() public { - vm.expectRevert(stdError.assertionError); - test.assertionError(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } - - function testExpectDiv() public { - vm.expectRevert(stdError.divisionError); - test.divError(0); - } - - function testExpectMod() public { - vm.expectRevert(stdError.divisionError); - test.modError(0); - } - - function testExpectEnum() public { - vm.expectRevert(stdError.enumConversionError); - test.enumConversion(1); - } - - function testExpectEncodeStg() public { - vm.expectRevert(stdError.encodeStorageError); - test.encodeStgError(); - } - - function testExpectPop() public { - vm.expectRevert(stdError.popError); - test.pop(); - } - - function testExpectOOB() public { - vm.expectRevert(stdError.indexOOBError); - test.indexOOBError(1); - } - - function testExpectMem() public { - vm.expectRevert(stdError.memOverflowError); - test.mem(); - } - - function testExpectIntern() public { - vm.expectRevert(stdError.zeroVarError); - test.intern(); - } -} - -contract ErrorsTest { - enum T {T1} - - uint256[] public someArr; - bytes someBytes; - - function assertionError() public pure { - assert(false); - } - - function arithmeticError(uint256 a) public pure { - a -= 100; - } - - function divError(uint256 a) public pure { - 100 / a; - } - - function modError(uint256 a) public pure { - 100 % a; - } - - function enumConversion(uint256 a) public pure { - T(a); - } - - function encodeStgError() public { - /// @solidity memory-safe-assembly - assembly { - sstore(someBytes.slot, 1) - } - keccak256(someBytes); - } - - function pop() public { - someArr.pop(); - } - - function indexOOBError(uint256 a) public pure { - uint256[] memory t = new uint256[](0); - t[a]; - } - - function mem() public pure { - uint256 l = 2 ** 256 / 32; - new uint256[](l); - } - - function intern() public returns (uint256) { - function(uint256) internal returns (uint256) x; - x(2); - return 7; - } -} diff --git a/lib/morpho-utils/lib/forge-std/test/StdMath.t.sol b/lib/morpho-utils/lib/forge-std/test/StdMath.t.sol deleted file mode 100644 index 95037ea..0000000 --- a/lib/morpho-utils/lib/forge-std/test/StdMath.t.sol +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import "../src/StdMath.sol"; -import "../src/Test.sol"; - -contract StdMathTest is Test { - function testGetAbs() external { - assertEq(stdMath.abs(-50), 50); - assertEq(stdMath.abs(50), 50); - assertEq(stdMath.abs(-1337), 1337); - assertEq(stdMath.abs(0), 0); - - assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); - assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); - } - - function testGetAbs_Fuzz(int256 a) external { - uint256 manualAbs = getAbs(a); - - uint256 abs = stdMath.abs(a); - - assertEq(abs, manualAbs); - } - - function testGetDelta_Uint() external { - assertEq(stdMath.delta(uint256(0), uint256(0)), 0); - assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); - assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); - assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); - assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); - - assertEq(stdMath.delta(0, uint256(0)), 0); - assertEq(stdMath.delta(1337, uint256(0)), 1337); - assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); - assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); - assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); - - assertEq(stdMath.delta(1337, uint256(1337)), 0); - assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); - assertEq(stdMath.delta(5000, uint256(1250)), 3750); - } - - function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external { - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function testGetDelta_Int() external { - assertEq(stdMath.delta(int256(0), int256(0)), 0); - assertEq(stdMath.delta(int256(0), int256(1337)), 1337); - assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); - assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); - assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); - - assertEq(stdMath.delta(0, int256(0)), 0); - assertEq(stdMath.delta(1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); - assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); - assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); - - assertEq(stdMath.delta(-0, int256(0)), 0); - assertEq(stdMath.delta(-1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(int256(0), -0), 0); - assertEq(stdMath.delta(int256(0), -1337), 1337); - assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(1337, int256(1337)), 0); - assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); - assertEq(stdMath.delta(5000, int256(1250)), 3750); - } - - function testGetDelta_Int_Fuzz(int256 a, int256 b) external { - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function testGetPercentDelta_Uint() external { - assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); - assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); - assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); - assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMath.percentDelta(uint256(1), 0); - } - - function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external { - vm.assume(b != 0); - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / b; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - function testGetPercentDelta_Int() external { - assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); - assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, int256(1337)), 0); - assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); - assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); - - assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, int256(2500)), 0); - assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMath.percentDelta(int256(1), 0); - } - - function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external { - vm.assume(b != 0); - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / absB; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - /*////////////////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////////////////*/ - - function getAbs(int256 a) private pure returns (uint256) { - if (a < 0) { - return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); - } - - return uint256(a); - } -} diff --git a/lib/morpho-utils/lib/forge-std/test/StdStorage.t.sol b/lib/morpho-utils/lib/forge-std/test/StdStorage.t.sol deleted file mode 100644 index d4c563a..0000000 --- a/lib/morpho-utils/lib/forge-std/test/StdStorage.t.sol +++ /dev/null @@ -1,283 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdStorage.sol"; -import "../src/Test.sol"; - -contract StdStorageTest is Test { - using stdStorage for StdStorage; - - StorageTest internal test; - - function setUp() public { - test = new StorageTest(); - } - - function testStorageHidden() public { - assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); - } - - function testStorageObvious() public { - assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); - } - - function testStorageCheckedWriteHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); - assertEq(uint256(test.hidden()), 100); - } - - function testStorageCheckedWriteObvious() public { - stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); - assertEq(test.exists(), 100); - } - - function testStorageMapStructA() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); - } - - function testStorageMapStructB() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); - } - - function testStorageDeepMap() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( - address(this) - ).find(); - assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); - } - - function testStorageCheckedWriteDeepMap() public { - stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) - .checked_write(100); - assertEq(100, test.deep_map(address(this), address(this))); - } - - function testStorageDeepMapStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(0).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), - bytes32(slot) - ); - } - - function testStorageDeepMapStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(1).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), - bytes32(slot) - ); - } - - function testStorageCheckedWriteDeepMapStructA() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(100, a); - assertEq(0, b); - } - - function testStorageCheckedWriteDeepMapStructB() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(0, a); - assertEq(100, b); - } - - function testStorageCheckedWriteMapStructA() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 100); - assertEq(b, 0); - } - - function testStorageCheckedWriteMapStructB() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 0); - assertEq(b, 100); - } - - function testStorageStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); - assertEq(uint256(7), slot); - } - - function testStorageStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); - assertEq(uint256(7) + 1, slot); - } - - function testStorageCheckedWriteStructA() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 100); - assertEq(b, 1337); - } - - function testStorageCheckedWriteStructB() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 1337); - assertEq(b, 100); - } - - function testStorageMapAddrFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); - assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); - } - - function testStorageMapUintFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); - assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); - } - - function testStorageCheckedWriteMapUint() public { - stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); - assertEq(100, test.map_uint(100)); - } - - function testStorageCheckedWriteMapAddr() public { - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); - assertEq(100, test.map_addr(address(this))); - } - - function testStorageCheckedWriteMapBool() public { - stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); - assertTrue(test.map_bool(address(this))); - } - - function testFailStorageCheckedWriteMapPacked() public { - // expect PackedSlot error but not external call so cant expectRevert - stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337))) - .checked_write(100); - } - - function testStorageCheckedWriteMapPackedSuccess() public { - uint256 full = test.map_packed(address(1337)); - // keep upper 128, set lower 128 to 1337 - full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; - stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( - full - ); - assertEq(1337, test.read_struct_lower(address(1337))); - } - - function testFailStorageConst() public { - // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); - stdstore.target(address(test)).sig("const()").find(); - } - - function testFailStorageNativePack() public { - stdstore.target(address(test)).sig(test.tA.selector).find(); - stdstore.target(address(test)).sig(test.tB.selector).find(); - - // these both would fail - stdstore.target(address(test)).sig(test.tC.selector).find(); - stdstore.target(address(test)).sig(test.tD.selector).find(); - } - - function testStorageReadBytes32() public { - bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); - assertEq(val, hex"1337"); - } - - function testStorageReadBool_False() public { - bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); - assertEq(val, false); - } - - function testStorageReadBool_True() public { - bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); - assertEq(val, true); - } - - function testStorageReadBool_Revert() public { - vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - this.readNonBoolValue(); - } - - function readNonBoolValue() public { - stdstore.target(address(test)).sig(test.tE.selector).read_bool(); - } - - function testStorageReadAddress() public { - address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); - assertEq(val, address(1337)); - } - - function testStorageReadUint() public { - uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); - assertEq(val, 1); - } - - function testStorageReadInt() public { - int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); - assertEq(val, type(int256).min); - } -} - -contract StorageTest { - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - mapping(uint256 => uint256) public map_uint; - mapping(address => uint256) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basic; - - uint248 public tA; - bool public tB; - - bool public tC = false; - uint248 public tD = 1; - - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - mapping(address => bool) public map_bool; - - bytes32 public tE = hex"1337"; - address public tF = address(1337); - int256 public tG = type(int256).min; - bool public tH = true; - - constructor() { - basic = UnpackedStruct({a: 1337, b: 1337}); - - uint256 two = (1 << 128) | 1; - map_packed[msg.sender] = two; - map_packed[address(uint160(1337))] = 1 << 128; - } - - function read_struct_upper(address who) public view returns (uint256) { - return map_packed[who] >> 128; - } - - function read_struct_lower(address who) public view returns (uint256) { - return map_packed[who] & ((1 << 128) - 1); - } - - function hidden() public view returns (bytes32 t) { - bytes32 slot = keccak256("my.random.var"); - /// @solidity memory-safe-assembly - assembly { - t := sload(slot) - } - } - - function const() public pure returns (bytes32 t) { - t = bytes32(hex"1337"); - } -} diff --git a/lib/morpho-utils/lib/forge-std/test/StdUtils.t.sol b/lib/morpho-utils/lib/forge-std/test/StdUtils.t.sol deleted file mode 100644 index 4782d82..0000000 --- a/lib/morpho-utils/lib/forge-std/test/StdUtils.t.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdUtilsTest is Test { - function testBound() public { - assertEq(bound(5, 0, 4), 0); - assertEq(bound(0, 69, 69), 69); - assertEq(bound(0, 68, 69), 68); - assertEq(bound(10, 150, 190), 174); - assertEq(bound(300, 2800, 3200), 3107); - assertEq(bound(9999, 1337, 6666), 4669); - } - - function testBound_WithinRange() public { - assertEq(bound(51, 50, 150), 51); - assertEq(bound(51, 50, 150), bound(bound(51, 50, 150), 50, 150)); - assertEq(bound(149, 50, 150), 149); - assertEq(bound(149, 50, 150), bound(bound(149, 50, 150), 50, 150)); - } - - function testBound_EdgeCoverage() public { - assertEq(bound(0, 50, 150), 50); - assertEq(bound(1, 50, 150), 51); - assertEq(bound(2, 50, 150), 52); - assertEq(bound(3, 50, 150), 53); - assertEq(bound(type(uint256).max, 50, 150), 150); - assertEq(bound(type(uint256).max - 1, 50, 150), 149); - assertEq(bound(type(uint256).max - 2, 50, 150), 148); - assertEq(bound(type(uint256).max - 3, 50, 150), 147); - } - - function testBound_DistributionIsEven(uint256 min, uint256 size) public { - size = size % 100 + 1; - min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); - uint256 max = min + size - 1; - uint256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + i, min, max); - assertEq(result, min + (i - 1) % size); - // x < min - result = bound(min - i, min, max); - assertEq(result, max - (i - 1) % size); - } - } - - function testBound(uint256 num, uint256 min, uint256 max) public { - if (min > max) (min, max) = (max, min); - - uint256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function testBoundUint256Max() public { - assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); - assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); - } - - function testCannotBoundMaxLessThanMin() public { - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - bound(5, 100, 10); - } - - function testCannotBoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - bound(num, min, max); - } - - function testGenerateCreateAddress() external { - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - uint256 nonce = 14; - address createAddress = computeCreateAddress(deployer, nonce); - assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); - } - - function testGenerateCreate2Address() external { - bytes32 salt = bytes32(uint256(31415)); - bytes32 initcodeHash = keccak256(abi.encode(0x6080)); - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - address create2Address = computeCreate2Address(salt, initcodeHash, deployer); - assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); - } - - function testAssumeNoPrecompilesL1(address addr) external { - assumeNoPrecompiles(addr, stdChains.Mainnet.chainId); - assertTrue(addr < address(1) || addr > address(9)); - } -} diff --git a/lib/morpho-utils/lib/forge-std/test/fixtures/broadcast.log.json b/lib/morpho-utils/lib/forge-std/test/fixtures/broadcast.log.json deleted file mode 100644 index 0a0200b..0000000 --- a/lib/morpho-utils/lib/forge-std/test/fixtures/broadcast.log.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "transactions": [ - { - "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", - "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0x73b9", - "value": "0x0", - "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", - "nonce": "0x3", - "accessList": [] - } - }, - { - "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "inc():(uint256)", - "arguments": [], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0xdcb2", - "value": "0x0", - "data": "0x371303c0", - "nonce": "0x4", - "accessList": [] - } - }, - { - "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "function": "t(uint256):(uint256)", - "arguments": ["1"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "gas": "0x8599", - "value": "0x0", - "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", - "nonce": "0x5", - "accessList": [] - } - } - ], - "receipts": [ - { - "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", - "transactionIndex": "0x0", - "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", - "blockNumber": "0x1", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x13f3a", - "gasUsed": "0x13f3a", - "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", - "transactionIndex": "0x0", - "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", - "blockNumber": "0x2", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x45d80", - "gasUsed": "0x45d80", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", - "transactionIndex": "0x0", - "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", - "blockNumber": "0x3", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "cumulativeGasUsed": "0x45feb", - "gasUsed": "0x45feb", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "transactionIndex": "0x0", - "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", - "blockNumber": "0x4", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0x5905", - "gasUsed": "0x5905", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "transactionIndex": "0x0", - "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", - "blockNumber": "0x5", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0xa9c4", - "gasUsed": "0xa9c4", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x0", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "cumulativeGasUsed": "0x66c5", - "gasUsed": "0x66c5", - "contractAddress": null, - "logs": [ - { - "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "topics": [ - "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x1", - "logIndex": "0x0", - "transactionLogIndex": "0x0", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", - "transactionIndex": "0x0", - "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", - "blockNumber": "0x7", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x0000000000000000000000000000000000001337", - "cumulativeGasUsed": "0x5208", - "gasUsed": "0x5208", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - } - ], - "libraries": [ - "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" - ], - "pending": [], - "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", - "returns": {}, - "timestamp": 1655140035 -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.changeset/new-ways-own.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.changeset/new-ways-own.md deleted file mode 100644 index f940bfe..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.changeset/new-ways-own.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'openzeppelin-solidity': patch ---- - -`ERC20Pausable`, `ERC721Pausable`, `ERC1155Pausable`: Add note regarding missing public pausing functionality diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.codecov.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.codecov.yml deleted file mode 100644 index 9455306..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.codecov.yml +++ /dev/null @@ -1,12 +0,0 @@ -comment: off -github_checks: - annotations: false -coverage: - status: - patch: - default: - target: 95% - only_pulls: true - project: - default: - threshold: 1% diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.editorconfig b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.editorconfig deleted file mode 100644 index f162e8d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.editorconfig +++ /dev/null @@ -1,21 +0,0 @@ -# EditorConfig is awesome: https://EditorConfig.org - -# top-most EditorConfig file -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = false -max_line_length = 120 - -[*.sol] -indent_size = 4 - -[*.js] -indent_size = 2 - -[*.{adoc,md}] -max_line_length = 0 diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.eslintrc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.eslintrc deleted file mode 100644 index 095d275..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.eslintrc +++ /dev/null @@ -1,62 +0,0 @@ -{ - "extends" : [ - "standard" - ], - "plugins": [ - "mocha" - ], - "env": { - "browser" : true, - "node" : true, - "mocha" : true, - "jest" : true, - }, - "globals" : { - "artifacts": false, - "contract": false, - "assert": false, - "web3": false, - "usePlugin": false, - "extendEnvironment": false, - }, - "rules": { - - // Strict mode - "strict": ["error", "global"], - - // Code style - "array-bracket-spacing": ["off"], - "camelcase": ["error", {"properties": "always"}], - "comma-dangle": ["error", "always-multiline"], - "comma-spacing": ["error", {"before": false, "after": true}], - "dot-notation": ["error", {"allowKeywords": true, "allowPattern": ""}], - "eol-last": ["error", "always"], - "eqeqeq": ["error", "smart"], - "generator-star-spacing": ["error", "before"], - "indent": ["error", 2], - "linebreak-style": ["error", "unix"], - "max-len": ["error", 120, 2], - "no-debugger": "off", - "no-dupe-args": "error", - "no-dupe-keys": "error", - "no-mixed-spaces-and-tabs": ["error", "smart-tabs"], - "no-redeclare": ["error", {"builtinGlobals": true}], - "no-trailing-spaces": ["error", { "skipBlankLines": false }], - "no-undef": "error", - "no-use-before-define": "off", - "no-var": "error", - "object-curly-spacing": ["error", "always"], - "prefer-const": "error", - "quotes": ["error", "single"], - "semi": ["error", "always"], - "space-before-function-paren": ["error", "always"], - - "mocha/no-exclusive-tests": ["error"], - - "promise/always-return": "off", - "promise/avoid-new": "off", - }, - "parserOptions": { - "ecmaVersion": 2020 - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitattributes b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitattributes deleted file mode 100644 index 52031de..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.sol linguist-language=Solidity diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/bug_report.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 2797a08..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: Bug report -about: Report a bug in OpenZeppelin Contracts - ---- - - - - - -**💻 Environment** - - - -**📝 Details** - - - -**🔢 Code to reproduce bug** - - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/config.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 4018cef..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,4 +0,0 @@ -contact_links: - - name: Questions & Support Requests - url: https://forum.openzeppelin.com/c/support/contracts/18 - about: Ask in the OpenZeppelin Forum diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/feature_request.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index ff596b0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for OpenZeppelin Contracts - ---- - -**🧐 Motivation** - - -**📝 Details** - - - - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/PULL_REQUEST_TEMPLATE.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 469c645..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -Fixes #???? - - - - - -#### PR Checklist - - - - - -- [ ] Tests -- [ ] Documentation -- [ ] Changelog entry diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/actions/gas-compare/action.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/actions/gas-compare/action.yml deleted file mode 100644 index e38c48e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/actions/gas-compare/action.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Compare gas costs -inputs: - token: - description: github token - required: true - report: - description: report to read from - required: false - default: gasReporterOutput.json - out_report: - description: report to read - required: false - default: ${{ github.ref_name }}.gasreport.json - ref_report: - description: report to read from - required: false - default: ${{ github.base_ref }}.gasreport.json - -runs: - using: composite - steps: - - name: Download reference report - if: github.event_name == 'pull_request' - run: | - RUN_ID=`gh run list --repo ${{ github.repository }} --branch ${{ github.base_ref }} --workflow ${{ github.workflow }} --limit 100 --json 'conclusion,databaseId,event' --jq 'map(select(.conclusion=="success" and .event!="pull_request"))[0].databaseId'` - gh run download ${RUN_ID} --repo ${{ github.repository }} -n gasreport - env: - GITHUB_TOKEN: ${{ inputs.token }} - shell: bash - continue-on-error: true - id: reference - - name: Compare reports - if: steps.reference.outcome == 'success' && github.event_name == 'pull_request' - run: | - node scripts/checks/compareGasReports.js ${{ inputs.report }} ${{ inputs.ref_report }} >> $GITHUB_STEP_SUMMARY - env: - STYLE: markdown - shell: bash - - name: Rename report for upload - if: github.event_name != 'pull_request' - run: | - mv ${{ inputs.report }} ${{ inputs.out_report }} - shell: bash - - name: Save report - if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v3 - with: - name: gasreport - path: ${{ inputs.out_report }} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/actions/setup/action.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/actions/setup/action.yml deleted file mode 100644 index 9e562eb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/actions/setup/action.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Setup - -runs: - using: composite - steps: - - uses: actions/setup-node@v3 - with: - node-version: 14.x - cache: npm - - uses: actions/cache@v3 - id: cache - with: - path: '**/node_modules' - key: npm-v3-${{ hashFiles('**/package-lock.json') }} - - name: Install dependencies - run: npm ci --prefer-offline - shell: bash - if: steps.cache.outputs.cache-hit != 'true' - env: - SKIP_COMPILE: true diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/changelog.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/changelog.yml deleted file mode 100644 index 9f2503b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/changelog.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: changelog - -on: - pull_request: - types: - - opened - - synchronize - - labeled - - unlabeled - -concurrency: - group: changelog-${{ github.ref }} - cancel-in-progress: true - -jobs: - check: - runs-on: ubuntu-latest - if: ${{ !contains(github.event.pull_request.labels.*.name, 'ignore-changelog') }} - steps: - - uses: actions/checkout@v3 - - name: Check diff - run: | - git fetch origin ${{ github.base_ref }} --depth=1 - if git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md ; then - echo 'Missing changelog entry' - exit 1 - fi - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/checks.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/checks.yml deleted file mode 100644 index d5d6659..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/checks.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: checks - -on: - push: - branches: - - master - - release-v* - pull_request: {} - workflow_dispatch: {} - -concurrency: - group: checks-${{ github.ref }} - cancel-in-progress: true - -jobs: - lint: - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - run: npm run lint - - tests: - runs-on: ubuntu-latest - env: - FORCE_COLOR: 1 - GAS: true - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set up environment - uses: ./.github/actions/setup - - name: Transpile - run: | - bash scripts/upgradeable/git-user-config.sh - bash scripts/upgradeable/merge-upstream.sh - bash scripts/upgradeable/transpile.sh - env: - REF: 'refs/heads/patches' - BASE_REF: HEAD - if: (github.base_ref || github.ref) == 'refs/heads/patches' - - name: Run tests and generate gas report - run: npm run test - - name: Check linearisation of the inheritance graph - run: npm run test:inheritance - - name: Check proceduraly generated contracts are up-to-date - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - run: npm run test:generation - - name: Compare gas costs - uses: ./.github/actions/gas-compare - with: - token: ${{ github.token }} - - foundry-tests: - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Run tests - run: forge test -vv - - coverage: - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - run: npm run coverage - env: - NODE_OPTIONS: --max_old_space_size=4096 - - uses: codecov/codecov-action@v3 - - slither: - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - uses: crytic/slither-action@v0.2.0 - - codespell: - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Run CodeSpell - uses: codespell-project/actions-codespell@v1.0 - with: - check_filenames: true - skip: package-lock.json diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/docs.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/docs.yml deleted file mode 100644 index 4b54ea6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/docs.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Build Docs - -on: - push: - branches: [release-v*] - -permissions: - contents: write - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - run: bash scripts/git-user-config.sh - - run: node scripts/update-docs-branch.js - - run: git push --all origin diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/merge-upstream.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/merge-upstream.yml deleted file mode 100644 index 20bbf33..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/merge-upstream.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Merge upstream - -on: - push: - branches: [patches] - workflow_dispatch: {} - repository_dispatch: - types: [Update] - # client_payload: { ref: string } - -concurrency: - group: merge-${{ github.event.client_payload.ref || github.ref }} - cancel-in-progress: true - -jobs: - merge: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: patches - fetch-depth: 0 - ssh-key: ${{ secrets.DEPLOY_KEY }} - - run: bash scripts/upgradeable/git-user-config.sh - - run: bash scripts/upgradeable/merge-upstream.sh - env: - REF: ${{ github.event.client_payload.ref || github.ref}} - - run: git push origin HEAD diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/transpile.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/transpile.yml deleted file mode 100644 index 7fd689a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.github/workflows/transpile.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Transpile - -on: - workflow_dispatch: {} - push: - branches: [patched/*] - -concurrency: - group: transpile-${{ github.ref_name }} - cancel-in-progress: true - -jobs: - transpile: - runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/heads/patched/') - steps: - - run: echo ::set-output name=name::"${GITHUB_REF#refs/heads/patched/}" - id: branch - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - ssh-key: ${{ secrets.DEPLOY_KEY }} - - name: Set up environment - uses: ./.github/actions/setup - - run: bash scripts/upgradeable/git-user-config.sh - - run: bash scripts/upgradeable/transpile-onto.sh ${{ steps.branch.outputs.name }} origin/${{ steps.branch.outputs.name }} - - run: git push origin ${{ steps.branch.outputs.name }} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitignore b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitignore deleted file mode 100644 index c60c5d9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitignore +++ /dev/null @@ -1,64 +0,0 @@ -*.swp -*.swo - -# Logs -logs -*.log - -# Runtime data -pids -*.pid -*.seed -allFiredEvents -scTopics - -# Coverage directory used by tools like istanbul -coverage -coverage.json -coverageEnv - -# node-waf configuration -.lock-wscript - -# Dependency directory -node_modules - -# Debug log from npm -npm-debug.log - -# local env variables -.env - -# truffle build directory -build/ - -# macOS -.DS_Store - -# truffle -.node-xmlhttprequest-* - -# IntelliJ IDE -.idea - -# docs artifacts -docs/modules/api - -# only used to package @openzeppelin/contracts -contracts/build/ -contracts/README.md - -# temporary artifact from solidity-coverage -allFiredEvents -.coverage_artifacts -.coverage_cache -.coverage_contracts - -# hardhat -cache -artifacts - -# Certora -.certora* -.last_confs -certora_* diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitmodules b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitmodules deleted file mode 100644 index 3f30ba7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "lib/forge-std"] - branch = v1 - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.mocharc.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.mocharc.js deleted file mode 100644 index 920662d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.mocharc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - require: 'hardhat/register', - timeout: 4000, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.prettierrc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.prettierrc deleted file mode 100644 index f91ad7e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.prettierrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "all", - "overrides": [ - { - "files": "*.sol", - "options": { - "singleQuote": false, - "printWidth": 120, - "explicitTypes": "always" - } - } - ] -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.solcover.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.solcover.js deleted file mode 100644 index 6cf991e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.solcover.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - norpc: true, - testCommand: 'npm test', - compileCommand: 'npm run compile', - skipFiles: [ - 'mocks', - ], - providerOptions: { - default_balance_ether: '10000000000000000000000000', - }, - mocha: { - fgrep: '[skip-on-coverage]', - invert: true, - }, -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.solhint.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.solhint.json deleted file mode 100644 index 7729288..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/.solhint.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "rules": { - "no-unused-vars": "error", - "const-name-snakecase": "error", - "contract-name-camelcase": "error", - "event-name-camelcase": "error", - "func-name-mixedcase": "error", - "func-param-name-mixedcase": "error", - "modifier-name-mixedcase": "error", - "private-vars-leading-underscore": "error", - "var-name-mixedcase": "error", - "imports-on-top": "error" - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CHANGELOG.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CHANGELOG.md deleted file mode 100644 index 8422657..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CHANGELOG.md +++ /dev/null @@ -1,635 +0,0 @@ -# Changelog - -## 4.8.3 (2023-04-13) - -- `GovernorCompatibilityBravo`: Fix encoding of proposal data when signatures are missing. -- `TransparentUpgradeableProxy`: Fix transparency in case of selector clash with non-decodable calldata or payable mutability. ([#4154](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4154)) - -## 4.8.2 (2023-03-02) - -- `ERC721Consecutive`: Fixed a bug when `_mintConsecutive` is used for batches of size 1 that could lead to balance overflow. Refer to the breaking changes section in the changelog for a note on the behavior of `ERC721._beforeTokenTransfer`. - -### Breaking changes - -- `ERC721`: The internal function `_beforeTokenTransfer` no longer updates balances, which it previously did when `batchSize` was greater than 1. This change has no consequence unless a custom ERC721 extension is explicitly invoking `_beforeTokenTransfer`. Balance updates in extensions must now be done explicitly using `__unsafe_increaseBalance`, with a name that indicates that there is an invariant that has to be manually verified. - -## 4.8.1 (2023-01-13) - - * `ERC4626`: Use staticcall instead of call when fetching underlying ERC-20 decimals. ([#3943](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3943)) - -## 4.8.0 (2022-11-08) - - * `TimelockController`: Added a new `admin` constructor parameter that is assigned the admin role instead of the deployer account. ([#3722](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3722)) - * `Initializable`: add internal functions `_getInitializedVersion` and `_isInitializing` ([#3598](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3598)) - * `ERC165Checker`: add `supportsERC165InterfaceUnchecked` for consulting individual interfaces without the full ERC165 protocol. ([#3339](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3339)) - * `Address`: optimize `functionCall` by calling `functionCallWithValue` directly. ([#3468](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3468)) - * `Address`: optimize `functionCall` functions by checking contract size only if there is no returned data. ([#3469](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3469)) - * `Governor`: make the `relay` function payable, and add support for EOA payments. ([#3730](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3730)) - * `GovernorCompatibilityBravo`: remove unused `using` statements. ([#3506](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3506)) - * `ERC20`: optimize `_transfer`, `_mint` and `_burn` by using `unchecked` arithmetic when possible. ([#3513](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3513)) - * `ERC20Votes`, `ERC721Votes`: optimize `getPastVotes` for looking up recent checkpoints. ([#3673](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3673)) - * `ERC20FlashMint`: add an internal `_flashFee` function for overriding. ([#3551](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3551)) - * `ERC4626`: use the same `decimals()` as the underlying asset by default (if available). ([#3639](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3639)) - * `ERC4626`: add internal `_initialConvertToShares` and `_initialConvertToAssets` functions to customize empty vaults behavior. ([#3639](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3639)) - * `ERC721`: optimize transfers by making approval clearing implicit instead of emitting an event. ([#3481](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3481)) - * `ERC721`: optimize burn by making approval clearing implicit instead of emitting an event. ([#3538](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3538)) - * `ERC721`: Fix balance accounting when a custom `_beforeTokenTransfer` hook results in a transfer of the token under consideration. ([#3611](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3611)) - * `ERC721`: use unchecked arithmetic for balance updates. ([#3524](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3524)) - * `ERC721Consecutive`: Implementation of EIP-2309 that allows batch minting of ERC721 tokens during construction. ([#3311](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3311)) - * `ReentrancyGuard`: Reduce code size impact of the modifier by using internal functions. ([#3515](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3515)) - * `SafeCast`: optimize downcasting of signed integers. ([#3565](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3565)) - * `ECDSA`: Remove redundant check on the `v` value. ([#3591](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3591)) - * `VestingWallet`: add `releasable` getters. ([#3580](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3580)) - * `VestingWallet`: remove unused library `Math.sol`. ([#3605](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3605)) - * `VestingWallet`: make constructor payable. ([#3665](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3665)) - * `Create2`: optimize address computation by using assembly instead of `abi.encodePacked`. ([#3600](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3600)) - * `Clones`: optimized the assembly to use only the scratch space during deployments, and optimized `predictDeterministicAddress` to use fewer operations. ([#3640](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3640)) - * `Checkpoints`: Use procedural generation to support multiple key/value lengths. ([#3589](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3589)) - * `Checkpoints`: Add new lookup mechanisms. ([#3589](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3589)) - * `Arrays`: Add `unsafeAccess` functions that allow reading and writing to an element in a storage array bypassing Solidity's "out-of-bounds" check. ([#3589](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3589)) - * `Strings`: optimize `toString`. ([#3573](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3573)) - * `Ownable2Step`: extension of `Ownable` that makes the ownership transfers a two step process. ([#3620](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3620)) - * `Math` and `SignedMath`: optimize function `max` by using `>` instead of `>=`. ([#3679](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3679)) - * `Math`: Add `log2`, `log10` and `log256`. ([#3670](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3670)) - * Arbitrum: Update the vendored arbitrum contracts to match the nitro upgrade. ([#3692](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3692)) - -### Breaking changes - - * `ERC721`: In order to add support for batch minting via `ERC721Consecutive` it was necessary to make a minor breaking change in the internal interface of `ERC721`. Namely, the hooks `_beforeTokenTransfer` and `_afterTokenTransfer` have one additional argument that may need to be added to overrides: - -```diff - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId, -+ uint256 batchSize - ) internal virtual override -``` - - * `ERC4626`: Conversion from shares to assets (and vice-versa) in an empty vault used to consider the possible mismatch between the underlying asset's and the vault's decimals. This initial conversion rate is now set to 1-to-1 irrespective of decimals, which are meant for usability purposes only. The vault now uses the assets decimals by default, so off-chain the numbers should appear the same. Developers overriding the vault decimals to a value that does not match the underlying asset may want to override the `_initialConvertToShares` and `_initialConvertToAssets` to replicate the previous behavior. - - * `TimelockController`: During deployment, the TimelockController used to grant the `TIMELOCK_ADMIN_ROLE` to the deployer and to the timelock itself. The deployer was then expected to renounce this role once configuration of the timelock is over. Failing to renounce that role allows the deployer to change the timelock permissions (but not to bypass the delay for any time-locked actions). The role is no longer given to the deployer by default. A new parameter `admin` can be set to a non-zero address to grant the admin role during construction (to the deployer or any other address). Just like previously, this admin role should be renounced after configuration. If this param is given `address(0)`, the role is not allocated and doesn't need to be revoked. In any case, the timelock itself continues to have this role. - -### Deprecations - - * `EIP712`: Added the file `EIP712.sol` and deprecated `draft-EIP712.sol` since the EIP is no longer a Draft. Developers are encouraged to update their imports. ([#3621](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3621)) - -```diff --import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"; -+import "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; -``` - - * `ERC721Votes`: Added the file `ERC721Votes.sol` and deprecated `draft-ERC721Votes.sol` since it no longer depends on a Draft EIP (EIP-712). Developers are encouraged to update their imports. ([#3699](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3699)) - -```diff --import "@openzeppelin/contracts/token/ERC721/extensions/draft-ERC721Votes.sol"; -+import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Votes.sol"; -``` - -### ERC-721 Compatibility Note - -ERC-721 integrators that interpret contract state from events should make sure that they implement the clearing of approval that is implicit in every transfer according to the EIP. Previous versions of OpenZeppelin Contracts emitted an explicit `Approval` event even though it was not required by the specification, and this is no longer the case. - -With the new `ERC721Consecutive` extension, the internal workings of `ERC721` are slightly changed. Custom extensions to ERC721 should be reviewed to ensure they remain correct. The internal functions that should be considered are `_ownerOf` (new), `_beforeTokenTransfer`, and `_afterTokenTransfer`. - -### ERC-4626 Upgrade Note - -Existing `ERC4626` contracts that are upgraded to 4.8 must initialize a new variable that holds the vault token decimals. The recommended way to do this is to use a [reinitializer]: - -[reinitializer]: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-reinitializer-uint8- - -```solidity -function migrateToV48() public reinitializer(2) { - __ERC4626_init(IERC20Upgradeable(asset())); -} -``` - -## 4.7.3 - -### Breaking changes - - * `ECDSA`: `recover(bytes32,bytes)` and `tryRecover(bytes32,bytes)` no longer accept compact signatures to prevent malleability. Compact signature support remains available using `recover(bytes32,bytes32,bytes32)` and `tryRecover(bytes32,bytes32,bytes32)`. - -## 4.7.2 - - * `LibArbitrumL2`, `CrossChainEnabledArbitrumL2`: Fixed detection of cross-chain calls for EOAs. Previously, calls from EOAs would be classified as cross-chain calls. ([#3578](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3578)) - * `GovernorVotesQuorumFraction`: Fixed quorum updates so they do not affect past proposals that failed due to lack of quorum. ([#3561](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3561)) - * `ERC165Checker`: Added protection against large returndata. ([#3587](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3587)) - -## 4.7.1 - - * `SignatureChecker`: Fix an issue that causes `isValidSignatureNow` to revert when the target contract returns ill-encoded data. ([#3552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3552)) - * `ERC165Checker`: Fix an issue that causes `supportsInterface` to revert when the target contract returns ill-encoded data. ([#3552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3552)) - -## 4.7.0 (2022-06-29) - - * `TimelockController`: Migrate `_call` to `_execute` and allow inheritance and overriding similar to `Governor`. ([#3317](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3317)) - * `CrossChainEnabledPolygonChild`: replace the `require` statement with the custom error `NotCrossChainCall`. ([#3380](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3380)) - * `ERC20FlashMint`: Add customizable flash fee receiver. ([#3327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3327)) - * `ERC4626`: add an extension of `ERC20` that implements the ERC4626 Tokenized Vault Standard. ([#3171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3171)) - * `SafeERC20`: add `safePermit` as mitigation against phantom permit functions. ([#3280](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3280)) - * `Math`: add a `mulDiv` function that can round the result either up or down. ([#3171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3171)) - * `Math`: Add a `sqrt` function to compute square roots of integers, rounding either up or down. ([#3242](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3242)) - * `Strings`: add a new overloaded function `toHexString` that converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. ([#3403](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3403)) - * `EnumerableMap`: add new `UintToUintMap` map type. ([#3338](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3338)) - * `EnumerableMap`: add new `Bytes32ToUintMap` map type. ([#3416](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3416)) - * `SafeCast`: add support for many more types, using procedural code generation. ([#3245](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3245)) - * `MerkleProof`: add `multiProofVerify` to prove multiple values are part of a Merkle tree. ([#3276](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3276)) - * `MerkleProof`: add calldata versions of the functions to avoid copying input arrays to memory and save gas. ([#3200](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3200)) - * `ERC721`, `ERC1155`: simplified revert reasons. ([#3254](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3254), ([#3438](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3438))) - * `ERC721`: removed redundant require statement. ([#3434](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3434)) - * `PaymentSplitter`: add `releasable` getters. ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) - * `Initializable`: refactored implementation of modifiers for easier understanding. ([#3450](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3450)) - * `Proxies`: remove runtime check of ERC1967 storage slots. ([#3455](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3455)) - -### Breaking changes - - * `Initializable`: functions decorated with the modifier `reinitializer(1)` may no longer invoke each other. - -## 4.6.0 (2022-04-26) - - * `crosschain`: Add a new set of contracts for cross-chain applications. `CrossChainEnabled` is a base contract with instantiations for several chains and bridges, and `AccessControlCrossChain` is an extension of access control that allows cross-chain operation. ([#3183](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3183)) - * `AccessControl`: add a virtual `_checkRole(bytes32)` function that can be overridden to alter the `onlyRole` modifier behavior. ([#3137](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3137)) - * `EnumerableMap`: add new `AddressToUintMap` map type. ([#3150](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3150)) - * `EnumerableMap`: add new `Bytes32ToBytes32Map` map type. ([#3192](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3192)) - * `ERC20FlashMint`: support infinite allowance when paying back a flash loan. ([#3226](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3226)) - * `ERC20Wrapper`: the `decimals()` function now tries to fetch the value from the underlying token instance. If that calls revert, then the default value is used. ([#3259](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3259)) - * `draft-ERC20Permit`: replace `immutable` with `constant` for `_PERMIT_TYPEHASH` since the `keccak256` of string literals is treated specially and the hash is evaluated at compile time. ([#3196](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3196)) - * `ERC1155`: Add a `_afterTokenTransfer` hook for improved extensibility. ([#3166](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3166)) - * `ERC1155URIStorage`: add a new extension that implements a `_setURI` behavior similar to ERC721's `_setTokenURI`. ([#3210](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3210)) - * `DoubleEndedQueue`: a new data structure that supports efficient push and pop to both front and back, useful for FIFO and LIFO queues. ([#3153](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3153)) - * `Governor`: improved security of `onlyGovernance` modifier when using an external executor contract (e.g. a timelock) that can operate without necessarily going through the governance protocol. ([#3147](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3147)) - * `Governor`: Add a way to parameterize votes. This can be used to implement voting systems such as fractionalized voting, ERC721 based voting, or any number of other systems. The `params` argument added to `_countVote` method, and included in the newly added `_getVotes` method, can be used by counting and voting modules respectively for such purposes. ([#3043](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3043)) - * `Governor`: rewording of revert reason for consistency. ([#3275](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3275)) - * `Governor`: fix an inconsistency in data locations that could lead to invalid bytecode being produced. ([#3295](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3295)) - * `Governor`: Implement `IERC721Receiver` and `IERC1155Receiver` to improve token custody by governors. ([#3230](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3230)) - * `TimelockController`: Implement `IERC721Receiver` and `IERC1155Receiver` to improve token custody by timelocks. ([#3230](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3230)) - * `TimelockController`: Add a separate canceller role for the ability to cancel. ([#3165](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3165)) - * `Initializable`: add a reinitializer modifier that enables the initialization of new modules, added to already initialized contracts through upgradeability. ([#3232](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3232)) - * `Initializable`: add an Initialized event that tracks initialized version numbers. ([#3294](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3294)) - * `ERC2981`: make `royaltyInfo` public to allow super call in overrides. ([#3305](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3305)) - -### Upgradeability notice - -* `TimelockController`: **(Action needed)** The upgrade from <4.6 to >=4.6 introduces a new `CANCELLER_ROLE` that requires set up to be assignable. After the upgrade, only addresses with this role will have the ability to cancel. Proposers will no longer be able to cancel. Assigning cancellers can be done by an admin (including the timelock itself) once the role admin is set up. To do this, we recommend upgrading to the `TimelockControllerWith46MigrationUpgradeable` contract and then calling the `migrateTo46` function. - -### Breaking changes - -* `Governor`: Adds internal virtual `_getVotes` method that must be implemented; this is a breaking change for existing concrete extensions to `Governor`. To fix this on an existing voting module extension, rename `getVotes` to `_getVotes` and add a `bytes memory` argument. ([#3043](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3043)) -* `Governor`: Adds `params` parameter to internal virtual `_countVote` method; this is a breaking change for existing concrete extensions to `Governor`. To fix this on an existing counting module extension, add a `bytes memory` argument to `_countVote`. ([#3043](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3043)) -* `Governor`: Does not emit `VoteCast` event when params data is non-empty; instead emits `VoteCastWithParams` event. To fix this on an integration that consumes the `VoteCast` event, also fetch/monitor `VoteCastWithParams` events. ([#3043](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3043)) -* `Votes`: The internal virtual function `_getVotingUnits` was made `view` (which was accidentally missing). Any overrides should now be updated so they are `view` as well. - -## 4.5.0 (2022-02-09) - - * `ERC2981`: add implementation of the royalty standard, and the respective extensions for `ERC721` and `ERC1155`. ([#3012](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3012)) - * `GovernorTimelockControl`: improve the `state()` function to have it reflect cases where a proposal has been canceled directly on the timelock. ([#2977](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2977)) - * Preset contracts are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com). ([#2986](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2986)) - * `Governor`: add a relay function to help recover assets sent to a governor that is not its own executor (e.g. when using a timelock). ([#2926](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2926)) - * `GovernorPreventLateQuorum`: add new module to ensure a minimum voting duration is available after the quorum is reached. ([#2973](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2973)) - * `ERC721`: improved revert reason when transferring from wrong owner. ([#2975](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2975)) - * `Votes`: Added a base contract for vote tracking with delegation. ([#2944](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2944)) - * `ERC721Votes`: Added an extension of ERC721 enabled with vote tracking and delegation. ([#2944](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2944)) - * `ERC2771Context`: use immutable storage to store the forwarder address, no longer an issue since Solidity >=0.8.8 allows reading immutable variables in the constructor. ([#2917](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2917)) - * `Base64`: add a library to parse bytes into base64 strings using `encode(bytes memory)` function, and provide examples to show how to use to build URL-safe `tokenURIs`. ([#2884](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2884)) - * `ERC20`: reduce allowance before triggering transfer. ([#3056](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3056)) - * `ERC20`: do not update allowance on `transferFrom` when allowance is `type(uint256).max`. ([#3085](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3085)) - * `ERC20`: add a `_spendAllowance` internal function. ([#3170](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3170)) - * `ERC20Burnable`: do not update allowance on `burnFrom` when allowance is `type(uint256).max`. ([#3170](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3170)) - * `ERC777`: do not update allowance on `transferFrom` when allowance is `type(uint256).max`. ([#3085](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3085)) - * `ERC777`: add a `_spendAllowance` internal function. ([#3170](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3170)) - * `SignedMath`: a new signed version of the Math library with `max`, `min`, and `average`. ([#2686](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2686)) - * `SignedMath`: add an `abs(int256)` method that returns the unsigned absolute value of a signed value. ([#2984](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2984)) - * `ERC1967Upgrade`: Refactor the secure upgrade to use `ERC1822` instead of the previous rollback mechanism. This reduces code complexity and attack surface with similar security guarantees. ([#3021](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3021)) - * `UUPSUpgradeable`: Add `ERC1822` compliance to support the updated secure upgrade mechanism. ([#3021](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3021)) - * Some more functions have been made virtual to customize them via overrides. In many cases this will not imply that other functions in the contract will automatically adapt to the overridden definitions. People who wish to override should consult the source code to understand the impact and if they need to override any additional functions to achieve the desired behavior. - -### Breaking changes - -* `ERC1967Upgrade`: The function `_upgradeToAndCallSecure` was renamed to `_upgradeToAndCallUUPS`, along with the change in security mechanism described above. -* `Address`: The Solidity pragma is increased from `^0.8.0` to `^0.8.1`. This is required by the `account.code.length` syntax that replaces inline assembly. This may require users to bump their compiler version from `0.8.0` to `0.8.1` or later. Note that other parts of the code already include stricter requirements. - -## 4.4.2 (2022-01-11) - -### Bugfixes - * `GovernorCompatibilityBravo`: Fix error in the encoding of calldata for proposals submitted through the compatibility interface with explicit signatures. ([#3100](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3100)) - -## 4.4.1 (2021-12-14) - - * `Initializable`: change the existing `initializer` modifier and add a new `onlyInitializing` modifier to prevent reentrancy risk. ([#3006](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3006)) - -### Breaking change - -It is no longer possible to call an `initializer`-protected function from within another `initializer` function outside the context of a constructor. Projects using OpenZeppelin upgradeable proxies should continue to work as is, since in the common case the initializer is invoked in the constructor directly. If this is not the case for you, the suggested change is to use the new `onlyInitializing` modifier in the following way: - -```diff - contract A { -- function initialize() public initializer { ... } -+ function initialize() internal onlyInitializing { ... } - } - contract B is A { - function initialize() public initializer { - A.initialize(); - } - } -``` - -## 4.4.0 (2021-11-25) - - * `Ownable`: add an internal `_transferOwnership(address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568)) - * `AccessControl`: add internal `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568)) - * `AccessControl`: mark `_setupRole(bytes32,address)` as deprecated in favor of `_grantRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568)) - * `AccessControlEnumerable`: hook into `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2946](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2946)) - * `EIP712`: cache `address(this)` to immutable storage to avoid potential issues if a vanilla contract is used in a delegatecall context. ([#2852](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2852)) - * Add internal `_setApprovalForAll` to `ERC721` and `ERC1155`. ([#2834](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2834)) - * `Governor`: shift vote start and end by one block to better match Compound's GovernorBravo and prevent voting at the Governor level if the voting snapshot is not ready. ([#2892](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2892)) - * `GovernorCompatibilityBravo`: consider quorum an inclusive rather than exclusive minimum to match Compound's GovernorBravo. ([#2974](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2974)) - * `GovernorSettings`: a new governor module that manages voting settings updatable through governance actions. ([#2904](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2904)) - * `PaymentSplitter`: now supports ERC20 assets in addition to Ether. ([#2858](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2858)) - * `ECDSA`: add a variant of `toEthSignedMessageHash` for arbitrary length message hashing. ([#2865](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2865)) - * `MerkleProof`: add a `processProof` function that returns the rebuilt root hash given a leaf and a proof. ([#2841](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2841)) - * `VestingWallet`: new contract that handles the vesting of Ether and ERC20 tokens following a customizable vesting schedule. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2748)) - * `Governor`: enable receiving Ether when a Timelock contract is not used. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849)) - * `GovernorTimelockCompound`: fix ability to use Ether stored in the Timelock contract. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849)) - -## 4.3.3 - - * `ERC1155Supply`: Handle `totalSupply` changes by hooking into `_beforeTokenTransfer` to ensure consistency of balances and supply during `IERC1155Receiver.onERC1155Received` calls. - -## 4.3.2 (2021-09-14) - - * `UUPSUpgradeable`: Add modifiers to prevent `upgradeTo` and `upgradeToAndCall` being executed on any contract that is not the active ERC1967 proxy. This prevents these functions being called on implementation contracts or minimal ERC1167 clones, in particular. - -## 4.3.1 (2021-08-26) - - * `TimelockController`: Add additional isOperationReady check. - -## 4.3.0 (2021-08-17) - - * `ERC2771Context`: use private variable from storage to store the forwarder address. Fixes issues where `_msgSender()` was not callable from constructors. ([#2754](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2754)) - * `EnumerableSet`: add `values()` functions that returns an array containing all values in a single call. ([#2768](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2768)) - * `Governor`: added a modular system of `Governor` contracts based on `GovernorAlpha` and `GovernorBravo`. ([#2672](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2672)) - * Add an `interfaces` folder containing solidity interfaces to final ERCs. ([#2517](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2517)) - * `ECDSA`: add `tryRecover` functions that will not throw if the signature is invalid, and will return an error flag instead. ([#2661](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2661)) - * `SignatureChecker`: Reduce gas usage of the `isValidSignatureNow` function for the "signature by EOA" case. ([#2661](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2661)) - -## 4.2.0 (2021-06-30) - - * `ERC20Votes`: add a new extension of the `ERC20` token with support for voting snapshots and delegation. ([#2632](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2632)) - * `ERC20VotesComp`: Variant of `ERC20Votes` that is compatible with Compound's `Comp` token interface but restricts supply to `uint96`. ([#2706](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2706)) - * `ERC20Wrapper`: add a new extension of the `ERC20` token which wraps an underlying token. Deposit and withdraw guarantee that the total supply is backed by a corresponding amount of underlying token. ([#2633](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2633)) - * Enumerables: Improve gas cost of removal in `EnumerableSet` and `EnumerableMap`. - * Enumerables: Improve gas cost of lookup in `EnumerableSet` and `EnumerableMap`. - * `Counter`: add a reset method. ([#2678](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2678)) - * Tokens: Wrap definitely safe subtractions in `unchecked` blocks. - * `Math`: Add a `ceilDiv` method for performing ceiling division. - * `ERC1155Supply`: add a new `ERC1155` extension that keeps track of the totalSupply of each tokenId. ([#2593](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2593)) - * `BitMaps`: add a new `BitMaps` library that provides a storage efficient datastructure for `uint256` to `bool` mapping with contiguous keys. ([#2710](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2710)) - -### Breaking Changes - - * `ERC20FlashMint` is no longer a Draft ERC. ([#2673](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2673))) - -**How to update:** Change your import paths by removing the `draft-` prefix from `@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20FlashMint.sol`. - -> See [Releases and Stability: Drafts](https://docs.openzeppelin.com/contracts/4.x/releases-stability#drafts). - -## 4.1.0 (2021-04-29) - - * `IERC20Metadata`: add a new extended interface that includes the optional `name()`, `symbol()` and `decimals()` functions. ([#2561](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2561)) - * `ERC777`: make reception acquirement optional in `_mint`. ([#2552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2552)) - * `ERC20Permit`: add a `_useNonce` to enable further usage of ERC712 signatures. ([#2565](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2565)) - * `ERC20FlashMint`: add an implementation of the ERC3156 extension for flash-minting ERC20 tokens. ([#2543](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2543)) - * `SignatureChecker`: add a signature verification library that supports both EOA and ERC1271 compliant contracts as signers. ([#2532](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2532)) - * `Multicall`: add abstract contract with `multicall(bytes[] calldata data)` function to bundle multiple calls together ([#2608](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2608)) - * `ECDSA`: add support for ERC2098 short-signatures. ([#2582](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2582)) - * `AccessControl`: add an `onlyRole` modifier to restrict specific function to callers bearing a specific role. ([#2609](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2609)) - * `StorageSlot`: add a library for reading and writing primitive types to specific storage slots. ([#2542](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2542)) - * UUPS Proxies: add `UUPSUpgradeable` to implement the UUPS proxy pattern together with `EIP1967Proxy`. ([#2542](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2542)) - -### Breaking changes - -This release includes two small breaking changes in `TimelockController`. - -1. The `onlyRole` modifier in this contract was designed to let anyone through if the role was granted to `address(0)`, - allowing the possibility to to make a role "open", which can be used for `EXECUTOR_ROLE`. This modifier is now - replaced by `AccessControl.onlyRole`, which does not have this ability. The previous behavior was moved to the - modifier `TimelockController.onlyRoleOrOpenRole`. -2. It was possible to make `PROPOSER_ROLE` an open role (as described in the previous item) if it was granted to - `address(0)`. This would affect the `schedule`, `scheduleBatch`, and `cancel` operations in `TimelockController`. - This ability was removed as it does not make sense to open up the `PROPOSER_ROLE` in the same way that it does for - `EXECUTOR_ROLE`. - -## 4.0.0 (2021-03-23) - - * Now targeting the 0.8.x line of Solidity compilers. For 0.6.x (resp 0.7.x) support, use version 3.4.0 (resp 3.4.0-solc-0.7) of OpenZeppelin. - * `Context`: making `_msgData` return `bytes calldata` instead of `bytes memory` ([#2492](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2492)) - * `ERC20`: removed the `_setDecimals` function and the storage slot associated to decimals. ([#2502](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2502)) - * `Strings`: addition of a `toHexString` function. ([#2504](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2504)) - * `EnumerableMap`: change implementation to optimize for `key → value` lookups instead of enumeration. ([#2518](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2518)) - * `GSN`: deprecate GSNv1 support in favor of upcoming support for GSNv2. ([#2521](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2521)) - * `ERC165`: remove uses of storage in the base ERC165 implementation. ERC165 based contracts now use storage-less virtual functions. Old behavior remains available in the `ERC165Storage` extension. ([#2505](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2505)) - * `Initializable`: make initializer check stricter during construction. ([#2531](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2531)) - * `ERC721`: remove enumerability of tokens from the base implementation. This feature is now provided separately through the `ERC721Enumerable` extension. ([#2511](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2511)) - * `AccessControl`: removed enumerability by default for a more lightweight contract. It is now opt-in through `AccessControlEnumerable`. ([#2512](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2512)) - * Meta Transactions: add `ERC2771Context` and a `MinimalForwarder` for meta-transactions. ([#2508](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2508)) - * Overall reorganization of the contract folder to improve clarity and discoverability. ([#2503](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2503)) - * `ERC20Capped`: optimize gas usage by enforcing the check directly in `_mint`. ([#2524](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2524)) - * Rename `UpgradeableProxy` to `ERC1967Proxy`. ([#2547](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2547)) - * `ERC777`: optimize the gas costs of the constructor. ([#2551](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2551)) - * `ERC721URIStorage`: add a new extension that implements the `_setTokenURI` behavior as it was available in 3.4.0. ([#2555](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2555)) - * `AccessControl`: added ERC165 interface detection. ([#2562](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2562)) - * `ERC1155`: make `uri` public so overloading function can call it using super. ([#2576](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2576)) - -### Bug fixes for beta releases - - * `AccessControlEnumerable`: Fixed `renounceRole` not updating enumerable set of addresses for a role. ([#2572](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2572)) - -### How to upgrade from 3.x - -Since this version has moved a few contracts to different directories, users upgrading from a previous version will need to adjust their import statements. To make this easier, the package includes a script that will migrate import statements automatically. After upgrading to the latest version of the package, run: - -``` -npx openzeppelin-contracts-migrate-imports -``` - -Make sure you're using git or another version control system to be able to recover from any potential error in our script. - -### How to upgrade from 4.0-beta.x - -Some further changes have been done between the different beta iterations. Transitions made during this period are configured in the `migrate-imports` script. Consequently, you can upgrade from any previous 4.0-beta.x version using the same script as described in the *How to upgrade from 3.x* section. - -## 3.4.2 - - * `TimelockController`: Add additional isOperationReady check. - -## 3.4.1 (2021-03-03) - - * `ERC721`: made `_approve` an internal function (was private). - -## 3.4.0 (2021-02-02) - - * `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411)) - * `EIP712`: added helpers to verify EIP712 typed data signatures on chain. ([#2418](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2418)) - * `ERC20Permit`: added an implementation of the ERC20 permit extension for gasless token approvals. ([#2237](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237)) - * Presets: added token presets with preminted fixed supply `ERC20PresetFixedSupply` and `ERC777PresetFixedSupply`. ([#2399](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2399)) - * `Clones`: added a library for deploying EIP 1167 minimal proxies. ([#2449](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2449)) - * `Context`: moved from `contracts/GSN` to `contracts/utils`. ([#2453](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2453)) - * `PaymentSplitter`: replace usage of `.transfer()` with `Address.sendValue` for improved compatibility with smart wallets. ([#2455](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2455)) - * `UpgradeableProxy`: bubble revert reasons from initialization calls. ([#2454](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2454)) - * `SafeMath`: fix a memory allocation issue by adding new `SafeMath.tryOp(uint,uint)→(bool,uint)` functions. `SafeMath.op(uint,uint,string)→uint` are now deprecated. ([#2462](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2462)) - * `EnumerableMap`: fix a memory allocation issue by adding new `EnumerableMap.tryGet(uint)→(bool,address)` functions. `EnumerableMap.get(uint)→string` is now deprecated. ([#2462](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2462)) - * `ERC165Checker`: added batch `getSupportedInterfaces`. ([#2469](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2469)) - * `RefundEscrow`: `beneficiaryWithdraw` will forward all available gas to the beneficiary. ([#2480](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2480)) - * Many view and pure functions have been made virtual to customize them via overrides. In many cases this will not imply that other functions in the contract will automatically adapt to the overridden definitions. People who wish to override should consult the source code to understand the impact and if they need to override any additional functions to achieve the desired behavior. - -### Security Fixes - - * `ERC777`: fix potential reentrancy issues for custom extensions to `ERC777`. ([#2483](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2483)) - -If you're using our implementation of ERC777 from version 3.3.0 or earlier, and you define a custom `_beforeTokenTransfer` function that writes to a storage variable, you may be vulnerable to a reentrancy attack. If you're affected and would like assistance please write to security@openzeppelin.com. [Read more in the pull request.](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2483) - -## 3.3.0 (2020-11-26) - - * Now supports both Solidity 0.6 and 0.7. Compiling with solc 0.7 will result in warnings. Install the `solc-0.7` tag to compile without warnings. - * `Address`: added `functionStaticCall`, similar to the existing `functionCall`. ([#2333](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2333)) - * `TimelockController`: added a contract to augment access control schemes with a delay. ([#2354](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2354)) - * `EnumerableSet`: added `Bytes32Set`, for sets of `bytes32`. ([#2395](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2395)) - -## Upgradeable 3.2.0 (2020-11-11) - - * First release of Upgradeable variant, replacing Ethereum Package variant which is now deprecated. - -## 3.2.2-solc-0.7 (2020-10-28) - * Resolve warnings introduced by Solidity 0.7.4. ([#2396](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2396)) - -## 3.2.1-solc-0.7 (2020-09-15) - * `ERC777`: Remove a warning about function state visibility in Solidity 0.7. ([#2327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2327)) - -## 3.2.0 (2020-09-10) - -### New features - * Proxies: added the proxy contracts from OpenZeppelin SDK. ([#2335](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2335)) - -#### Proxy changes with respect to OpenZeppelin SDK - -Aside from upgrading them from Solidity 0.5 to 0.6, we've changed a few minor things from the proxy contracts as they were found in OpenZeppelin SDK. - -- `UpgradeabilityProxy` was renamed to `UpgradeableProxy`. -- `AdminUpgradeabilityProxy` was renamed to `TransparentUpgradeableProxy`. -- `Proxy._willFallback` was renamed to `Proxy._beforeFallback`. -- `UpgradeabilityProxy._setImplementation` and `AdminUpgradeabilityProxy._setAdmin` were made private. - -### Improvements - * `Address.isContract`: switched from `extcodehash` to `extcodesize` for less gas usage. ([#2311](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2311)) - -### Breaking changes - * `ERC20Snapshot`: switched to using `_beforeTokenTransfer` hook instead of overriding ERC20 operations. ([#2312](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2312)) - -This small change in the way we implemented `ERC20Snapshot` may affect users who are combining this contract with -other ERC20 flavors, since it no longer overrides `_transfer`, `_mint`, and `_burn`. This can result in having to remove Solidity `override(...)` specifiers in derived contracts for these functions, and to instead have to add it for `_beforeTokenTransfer`. See [Using Hooks](https://docs.openzeppelin.com/contracts/3.x/extending-contracts#using-hooks) in the documentation. - -## 3.1.0 (2020-06-23) - -### New features - * `SafeCast`: added functions to downcast signed integers (e.g. `toInt32`), improving usability of `SignedSafeMath`. ([#2243](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2243)) - * `functionCall`: new helpers that replicate Solidity's function call semantics, reducing the need to rely on `call`. ([#2264](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2264)) - * `ERC1155`: added support for a base implementation, non-standard extensions and a preset contract. ([#2014](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2014), [#2230](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2230)) - -### Improvements - * `ReentrancyGuard`: reduced overhead of using the `nonReentrant` modifier. ([#2171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2171)) - * `AccessControl`: added a `RoleAdminChanged` event to `_setAdminRole`. ([#2214](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2214)) - * Made all `public` functions in the token preset contracts `virtual`. ([#2257](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2257)) - -### Deprecations - * `SafeERC20`: deprecated `safeApprove`. ([#2268](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2268)) - -## 3.0.2 (2020-06-08) - -### Improvements - * Added SPX license identifier to all contracts. ([#2235](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2235)) - -## 3.0.1 (2020-04-27) - -### Bugfixes - * `ERC777`: fixed the `_approve` internal function not validating some of their arguments for non-zero addresses. ([#2213](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2213)) - -## 3.0.0 (2020-04-20) - -### New features - * `AccessControl`: new contract for managing permissions in a system, replacement for `Ownable` and `Roles`. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112)) - * `SafeCast`: new functions to convert to and from signed and unsigned values: `toUint256` and `toInt256`. ([#2123](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2123)) - * `EnumerableMap`: a new data structure for key-value pairs (like `mapping`) that can be iterated over. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160)) - -### Breaking changes - * `ERC721`: `burn(owner, tokenId)` was removed, use `burn(tokenId)` instead. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125)) - * `ERC721`: `_checkOnERC721Received` was removed. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125)) - * `ERC721`: `_transferFrom` and `_safeTransferFrom` were renamed to `_transfer` and `_safeTransfer`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162)) - * `Ownable`: removed `_transferOwnership`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162)) - * `PullPayment`, `Escrow`: `withdrawWithGas` was removed. The old `withdraw` function now forwards all gas. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125)) - * `Roles` was removed, use `AccessControl` as a replacement. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112)) - * `ECDSA`: when receiving an invalid signature, `recover` now reverts instead of returning the zero address. ([#2114](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2114)) - * `Create2`: added an `amount` argument to `deploy` for contracts with `payable` constructors. ([#2117](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2117)) - * `Pausable`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `Strings`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `Counters`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `SignedSafeMath`: moved to the `math` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `ERC20Snapshot`: moved to the `token/ERC20` directory. `snapshot` was changed into an `internal` function. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `Ownable`: moved to the `access` directory. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120)) - * `Ownable`: removed `isOwner`. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120)) - * `Secondary`: removed from the library, use `Ownable` instead. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120)) - * `Escrow`, `ConditionalEscrow`, `RefundEscrow`: these now use `Ownable` instead of `Secondary`, their external API changed accordingly. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120)) - * `ERC20`: removed `_burnFrom`. ([#2119](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2119)) - * `Address`: removed `toPayable`, use `payable(address)` instead. ([#2133](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2133)) - * `ERC777`: `_send`, `_mint` and `_burn` now use the caller as the operator. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134)) - * `ERC777`: removed `_callsTokensToSend` and `_callTokensReceived`. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134)) - * `EnumerableSet`: renamed `get` to `at`. ([#2151](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2151)) - * `ERC165Checker`: functions no longer have a leading underscore. ([#2150](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2150)) - * `ERC721Metadata`, `ERC721Enumerable`: these contracts were removed, and their functionality merged into `ERC721`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160)) - * `ERC721`: added a constructor for `name` and `symbol`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160)) - * `ERC20Detailed`: this contract was removed and its functionality merged into `ERC20`. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161)) - * `ERC20`: added a constructor for `name` and `symbol`. `decimals` now defaults to 18. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161)) - * `Strings`: renamed `fromUint256` to `toString` ([#2188](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2188)) - -## 2.5.1 (2020-04-24) - -### Bugfixes - * `ERC777`: fixed the `_send` and `_approve` internal functions not validating some of their arguments for non-zero addresses. ([#2212](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2212)) - -## 2.5.0 (2020-02-04) - -### New features - * `SafeCast.toUintXX`: new library for integer downcasting, which allows for safe operation on smaller types (e.g. `uint32`) when combined with `SafeMath`. ([#1926](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1926)) - * `ERC721Metadata`: added `baseURI`, which can be used for dramatic gas savings when all token URIs share a prefix (e.g. `http://api.myapp.com/tokens/`). ([#1970](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1970)) - * `EnumerableSet`: new library for storing enumerable sets of values. Only `AddressSet` is supported in this release. ([#2061](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/2061)) - * `Create2`: simple library to make usage of the `CREATE2` opcode easier. ([#1744](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1744)) - -### Improvements - * `ERC777`: `_burn` is now internal, providing more flexibility and making it easier to create tokens that deflate. ([#1908](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1908)) - * `ReentrancyGuard`: greatly improved gas efficiency by using the net gas metering mechanism introduced in the Istanbul hardfork. ([#1992](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1992), [#1996](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1996)) - * `ERC777`: improve extensibility by making `_send` and related functions `internal`. ([#2027](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2027)) - * `ERC721`: improved revert reason when transferring tokens to a non-recipient contract. ([#2018](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2018)) - -### Breaking changes - * `ERC165Checker` now requires a minimum Solidity compiler version of 0.5.10. ([#1829](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1829)) - -## 2.4.0 (2019-10-29) - -### New features - * `Address.toPayable`: added a helper to convert between address types without having to resort to low-level casting. ([#1773](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1773)) - * Facilities to make metatransaction-enabled contracts through the Gas Station Network. ([#1844](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1844)) - * `Address.sendValue`: added a replacement to Solidity's `transfer`, removing the fixed gas stipend. ([#1962](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1962)) - * Added replacement for functions that don't forward all gas (which have been deprecated): ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976)) - * `PullPayment.withdrawPaymentsWithGas(address payable payee)` - * `Escrow.withdrawWithGas(address payable payee)` - * `SafeMath`: added support for custom error messages to `sub`, `div` and `mod` functions. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828)) - -### Improvements - * `Address.isContract`: switched from `extcodesize` to `extcodehash` for less gas usage. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802)) - * `ERC20` and `ERC777` updated to throw custom errors on subtraction overflows. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828)) - -### Deprecations - * Deprecated functions that don't forward all gas: ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976)) - * `PullPayment.withdrawPayments(address payable payee)` - * `Escrow.withdraw(address payable payee)` - -### Breaking changes - * `Address` now requires a minimum Solidity compiler version of 0.5.5. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802)) - * `SignatureBouncer` has been removed from drafts, both to avoid confusions with the GSN and `GSNRecipientSignature` (previously called `GSNBouncerSignature`) and because the API was not very clear. ([#1879](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1879)) - -### How to upgrade from 2.4.0-beta - -The final 2.4.0 release includes a refactor of the GSN contracts that will be a breaking change for 2.4.0-beta users. - - * The default empty implementations of `_preRelayedCall` and `_postRelayedCall` were removed and must now be explicitly implemented always in custom recipients. If your custom recipient didn't include an implementation, you can provide an empty one. - * `GSNRecipient`, `GSNBouncerBase`, and `GSNContext` were all merged into `GSNRecipient`. - * `GSNBouncerSignature` and `GSNBouncerERC20Fee` were renamed to `GSNRecipientSignature` and `GSNRecipientERC20Fee`. - * It is no longer necessary to inherit from `GSNRecipient` when using `GSNRecipientSignature` and `GSNRecipientERC20Fee`. - -For example, a contract using `GSNBouncerSignature` would have to be changed in the following way. - -```diff --contract MyDapp is GSNRecipient, GSNBouncerSignature { -+contract MyDapp is GSNRecipientSignature { -``` - -Refer to the table below to adjust your inheritance list. - -| 2.4.0-beta | 2.4.0 | -| ---------------------------------- | ---------------------------- | -| `GSNRecipient, GSNBouncerSignature`| `GSNRecipientSignature` | -| `GSNRecipient, GSNBouncerERC20Fee` | `GSNRecipientERC20Fee` | -| `GSNBouncerBase` | `GSNRecipient` | - -## 2.3.0 (2019-05-27) - -### New features - * `ERC1820`: added support for interacting with the [ERC1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract (`IERC1820Registry`), as well as base contracts that can be registered as implementers there. ([#1677](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1677)) - * `ERC777`: support for the [ERC777 token](https://eips.ethereum.org/EIPS/eip-777), which has multiple improvements over `ERC20` (but is backwards compatible with it) such as built-in burning, a more straightforward permission system, and optional sender and receiver hooks on transfer (mandatory for contracts!). ([#1684](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1684)) - * All contracts now have revert reason strings, which give insight into error conditions, and help debug failing transactions. ([#1704](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1704)) - -### Improvements - * Reverted the Solidity version bump done in v2.2.0, setting the minimum compiler version to v0.5.0, to prevent unexpected build breakage. Users are encouraged however to stay on top of new compiler releases, which usually include bugfixes. ([#1729](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1729)) - -### Bugfixes - * `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721)) - * `ERC20._transfer`: the `from` argument was allowed to be the zero address, so it was possible to internally trigger a transfer of 0 tokens from the zero address. This address is not a valid destinatary of transfers, nor can it give or receive allowance, so this behavior was inconsistent. It now reverts. ([#1752](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1752)) - -## 2.2.0 (2019-03-14) - -### New features - * `ERC20Snapshot`: create snapshots on demand of the token balances and total supply, to later retrieve and e.g. calculate dividends at a past time. ([#1617](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1617)) - * `SafeERC20`: `ERC20` contracts with no return value (i.e. that revert on failure) are now supported. ([#1655](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1655)) - * `ERC20`: added internal `_approve(address owner, address spender, uint256 value)`, allowing derived contracts to set the allowance of arbitrary accounts. ([#1609](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1609)) - * `ERC20Metadata`: added internal `_setTokenURI(string memory tokenURI)`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618)) - * `TimedCrowdsale`: added internal `_extendTime(uint256 newClosingTime)` as well as `TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime)` event allowing to extend the crowdsale, as long as it hasn't already closed. - -### Improvements - * Upgraded the minimum compiler version to v0.5.2: this removes many Solidity warnings that were false positives. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606)) - * `ECDSA`: `recover` no longer accepts malleable signatures (those using upper-range values for `s`, or 0/1 for `v`). ([#1622](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1622)) - * ``ERC721``'s transfers are now more gas efficient due to removal of unnecessary `SafeMath` calls. ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610)) - * Fixed variable shadowing issues. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606)) - -### Bugfixes - * (minor) `SafeERC20`: `safeApprove` wasn't properly checking for a zero allowance when attempting to set a non-zero allowance. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647)) - -### Breaking changes in drafts - * `TokenMetadata` has been renamed to `ERC20Metadata`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618)) - * The library `Counter` has been renamed to `Counters` and its API has been improved. See an example in `ERC721`, lines [17](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L17) and [204](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L204). ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610)) - -## 2.1.3 (2019-02-26) - * Backported `SafeERC20.safeApprove` bugfix. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647)) - -## 2.1.2 (2019-01-17) - * Removed most of the test suite from the npm package, except `PublicRole.behavior.js`, which may be useful to users testing their own `Roles`. - -## 2.1.1 (2019-01-04) - * Version bump to avoid conflict in the npm registry. - -## 2.1.0 (2019-01-04) - -### New features - * Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin. - * `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelist admins (`WhitelistAdminRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525), [#1589](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1589)) - * `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543)) - * `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832)) - * `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524)) - * `ERC721`: added `_burn(uint256 tokenId)`, replacing the similar deprecated function (see below). ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550)) - * `ERC721`: added `_tokensOfOwner(address owner)`, allowing to internally retrieve the array of an account's owned tokens. ([#1522](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1522)) - * Crowdsales: all constructors are now `public`, meaning it is not necessary to extend these contracts in order to deploy them. The exception is `FinalizableCrowdsale`, since it is meaningless unless extended. ([#1564](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1564)) - * `SignedSafeMath`: added overflow-safe operations for signed integers (`int256`). ([#1559](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1559), [#1588](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1588)) - -### Improvements - * The compiler version required by `Array` was behind the rest of the library so it was updated to `v0.4.24`. ([#1553](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1553)) - * Now conforming to a 4-space indentation code style. ([1508](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1508)) - * `ERC20`: more gas efficient due to removed redundant `require`s. ([#1409](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1409)) - * `ERC721`: fixed a bug that prevented internal data structures from being properly cleaned, missing potential gas refunds. ([#1539](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1539) and [#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549)) - * `ERC721`: general gas savings on `transferFrom`, `_mint` and `_burn`, due to redundant `require`s and `SSTORE`s. ([#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549)) - -### Bugfixes - -### Breaking changes - -### Deprecations - * `ERC721._burn(address owner, uint256 tokenId)`: due to the `owner` parameter being unnecessary. ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550)) - * `RefundableCrowdsale`: due to trading abuse potential on crowdsales that miss their goal. ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543)) diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CODE_OF_CONDUCT.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CODE_OF_CONDUCT.md deleted file mode 100644 index 86c0474..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,73 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at maintainers@openzeppelin.org. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CONTRIBUTING.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CONTRIBUTING.md deleted file mode 100644 index 5012847..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/CONTRIBUTING.md +++ /dev/null @@ -1,64 +0,0 @@ -Contributing to OpenZeppelin Contracts -======= - -We really appreciate and value contributions to OpenZeppelin Contracts. Please take 5' to review the items listed below to make sure that your contributions are merged as soon as possible. - -## Contribution guidelines - -Smart contracts manage value and are highly vulnerable to errors and attacks. We have very strict [guidelines], please make sure to review them! - -## Creating Pull Requests (PRs) - -As a contributor, you are expected to fork this repository, work on your own fork and then submit pull requests. The pull requests will be reviewed and eventually merged into the main repo. See ["Fork-a-Repo"](https://help.github.com/articles/fork-a-repo/) for how this works. - -## A typical workflow - -1) Make sure your fork is up to date with the main repository: - -``` -cd openzeppelin-contracts -git remote add upstream https://github.com/OpenZeppelin/openzeppelin-contracts.git -git fetch upstream -git pull --rebase upstream master -``` -NOTE: The directory `openzeppelin-contracts` represents your fork's local copy. - -2) Branch out from `master` into `fix/some-bug-#123`: -(Postfixing #123 will associate your PR with the issue #123 and make everyone's life easier =D) -``` -git checkout -b fix/some-bug-#123 -``` - -3) Make your changes, add your files, commit, and push to your fork. - -``` -git add SomeFile.js -git commit "Fix some bug #123" -git push origin fix/some-bug-#123 -``` - -4) Run tests, linter, etc. This can be done by running local continuous integration and make sure it passes. - -```bash -npm test -npm run lint -``` - -5) Go to [github.com/OpenZeppelin/openzeppelin-contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) in your web browser and issue a new pull request. - -*IMPORTANT* Read the PR template very carefully and make sure to follow all the instructions. These instructions -refer to some very important conditions that your PR must meet in order to be accepted, such as making sure that all tests pass, JS linting tests pass, Solidity linting tests pass, etc. - -6) Maintainers will review your code and possibly ask for changes before your code is pulled in to the main repository. We'll check that all tests pass, review the coding style, and check for general code correctness. If everything is OK, we'll merge your pull request and your code will be part of OpenZeppelin Contracts. - -*IMPORTANT* Please pay attention to the maintainer's feedback, since it's a necessary step to keep up with the standards OpenZeppelin Contracts attains to. - -## All set! - -If you have any questions, feel free to post them to github.com/OpenZeppelin/openzeppelin-contracts/issues. - -Finally, if you're looking to collaborate and want to find easy tasks to start, look at the issues we marked as ["Good first issue"](https://github.com/OpenZeppelin/openzeppelin-contracts/labels/good%20first%20issue). - -Thanks for your time and code! - -[guidelines]: GUIDELINES.md diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/DOCUMENTATION.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/DOCUMENTATION.md deleted file mode 100644 index ca39e51..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/DOCUMENTATION.md +++ /dev/null @@ -1,16 +0,0 @@ -Documentation is hosted at https://docs.openzeppelin.com/contracts. - -All of the content for the site is in this repository. The guides are in the -[docs](/docs) directory, and the API Reference is extracted from comments in -the source code. If you want to help improve the content, this is the -repository you should be contributing to. - -[`solidity-docgen`](https://github.com/OpenZeppelin/solidity-docgen) is the -program that extracts the API Reference from source code. - -The [`docs.openzeppelin.com`](https://github.com/OpenZeppelin/docs.openzeppelin.com) -repository hosts the configuration for the entire site, which includes -documentation for all of the OpenZeppelin projects. - -To run the docs locally you should run `npm run docs:watch` on this -repository. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/GUIDELINES.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/GUIDELINES.md deleted file mode 100644 index 9706750..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/GUIDELINES.md +++ /dev/null @@ -1,105 +0,0 @@ -Design Guidelines -======= - -These are some global design goals in OpenZeppelin Contracts. - -#### D0 - Security in Depth -We strive to provide secure, tested, audited code. To achieve this, we need to match intention with function. Thus, documentation, code clarity, community review and security discussions are fundamental. - -#### D1 - Simple and Modular -Simpler code means easier audits, and better understanding of what each component does. We look for small files, small contracts, and small functions. If you can separate a contract into two independent functionalities you should probably do it. - -#### D2 - Naming Matters - -We take our time with picking names. Code is going to be written once, and read hundreds of times. Renaming for clarity is encouraged. - -#### D3 - Tests - -Write tests for all your code. We encourage Test Driven Development so we know when our code is right. Even though not all code in the repository is tested at the moment, we aim to test every line of code in the future. - -#### D4 - Check preconditions and post-conditions - -A very important way to prevent vulnerabilities is to catch a contract’s inconsistent state as early as possible. This is why we want functions to check pre- and post-conditions for executing its logic. When writing code, ask yourself what you are expecting to be true before and after the function runs, and express it in code. - -#### D5 - Code Consistency - -Consistency on the way classes are used is paramount to an easier understanding of the library. The codebase should be as unified as possible. Read existing code and get inspired before you write your own. Follow the style guidelines. Don’t hesitate to ask for help on how to best write a specific piece of code. - -#### D6 - Regular Audits -Following good programming practices is a way to reduce the risk of vulnerabilities, but professional code audits are still needed. We will perform regular code audits on major releases, and hire security professionals to provide independent review. - -# Style Guidelines - -The design guidelines have quite a high abstraction level. These style guidelines are more concrete and easier to apply, and also more opinionated. We value clean code and consistency, and those are prerequisites for us to include new code in the repository. Before proposing a change, please read these guidelines and take some time to familiarize yourself with the style of the existing codebase. - -## Solidity code - -In order to be consistent with all the other Solidity projects, we follow the -[official recommendations documented in the Solidity style guide](http://solidity.readthedocs.io/en/latest/style-guide.html). - -Any exception or additions specific to our project are documented below. - -* Try to avoid acronyms and abbreviations. - -* All state variables should be private. - -* Private state variables should have an underscore prefix. - - ``` - contract TestContract { - uint256 private _privateVar; - uint256 internal _internalVar; - } - ``` - -* Parameters must not be prefixed with an underscore. - - ``` - function test(uint256 testParameter1, uint256 testParameter2) { - ... - } - ``` - -* Internal and private functions should have an underscore prefix. - - ``` - function _testInternal() internal { - ... - } - ``` - - ``` - function _testPrivate() private { - ... - } - ``` - -* Events should be emitted immediately after the state change that they - represent, and consequently they should be named in past tense. - - ``` - function _burn(address who, uint256 value) internal { - super._burn(who, value); - emit TokensBurned(who, value); - } - ``` - - Some standards (e.g. ERC20) use present tense, and in those cases the - standard specification prevails. - -* Interface names should have a capital I prefix. - - ``` - interface IERC777 { - ``` - - -## Tests - -* Tests Must be Written Elegantly - - Tests are a good way to show how to use the library, and maintaining them is extremely necessary. Don't write long tests, write helper functions to make them be as short and concise as possible (they should take just a few lines each), and use good variable names. - -* Tests Must not be Random - - Inputs for tests should not be generated randomly. Accounts used to create test contracts are an exception, those can be random. Also, the type and structure of outputs should be checked. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/LICENSE b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/LICENSE deleted file mode 100644 index 4f51be0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016-2022 zOS Global Limited and contributors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/README.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/README.md deleted file mode 100644 index 65299bc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# OpenZeppelin OpenZeppelin Contracts Upgradeable - -[![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.openzeppelin.com/contracts) -[![NPM Package](https://img.shields.io/npm/v/@openzeppelin/contracts.svg)](https://www.npmjs.org/package/@openzeppelin/contracts) -[![Coverage Status](https://codecov.io/gh/OpenZeppelin/openzeppelin-contracts/graph/badge.svg)](https://codecov.io/gh/OpenZeppelin/openzeppelin-contracts) -[![gitpoap badge](https://public-api.gitpoap.io/v1/repo/OpenZeppelin/openzeppelin-contracts/badge)](https://www.gitpoap.io/gh/OpenZeppelin/openzeppelin-contracts) - -This repository hosts the Upgradeable variant of [OpenZeppelin Contracts], meant for use in upgradeable contracts. This variant is available as separate package called `@openzeppelin/contracts-upgradeable`. - -[OpenZeppelin Contracts]: https://github.com/OpenZeppelin/openzeppelin-contracts - -It follows all of the rules for [Writing Upgradeable Contracts]: constructors are replaced by initializer functions, state variables are initialized in initializer functions, and we additionally check for storage incompatibilities across minor versions. - -[Writing Upgradeable Contracts]: https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable - -> :warning: **Warning** -> -> There will be storage incompatibilities across major versions of this package, which makes it unsafe to upgrade a deployed contract from one major version to another, for example from 3.4.0 to 4.0.0. -> -> Similarly, it is not safe to upgrade from `@openzeppelin/contracts-ethereum-package` (a similar previous package) to `@openzeppelin/contracts-upgradeable`. -> -> **It is strongly encouraged to use these contracts together with a tool that can automatically guarantee the safety of an upgradeable contract, such as the [OpenZeppelin Upgrades Plugins](https://github.com/OpenZeppelin/openzeppelin-upgrades).** - -:building_construction: **Want to scale your decentralized application?** Check out [OpenZeppelin Defender](https://openzeppelin.com/defender) — a secure platform for automating and monitoring your operations. - -## Overview - -### Installation - -```console -$ npm install @openzeppelin/contracts-upgradeable -``` - -OpenZeppelin Contracts features a [stable API](https://docs.openzeppelin.com/contracts/releases-stability#api-stability), which means that your contracts won't break unexpectedly when upgrading to a newer minor version. - -An alternative to npm is to use the GitHub repository (`openzeppelin/openzeppelin-contracts`) to retrieve the contracts. When doing this, make sure to specify the tag for a release such as `v4.5.0`, instead of using the `master` branch. - -### Usage - -The package replicates the structure of the main OpenZeppelin Contracts package, but every file and contract has the suffix `Upgradeable`. - -```diff --import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -+import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; - --contract MyCollectible is ERC721 { -+contract MyCollectible is ERC721Upgradeable { -``` - -Constructors are replaced by internal initializer functions following the naming convention `__{ContractName}_init`. Since these are internal, you must always define your own public initializer function and call the parent initializer of the contract you extend. - -```diff -- constructor() ERC721("MyCollectible", "MCO") { -+ function initialize() initializer public { -+ __ERC721_init("MyCollectible", "MCO"); - } -``` - -> **Caution** -> -> Use with multiple inheritance requires special care. Initializer functions are not linearized by the compiler like constructors. Because of this, each `__{ContractName}_init` function embeds the linearized calls to all parent initializers. As a consequence, calling two of these `init` functions can potentially initialize the same contract twice. -> -> The function `__{ContractName}_init_unchained` found in every contract is the initializer function minus the calls to parent initializers, and can be used to avoid the double initialization problem, but doing this manually is not recommended. We hope to be able to implement safety checks for this in future versions of the Upgrades Plugins. - -_If you're new to smart contract development, head to [Developing Smart Contracts](https://docs.openzeppelin.com/learn/developing-smart-contracts) to learn about creating a new project and compiling your contracts._ - -To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources nor modify it yourself. The library is designed so that only the contracts and functions you use are deployed, so you don't need to worry about it needlessly increasing gas costs. - -## Learn More - -The guides in the [documentation site](https://docs.openzeppelin.com/contracts) will teach about different concepts, and how to use the related contracts that OpenZeppelin Contracts provides: - -* [Access Control](https://docs.openzeppelin.com/contracts/access-control): decide who can perform each of the actions on your system. -* [Tokens](https://docs.openzeppelin.com/contracts/tokens): create tradeable assets or collectives, and distribute them via [Crowdsales](https://docs.openzeppelin.com/contracts/crowdsales). -* [Gas Station Network](https://docs.openzeppelin.com/contracts/gsn): let your users interact with your contracts without having to pay for gas themselves. -* [Utilities](https://docs.openzeppelin.com/contracts/utilities): generic useful tools including non-overflowing math, signature verification, and trustless paying systems. - -The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts's development in the [community forum](https://forum.openzeppelin.com). - -Finally, you may want to take a look at the [guides on our blog](https://blog.openzeppelin.com/guides), which cover several common use cases and good practices. The following articles provide great background reading, though please note that some of the referenced tools have changed, as the tooling in the ecosystem continues to rapidly evolve. - -* [The Hitchhiker’s Guide to Smart Contracts in Ethereum](https://blog.openzeppelin.com/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05) will help you get an overview of the various tools available for smart contract development, and help you set up your environment. -* [A Gentle Introduction to Ethereum Programming, Part 1](https://blog.openzeppelin.com/a-gentle-introduction-to-ethereum-programming-part-1-783cc7796094) provides very useful information on an introductory level, including many basic concepts from the Ethereum platform. -* For a more in-depth dive, you may read the guide [Designing the Architecture for Your Ethereum Application](https://blog.openzeppelin.com/designing-the-architecture-for-your-ethereum-application-9cec086f8317), which discusses how to better structure your application and its relationship to the real world. - -## Security - -This project is maintained by [OpenZeppelin](https://openzeppelin.com), and developed following our high standards for code quality and security. OpenZeppelin Contracts is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience. - -The core development principles and strategies that OpenZeppelin Contracts is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits. - -The latest audit was done on October 2018 on version 2.0.0. - -We have a [**bug bounty program** on Immunefi](https://www.immunefi.com/bounty/openzeppelin). Please report any security issues you find through the Immunefi dashboard, or reach out to security@openzeppelin.com. - -Critical bug fixes will be backported to past major releases. - -## Contribute - -OpenZeppelin Contracts exists thanks to its contributors. There are many ways you can participate and help build high quality software. Check out the [contribution guide](CONTRIBUTING.md)! - -## License - -OpenZeppelin Contracts is released under the [MIT License](LICENSE). diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/RELEASING.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/RELEASING.md deleted file mode 100644 index f356ab2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/RELEASING.md +++ /dev/null @@ -1,36 +0,0 @@ -# Releasing - -> Visit the documentation for [details about release schedule]. - -Start on an up-to-date `master` branch. - -Create the release branch with `npm run release start minor`. - -Publish a release candidate with `npm run release rc`. - -Publish the final release with `npm run release final`. - -Follow the general [OpenZeppelin Contracts release checklist]. - -[details about release schedule]: https://docs.openzeppelin.com/contracts/releases-stability -[OpenZeppelin Contracts release checklist]: https://github.com/OpenZeppelin/code-style/blob/master/RELEASE_CHECKLIST.md - - -## Merging the release branch - -After the final release, the release branch should be merged back into `master`. This merge must not be squashed because it would lose the tagged release commit. Since the GitHub repo is set up to only allow squashed merges, the merge should be done locally and pushed. - -Make sure to have the latest changes from `upstream` in your local release branch. - -``` -git checkout release-vX.Y.Z -git pull upstream -``` - -``` -git checkout master -git merge --no-ff release-vX.Y.Z -git push upstream master -``` - -The release branch can then be deleted on GitHub. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/SECURITY.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/SECURITY.md deleted file mode 100644 index 98701be..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/SECURITY.md +++ /dev/null @@ -1,20 +0,0 @@ -# Security Policy - -## Bug Bounty - -We have a [**bug bounty program** on Immunefi](https://www.immunefi.com/bounty/openzeppelin). Please report any security issues you find through the Immunefi dashboard, or reach out to security@openzeppelin.com. - -Critical bug fixes will be backported to past major releases. - -## Supported Versions - -The recommendation is to use the latest version available. - -| Version | Supported | -| ------- | ------------------------------------ | -| 4.x | :white_check_mark::white_check_mark: | -| 3.4 | :white_check_mark: | -| 2.5 | :white_check_mark: | -| < 2.0 | :x: | - -Note that the Solidity language itself only guarantees security updates for the latest release. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/UPGRADEABLE.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/UPGRADEABLE.md deleted file mode 100644 index ea67e2f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/UPGRADEABLE.md +++ /dev/null @@ -1,47 +0,0 @@ -# Technical notes about the Upgradeable repository - -## [Branches](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/branches) - -### `patches` - -Built on top of the `master` branch of the vanilla Contracts repo, contains the changes necessary to build this package: it adds the scripts to transpile and GitHub Actions for it to work automatically, changes the package name, etc. - -It can also include small changes to the Solidity code, such as reordering of state variables, in order to ensure storage compatibility. - -It's an important goal that this branch should be easy to merge with the vanilla Contracts repo, avoiding merge conflicts as much as possible. This is necessary to reduce manual intervention and ensure automation runs smoothly. - -This branch will not necessarily be up to date with the vanilla `master` branch, only up to the point necessary to guarantee successful merging with any new updates. In some cases it will be necessary to apply a manual merge with new changes, it is this branch that should be updated for the changes to propagate to all other branches. - -### `patched/master`, `patched/release-vX.Y` - -These branches are the merge between `patches` and the corresponding branch from vanilla Contracts. These branches should generally not be updated manually. - -### `master`, `release-vX.Y` - -Contains the transpiled code corresponding to the branch from vanilla Contracts of the same name. These are generated automatically based on their `patched/*` branch. These branches should never be manually updated, because they will be overwritten automatically with the transpiled version of `patched/*`. Instead, changes should be made in `patches`. - -## [Actions Workflows](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/actions) - -### [Merge upstream](/.github/workflows/merge-upstream.yml) - -All this does is fetch the latest changes from a corresponding branch in the vanilla Contracts repo, tries to merge them with `patches`, and then pushes the updated branch to `patched/*`. If the merge has conflicts, the worfklow will fail. We should be notified of this so that we can updated the `patches` branch resolving conflicts and trigger the merge again. This should not happen often. - -### [Transpile](/.github/workflows/transpile.yml) - -Runs every time a `patched/*` branch is pushed to (for example as part of the Merge upstream workflow), transpiles the contents of that branch, and pushes the results as a new commit on the transpiled branch. - -### [Test](/.github/workflows/test.yml) - -Runs normal Contracts tests on the `master` and `release-v*` branches. - -## Scripts - -### `transpile-onto.sh` - -``` -bash scripts/upgradeable/transpile-onto.sh [base] -``` - -Transpiles the contents of the current git branch and commits the result as a new commit on branch ``. If branch `` doesn't exist, it will copy the commit history of `[base]` (this is used in GitHub Actions, but is usually not necessary locally). - -This script can be used manually to build transpiled versions of specific commits, or branches other than the `master` Contracts branch. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/audit/2017-03.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/audit/2017-03.md deleted file mode 100644 index 5ca874b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/audit/2017-03.md +++ /dev/null @@ -1,292 +0,0 @@ -# OpenZeppelin Audit - -NOTE ON 2021-07-19: This report makes reference to Zeppelin, OpenZeppelin, OpenZeppelin [C]ontracts, the OpenZeppelin team, and OpenZeppelin library. Many of these things have since been renamed and know that this audit applies to what is currently called the OpenZeppelin Contracts which are maintained by the OpenZeppelin Conracts Community. - -March, 2017 -Authored by Dennis Peterson and Peter Vessenes - -# Introduction - -Zeppelin requested that New Alchemy perform an audit of the contracts in their OpenZeppelin library. The OpenZeppelin contracts are a set of contracts intended to be a safe building block for a variety of uses by parties that may not be as sophisticated as the OpenZeppelin team. It is a design goal that the contracts be deployable safely and "as-is". - -The contracts are hosted at: - -https://github.com/OpenZeppelin/zeppelin-solidity - -All the contracts in the "contracts" folder are in scope. - -The git commit hash we evaluated is: -9c5975a706b076b7000e8179f8101e0c61024c87 - -# Disclaimer - -The audit makes no statements or warrantees about utility of the code, safety of the code, suitability of the business model, regulatory regime for the business model, or any other statements about fitness of the contracts to purpose, or their bugfree status. The audit documentation is for discussion purposes only. - -# Executive Summary - -Overall the OpenZeppelin codebase is of reasonably high quality -- it is clean, modular and follows best practices throughout. - -It is still in flux as a codebase, and needs better documentation per file as to expected behavior and future plans. It probably needs more comprehensive and aggressive tests written by people less nice than the current OpenZeppelin team. - -We identified two critical errors and one moderate issue, and would not recommend this commit hash for public use until these bugs are remedied. - -The repository includes a set of Truffle unit tests, a requirement and best practice for smart contracts like these; we recommend these be bulked up. - -# Discussion - -## Big Picture: Is This A Worthwhile Project? - -As soon as a developer touches OpenZeppelin contracts, they will modify something, leaving them in an un-audited state. We do not recommend developers deploy any unaudited code to the Blockchain if it will handle money, information or other things of value. - -> "In accordance with Unix philosophy, Perl gives you enough rope to hang yourself" -> --Larry Wall - -We think this is an incredibly worthwhile project -- aided by the high code quality. Creating a framework that can be easily extended helps increase the average code quality on the Blockchain by charting a course for developers and encouraging containment of modifications to certain sections. - -> "Rust: The language that makes you take the safety off before shooting yourself in the foot" -> -- (@mbrubeck) - -We think much more could be done here, and recommend the OpenZeppelin team keep at this and keep focusing on the design goal of removing rope and adding safety. - -## Solidity Version Updates Recommended - -Most of the code uses Solidity 0.4.11, but some files under `Ownership` are marked 0.4.0. These should be updated. - -Solidity 0.4.10 will add several features which could be useful in these contracts: - -- `assert(condition)`, which throws if the condition is false - -- `revert()`, which rolls back without consuming all remaining gas. - -- `address.transfer(value)`, which is like `send` but automatically propagates exceptions, and supports `.gas()`. See https://github.com/ethereum/solidity/issues/610 for more on this. - -## Error Handling: Throw vs Return False -Solidity standards allow two ways to handle an error -- either calling `throw` or returning `false`. Both have benefits. In particular, a `throw` guarantees a complete wipe of the call stack (up to the preceding external call), whereas `false` allows a function to continue. - -In general we prefer `throw` in our code audits, because it is simpler -- it's less for an engineer to keep track of. Returning `false` and using logic to check results can quickly become a poorly-tracked state machine, and this sort of complexity can cause errors. - -In the OpenZeppelin contracts, both styles are used in different parts of the codebase. `SimpleToken` transfers throw upon failure, while the full ERC20 token returns `false`. Some modifiers `throw`, others just wrap the function body in a conditional, effectively allowing the function to return false if the condition is not met. - -We don't love this, and would usually recommend you stick with one style or the other throughout the codebase. - -In at least one case, these different techniques are combined cleverly (see the Multisig comments, line 65). As a set of contracts intended for general use, we recommend you either strive for more consistency or document explicit design criteria that govern which techniques are used where. - -Note that it may be impossible to use either one in all situations. For example, SafeMath functions pretty much have to throw upon failure, but ERC20 specifies returning booleans. Therefore we make no particular recommendations, but simply point out inconsistencies to consider. - -# Critical Issues - -## Stuck Ether in Crowdsale contract -CrowdsaleToken.sol has no provision for withdrawing the raised ether. We *strongly* recommend a standard `withdraw` function be added. There is no scenario in which someone should deploy this contract as is, whether for testing or live. - -## Recursive Call in MultisigWallet -Line 45 of `MultisigWallet.sol` checks if the amount being sent by `execute` is under a daily limit. - -This function can only be called by the "Owner". As a first angle of attack, it's worth asking what will happen if the multisig wallet owners reset the daily limit by approving a call to `resetSpentToday`. - -If a chain of calls can be constructed in which the owner confirms the `resetSpentToday` function and then withdraws through `execute` in a recursive call, the contract can be drained. In fact, this could be done without a recursive call, just through repeated `execute` calls alternating with the `confirm` calls. - -We are still working through the confirmation protocol in `Shareable.sol`, but we are not convinced that this is impossible, in fact it looks possible. The flexibility any shared owner has in being able to revoke confirmation later is another worrisome angle of approach even if some simple patches are included. - -This bug has a number of causes that need to be addressed: - -1. `resetSpentToday` and `confirm` together do not limit the days on which the function can be called or (it appears) the number of times it can be called. -1. Once a call has been confirmed and `execute`d it appears that it can be re-executed. This is not good. -3. `confirmandCheck` doesn't seem to have logic about whether or not the function in question has been called. -4. Even if it did, `revoke` would need updates and logic to deal with revocation requests after a function call had been completed. - -We do not recommend using the MultisigWallet until these issues are fixed. - -# Moderate to Minor Issues - -## PullPayment -PullPayment.sol needs some work. It has no explicit provision for cancelling a payment. This would be desirable in a number of scenarios; consider a payee losing their wallet, or giving a griefing address, or just an address that requires more than the default gas offered by `send`. - -`asyncSend` has no overflow checking. This is a bad plan. We recommend overflow and underflow checking at the layer closest to the data manipulation. - -`asyncSend` allows more balance to be queued up for sending than the contract holds. This is probably a bad idea, or at the very least should be called something different. If the intent is to allow this, it should have provisions for dealing with race conditions between competing `withdrawPayments` calls. - -It would be nice to see how many payments are pending. This would imply a bit of a rewrite; we recommend this contract get some design time, and that developers don't rely on it in its current state. - -## Shareable Contract - -We do not believe the `Shareable.sol` contract is ready for primetime. It is missing functions, and as written may be vulnerable to a reordering attack -- an attack in which a miner or other party "racing" with a smart contract participant inserts their own information into a list or mapping. - -The confirmation and revocation code needs to be looked over with a very careful eye imagining extraordinarily bad behavior by shared owners before this contract can be called safe. - -No sanity checks on the initial constructor's `required` argument are worrisome as well. - -# Line by Line Comments - -## Lifecycle - -### Killable - -Very simple, allows owner to call selfdestruct, sending funds to owner. No issues. However, note that `selfdestruct` should typically not be used; it is common that a developer may want to access data in a former contract, and they may not understand that `selfdestruct` limits access to the contract. We recommend better documentation about this dynamic, and an alternate function name for `kill` like `completelyDestroy` while `kill` would perhaps merely send funds to the owner. - -Also note that a killable function allows the owner to take funds regardless of other logic. This may be desirable or undesirable depending on the circumstances. Perhaps `Killable` should have a different name as well. - -### Migrations - -I presume that the goal of this contract is to allow and annotate a migration to a new smart contract address. We are not clear here how this would be accomplished by the code; we'd like to review with the OpenZeppelin team. - -### Pausable - -We like these pauses! Note that these allow significant griefing potential by owners, and that this might not be obvious to participants in smart contracts using the OpenZeppelin framework. We would recommend that additional sample logic be added to for instance the TokenContract showing safer use of the pause and resume functions. In particular, we would recommend a timelock after which anyone could unpause the contract. - -The modifiers use the pattern `if(bool){_;}`. This is fine for functions that return false upon failure, but could be problematic for functions expected to throw upon failure. See our comments above on standardizing on `throw` or `return(false)`. - -## Ownership - -### Ownable - -Line 19: Modifier throws if doesn't meet condition, in contrast to some other inheritable modifiers (e.g. in Pausable) that use `if(bool){_;}`. - -### Claimable - -Inherits from Ownable but the existing owner sets a pendingOwner who has to claim ownership. - -Line 17: Another modifier that throws. - -### DelayedClaimable - -Is there any reason to descend from Ownable directly, instead of just Claimable, which descends from Ownable? If not, descending from both just adds confusion. - -### Contactable - -Allows owner to set a public string of contract information. No issues. - -### Shareable - -This needs some work. Doesn't check if `_required <= len(_owners)` for instance, that would be a bummer. What if _required were like `MAX - 1`? - -I have a general concern about the difference between `owners`, `_owners`, and `owner` in `Ownable.sol`. I recommend "Owners" be renamed. In general we do not recomment single character differences in variable names, although a preceding underscore is not uncommon in Solidity code. - -Line 34: "this contract only has six types of events"...actually only two. - -Line 61: Why is `ownerIndex` keyed by addresses hashed to `uint`s? Why not use the addresses directly, so `ownerIndex` is less obscure, and so there's stronger typing? - -Line 62: Do not love `++i) ... owners[2+ i]`. Makes me do math, which is not what I want to do. I want to not have to do math. - -There should probably be a function for adding a new operation, so the developer doesn't have to work directly with the internal data. (This would make the multisig contract even shorter.) - -There's a `revoke` function but not a `propose` function that we can see. - -Beware reordering. If `propose` allows the user to choose a bytes string for their proposal, bad things(TM) will happen as currently written. - - -### Multisig - -Just an interface. Note it allows changing an owner address, but not changing the number of owners. This is somewhat limiting but also simplifies implementation. - -## Payment - -### PullPayment - -Safe from reentrance attack since ether send is at the end, plus it uses `.send()` rather than `.call.value()`. - -There's an argument to be made that `.call.value()` is a better option *if* you're sure that it will be done after all state updates, since `.send` will fail if the recipient has an expensive fallback function. However, in the context of a function meant to be embedded in other contracts, it's probably better to use `.send`. One possible compromise is to add a function which allows only the owner to send ether via `.call.value`. - -If you don't use `call.value` you should implement a `cancel` function in case some value is pending here. - -Line 14: -Doesn't use safeAdd. Although it appears that payout amounts can only be increased, in fact the payer could lower the payout as much as desired via overflow. Also, the payer could add a large non-overflowing amount, causing the payment to exceed the contract balance and therefore fail when withdraw is attempted. - -Recommendation: track the sum of non-withdrawn asyncSends, and don't allow a new one which exceeds the leftover balance. If it's ever desirable to make payments revocable, it should be done explicitly. - -## Tokens - -### ERC20 - -Standard ERC20 interface only. - -There's a security hole in the standard, reported at Edcon: `approve` does not protect against race conditions and simply replaces the current value. An approved spender could wait for the owner to call `approve` again, then attempt to spend the old limit before the new limit is applied. If successful, this attacker could successfully spend the sum of both limits. - -This could be fixed by either (1) including the old limit as a parameter, so the update will fail if some gets spent, or (2) using the value parameter as a delta instead of replacement value. - -This is not fixable while adhering to the current full ERC20 standard, though it would be possible to add a "secureApprove" function. The impact isn't extreme since at least you can only be attacked by addresses you approved. Also, users could mitigate this by always setting spending limits to zero and checking for spends, before setting the new limit. - -Edcon slides: -https://drive.google.com/file/d/0ByMtMw2hul0EN3NCaVFHSFdxRzA/view - -### ERC20Basic - -Simpler interface skipping the Approve function. Note this departs from ERC20 in another way: transfer throws instead of returning false. - -### BasicToken - -Uses `SafeSub` and `SafeMath`, so transfer `throw`s instead of returning false. This complies with ERC20Basic but not the actual ERC20 standard. - -### StandardToken - -Implementation of full ERC20 token. - -Transfer() and transferFrom() use SafeMath functions, which will cause them to throw instead of returning false. Not a security issue but departs from standard. - -### SimpleToken - -Sample instantiation of StandardToken. Note that in this sample, decimals is 18 and supply only 10,000, so the supply is a small fraction of a single nominal token. - -### CrowdsaleToken - -StandardToken which mints tokens at a fixed price when sent ether. - -There's no provision for owner withdrawing the ether. As a sample for crowdsales it should be Ownable and allow the owner to withdraw ether, rather than stranding the ether in the contract. - -Note: an alternative pattern is a mint() function which is only callable from a separate crowdsale contract, so any sort of rules can be added without modifying the token itself. - -### VestedToken - -Lines 23, 27: -Functions `transfer()` and `transferFrom()` have a modifier canTransfer which throws if not enough tokens are available. However, transfer() returns a boolean success. Inconsistent treatment of failure conditions may cause problems for other contracts using the token. (Note that transferableTokens() relies on safeSub(), so will also throw if there's insufficient balance.) - -Line 64: -Delete not actually necessary since the value is overwritten in the next line anyway. - -## Root level - -### Bounty - -Avoids potential race condition by having each researcher deploy a separate contract for attack; if a research manages to break his associated contract, other researchers can't immediately claim the reward, they have to reproduce the attack in their own contracts. - -A developer could subvert this intent by implementing `deployContract()` to always return the same address. However, this would break the `researchers` mapping, updating the researcher address associated with the contract. This could be prevented by blocking rewrites in `researchers`. - -### DayLimit - -The modifier `limitedDaily` calls `underLimit`, which both checks that the spend is below the daily limit, and adds the input value to the daily spend. This is fine if all functions throw upon failure. However, not all OpenZeppelin functions do this; there are functions that returns false, and modifiers that wrap the function body in `if (bool) {_;}`. In these cases, `_value` will be added to `spentToday`, but ether may not actually be sent because other preconditions were not met. (However in the OpenZeppelin multisig this is not a problem.) - -Lines 4, 11: -Comment claims that `DayLimit` is multiowned, and Shareable is imported, but DayLimit does not actually inherit from Shareable. The intent may be for child contracts to inherit from Shareable (as Multisig does); in this case the import should be removed and the comment altered. - -Line 46: -Manual overflow check instead of using safeAdd. Since this is called from a function that throws upon failure anyway, there's no real downside to using safeAdd. - -### LimitBalance - -No issues. - -### MultisigWallet - -Lines 28, 76, 80: -`kill`, `setDailyLimit`, and `resetSpentToday` only happen with multisig approval, and hashes for these actions are logged by Shareable. However, they should probably post their own events for easy reading. - -Line 45: -This call to underLimit will reduce the daily limit, and then either throw or return 0. So in this case there's no danger that the limit will be reduced without the operation going through. - -Line 65: -Shareable's onlyManyOwners will take the user's confirmation, and execute the function body if and only if enough users have confirmed. Whole thing throws if the send fails, which will roll back the confirmation. Confirm returns false if not enough have confirmed yet, true if the whole thing succeeds, and throws only in the exceptional circumstance that the designated transaction unexpectedly fails. Elegant design. - -Line 68: -Throw here is good but note this function can fail either by returning false or by throwing. - -Line 92: -A bit odd to split `clearPending()` between this contract and Shareable. However this does allow contracts inheriting from Shareable to use custom structs for pending transactions. - - -### SafeMath - -Another interesting comment from the same Edcon presentation was that the overflow behavior of Solidity is undocumented, so in theory, source code that relies on it could break with a future revision. - -However, compiled code should be fine, and in the unlikely event that the compiler is revised in this way, there should be plenty of warning. (But this is an argument for keeping overflow checks isolated in SafeMath.) - -Aside from that small caveat, these are fine. - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/audit/2018-10.pdf b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/audit/2018-10.pdf deleted file mode 100644 index d5bf12741c8a6d44ed597de7204fde72d91dec35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1000527 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%0AXGSxD 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%0Ds@WxhHVsCq?&%C$272odl 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

    {23QAMhgmDFwY9!) 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

    %X-{jq)zF)pGEGKPHkt7x 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

    @!c9KnY4NvNgEvnPA? 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

    QsKH{N_IQtXo9hrt1|lnPuADU$b1Mf#WXL540@w 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%0DQ_tNgAAku*dN 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

    fwy2<7q zDUf=Nh}CM0fE@!qOXtsLFjQ>$FZ2yw)|OeY5B{dg9ZVSOX9Cpw#z`7!j7aa6(6{a$4FhsBu72G5Gt3ar2e+Aijb6l&EFnK zgbkye>R;w7rO=AxuAv~#+b(Q)j+Y#7Nn#15O)!WjhFJ*}vDBRwPW>2EYH(nfeo!Zs zP>e)wKb@f2;oB4uV%v|fqUSmpTAMbtW&7L?cX91cn|dOtrX8qUXNP$Ynz=hWo;#yF zeTFVdpOqs}-XfM|7RKBO^#dvUB!<69j0Pv*DFGL^*?2Xg4WcIZ81Ze(rMDXv=B5gr z<9w|<*ww7#S7KM{6vkIj!s}wu^RAU+} z_+K98!d36qresKVe%TT&ENQq3Sg+fC`0q?GZUKkR?AYGfa}DTY*=Qf_l#vck<3kiw z)H!4f1H7PuBOsy~O!MjSBzK9$Qk%vRJ3`)gI9gz7WnCOjxn86hH5G zgD2-V=1O-9F}V6$>;W)YiiN_{+hFUvN-Wr1Z;}-~3CYu48b8G4sV%T5_<6e;?41i< zjxjYG61gXMT!-zH)h1a@ zzc@*6>iAi^b8nC5UC}~_MsyT}^^(~wsL=@x7|M-zzxr9lm%+QP@EdH+{C$fX`+;Q( z6QV%O;N3e8@LmWGzhK^LA0Q5QC4-Bno^1V-xPGwh2!?h-RL=3UU`*a$N(Myz9YXbe zGV-Jy;QRF*wM$$KEGL|k|4~5yvx}Jma+ZO|rC!)gkGV|_;9cFr$DKk)>BWN~(;Eu9o zomyAR7ZTY?Mw9i78#mq71J%i>vEvcO@L4c;SS7$}G0MR95G$TbzhB=wK7TeZ^v?q7 ziLHMk4zvAQPw@rFW*L67mPFv?af}v=)9%L|y^|wk-!-aR|Llg~K39@`R9^xSxPBM= z%b2T` zPo$0~?@P|iQG+?;Gs3Zeo zXbX#;hntIv%fKX0ES1%mVtNWu);V)bS{0CYn#r{ph#h?w# z6aK&5lWm|BG){A;kL3ay6mvhXy9Cy3k{vbYCUbt;C6TYg5`sON*TKz6$DWUL*^*E{x;lj@bJ z`4&lWklridPA3CY5l%c%$^n1Pm&%PAQplvCa{3Hib?3gz27P1s91=R+^1+6H6s zX}R-IsHye2ggRzPgJVhe%bq-+OzFo;e9%7PGPj1Aleg=h9i%k;OnTRh-aB0J;p<7I zw8+$Jd~qD@_#kGO7hC21FO8qv#;DYxlStWbP@_fqy&$j#>utVouc?l14i?Wu0^zp8s}gvot|7hnFNC zNiTi`YloFI@S9Z0z=e9|Zi9c5kfAEH;n^;ShS75#=|_e?dpF__yh8mH z@lHAhs3jbuCqTWS2G)ou-vDLCDK&o^B(jY&xUPFgnaQZU-r>t&d!_}x_}*z9Py%dJ zo~*7^s3fb$Hh);$S4u^*)^*L&3AJx#kqJWrpA%fu8vwaoV>(@ZVbbi9->7^y3+t`j zOdyK|8R>PHS>NTy{V24#@~TB{Ai*l~%)=y%p0F5LwJi!m{hd_H>zP%|P&@OPnn{(p z)I&0*F`{<3ibJlFcSRyTh*HXKypRwbS9wdOry13AL+CQ-QzNa5dJR*(3EzXU-09Q2 z$F+?M%r#y(sagSlaDIZ#Eb7m`f~_?_>%~Z)9B&#@`Qs7Z=aw|SF4b$MV9zTjxm^UQ&3@=GE<<&7(JLN9}mZ)$p_t0B4G1_N`E7X0ysF_!kS!O6?rx z)DQcdDb-YS_Km5JRCsx{yrWTQgN%2B{gCK!8Y`28OY9u+Ko1@@IW}nN?#MruYBeF; vmz$7%8{kQOm<9x(L!%4$|Fbnt&IXRo?v5s=upAsL9Bk~cBqSnoqOku9foUHh diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/Makefile b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/Makefile deleted file mode 100644 index bbbddbc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -default: help - -PATCH = applyHarness.patch -CONTRACTS_DIR = ../contracts -MUNGED_DIR = munged - -help: - @echo "usage:" - @echo " make clean: remove all generated files (those ignored by git)" - @echo " make $(MUNGED_DIR): create $(MUNGED_DIR) directory by applying the patch file to $(CONTRACTS_DIR)" - @echo " make record: record a new patch file capturing the differences between $(CONTRACTS_DIR) and $(MUNGED_DIR)" - -munged: $(wildcard $(CONTRACTS_DIR)/*.sol) $(PATCH) - rm -rf $@ - cp -r $(CONTRACTS_DIR) $@ - patch -p0 -d $@ < $(PATCH) - -record: - diff -ruN $(CONTRACTS_DIR) $(MUNGED_DIR) | sed 's+../contracts/++g' | sed 's+munged/++g' > $(PATCH) - -clean: - git clean -fdX - touch $(PATCH) - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/README.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/README.md deleted file mode 100644 index 55f84d4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Running the certora verification tool - -These instructions detail the process for running CVT on the OpenZeppelin (Wizard/Governor) contracts. - -Documentation for CVT and the specification language are available -[here](https://certora.atlassian.net/wiki/spaces/CPD/overview) - -## Running the verification - -The scripts in the `certora/scripts` directory are used to submit verification -jobs to the Certora verification service. After the job is complete, the results will be available on -[the Certora portal](https://vaas-stg.certora.com/). - -These scripts should be run from the root directory; for example by running - -``` -sh certora/scripts/verifyAll.sh -``` - -The most important of these is `verifyAll.sh`, which checks -all of the harnessed contracts (`certora/harness/Wizard*.sol`) against all of -the specifications (`certora/spec/*.spec`). - -The other scripts run a subset of the specifications or the contracts. You can -verify different contracts or specifications by changing the `--verify` option, -and you can run a single rule or method with the `--rule` or `--method` option. - -For example, to verify the `WizardFirstPriority` contract against the -`GovernorCountingSimple` specification, you could change the `--verify` line of -the `WizardControlFirstPriortity.sh` script to: - -``` ---verify WizardFirstPriority:certora/specs/GovernorCountingSimple.spec \ -``` - -## Adapting to changes in the contracts - -Some of our rules require the code to be simplified in various ways. Our -primary tool for performing these simplifications is to run verification on a -contract that extends the original contracts and overrides some of the methods. -These "harness" contracts can be found in the `certora/harness` directory. - -This pattern does require some modifications to the original code: some methods -need to be made virtual or public, for example. These changes are handled by -applying a patch to the code before verification. - -When one of the `verify` scripts is executed, it first applies the patch file -`certora/applyHarness.patch` to the `contracts` directory, placing the output -in the `certora/munged` directory. We then verify the contracts in the -`certora/munged` directory. - -If the original contracts change, it is possible to create a conflict with the -patch. In this case, the verify scripts will report an error message and output -rejected changes in the `munged` directory. After merging the changes, run -`make record` in the `certora` directory; this will regenerate the patch file, -which can then be checked into git. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/applyHarness.patch b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/applyHarness.patch deleted file mode 100644 index 0fbe9ac..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/applyHarness.patch +++ /dev/null @@ -1,101 +0,0 @@ -diff -ruN .gitignore .gitignore ---- .gitignore 1969-12-31 19:00:00.000000000 -0500 -+++ .gitignore 2021-12-09 14:46:33.923637220 -0500 -@@ -0,0 +1,2 @@ -+* -+!.gitignore -diff -ruN governance/compatibility/GovernorCompatibilityBravo.sol governance/compatibility/GovernorCompatibilityBravo.sol ---- governance/compatibility/GovernorCompatibilityBravo.sol 2021-12-03 15:24:56.523654357 -0500 -+++ governance/compatibility/GovernorCompatibilityBravo.sol 2021-12-09 14:46:33.923637220 -0500 -@@ -245,7 +245,7 @@ - /** - * @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum. - */ -- function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { -+ function _quorumReached(uint256 proposalId) public view virtual override returns (bool) { // HARNESS: changed to public from internal - ProposalDetails storage details = _proposalDetails[proposalId]; - return quorum(proposalSnapshot(proposalId)) <= details.forVotes; - } -@@ -253,7 +253,7 @@ - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be scritly over the againstVotes. - */ -- function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { -+ function _voteSucceeded(uint256 proposalId) public view virtual override returns (bool) { // HARNESS: changed to public from internal - ProposalDetails storage details = _proposalDetails[proposalId]; - return details.forVotes > details.againstVotes; - } -diff -ruN governance/extensions/GovernorCountingSimple.sol governance/extensions/GovernorCountingSimple.sol ---- governance/extensions/GovernorCountingSimple.sol 2021-12-03 15:24:56.523654357 -0500 -+++ governance/extensions/GovernorCountingSimple.sol 2021-12-09 14:46:33.923637220 -0500 -@@ -64,7 +64,7 @@ - /** - * @dev See {Governor-_quorumReached}. - */ -- function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { -+ function _quorumReached(uint256 proposalId) public view virtual override returns (bool) { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - return quorum(proposalSnapshot(proposalId)) <= proposalvote.forVotes + proposalvote.abstainVotes; -@@ -73,7 +73,7 @@ - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. - */ -- function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { -+ function _voteSucceeded(uint256 proposalId) public view virtual override returns (bool) { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - return proposalvote.forVotes > proposalvote.againstVotes; -diff -ruN governance/extensions/GovernorTimelockControl.sol governance/extensions/GovernorTimelockControl.sol ---- governance/extensions/GovernorTimelockControl.sol 2021-12-03 15:24:56.523654357 -0500 -+++ governance/extensions/GovernorTimelockControl.sol 2021-12-09 14:46:33.923637220 -0500 -@@ -111,7 +111,7 @@ - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override { -- _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash); -+ _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash); - } - - /** -diff -ruN governance/Governor.sol governance/Governor.sol ---- governance/Governor.sol 2021-12-03 15:24:56.523654357 -0500 -+++ governance/Governor.sol 2021-12-09 14:46:56.411503587 -0500 -@@ -38,8 +38,8 @@ - - string private _name; - -- mapping(uint256 => ProposalCore) private _proposals; -- -+ mapping(uint256 => ProposalCore) public _proposals; -+ - /** - * @dev Restrict access to governor executing address. Some module might override the _executor function to make - * sure this modifier is consistent with the execution model. -@@ -167,12 +167,12 @@ - /** - * @dev Amount of votes already cast passes the threshold limit. - */ -- function _quorumReached(uint256 proposalId) internal view virtual returns (bool); -+ function _quorumReached(uint256 proposalId) public view virtual returns (bool); // HARNESS: changed to public from internal - - /** - * @dev Is the proposal successful or not. - */ -- function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); -+ function _voteSucceeded(uint256 proposalId) public view virtual returns (bool); // HARNESS: changed to public from internal - - /** - * @dev Register a vote with a given support and voting weight. -diff -ruN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Votes.sol ---- token/ERC20/extensions/ERC20Votes.sol 2021-12-03 15:24:56.527654330 -0500 -+++ token/ERC20/extensions/ERC20Votes.sol 2021-12-09 14:46:33.927637196 -0500 -@@ -84,7 +84,7 @@ - * - * - `blockNumber` must have been already mined - */ -- function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) { -+ function getPastVotes(address account, uint256 blockNumber) public view virtual returns (uint256) { - require(blockNumber < block.number, "ERC20Votes: block not yet mined"); - return _checkpointsLookup(_checkpoints[account], blockNumber); - } diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/ERC20VotesHarness.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/ERC20VotesHarness.sol deleted file mode 100644 index 5067ecf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/ERC20VotesHarness.sol +++ /dev/null @@ -1,28 +0,0 @@ -import "../munged/token/ERC20/extensions/ERC20Votes.sol"; - -contract ERC20VotesHarness is ERC20Votes { - constructor(string memory name, string memory symbol) ERC20Permit(name) ERC20(name, symbol) {} - - mapping(address => mapping(uint256 => uint256)) public _getPastVotes; - - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - super._afterTokenTransfer(from, to, amount); - _getPastVotes[from][block.number] -= amount; - _getPastVotes[to][block.number] += amount; - } - - /** - * @dev Change delegation for `delegator` to `delegatee`. - * - * Emits events {DelegateChanged} and {DelegateVotesChanged}. - */ - function _delegate(address delegator, address delegatee) internal virtual override{ - super._delegate(delegator, delegatee); - _getPastVotes[delegator][block.number] -= balanceOf(delegator); - _getPastVotes[delegatee][block.number] += balanceOf(delegator); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/WizardControlFirstPriority.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/WizardControlFirstPriority.sol deleted file mode 100644 index 5ae7fe0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/WizardControlFirstPriority.sol +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../munged/governance/Governor.sol"; -import "../munged/governance/extensions/GovernorCountingSimple.sol"; -import "../munged/governance/extensions/GovernorVotes.sol"; -import "../munged/governance/extensions/GovernorVotesQuorumFraction.sol"; -import "../munged/governance/extensions/GovernorTimelockControl.sol"; -import "../munged/governance/extensions/GovernorProposalThreshold.sol"; - -/* -Wizard options: -ProposalThreshhold = 10 -ERC20Votes -TimelockController -*/ - -contract WizardControlFirstPriority is Governor, GovernorProposalThreshold, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl { - constructor(ERC20Votes _token, TimelockController _timelock, string memory name, uint256 quorumFraction) - Governor(name) - GovernorVotes(_token) - GovernorVotesQuorumFraction(quorumFraction) - GovernorTimelockControl(_timelock) - {} - - //HARNESS - - function isExecuted(uint256 proposalId) public view returns (bool) { - return _proposals[proposalId].executed; - } - - function isCanceled(uint256 proposalId) public view returns (bool) { - return _proposals[proposalId].canceled; - } - - uint256 _votingDelay; - - uint256 _votingPeriod; - - uint256 _proposalThreshold; - - mapping(uint256 => uint256) public ghost_sum_vote_power_by_id; - - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason - ) internal override virtual returns (uint256) { - - uint256 deltaWeight = super._castVote(proposalId, account, support, reason); //HARNESS - ghost_sum_vote_power_by_id[proposalId] += deltaWeight; - - return deltaWeight; - } - - function snapshot(uint256 proposalId) public view returns (uint64) { - return _proposals[proposalId].voteStart._deadline; - } - - - function getExecutor() public view returns (address){ - return _executor(); - } - - // original code, harnessed - - function votingDelay() public view override returns (uint256) { // HARNESS: pure -> view - return _votingDelay; // HARNESS: parametric - } - - function votingPeriod() public view override returns (uint256) { // HARNESS: pure -> view - return _votingPeriod; // HARNESS: parametric - } - - function proposalThreshold() public view override returns (uint256) { // HARNESS: pure -> view - return _proposalThreshold; // HARNESS: parametric - } - - // original code, not harnessed - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function getVotes(address account, uint256 blockNumber) - public - view - override(IGovernor, GovernorVotes) - returns (uint256) - { - return super.getVotes(account, blockNumber); - } - - function state(uint256 proposalId) - public - view - override(Governor, GovernorTimelockControl) - returns (ProposalState) - { - return super.state(proposalId); - } - - function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) - public - override(Governor, GovernorProposalThreshold, IGovernor) - returns (uint256) - { - return super.propose(targets, values, calldatas, description); - } - - function _execute(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) - internal - override(Governor, GovernorTimelockControl) - { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) - internal - override(Governor, GovernorTimelockControl) - returns (uint256) - { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() - internal - view - override(Governor, GovernorTimelockControl) - returns (address) - { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(Governor, GovernorTimelockControl) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/WizardFirstTry.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/WizardFirstTry.sol deleted file mode 100644 index 83fece0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/harnesses/WizardFirstTry.sol +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../munged/governance/Governor.sol"; -import "../munged/governance/extensions/GovernorCountingSimple.sol"; -import "../munged/governance/extensions/GovernorVotes.sol"; -import "../munged/governance/extensions/GovernorVotesQuorumFraction.sol"; -import "../munged/governance/extensions/GovernorTimelockCompound.sol"; - -/* -Wizard options: -ERC20Votes -TimelockCompound -*/ - -contract WizardFirstTry is Governor, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockCompound { - constructor(ERC20Votes _token, ICompoundTimelock _timelock, string memory name, uint256 quorumFraction) - Governor(name) - GovernorVotes(_token) - GovernorVotesQuorumFraction(quorumFraction) - GovernorTimelockCompound(_timelock) - {} - - //HARNESS - - function isExecuted(uint256 proposalId) public view returns (bool) { - return _proposals[proposalId].executed; - } - - function isCanceled(uint256 proposalId) public view returns (bool) { - return _proposals[proposalId].canceled; - } - - function snapshot(uint256 proposalId) public view returns (uint64) { - return _proposals[proposalId].voteStart._deadline; - } - - function getExecutor() public view returns (address){ - return _executor(); - } - - uint256 _votingDelay; - - uint256 _votingPeriod; - - mapping(uint256 => uint256) public ghost_sum_vote_power_by_id; - - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason - ) internal override virtual returns (uint256) { - - uint256 deltaWeight = super._castVote(proposalId, account, support, reason); //HARNESS - ghost_sum_vote_power_by_id[proposalId] += deltaWeight; - - return deltaWeight; - } - - // original code, harnessed - - function votingDelay() public view override virtual returns (uint256) { // HARNESS: pure -> view - return _votingDelay; // HARNESS: parametric - } - - function votingPeriod() public view override virtual returns (uint256) { // HARNESS: pure -> view - return _votingPeriod; // HARNESS: parametric - } - - // original code, not harnessed - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function getVotes(address account, uint256 blockNumber) - public - view - override(IGovernor, GovernorVotes) - returns (uint256) - { - return super.getVotes(account, blockNumber); - } - - function state(uint256 proposalId) - public - view - override(Governor, GovernorTimelockCompound) - returns (ProposalState) - { - return super.state(proposalId); - } - - function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) - public - override(Governor, IGovernor) - returns (uint256) - { - return super.propose(targets, values, calldatas, description); - } - - function _execute(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) - internal - override(Governor, GovernorTimelockCompound) - { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) - internal - override(Governor, GovernorTimelockCompound) - returns (uint256) - { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() - internal - view - override(Governor, GovernorTimelockCompound) - returns (address) - { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(Governor, GovernorTimelockCompound) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/munged/.gitignore b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/munged/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/munged/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/Governor.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/Governor.sh deleted file mode 100755 index 53ade50..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/Governor.sh +++ /dev/null @@ -1,10 +0,0 @@ -make -C certora munged - -certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/GovernorHarness.sol \ - --verify GovernorHarness:certora/specs/GovernorBase.spec \ - --solc solc8.0 \ - --staging shelly/forSasha \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --rule voteStartBeforeVoteEnd \ - --msg "$1" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/GovernorCountingSimple-counting.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/GovernorCountingSimple-counting.sh deleted file mode 100644 index 9ed8fe3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/GovernorCountingSimple-counting.sh +++ /dev/null @@ -1,10 +0,0 @@ -make -C certora munged - -certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/GovernorBasicHarness.sol \ - --verify GovernorBasicHarness:certora/specs/GovernorCountingSimple.spec \ - --solc solc8.2 \ - --staging shelly/forSasha \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --rule hasVotedCorrelation \ - --msg "$1" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/WizardControlFirstPriority.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/WizardControlFirstPriority.sh deleted file mode 100644 index b815986..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/WizardControlFirstPriority.sh +++ /dev/null @@ -1,12 +0,0 @@ -make -C certora munged - -certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/WizardControlFirstPriority.sol \ - --link WizardControlFirstPriority:token=ERC20VotesHarness \ - --verify WizardControlFirstPriority:certora/specs/GovernorBase.spec \ - --solc solc8.2 \ - --disableLocalTypeChecking \ - --staging shelly/forSasha \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --rule canVoteDuringVotingPeriod \ - --msg "$1" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/WizardFirstTry.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/WizardFirstTry.sh deleted file mode 100644 index fd5a32a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/WizardFirstTry.sh +++ /dev/null @@ -1,10 +0,0 @@ -make -C certora munged - -certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/WizardFirstTry.sol \ - --verify WizardFirstTry:certora/specs/GovernorBase.spec \ - --solc solc8.2 \ - --staging shelly/forSasha \ - --optimistic_loop \ - --disableLocalTypeChecking \ - --settings -copyLoopUnroll=4 \ - --msg "$1" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/sanity.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/sanity.sh deleted file mode 100644 index b6cdb4e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/sanity.sh +++ /dev/null @@ -1,14 +0,0 @@ -make -C certora munged - -for f in certora/harnesses/Wizard*.sol -do - echo "Processing $f" - file=$(basename $f) - echo ${file%.*} - certoraRun certora/harnesses/$file \ - --verify ${file%.*}:certora/specs/sanity.spec "$@" \ - --solc solc8.2 --staging shelly/forSasha \ - --optimistic_loop \ - --msg "checking sanity on ${file%.*}" - --settings -copyLoopUnroll=4 -done diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/verifyAll.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/verifyAll.sh deleted file mode 100644 index 90d7691..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/scripts/verifyAll.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -make -C certora munged - -for contract in certora/harnesses/Wizard*.sol; -do - for spec in certora/specs/*.spec; - do - contractFile=$(basename $contract) - specFile=$(basename $spec) - if [[ "${specFile%.*}" != "RulesInProgress" ]]; - then - echo "Processing ${contractFile%.*} with $specFile" - if [[ "${contractFile%.*}" = *"WizardControl"* ]]; - then - certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/$contractFile \ - --link ${contractFile%.*}:token=ERC20VotesHarness \ - --verify ${contractFile%.*}:certora/specs/$specFile "$@" \ - --solc solc8.2 \ - --staging shelly/forSasha \ - --disableLocalTypeChecking \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --send_only \ - --msg "checking $specFile on ${contractFile%.*}" - else - certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/$contractFile \ - --verify ${contractFile%.*}:certora/specs/$specFile "$@" \ - --solc solc8.2 \ - --staging shelly/forSasha \ - --disableLocalTypeChecking \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --send_only \ - --msg "checking $specFile on ${contractFile%.*}" - fi - fi - done -done diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/GovernorBase.spec b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/GovernorBase.spec deleted file mode 100644 index de728dd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/GovernorBase.spec +++ /dev/null @@ -1,333 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -///////////////////// Governor.sol base definitions ////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -using ERC20VotesHarness as erc20votes - -methods { - proposalSnapshot(uint256) returns uint256 envfree // matches proposalVoteStart - proposalDeadline(uint256) returns uint256 envfree // matches proposalVoteEnd - hashProposal(address[],uint256[],bytes[],bytes32) returns uint256 envfree - isExecuted(uint256) returns bool envfree - isCanceled(uint256) returns bool envfree - execute(address[], uint256[], bytes[], bytes32) returns uint256 - hasVoted(uint256, address) returns bool - castVote(uint256, uint8) returns uint256 - updateQuorumNumerator(uint256) - queue(address[], uint256[], bytes[], bytes32) returns uint256 - - // internal functions made public in harness: - _quorumReached(uint256) returns bool - _voteSucceeded(uint256) returns bool envfree - - // function summarization - proposalThreshold() returns uint256 envfree - - getVotes(address, uint256) returns uint256 => DISPATCHER(true) - - getPastTotalSupply(uint256 t) returns uint256 => PER_CALLEE_CONSTANT - getPastVotes(address a, uint256 t) returns uint256 => PER_CALLEE_CONSTANT - - //scheduleBatch(address[],uint256[],bytes[],bytes32,bytes32,uint256) => DISPATCHER(true) - //executeBatch(address[], uint256[], bytes[], bytes32, bytes32) => DISPATCHER(true) -} - -////////////////////////////////////////////////////////////////////////////// -//////////////////////////////// Definitions ///////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -// proposal was created - relation proved in noStartBeforeCreation -definition proposalCreated(uint256 pId) returns bool = proposalSnapshot(pId) > 0; - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////// Helper Functions /////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -function helperFunctionsWithRevert(uint256 proposalId, method f, env e) { - address[] targets; uint256[] values; bytes[] calldatas; string reason; bytes32 descriptionHash; - uint8 support; uint8 v; bytes32 r; bytes32 s; - if (f.selector == propose(address[], uint256[], bytes[], string).selector) { - uint256 result = propose@withrevert(e, targets, values, calldatas, reason); - require(result == proposalId); - } else if (f.selector == execute(address[], uint256[], bytes[], bytes32).selector) { - uint256 result = execute@withrevert(e, targets, values, calldatas, descriptionHash); - require(result == proposalId); - } else if (f.selector == castVote(uint256, uint8).selector) { - castVote@withrevert(e, proposalId, support); - } else if (f.selector == castVoteWithReason(uint256, uint8, string).selector) { - castVoteWithReason@withrevert(e, proposalId, support, reason); - } else if (f.selector == castVoteBySig(uint256, uint8,uint8, bytes32, bytes32).selector) { - castVoteBySig@withrevert(e, proposalId, support, v, r, s); - } else if (f.selector == queue(address[], uint256[], bytes[], bytes32).selector) { - queue@withrevert(e, targets, values, calldatas, descriptionHash); - } else { - calldataarg args; - f@withrevert(e, args); - } -} - -/* - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////// State Diagram ////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // // - // castVote(s)() // - // ------------- propose() ---------------------- time pass --------------- time passes ----------- // - // | No Proposal | --------> | Before Start (Delay) | --------> | Voting Period | ----------------------> | execute() | // - // ------------- ---------------------- --------------- -> Executed/Canceled ----------- // - // ------------------------------------------------------------|---------------|-------------------------|--------------> // - // t start end timelock // - // // - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -*/ - - -/////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// Global Valid States ///////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// - - -/* - * Start and end date are either initialized (non zero) or uninitialized (zero) simultaneously - * This invariant assumes that the block number cannot be 0 at any stage of the contract cycle - * This is very safe assumption as usually the 0 block is genesis block which is uploaded with data - * by the developers and will not be valid to raise proposals (at the current way that block chain is functioning) - */ - // To use env with general preserved block disable type checking [--disableLocalTypeChecking] -invariant startAndEndDatesNonZero(uint256 pId) - proposalSnapshot(pId) != 0 <=> proposalDeadline(pId) != 0 - { preserved with (env e){ - require e.block.number > 0; - }} - - -/* - * If a proposal is canceled it must have a start and an end date - */ - // To use env with general preserved block disable type checking [--disableLocalTypeChecking] -invariant canceledImplyStartAndEndDateNonZero(uint pId) - isCanceled(pId) => proposalSnapshot(pId) != 0 - {preserved with (env e){ - require e.block.number > 0; - }} - - -/* - * If a proposal is executed it must have a start and an end date - */ - // To use env with general preserved block disable type checking [--disableLocalTypeChecking] -invariant executedImplyStartAndEndDateNonZero(uint pId) - isExecuted(pId) => proposalSnapshot(pId) != 0 - { preserved with (env e){ - requireInvariant startAndEndDatesNonZero(pId); - require e.block.number > 0; - }} - - -/* - * A proposal starting block number must be less or equal than the proposal end date - */ -invariant voteStartBeforeVoteEnd(uint256 pId) - // from < to <= because snapshot and deadline can be the same block number if delays are set to 0 - // This is possible before the integration of GovernorSettings.sol to the system. - // After integration of GovernorSettings.sol the invariant expression should be changed from <= to < - (proposalSnapshot(pId) > 0 => proposalSnapshot(pId) <= proposalDeadline(pId)) - // (proposalSnapshot(pId) > 0 => proposalSnapshot(pId) <= proposalDeadline(pId)) - { preserved { - requireInvariant startAndEndDatesNonZero(pId); - }} - - -/* - * A proposal cannot be both executed and canceled simultaneously. - */ -invariant noBothExecutedAndCanceled(uint256 pId) - !isExecuted(pId) || !isCanceled(pId) - - -/* - * A proposal could be executed only if quorum was reached and vote succeeded - */ -rule executionOnlyIfQuoromReachedAndVoteSucceeded(uint256 pId, env e, method f){ - bool isExecutedBefore = isExecuted(pId); - bool quorumReachedBefore = _quorumReached(e, pId); - bool voteSucceededBefore = _voteSucceeded(pId); - - calldataarg args; - f(e, args); - - bool isExecutedAfter = isExecuted(pId); - assert (!isExecutedBefore && isExecutedAfter) => (quorumReachedBefore && voteSucceededBefore), "quorum was changed"; -} - -/////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////// In-State Rules ///////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// - -//========================================== -//------------- Voting Period -------------- -//========================================== - -/* - * A user cannot vote twice - */ - // Checked for castVote only. all 3 castVote functions call _castVote, so the completeness of the verification is counted on - // the fact that the 3 functions themselves makes no changes, but rather call an internal function to execute. - // That means that we do not check those 3 functions directly, however for castVote & castVoteWithReason it is quite trivial - // to understand why this is ok. For castVoteBySig we basically assume that the signature referendum is correct without checking it. - // We could check each function separately and pass the rule, but that would have uglyfied the code with no concrete - // benefit, as it is evident that nothing is happening in the first 2 functions (calling a view function), and we do not desire to check the signature verification. -rule doubleVoting(uint256 pId, uint8 sup, method f) { - env e; - address user = e.msg.sender; - bool votedCheck = hasVoted(e, pId, user); - - castVote@withrevert(e, pId, sup); - - assert votedCheck => lastReverted, "double voting occurred"; -} - - -/////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////// State Transitions Rules ////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// - -//=========================================== -//-------- Propose() --> End of Time -------- -//=========================================== - - -/* - * Once a proposal is created, voteStart and voteEnd are immutable - */ -rule immutableFieldsAfterProposalCreation(uint256 pId, method f) { - uint256 _voteStart = proposalSnapshot(pId); - uint256 _voteEnd = proposalDeadline(pId); - - require proposalCreated(pId); // startDate > 0 - - env e; calldataarg arg; - f(e, arg); - - uint256 voteStart_ = proposalSnapshot(pId); - uint256 voteEnd_ = proposalDeadline(pId); - assert _voteStart == voteStart_, "Start date was changed"; - assert _voteEnd == voteEnd_, "End date was changed"; -} - - -/* - * Voting cannot start at a block number prior to proposal’s creation block number - */ -rule noStartBeforeCreation(uint256 pId) { - uint256 previousStart = proposalSnapshot(pId); - // This line makes sure that we see only cases where start date is changed from 0, i.e. creation of proposal - // We proved in immutableFieldsAfterProposalCreation that once dates set for proposal, it cannot be changed - require !proposalCreated(pId); // previousStart == 0; - - env e; calldataarg args; - propose(e, args); - - uint256 newStart = proposalSnapshot(pId); - // if created, start is after current block number (creation block) - assert(newStart != previousStart => newStart >= e.block.number); -} - - -//============================================ -//--- End of Voting Period --> End of Time --- -//============================================ - - -/* - * A proposal can neither be executed nor canceled before it ends - */ - // By induction it cannot be executed nor canceled before it starts, due to voteStartBeforeVoteEnd -rule noExecuteOrCancelBeforeDeadline(uint256 pId, method f){ - require !isExecuted(pId) && !isCanceled(pId); - - env e; calldataarg args; - f(e, args); - - assert e.block.number < proposalDeadline(pId) => (!isExecuted(pId) && !isCanceled(pId)), "executed/cancelled before deadline"; -} - -//////////////////////////////////////////////////////////////////////////////// -////////////////////// Integrity Of Functions (Unit Tests) ///////////////////// -//////////////////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////////////////// -////////////////////////////// High Level Rules //////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////////////////// -///////////////////////////// Not Categorized Yet ////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - - -/* - * All proposal specific (non-view) functions should revert if proposal is executed - */ - // In this rule we show that if a function is executed, i.e. execute() was called on the proposal ID, - // non of the proposal specific functions can make changes again. In executedOnlyAfterExecuteFunc - // we connected the executed attribute to the execute() function, showing that only execute() can - // change it, and that it will always change it. -rule allFunctionsRevertIfExecuted(method f) filtered { f -> - !f.isView && !f.isFallback - && f.selector != updateTimelock(address).selector - && f.selector != updateQuorumNumerator(uint256).selector - && f.selector != queue(address[],uint256[],bytes[],bytes32).selector - && f.selector != relay(address,uint256,bytes).selector - && f.selector != 0xb9a61961 // __acceptAdmin() -} { - env e; calldataarg args; - uint256 pId; - require(isExecuted(pId)); - requireInvariant noBothExecutedAndCanceled(pId); - requireInvariant executedImplyStartAndEndDateNonZero(pId); - - helperFunctionsWithRevert(pId, f, e); - - assert(lastReverted, "Function was not reverted"); -} - -/* - * All proposal specific (non-view) functions should revert if proposal is canceled - */ -rule allFunctionsRevertIfCanceled(method f) filtered { - f -> !f.isView && !f.isFallback - && f.selector != updateTimelock(address).selector - && f.selector != updateQuorumNumerator(uint256).selector - && f.selector != queue(address[],uint256[],bytes[],bytes32).selector - && f.selector != relay(address,uint256,bytes).selector - && f.selector != 0xb9a61961 // __acceptAdmin() -} { - env e; calldataarg args; - uint256 pId; - require(isCanceled(pId)); - requireInvariant noBothExecutedAndCanceled(pId); - requireInvariant canceledImplyStartAndEndDateNonZero(pId); - - helperFunctionsWithRevert(pId, f, e); - - assert(lastReverted, "Function was not reverted"); -} - -/* - * Proposal can be switched to executed only via execute() function - */ -rule executedOnlyAfterExecuteFunc(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash, method f) { - env e; calldataarg args; - uint256 pId; - bool executedBefore = isExecuted(pId); - require(!executedBefore); - - helperFunctionsWithRevert(pId, f, e); - - bool executedAfter = isExecuted(pId); - assert(executedAfter != executedBefore => f.selector == execute(address[], uint256[], bytes[], bytes32).selector, "isExecuted only changes in the execute method"); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/GovernorCountingSimple.spec b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/GovernorCountingSimple.spec deleted file mode 100644 index 7af73be..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/GovernorCountingSimple.spec +++ /dev/null @@ -1,221 +0,0 @@ -import "GovernorBase.spec" - -using ERC20VotesHarness as erc20votes - -methods { - ghost_sum_vote_power_by_id(uint256) returns uint256 envfree - - quorum(uint256) returns uint256 - proposalVotes(uint256) returns (uint256, uint256, uint256) envfree - - quorumNumerator() returns uint256 - _executor() returns address - - erc20votes._getPastVotes(address, uint256) returns uint256 - - getExecutor() returns address - - timelock() returns address -} - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// GHOSTS ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -//////////// ghosts to keep track of votes counting //////////// - -/* - * the sum of voting power of those who voted - */ -ghost sum_all_votes_power() returns uint256 { - init_state axiom sum_all_votes_power() == 0; -} - -hook Sstore ghost_sum_vote_power_by_id [KEY uint256 pId] uint256 current_power(uint256 old_power) STORAGE { - havoc sum_all_votes_power assuming sum_all_votes_power@new() == sum_all_votes_power@old() - old_power + current_power; -} - -/* - * sum of all votes casted per proposal - */ -ghost tracked_weight(uint256) returns uint256 { - init_state axiom forall uint256 p. tracked_weight(p) == 0; -} - -/* - * sum of all votes casted - */ -ghost sum_tracked_weight() returns uint256 { - init_state axiom sum_tracked_weight() == 0; -} - -/* - * getter for _proposalVotes.againstVotes - */ -ghost votesAgainst() returns uint256 { - init_state axiom votesAgainst() == 0; -} - -/* - * getter for _proposalVotes.forVotes - */ -ghost votesFor() returns uint256 { - init_state axiom votesFor() == 0; -} - -/* - * getter for _proposalVotes.abstainVotes - */ -ghost votesAbstain() returns uint256 { - init_state axiom votesAbstain() == 0; -} - -hook Sstore _proposalVotes [KEY uint256 pId].againstVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesAgainst assuming votesAgainst@new() == votesAgainst@old() - old_votes + votes; -} - -hook Sstore _proposalVotes [KEY uint256 pId].forVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesFor assuming votesFor@new() == votesFor@old() - old_votes + votes; -} - -hook Sstore _proposalVotes [KEY uint256 pId].abstainVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesAbstain assuming votesAbstain@new() == votesAbstain@old() - old_votes + votes; -} - - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////// INVARIANTS //////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -/* - * sum of all votes casted is equal to the sum of voting power of those who voted, per each proposal - */ -invariant SumOfVotesCastEqualSumOfPowerOfVotedPerProposal(uint256 pId) - tracked_weight(pId) == ghost_sum_vote_power_by_id(pId) - - -/* - * sum of all votes casted is equal to the sum of voting power of those who voted - */ -invariant SumOfVotesCastEqualSumOfPowerOfVoted() - sum_tracked_weight() == sum_all_votes_power() - - -/* -* sum of all votes casted is greater or equal to the sum of voting power of those who voted at a specific proposal -*/ -invariant OneIsNotMoreThanAll(uint256 pId) - sum_all_votes_power() >= tracked_weight(pId) - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// RULES ////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -/* - * Only sender's voting status can be changed by execution of any cast vote function - */ -// Checked for castVote only. all 3 castVote functions call _castVote, so the completeness of the verification is counted on - // the fact that the 3 functions themselves makes no changes, but rather call an internal function to execute. - // That means that we do not check those 3 functions directly, however for castVote & castVoteWithReason it is quite trivial - // to understand why this is ok. For castVoteBySig we basically assume that the signature referendum is correct without checking it. - // We could check each function separately and pass the rule, but that would have uglyfied the code with no concrete - // benefit, as it is evident that nothing is happening in the first 2 functions (calling a view function), and we do not desire to check the signature verification. -rule noVoteForSomeoneElse(uint256 pId, uint8 sup, method f) { - env e; calldataarg args; - - address voter = e.msg.sender; - address user; - - bool hasVotedBefore_User = hasVoted(e, pId, user); - - castVote@withrevert(e, pId, sup); - require(!lastReverted); - - bool hasVotedAfter_User = hasVoted(e, pId, user); - - assert user != voter => hasVotedBefore_User == hasVotedAfter_User; -} - - -/* -* Total voting tally is monotonically non-decreasing in every operation -*/ -rule votingWeightMonotonicity(method f){ - uint256 votingWeightBefore = sum_tracked_weight(); - - env e; - calldataarg args; - f(e, args); - - uint256 votingWeightAfter = sum_tracked_weight(); - - assert votingWeightBefore <= votingWeightAfter, "Voting weight was decreased somehow"; -} - - -/* -* A change in hasVoted must be correlated with an non-decreasing of the vote supports (nondecrease because user can vote with weight 0) -*/ -rule hasVotedCorrelation(uint256 pId, method f, env e, uint256 bn) { - address acc = e.msg.sender; - - uint256 againstBefore = votesAgainst(); - uint256 forBefore = votesFor(); - uint256 abstainBefore = votesAbstain(); - - bool hasVotedBefore = hasVoted(e, pId, acc); - - helperFunctionsWithRevert(pId, f, e); - require(!lastReverted); - - uint256 againstAfter = votesAgainst(); - uint256 forAfter = votesFor(); - uint256 abstainAfter = votesAbstain(); - - bool hasVotedAfter = hasVoted(e, pId, acc); - - assert (!hasVotedBefore && hasVotedAfter) => againstBefore <= againstAfter || forBefore <= forAfter || abstainBefore <= abstainAfter, "no correlation"; -} - - -/* -* Only privileged users can execute privileged operations, e.g. change _quorumNumerator or _timelock -*/ -rule privilegedOnlyNumerator(method f, uint256 newQuorumNumerator){ - env e; - calldataarg arg; - uint256 quorumNumBefore = quorumNumerator(e); - - f(e, arg); - - uint256 quorumNumAfter = quorumNumerator(e); - address executorCheck = getExecutor(e); - - assert quorumNumBefore != quorumNumAfter => e.msg.sender == executorCheck, "non privileged user changed quorum numerator"; -} - -rule privilegedOnlyTimelock(method f, uint256 newQuorumNumerator){ - env e; - calldataarg arg; - uint256 timelockBefore = timelock(e); - - f(e, arg); - - uint256 timelockAfter = timelock(e); - - assert timelockBefore != timelockAfter => e.msg.sender == timelockBefore, "non privileged user changed timelock"; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/RulesInProgress.spec b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/RulesInProgress.spec deleted file mode 100644 index cbad333..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/RulesInProgress.spec +++ /dev/null @@ -1,139 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -////////////// THIS SPEC IS A RESERVE FOR NOT IN PROGRESS ////////////// -////////////////////////////////////////////////////////////////////////////// - -import "GovernorBase.spec" - -using ERC20VotesHarness as erc20votes - -methods { - ghost_sum_vote_power_by_id(uint256) returns uint256 envfree - - quorum(uint256) returns uint256 - proposalVotes(uint256) returns (uint256, uint256, uint256) envfree - - quorumNumerator() returns uint256 - _executor() returns address - - erc20votes._getPastVotes(address, uint256) returns uint256 - - getExecutor() returns address - - timelock() returns address -} - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// GHOSTS ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -//////////// ghosts to keep track of votes counting //////////// - -/* - * the sum of voting power of those who voted - */ -ghost sum_all_votes_power() returns uint256 { - init_state axiom sum_all_votes_power() == 0; -} - -hook Sstore ghost_sum_vote_power_by_id [KEY uint256 pId] uint256 current_power(uint256 old_power) STORAGE { - havoc sum_all_votes_power assuming sum_all_votes_power@new() == sum_all_votes_power@old() - old_power + current_power; -} - -/* - * sum of all votes casted per proposal - */ -ghost tracked_weight(uint256) returns uint256 { - init_state axiom forall uint256 p. tracked_weight(p) == 0; -} - -/* - * sum of all votes casted - */ -ghost sum_tracked_weight() returns uint256 { - init_state axiom sum_tracked_weight() == 0; -} - -/* - * getter for _proposalVotes.againstVotes - */ -ghost votesAgainst() returns uint256 { - init_state axiom votesAgainst() == 0; -} - -/* - * getter for _proposalVotes.forVotes - */ -ghost votesFor() returns uint256 { - init_state axiom votesFor() == 0; -} - -/* - * getter for _proposalVotes.abstainVotes - */ -ghost votesAbstain() returns uint256 { - init_state axiom votesAbstain() == 0; -} - -hook Sstore _proposalVotes [KEY uint256 pId].againstVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesAgainst assuming votesAgainst@new() == votesAgainst@old() - old_votes + votes; -} - -hook Sstore _proposalVotes [KEY uint256 pId].forVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesFor assuming votesFor@new() == votesFor@old() - old_votes + votes; -} - -hook Sstore _proposalVotes [KEY uint256 pId].abstainVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesAbstain assuming votesAbstain@new() == votesAbstain@old() - old_votes + votes; -} - - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////// INVARIANTS //////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// RULES ////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -//NOT FINISHED -/* -* the sum of voting power of those who voted is less or equal to the maximum possible votes, per each proposal -*/ -rule possibleTotalVotes(uint256 pId, uint8 sup, env e, method f) { - - // add requireinvariant for all i, j. i = i - 1 && i < j => checkpointlookup[i] < checkpointlookup[j]; - require tracked_weight(pId) <= erc20votes.getPastTotalSupply(e, proposalSnapshot(pId)); - - uint256 againstB; - uint256 forB; - uint256 absatinB; - againstB, forB, absatinB = proposalVotes(pId); - - calldataarg args; - //f(e, args); - - castVote(e, pId, sup); - - uint256 against; - uint256 for; - uint256 absatin; - against, for, absatin = proposalVotes(pId); - - uint256 ps = proposalSnapshot(pId); - - assert tracked_weight(pId) <= erc20votes.getPastTotalSupply(e, proposalSnapshot(pId)), "bla bla bla"; -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/sanity.spec b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/sanity.spec deleted file mode 100644 index e08f688..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/certora/specs/sanity.spec +++ /dev/null @@ -1,14 +0,0 @@ -/* -This rule looks for a non-reverting execution path to each method, including those overridden in the harness. -A method has such an execution path if it violates this rule. -How it works: - - If there is a non-reverting execution path, we reach the false assertion, and the sanity fails. - - If all execution paths are reverting, we never call the assertion, and the method will pass this rule vacuously. -*/ - -rule sanity(method f) { - env e; - calldataarg arg; - f(e, arg); - assert false; -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlCrossChainUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlCrossChainUpgradeable.sol deleted file mode 100644 index 714abdd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlCrossChainUpgradeable.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControlCrossChain.sol) - -pragma solidity ^0.8.4; - -import "./AccessControlUpgradeable.sol"; -import "../crosschain/CrossChainEnabledUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev An extension to {AccessControl} with support for cross-chain access management. - * For each role, is extension implements an equivalent "aliased" role that is used for - * restricting calls originating from other chains. - * - * For example, if a function `myFunction` is protected by `onlyRole(SOME_ROLE)`, and - * if an address `x` has role `SOME_ROLE`, it would be able to call `myFunction` directly. - * A wallet or contract at the same address on another chain would however not be able - * to call this function. In order to do so, it would require to have the role - * `_crossChainRoleAlias(SOME_ROLE)`. - * - * This aliasing is required to protect against multiple contracts living at the same - * address on different chains but controlled by conflicting entities. - * - * _Available since v4.6._ - */ -abstract contract AccessControlCrossChainUpgradeable is Initializable, AccessControlUpgradeable, CrossChainEnabledUpgradeable { - function __AccessControlCrossChain_init() internal onlyInitializing { - } - - function __AccessControlCrossChain_init_unchained() internal onlyInitializing { - } - bytes32 public constant CROSSCHAIN_ALIAS = keccak256("CROSSCHAIN_ALIAS"); - - /** - * @dev See {AccessControl-_checkRole}. - */ - function _checkRole(bytes32 role) internal view virtual override { - if (_isCrossChain()) { - _checkRole(_crossChainRoleAlias(role), _crossChainSender()); - } else { - super._checkRole(role); - } - } - - /** - * @dev Returns the aliased role corresponding to `role`. - */ - function _crossChainRoleAlias(bytes32 role) internal pure virtual returns (bytes32) { - return role ^ CROSSCHAIN_ALIAS; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlEnumerableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlEnumerableUpgradeable.sol deleted file mode 100644 index 944f3a2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlEnumerableUpgradeable.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) - -pragma solidity ^0.8.0; - -import "./IAccessControlEnumerableUpgradeable.sol"; -import "./AccessControlUpgradeable.sol"; -import "../utils/structs/EnumerableSetUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {AccessControl} that allows enumerating the members of each role. - */ -abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable { - function __AccessControlEnumerable_init() internal onlyInitializing { - } - - function __AccessControlEnumerable_init_unchained() internal onlyInitializing { - } - using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; - - mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Returns one of the accounts that have `role`. `index` must be a - * value between 0 and {getRoleMemberCount}, non-inclusive. - * - * Role bearers are not sorted in any particular way, and their ordering may - * change at any point. - * - * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure - * you perform all queries on the same block. See the following - * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] - * for more information. - */ - function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { - return _roleMembers[role].at(index); - } - - /** - * @dev Returns the number of accounts that have `role`. Can be used - * together with {getRoleMember} to enumerate all bearers of a role. - */ - function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { - return _roleMembers[role].length(); - } - - /** - * @dev Overload {_grantRole} to track enumerable memberships - */ - function _grantRole(bytes32 role, address account) internal virtual override { - super._grantRole(role, account); - _roleMembers[role].add(account); - } - - /** - * @dev Overload {_revokeRole} to track enumerable memberships - */ - function _revokeRole(bytes32 role, address account) internal virtual override { - super._revokeRole(role, account); - _roleMembers[role].remove(account); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol deleted file mode 100644 index b0fb7d4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol +++ /dev/null @@ -1,260 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) - -pragma solidity ^0.8.0; - -import "./IAccessControlUpgradeable.sol"; -import "../utils/ContextUpgradeable.sol"; -import "../utils/StringsUpgradeable.sol"; -import "../utils/introspection/ERC165Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Contract module that allows children to implement role-based access - * control mechanisms. This is a lightweight version that doesn't allow enumerating role - * members except through off-chain means by accessing the contract event logs. Some - * applications may benefit from on-chain enumerability, for those cases see - * {AccessControlEnumerable}. - * - * Roles are referred to by their `bytes32` identifier. These should be exposed - * in the external API and be unique. The best way to achieve this is by - * using `public constant` hash digests: - * - * ``` - * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); - * ``` - * - * Roles can be used to represent a set of permissions. To restrict access to a - * function call, use {hasRole}: - * - * ``` - * function foo() public { - * require(hasRole(MY_ROLE, msg.sender)); - * ... - * } - * ``` - * - * Roles can be granted and revoked dynamically via the {grantRole} and - * {revokeRole} functions. Each role has an associated admin role, and only - * accounts that have a role's admin role can call {grantRole} and {revokeRole}. - * - * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means - * that only accounts with this role will be able to grant or revoke other - * roles. More complex role relationships can be created by using - * {_setRoleAdmin}. - * - * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to - * grant and revoke this role. Extra precautions should be taken to secure - * accounts that have been granted it. - */ -abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { - function __AccessControl_init() internal onlyInitializing { - } - - function __AccessControl_init_unchained() internal onlyInitializing { - } - struct RoleData { - mapping(address => bool) members; - bytes32 adminRole; - } - - mapping(bytes32 => RoleData) private _roles; - - bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; - - /** - * @dev Modifier that checks that an account has a specific role. Reverts - * with a standardized message including the required role. - * - * The format of the revert reason is given by the following regular expression: - * - * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ - * - * _Available since v4.1._ - */ - modifier onlyRole(bytes32 role) { - _checkRole(role); - _; - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Returns `true` if `account` has been granted `role`. - */ - function hasRole(bytes32 role, address account) public view virtual override returns (bool) { - return _roles[role].members[account]; - } - - /** - * @dev Revert with a standard message if `_msgSender()` is missing `role`. - * Overriding this function changes the behavior of the {onlyRole} modifier. - * - * Format of the revert message is described in {_checkRole}. - * - * _Available since v4.6._ - */ - function _checkRole(bytes32 role) internal view virtual { - _checkRole(role, _msgSender()); - } - - /** - * @dev Revert with a standard message if `account` is missing `role`. - * - * The format of the revert reason is given by the following regular expression: - * - * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ - */ - function _checkRole(bytes32 role, address account) internal view virtual { - if (!hasRole(role, account)) { - revert( - string( - abi.encodePacked( - "AccessControl: account ", - StringsUpgradeable.toHexString(account), - " is missing role ", - StringsUpgradeable.toHexString(uint256(role), 32) - ) - ) - ); - } - } - - /** - * @dev Returns the admin role that controls `role`. See {grantRole} and - * {revokeRole}. - * - * To change a role's admin, use {_setRoleAdmin}. - */ - function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { - return _roles[role].adminRole; - } - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - * - * May emit a {RoleGranted} event. - */ - function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { - _grantRole(role, account); - } - - /** - * @dev Revokes `role` from `account`. - * - * If `account` had been granted `role`, emits a {RoleRevoked} event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - * - * May emit a {RoleRevoked} event. - */ - function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { - _revokeRole(role, account); - } - - /** - * @dev Revokes `role` from the calling account. - * - * Roles are often managed via {grantRole} and {revokeRole}: this function's - * purpose is to provide a mechanism for accounts to lose their privileges - * if they are compromised (such as when a trusted device is misplaced). - * - * If the calling account had been revoked `role`, emits a {RoleRevoked} - * event. - * - * Requirements: - * - * - the caller must be `account`. - * - * May emit a {RoleRevoked} event. - */ - function renounceRole(bytes32 role, address account) public virtual override { - require(account == _msgSender(), "AccessControl: can only renounce roles for self"); - - _revokeRole(role, account); - } - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. Note that unlike {grantRole}, this function doesn't perform any - * checks on the calling account. - * - * May emit a {RoleGranted} event. - * - * [WARNING] - * ==== - * This function should only be called from the constructor when setting - * up the initial roles for the system. - * - * Using this function in any other way is effectively circumventing the admin - * system imposed by {AccessControl}. - * ==== - * - * NOTE: This function is deprecated in favor of {_grantRole}. - */ - function _setupRole(bytes32 role, address account) internal virtual { - _grantRole(role, account); - } - - /** - * @dev Sets `adminRole` as ``role``'s admin role. - * - * Emits a {RoleAdminChanged} event. - */ - function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { - bytes32 previousAdminRole = getRoleAdmin(role); - _roles[role].adminRole = adminRole; - emit RoleAdminChanged(role, previousAdminRole, adminRole); - } - - /** - * @dev Grants `role` to `account`. - * - * Internal function without access restriction. - * - * May emit a {RoleGranted} event. - */ - function _grantRole(bytes32 role, address account) internal virtual { - if (!hasRole(role, account)) { - _roles[role].members[account] = true; - emit RoleGranted(role, account, _msgSender()); - } - } - - /** - * @dev Revokes `role` from `account`. - * - * Internal function without access restriction. - * - * May emit a {RoleRevoked} event. - */ - function _revokeRole(bytes32 role, address account) internal virtual { - if (hasRole(role, account)) { - _roles[role].members[account] = false; - emit RoleRevoked(role, account, _msgSender()); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlEnumerableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlEnumerableUpgradeable.sol deleted file mode 100644 index d7f00e9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlEnumerableUpgradeable.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) - -pragma solidity ^0.8.0; - -import "./IAccessControlUpgradeable.sol"; - -/** - * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. - */ -interface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable { - /** - * @dev Returns one of the accounts that have `role`. `index` must be a - * value between 0 and {getRoleMemberCount}, non-inclusive. - * - * Role bearers are not sorted in any particular way, and their ordering may - * change at any point. - * - * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure - * you perform all queries on the same block. See the following - * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] - * for more information. - */ - function getRoleMember(bytes32 role, uint256 index) external view returns (address); - - /** - * @dev Returns the number of accounts that have `role`. Can be used - * together with {getRoleMember} to enumerate all bearers of a role. - */ - function getRoleMemberCount(bytes32 role) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlUpgradeable.sol deleted file mode 100644 index 963fdd1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/IAccessControlUpgradeable.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) - -pragma solidity ^0.8.0; - -/** - * @dev External interface of AccessControl declared to support ERC165 detection. - */ -interface IAccessControlUpgradeable { - /** - * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` - * - * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite - * {RoleAdminChanged} not being emitted signaling this. - * - * _Available since v3.1._ - */ - event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); - - /** - * @dev Emitted when `account` is granted `role`. - * - * `sender` is the account that originated the contract call, an admin role - * bearer except when using {AccessControl-_setupRole}. - */ - event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Emitted when `account` is revoked `role`. - * - * `sender` is the account that originated the contract call: - * - if using `revokeRole`, it is the admin role bearer - * - if using `renounceRole`, it is the role bearer (i.e. `account`) - */ - event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Returns `true` if `account` has been granted `role`. - */ - function hasRole(bytes32 role, address account) external view returns (bool); - - /** - * @dev Returns the admin role that controls `role`. See {grantRole} and - * {revokeRole}. - * - * To change a role's admin, use {AccessControl-_setRoleAdmin}. - */ - function getRoleAdmin(bytes32 role) external view returns (bytes32); - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function grantRole(bytes32 role, address account) external; - - /** - * @dev Revokes `role` from `account`. - * - * If `account` had been granted `role`, emits a {RoleRevoked} event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function revokeRole(bytes32 role, address account) external; - - /** - * @dev Revokes `role` from the calling account. - * - * Roles are often managed via {grantRole} and {revokeRole}: this function's - * purpose is to provide a mechanism for accounts to lose their privileges - * if they are compromised (such as when a trusted device is misplaced). - * - * If the calling account had been granted `role`, emits a {RoleRevoked} - * event. - * - * Requirements: - * - * - the caller must be `account`. - */ - function renounceRole(bytes32 role, address account) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol deleted file mode 100644 index 86fd4fd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol) - -pragma solidity ^0.8.0; - -import "./OwnableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Contract module which provides access control mechanism, where - * there is an account (an owner) that can be granted exclusive access to - * specific functions. - * - * By default, the owner account will be the one that deploys the contract. This - * can later be changed with {transferOwnership} and {acceptOwnership}. - * - * This module is used through inheritance. It will make available all functions - * from parent (Ownable). - */ -abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable { - function __Ownable2Step_init() internal onlyInitializing { - __Ownable_init_unchained(); - } - - function __Ownable2Step_init_unchained() internal onlyInitializing { - } - address private _pendingOwner; - - event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); - - /** - * @dev Returns the address of the pending owner. - */ - function pendingOwner() public view virtual returns (address) { - return _pendingOwner; - } - - /** - * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. - * Can only be called by the current owner. - */ - function transferOwnership(address newOwner) public virtual override onlyOwner { - _pendingOwner = newOwner; - emit OwnershipTransferStarted(owner(), newOwner); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. - * Internal function without access restriction. - */ - function _transferOwnership(address newOwner) internal virtual override { - delete _pendingOwner; - super._transferOwnership(newOwner); - } - - /** - * @dev The new owner accepts the ownership transfer. - */ - function acceptOwnership() external { - address sender = _msgSender(); - require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); - _transferOwnership(sender); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol deleted file mode 100644 index affb7cd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) - -pragma solidity ^0.8.0; - -import "../utils/ContextUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Contract module which provides a basic access control mechanism, where - * there is an account (an owner) that can be granted exclusive access to - * specific functions. - * - * By default, the owner account will be the one that deploys the contract. This - * can later be changed with {transferOwnership}. - * - * This module is used through inheritance. It will make available the modifier - * `onlyOwner`, which can be applied to your functions to restrict their use to - * the owner. - */ -abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { - address private _owner; - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - /** - * @dev Initializes the contract setting the deployer as the initial owner. - */ - function __Ownable_init() internal onlyInitializing { - __Ownable_init_unchained(); - } - - function __Ownable_init_unchained() internal onlyInitializing { - _transferOwnership(_msgSender()); - } - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - _checkOwner(); - _; - } - - /** - * @dev Returns the address of the current owner. - */ - function owner() public view virtual returns (address) { - return _owner; - } - - /** - * @dev Throws if the sender is not the owner. - */ - function _checkOwner() internal view virtual { - require(owner() == _msgSender(), "Ownable: caller is not the owner"); - } - - /** - * @dev Leaves the contract without owner. It will not be possible to call - * `onlyOwner` functions anymore. Can only be called by the current owner. - * - * NOTE: Renouncing ownership will leave the contract without an owner, - * thereby removing any functionality that is only available to the owner. - */ - function renounceOwnership() public virtual onlyOwner { - _transferOwnership(address(0)); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Can only be called by the current owner. - */ - function transferOwnership(address newOwner) public virtual onlyOwner { - require(newOwner != address(0), "Ownable: new owner is the zero address"); - _transferOwnership(newOwner); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Internal function without access restriction. - */ - function _transferOwnership(address newOwner) internal virtual { - address oldOwner = _owner; - _owner = newOwner; - emit OwnershipTransferred(oldOwner, newOwner); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/README.adoc deleted file mode 100644 index 888d0e9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/README.adoc +++ /dev/null @@ -1,25 +0,0 @@ -= Access Control - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/access - -This directory provides ways to restrict who can access the functions of a contract or when they can do it. - -- {AccessControl} provides a general role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts. -- {Ownable} is a simpler mechanism with a single owner "role" that can be assigned to a single account. This simpler mechanism can be useful for quick tests but projects with production concerns are likely to outgrow it. - -== Authorization - -{{Ownable}} - -{{Ownable2Step}} - -{{IAccessControl}} - -{{AccessControl}} - -{{AccessControlCrossChain}} - -{{IAccessControlEnumerable}} - -{{AccessControlEnumerable}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/CrossChainEnabledUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/CrossChainEnabledUpgradeable.sol deleted file mode 100644 index 8aab592..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/CrossChainEnabledUpgradeable.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/CrossChainEnabled.sol) - -pragma solidity ^0.8.4; - -import "./errorsUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Provides information for building cross-chain aware contracts. This - * abstract contract provides accessors and modifiers to control the execution - * flow when receiving cross-chain messages. - * - * Actual implementations of cross-chain aware contracts, which are based on - * this abstraction, will have to inherit from a bridge-specific - * specialization. Such specializations are provided under - * `crosschain//CrossChainEnabled.sol`. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabledUpgradeable is Initializable { - function __CrossChainEnabled_init() internal onlyInitializing { - } - - function __CrossChainEnabled_init_unchained() internal onlyInitializing { - } - /** - * @dev Throws if the current function call is not the result of a - * cross-chain execution. - */ - modifier onlyCrossChain() { - if (!_isCrossChain()) revert NotCrossChainCall(); - _; - } - - /** - * @dev Throws if the current function call is not the result of a - * cross-chain execution initiated by `account`. - */ - modifier onlyCrossChainSender(address expected) { - address actual = _crossChainSender(); - if (expected != actual) revert InvalidCrossChainSender(actual, expected); - _; - } - - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message. - */ - function _isCrossChain() internal view virtual returns (bool); - - /** - * @dev Returns the address of the sender of the cross-chain message that - * triggered the current function call. - * - * IMPORTANT: Should revert with `NotCrossChainCall` if the current function - * call is not the result of a cross-chain message. - */ - function _crossChainSender() internal view virtual returns (address); - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/README.adoc deleted file mode 100644 index 266b153..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/README.adoc +++ /dev/null @@ -1,34 +0,0 @@ -= Cross Chain Awareness - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/crosschain - -This directory provides building blocks to improve cross-chain awareness of smart contracts. - -- {CrossChainEnabled} is an abstraction that contains accessors and modifiers to control the execution flow when receiving cross-chain messages. - -== CrossChainEnabled specializations - -The following specializations of {CrossChainEnabled} provide implementations of the {CrossChainEnabled} abstraction for specific bridges. This can be used to complex cross-chain aware components such as {AccessControlCrossChain}. - -{{CrossChainEnabledAMB}} - -{{CrossChainEnabledArbitrumL1}} - -{{CrossChainEnabledArbitrumL2}} - -{{CrossChainEnabledOptimism}} - -{{CrossChainEnabledPolygonChild}} - -== Libraries for cross-chain - -In addition to the {CrossChainEnabled} abstraction, cross-chain awareness is also available through libraries. These libraries can be used to build complex designs such as contracts with the ability to interact with multiple bridges. - -{{LibAMB}} - -{{LibArbitrumL1}} - -{{LibArbitrumL2}} - -{{LibOptimism}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/amb/CrossChainEnabledAMBUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/amb/CrossChainEnabledAMBUpgradeable.sol deleted file mode 100644 index 687e212..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/amb/CrossChainEnabledAMBUpgradeable.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/amb/CrossChainEnabledAMB.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabledUpgradeable.sol"; -import "./LibAMBUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev https://docs.tokenbridge.net/amb-bridge/about-amb-bridge[AMB] - * specialization or the {CrossChainEnabled} abstraction. - * - * As of february 2020, AMB bridges are available between the following chains: - * - * - https://docs.tokenbridge.net/eth-xdai-amb-bridge/about-the-eth-xdai-amb[ETH ⇌ xDai] - * - https://docs.tokenbridge.net/eth-qdai-bridge/about-the-eth-qdai-amb[ETH ⇌ qDai] - * - https://docs.tokenbridge.net/eth-etc-amb-bridge/about-the-eth-etc-amb[ETH ⇌ ETC] - * - https://docs.tokenbridge.net/eth-bsc-amb/about-the-eth-bsc-amb[ETH ⇌ BSC] - * - https://docs.tokenbridge.net/eth-poa-amb-bridge/about-the-eth-poa-amb[ETH ⇌ POA] - * - https://docs.tokenbridge.net/bsc-xdai-amb/about-the-bsc-xdai-amb[BSC ⇌ xDai] - * - https://docs.tokenbridge.net/poa-xdai-amb/about-the-poa-xdai-amb[POA ⇌ xDai] - * - https://docs.tokenbridge.net/rinkeby-xdai-amb-bridge/about-the-rinkeby-xdai-amb[Rinkeby ⇌ xDai] - * - https://docs.tokenbridge.net/kovan-sokol-amb-bridge/about-the-kovan-sokol-amb[Kovan ⇌ Sokol] - * - * _Available since v4.6._ - */ -contract CrossChainEnabledAMBUpgradeable is Initializable, CrossChainEnabledUpgradeable { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _bridge; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) { - _bridge = bridge; - } - - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return LibAMBUpgradeable.isCrossChain(_bridge); - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return LibAMBUpgradeable.crossChainSender(_bridge); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/amb/LibAMBUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/amb/LibAMBUpgradeable.sol deleted file mode 100644 index b5f32d0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/amb/LibAMBUpgradeable.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/amb/LibAMB.sol) - -pragma solidity ^0.8.4; - -import { IAMBUpgradeable as AMB_Bridge } from "../../vendor/amb/IAMBUpgradeable.sol"; -import "../errorsUpgradeable.sol"; - -/** - * @dev Primitives for cross-chain aware contracts using the - * https://docs.tokenbridge.net/amb-bridge/about-amb-bridge[AMB] - * family of bridges. - */ -library LibAMBUpgradeable { - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message relayed by `bridge`. - */ - function isCrossChain(address bridge) internal view returns (bool) { - return msg.sender == bridge; - } - - /** - * @dev Returns the address of the sender that triggered the current - * cross-chain message through `bridge`. - * - * NOTE: {isCrossChain} should be checked before trying to recover the - * sender, as it will revert with `NotCrossChainCall` if the current - * function call is not the result of a cross-chain message. - */ - function crossChainSender(address bridge) internal view returns (address) { - if (!isCrossChain(bridge)) revert NotCrossChainCall(); - return AMB_Bridge(bridge).messageSender(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1Upgradeable.sol deleted file mode 100644 index afbb030..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1Upgradeable.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabledUpgradeable.sol"; -import "./LibArbitrumL1Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev https://arbitrum.io/[Arbitrum] specialization or the - * {CrossChainEnabled} abstraction the L1 side (mainnet). - * - * This version should only be deployed on L1 to process cross-chain messages - * originating from L2. For the other side, use {CrossChainEnabledArbitrumL2}. - * - * The bridge contract is provided and maintained by the arbitrum team. You can - * find the address of this contract on the rinkeby testnet in - * https://developer.offchainlabs.com/docs/useful_addresses[Arbitrum's developer documentation]. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabledArbitrumL1Upgradeable is Initializable, CrossChainEnabledUpgradeable { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _bridge; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) { - _bridge = bridge; - } - - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return LibArbitrumL1Upgradeable.isCrossChain(_bridge); - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return LibArbitrumL1Upgradeable.crossChainSender(_bridge); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2Upgradeable.sol deleted file mode 100644 index 37ed840..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2Upgradeable.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabledUpgradeable.sol"; -import "./LibArbitrumL2Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev https://arbitrum.io/[Arbitrum] specialization or the - * {CrossChainEnabled} abstraction the L2 side (arbitrum). - * - * This version should only be deployed on L2 to process cross-chain messages - * originating from L1. For the other side, use {CrossChainEnabledArbitrumL1}. - * - * Arbitrum L2 includes the `ArbSys` contract at a fixed address. Therefore, - * this specialization of {CrossChainEnabled} does not include a constructor. - * - * _Available since v4.6._ - * - * WARNING: There is currently a bug in Arbitrum that causes this contract to - * fail to detect cross-chain calls when deployed behind a proxy. This will be - * fixed when the network is upgraded to Arbitrum Nitro, currently scheduled for - * August 31st 2022. - */ -abstract contract CrossChainEnabledArbitrumL2Upgradeable is Initializable, CrossChainEnabledUpgradeable { - function __CrossChainEnabledArbitrumL2_init() internal onlyInitializing { - } - - function __CrossChainEnabledArbitrumL2_init_unchained() internal onlyInitializing { - } - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return LibArbitrumL2Upgradeable.isCrossChain(LibArbitrumL2Upgradeable.ARBSYS); - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return LibArbitrumL2Upgradeable.crossChainSender(LibArbitrumL2Upgradeable.ARBSYS); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/LibArbitrumL1Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/LibArbitrumL1Upgradeable.sol deleted file mode 100644 index a15e58f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/LibArbitrumL1Upgradeable.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (crosschain/arbitrum/LibArbitrumL1.sol) - -pragma solidity ^0.8.4; - -import { IBridgeUpgradeable as ArbitrumL1_Bridge } from "../../vendor/arbitrum/IBridgeUpgradeable.sol"; -import { IOutboxUpgradeable as ArbitrumL1_Outbox } from "../../vendor/arbitrum/IOutboxUpgradeable.sol"; -import "../errorsUpgradeable.sol"; - -/** - * @dev Primitives for cross-chain aware contracts for - * https://arbitrum.io/[Arbitrum]. - * - * This version should only be used on L1 to process cross-chain messages - * originating from L2. For the other side, use {LibArbitrumL2}. - */ -library LibArbitrumL1Upgradeable { - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message relayed by the `bridge`. - */ - function isCrossChain(address bridge) internal view returns (bool) { - return msg.sender == bridge; - } - - /** - * @dev Returns the address of the sender that triggered the current - * cross-chain message through the `bridge`. - * - * NOTE: {isCrossChain} should be checked before trying to recover the - * sender, as it will revert with `NotCrossChainCall` if the current - * function call is not the result of a cross-chain message. - */ - function crossChainSender(address bridge) internal view returns (address) { - if (!isCrossChain(bridge)) revert NotCrossChainCall(); - - address sender = ArbitrumL1_Outbox(ArbitrumL1_Bridge(bridge).activeOutbox()).l2ToL1Sender(); - require(sender != address(0), "LibArbitrumL1: system messages without sender"); - - return sender; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/LibArbitrumL2Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/LibArbitrumL2Upgradeable.sol deleted file mode 100644 index 5d6ab61..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/arbitrum/LibArbitrumL2Upgradeable.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (crosschain/arbitrum/LibArbitrumL2.sol) - -pragma solidity ^0.8.4; - -import { IArbSysUpgradeable as ArbitrumL2_Bridge } from "../../vendor/arbitrum/IArbSysUpgradeable.sol"; -import "../errorsUpgradeable.sol"; - -/** - * @dev Primitives for cross-chain aware contracts for - * https://arbitrum.io/[Arbitrum]. - * - * This version should only be used on L2 to process cross-chain messages - * originating from L1. For the other side, use {LibArbitrumL1}. - * - * WARNING: There is currently a bug in Arbitrum that causes this contract to - * fail to detect cross-chain calls when deployed behind a proxy. This will be - * fixed when the network is upgraded to Arbitrum Nitro, currently scheduled for - * August 31st 2022. - */ -library LibArbitrumL2Upgradeable { - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message relayed by `arbsys`. - */ - address public constant ARBSYS = 0x0000000000000000000000000000000000000064; - - function isCrossChain(address arbsys) internal view returns (bool) { - return ArbitrumL2_Bridge(arbsys).wasMyCallersAddressAliased(); - } - - /** - * @dev Returns the address of the sender that triggered the current - * cross-chain message through `arbsys`. - * - * NOTE: {isCrossChain} should be checked before trying to recover the - * sender, as it will revert with `NotCrossChainCall` if the current - * function call is not the result of a cross-chain message. - */ - function crossChainSender(address arbsys) internal view returns (address) { - if (!isCrossChain(arbsys)) revert NotCrossChainCall(); - - return ArbitrumL2_Bridge(arbsys).myCallersAddressWithoutAliasing(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/errorsUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/errorsUpgradeable.sol deleted file mode 100644 index 004460e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/errorsUpgradeable.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/errors.sol) - -pragma solidity ^0.8.4; - -error NotCrossChainCall(); -error InvalidCrossChainSender(address actual, address expected); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/optimism/CrossChainEnabledOptimismUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/optimism/CrossChainEnabledOptimismUpgradeable.sol deleted file mode 100644 index f7fa973..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/optimism/CrossChainEnabledOptimismUpgradeable.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/CrossChainEnabledOptimism.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabledUpgradeable.sol"; -import "./LibOptimismUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev https://www.optimism.io/[Optimism] specialization or the - * {CrossChainEnabled} abstraction. - * - * The messenger (`CrossDomainMessenger`) contract is provided and maintained by - * the optimism team. You can find the address of this contract on mainnet and - * kovan in the https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/deployments[deployments section of Optimism monorepo]. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabledOptimismUpgradeable is Initializable, CrossChainEnabledUpgradeable { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _messenger; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address messenger) { - _messenger = messenger; - } - - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return LibOptimismUpgradeable.isCrossChain(_messenger); - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return LibOptimismUpgradeable.crossChainSender(_messenger); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/optimism/LibOptimismUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/optimism/LibOptimismUpgradeable.sol deleted file mode 100644 index b1260dd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/optimism/LibOptimismUpgradeable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/LibOptimism.sol) - -pragma solidity ^0.8.4; - -import { ICrossDomainMessengerUpgradeable as Optimism_Bridge } from "../../vendor/optimism/ICrossDomainMessengerUpgradeable.sol"; -import "../errorsUpgradeable.sol"; - -/** - * @dev Primitives for cross-chain aware contracts for https://www.optimism.io/[Optimism]. - * See the https://community.optimism.io/docs/developers/bridge/messaging/#accessing-msg-sender[documentation] - * for the functionality used here. - */ -library LibOptimismUpgradeable { - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message relayed by `messenger`. - */ - function isCrossChain(address messenger) internal view returns (bool) { - return msg.sender == messenger; - } - - /** - * @dev Returns the address of the sender that triggered the current - * cross-chain message through `messenger`. - * - * NOTE: {isCrossChain} should be checked before trying to recover the - * sender, as it will revert with `NotCrossChainCall` if the current - * function call is not the result of a cross-chain message. - */ - function crossChainSender(address messenger) internal view returns (address) { - if (!isCrossChain(messenger)) revert NotCrossChainCall(); - - return Optimism_Bridge(messenger).xDomainMessageSender(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/polygon/CrossChainEnabledPolygonChildUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/polygon/CrossChainEnabledPolygonChildUpgradeable.sol deleted file mode 100644 index 862e484..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/crosschain/polygon/CrossChainEnabledPolygonChildUpgradeable.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/polygon/CrossChainEnabledPolygonChild.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabledUpgradeable.sol"; -import "../../security/ReentrancyGuardUpgradeable.sol"; -import "../../utils/AddressUpgradeable.sol"; -import "../../vendor/polygon/IFxMessageProcessorUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -address constant DEFAULT_SENDER = 0x000000000000000000000000000000000000dEaD; - -/** - * @dev https://polygon.technology/[Polygon] specialization or the - * {CrossChainEnabled} abstraction the child side (polygon/mumbai). - * - * This version should only be deployed on child chain to process cross-chain - * messages originating from the parent chain. - * - * The fxChild contract is provided and maintained by the polygon team. You can - * find the address of this contract polygon and mumbai in - * https://docs.polygon.technology/docs/develop/l1-l2-communication/fx-portal/#contract-addresses[Polygon's Fx-Portal documentation]. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabledPolygonChildUpgradeable is Initializable, IFxMessageProcessorUpgradeable, CrossChainEnabledUpgradeable, ReentrancyGuardUpgradeable { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _fxChild; - address private _sender = DEFAULT_SENDER; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address fxChild) { - _fxChild = fxChild; - } - - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return msg.sender == _fxChild; - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return _sender; - } - - /** - * @dev External entry point to receive and relay messages originating - * from the fxChild. - * - * Non-reentrancy is crucial to avoid a cross-chain call being able - * to impersonate anyone by just looping through this with user-defined - * arguments. - * - * Note: if _fxChild calls any other function that does a delegate-call, - * then security could be compromised. - */ - function processMessageFromRoot( - uint256, /* stateId */ - address rootMessageSender, - bytes calldata data - ) external override nonReentrant { - if (!_isCrossChain()) revert NotCrossChainCall(); - - _sender = rootMessageSender; - __functionDelegateCall(address(this), data); - _sender = DEFAULT_SENDER; - } - - // ERC1967Upgrade._functionDelegateCall is private so we reproduce it here. - // An extra underscore prevents a name clash error. - function __functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { - require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); - - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory returndata) = target.delegatecall(data); - return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/PaymentSplitterUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/PaymentSplitterUpgradeable.sol deleted file mode 100644 index 5943c89..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/PaymentSplitterUpgradeable.sol +++ /dev/null @@ -1,226 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (finance/PaymentSplitter.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/utils/SafeERC20Upgradeable.sol"; -import "../utils/AddressUpgradeable.sol"; -import "../utils/ContextUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @title PaymentSplitter - * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware - * that the Ether will be split in this way, since it is handled transparently by the contract. - * - * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each - * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim - * an amount proportional to the percentage of total shares they were assigned. The distribution of shares is set at the - * time of contract deployment and can't be updated thereafter. - * - * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the - * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release} - * function. - * - * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and - * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you - * to run tests before sending real value to this contract. - */ -contract PaymentSplitterUpgradeable is Initializable, ContextUpgradeable { - event PayeeAdded(address account, uint256 shares); - event PaymentReleased(address to, uint256 amount); - event ERC20PaymentReleased(IERC20Upgradeable indexed token, address to, uint256 amount); - event PaymentReceived(address from, uint256 amount); - - uint256 private _totalShares; - uint256 private _totalReleased; - - mapping(address => uint256) private _shares; - mapping(address => uint256) private _released; - address[] private _payees; - - mapping(IERC20Upgradeable => uint256) private _erc20TotalReleased; - mapping(IERC20Upgradeable => mapping(address => uint256)) private _erc20Released; - - /** - * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at - * the matching position in the `shares` array. - * - * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no - * duplicates in `payees`. - */ - function __PaymentSplitter_init(address[] memory payees, uint256[] memory shares_) internal onlyInitializing { - __PaymentSplitter_init_unchained(payees, shares_); - } - - function __PaymentSplitter_init_unchained(address[] memory payees, uint256[] memory shares_) internal onlyInitializing { - require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch"); - require(payees.length > 0, "PaymentSplitter: no payees"); - - for (uint256 i = 0; i < payees.length; i++) { - _addPayee(payees[i], shares_[i]); - } - } - - /** - * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully - * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the - * reliability of the events, and not the actual splitting of Ether. - * - * To learn more about this see the Solidity documentation for - * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback - * functions]. - */ - receive() external payable virtual { - emit PaymentReceived(_msgSender(), msg.value); - } - - /** - * @dev Getter for the total shares held by payees. - */ - function totalShares() public view returns (uint256) { - return _totalShares; - } - - /** - * @dev Getter for the total amount of Ether already released. - */ - function totalReleased() public view returns (uint256) { - return _totalReleased; - } - - /** - * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20 - * contract. - */ - function totalReleased(IERC20Upgradeable token) public view returns (uint256) { - return _erc20TotalReleased[token]; - } - - /** - * @dev Getter for the amount of shares held by an account. - */ - function shares(address account) public view returns (uint256) { - return _shares[account]; - } - - /** - * @dev Getter for the amount of Ether already released to a payee. - */ - function released(address account) public view returns (uint256) { - return _released[account]; - } - - /** - * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an - * IERC20 contract. - */ - function released(IERC20Upgradeable token, address account) public view returns (uint256) { - return _erc20Released[token][account]; - } - - /** - * @dev Getter for the address of the payee number `index`. - */ - function payee(uint256 index) public view returns (address) { - return _payees[index]; - } - - /** - * @dev Getter for the amount of payee's releasable Ether. - */ - function releasable(address account) public view returns (uint256) { - uint256 totalReceived = address(this).balance + totalReleased(); - return _pendingPayment(account, totalReceived, released(account)); - } - - /** - * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an - * IERC20 contract. - */ - function releasable(IERC20Upgradeable token, address account) public view returns (uint256) { - uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token); - return _pendingPayment(account, totalReceived, released(token, account)); - } - - /** - * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the - * total shares and their previous withdrawals. - */ - function release(address payable account) public virtual { - require(_shares[account] > 0, "PaymentSplitter: account has no shares"); - - uint256 payment = releasable(account); - - require(payment != 0, "PaymentSplitter: account is not due payment"); - - // _totalReleased is the sum of all values in _released. - // If "_totalReleased += payment" does not overflow, then "_released[account] += payment" cannot overflow. - _totalReleased += payment; - unchecked { - _released[account] += payment; - } - - AddressUpgradeable.sendValue(account, payment); - emit PaymentReleased(account, payment); - } - - /** - * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their - * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20 - * contract. - */ - function release(IERC20Upgradeable token, address account) public virtual { - require(_shares[account] > 0, "PaymentSplitter: account has no shares"); - - uint256 payment = releasable(token, account); - - require(payment != 0, "PaymentSplitter: account is not due payment"); - - // _erc20TotalReleased[token] is the sum of all values in _erc20Released[token]. - // If "_erc20TotalReleased[token] += payment" does not overflow, then "_erc20Released[token][account] += payment" - // cannot overflow. - _erc20TotalReleased[token] += payment; - unchecked { - _erc20Released[token][account] += payment; - } - - SafeERC20Upgradeable.safeTransfer(token, account, payment); - emit ERC20PaymentReleased(token, account, payment); - } - - /** - * @dev internal logic for computing the pending payment of an `account` given the token historical balances and - * already released amounts. - */ - function _pendingPayment( - address account, - uint256 totalReceived, - uint256 alreadyReleased - ) private view returns (uint256) { - return (totalReceived * _shares[account]) / _totalShares - alreadyReleased; - } - - /** - * @dev Add a new payee to the contract. - * @param account The address of the payee to add. - * @param shares_ The number of shares owned by the payee. - */ - function _addPayee(address account, uint256 shares_) private { - require(account != address(0), "PaymentSplitter: account is the zero address"); - require(shares_ > 0, "PaymentSplitter: shares are 0"); - require(_shares[account] == 0, "PaymentSplitter: account already has shares"); - - _payees.push(account); - _shares[account] = shares_; - _totalShares = _totalShares + shares_; - emit PayeeAdded(account, shares_); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[43] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/README.adoc deleted file mode 100644 index b64af31..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/README.adoc +++ /dev/null @@ -1,20 +0,0 @@ -= Finance - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/finance - -This directory includes primitives for financial systems: - -- {PaymentSplitter} allows to split Ether and ERC20 payments among a group of accounts. The sender does not need to be - aware that the assets will be split in this way, since it is handled transparently by the contract. The split can be - in equal parts or in any other arbitrary proportion. - -- {VestingWallet} handles the vesting of Ether and ERC20 tokens for a given beneficiary. Custody of multiple tokens can - be given to this contract, which will release the token to the beneficiary following a given, customizable, vesting - schedule. - -== Contracts - -{{PaymentSplitter}} - -{{VestingWallet}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/VestingWalletUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/VestingWalletUpgradeable.sol deleted file mode 100644 index 5b35a21..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/finance/VestingWalletUpgradeable.sol +++ /dev/null @@ -1,167 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (finance/VestingWallet.sol) -pragma solidity ^0.8.0; - -import "../token/ERC20/utils/SafeERC20Upgradeable.sol"; -import "../utils/AddressUpgradeable.sol"; -import "../utils/ContextUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @title VestingWallet - * @dev This contract handles the vesting of Eth and ERC20 tokens for a given beneficiary. Custody of multiple tokens - * can be given to this contract, which will release the token to the beneficiary following a given vesting schedule. - * The vesting schedule is customizable through the {vestedAmount} function. - * - * Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning. - * Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly) - * be immediately releasable. - * - * @custom:storage-size 52 - */ -contract VestingWalletUpgradeable is Initializable, ContextUpgradeable { - event EtherReleased(uint256 amount); - event ERC20Released(address indexed token, uint256 amount); - - uint256 private _released; - mapping(address => uint256) private _erc20Released; - address private _beneficiary; - uint64 private _start; - uint64 private _duration; - - /** - * @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet. - */ - function __VestingWallet_init( - address beneficiaryAddress, - uint64 startTimestamp, - uint64 durationSeconds - ) internal onlyInitializing { - __VestingWallet_init_unchained(beneficiaryAddress, startTimestamp, durationSeconds); - } - - function __VestingWallet_init_unchained( - address beneficiaryAddress, - uint64 startTimestamp, - uint64 durationSeconds - ) internal onlyInitializing { - require(beneficiaryAddress != address(0), "VestingWallet: beneficiary is zero address"); - _beneficiary = beneficiaryAddress; - _start = startTimestamp; - _duration = durationSeconds; - } - - /** - * @dev The contract should be able to receive Eth. - */ - receive() external payable virtual {} - - /** - * @dev Getter for the beneficiary address. - */ - function beneficiary() public view virtual returns (address) { - return _beneficiary; - } - - /** - * @dev Getter for the start timestamp. - */ - function start() public view virtual returns (uint256) { - return _start; - } - - /** - * @dev Getter for the vesting duration. - */ - function duration() public view virtual returns (uint256) { - return _duration; - } - - /** - * @dev Amount of eth already released - */ - function released() public view virtual returns (uint256) { - return _released; - } - - /** - * @dev Amount of token already released - */ - function released(address token) public view virtual returns (uint256) { - return _erc20Released[token]; - } - - /** - * @dev Getter for the amount of releasable eth. - */ - function releasable() public view virtual returns (uint256) { - return vestedAmount(uint64(block.timestamp)) - released(); - } - - /** - * @dev Getter for the amount of releasable `token` tokens. `token` should be the address of an - * IERC20 contract. - */ - function releasable(address token) public view virtual returns (uint256) { - return vestedAmount(token, uint64(block.timestamp)) - released(token); - } - - /** - * @dev Release the native token (ether) that have already vested. - * - * Emits a {EtherReleased} event. - */ - function release() public virtual { - uint256 amount = releasable(); - _released += amount; - emit EtherReleased(amount); - AddressUpgradeable.sendValue(payable(beneficiary()), amount); - } - - /** - * @dev Release the tokens that have already vested. - * - * Emits a {ERC20Released} event. - */ - function release(address token) public virtual { - uint256 amount = releasable(token); - _erc20Released[token] += amount; - emit ERC20Released(token, amount); - SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(token), beneficiary(), amount); - } - - /** - * @dev Calculates the amount of ether that has already vested. Default implementation is a linear vesting curve. - */ - function vestedAmount(uint64 timestamp) public view virtual returns (uint256) { - return _vestingSchedule(address(this).balance + released(), timestamp); - } - - /** - * @dev Calculates the amount of tokens that has already vested. Default implementation is a linear vesting curve. - */ - function vestedAmount(address token, uint64 timestamp) public view virtual returns (uint256) { - return _vestingSchedule(IERC20Upgradeable(token).balanceOf(address(this)) + released(token), timestamp); - } - - /** - * @dev Virtual implementation of the vesting formula. This returns the amount vested, as a function of time, for - * an asset given its total historical allocation. - */ - function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256) { - if (timestamp < start()) { - return 0; - } else if (timestamp > start() + duration()) { - return totalAllocation; - } else { - return (totalAllocation * (timestamp - start())) / duration(); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/GovernorUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/GovernorUpgradeable.sol deleted file mode 100644 index 993740f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/GovernorUpgradeable.sol +++ /dev/null @@ -1,610 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (governance/Governor.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/IERC721ReceiverUpgradeable.sol"; -import "../token/ERC1155/IERC1155ReceiverUpgradeable.sol"; -import "../utils/cryptography/ECDSAUpgradeable.sol"; -import "../utils/cryptography/EIP712Upgradeable.sol"; -import "../utils/introspection/ERC165Upgradeable.sol"; -import "../utils/math/SafeCastUpgradeable.sol"; -import "../utils/structs/DoubleEndedQueueUpgradeable.sol"; -import "../utils/AddressUpgradeable.sol"; -import "../utils/ContextUpgradeable.sol"; -import "../utils/TimersUpgradeable.sol"; -import "./IGovernorUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Core of the governance system, designed to be extended though various modules. - * - * This contract is abstract and requires several function to be implemented in various modules: - * - * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} - * - A voting module must implement {_getVotes} - * - Additionanly, the {votingPeriod} must also be implemented - * - * _Available since v4.3._ - */ -abstract contract GovernorUpgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, EIP712Upgradeable, IGovernorUpgradeable, IERC721ReceiverUpgradeable, IERC1155ReceiverUpgradeable { - using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque; - using SafeCastUpgradeable for uint256; - using TimersUpgradeable for TimersUpgradeable.BlockNumber; - - bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); - bytes32 public constant EXTENDED_BALLOT_TYPEHASH = - keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); - - struct ProposalCore { - TimersUpgradeable.BlockNumber voteStart; - TimersUpgradeable.BlockNumber voteEnd; - bool executed; - bool canceled; - } - - string private _name; - - mapping(uint256 => ProposalCore) private _proposals; - - // This queue keeps track of the governor operating on itself. Calls to functions protected by the - // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, - // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the - // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. - DoubleEndedQueueUpgradeable.Bytes32Deque private _governanceCall; - - /** - * @dev Restricts a function so it can only be executed through governance proposals. For example, governance - * parameter setters in {GovernorSettings} are protected using this modifier. - * - * The governance executing address may be different from the Governor's own address, for example it could be a - * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these - * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, - * for example, additional timelock proposers are not able to change governance parameters without going through the - * governance protocol (since v4.6). - */ - modifier onlyGovernance() { - require(_msgSender() == _executor(), "Governor: onlyGovernance"); - if (_executor() != address(this)) { - bytes32 msgDataHash = keccak256(_msgData()); - // loop until popping the expected operation - throw if deque is empty (operation not authorized) - while (_governanceCall.popFront() != msgDataHash) {} - } - _; - } - - /** - * @dev Sets the value for {name} and {version} - */ - function __Governor_init(string memory name_) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - } - - function __Governor_init_unchained(string memory name_) internal onlyInitializing { - _name = name_; - } - - /** - * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) - */ - receive() external payable virtual { - require(_executor() == address(this)); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) { - // In addition to the current interfaceId, also support previous version of the interfaceId that did not - // include the castVoteWithReasonAndParams() function as standard - return - interfaceId == - (type(IGovernorUpgradeable).interfaceId ^ - this.castVoteWithReasonAndParams.selector ^ - this.castVoteWithReasonAndParamsBySig.selector ^ - this.getVotesWithParams.selector) || - interfaceId == type(IGovernorUpgradeable).interfaceId || - interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @dev See {IGovernor-name}. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev See {IGovernor-version}. - */ - function version() public view virtual override returns (string memory) { - return "1"; - } - - /** - * @dev See {IGovernor-hashProposal}. - * - * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array - * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id - * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in - * advance, before the proposal is submitted. - * - * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the - * same proposal (with same operation and same description) will have the same id if submitted on multiple governors - * across multiple networks. This also means that in order to execute the same operation twice (on the same - * governor) the proposer will have to change the description in order to avoid proposal id conflicts. - */ - function hashProposal( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public pure virtual override returns (uint256) { - return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); - } - - /** - * @dev See {IGovernor-state}. - */ - function state(uint256 proposalId) public view virtual override returns (ProposalState) { - ProposalCore storage proposal = _proposals[proposalId]; - - if (proposal.executed) { - return ProposalState.Executed; - } - - if (proposal.canceled) { - return ProposalState.Canceled; - } - - uint256 snapshot = proposalSnapshot(proposalId); - - if (snapshot == 0) { - revert("Governor: unknown proposal id"); - } - - if (snapshot >= block.number) { - return ProposalState.Pending; - } - - uint256 deadline = proposalDeadline(proposalId); - - if (deadline >= block.number) { - return ProposalState.Active; - } - - if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { - return ProposalState.Succeeded; - } else { - return ProposalState.Defeated; - } - } - - /** - * @dev See {IGovernor-proposalSnapshot}. - */ - function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { - return _proposals[proposalId].voteStart.getDeadline(); - } - - /** - * @dev See {IGovernor-proposalDeadline}. - */ - function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { - return _proposals[proposalId].voteEnd.getDeadline(); - } - - /** - * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. - */ - function proposalThreshold() public view virtual returns (uint256) { - return 0; - } - - /** - * @dev Amount of votes already cast passes the threshold limit. - */ - function _quorumReached(uint256 proposalId) internal view virtual returns (bool); - - /** - * @dev Is the proposal successful or not. - */ - function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); - - /** - * @dev Get the voting weight of `account` at a specific `blockNumber`, for a vote as described by `params`. - */ - function _getVotes( - address account, - uint256 blockNumber, - bytes memory params - ) internal view virtual returns (uint256); - - /** - * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. - * - * Note: Support is generic and can represent various things depending on the voting system used. - */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory params - ) internal virtual; - - /** - * @dev Default additional encoded parameters used by castVote methods that don't include them - * - * Note: Should be overridden by specific implementations to use an appropriate value, the - * meaning of the additional params, in the context of that implementation - */ - function _defaultParams() internal view virtual returns (bytes memory) { - return ""; - } - - /** - * @dev See {IGovernor-propose}. - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override returns (uint256) { - require( - getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), - "Governor: proposer votes below proposal threshold" - ); - - uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - require(targets.length == values.length, "Governor: invalid proposal length"); - require(targets.length == calldatas.length, "Governor: invalid proposal length"); - require(targets.length > 0, "Governor: empty proposal"); - - ProposalCore storage proposal = _proposals[proposalId]; - require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); - - uint64 snapshot = block.number.toUint64() + votingDelay().toUint64(); - uint64 deadline = snapshot + votingPeriod().toUint64(); - - proposal.voteStart.setDeadline(snapshot); - proposal.voteEnd.setDeadline(deadline); - - emit ProposalCreated( - proposalId, - _msgSender(), - targets, - values, - new string[](targets.length), - calldatas, - snapshot, - deadline, - description - ); - - return proposalId; - } - - /** - * @dev See {IGovernor-execute}. - */ - function execute( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public payable virtual override returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - ProposalState status = state(proposalId); - require( - status == ProposalState.Succeeded || status == ProposalState.Queued, - "Governor: proposal not successful" - ); - _proposals[proposalId].executed = true; - - emit ProposalExecuted(proposalId); - - _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); - _execute(proposalId, targets, values, calldatas, descriptionHash); - _afterExecute(proposalId, targets, values, calldatas, descriptionHash); - - return proposalId; - } - - /** - * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism - */ - function _execute( - uint256, /* proposalId */ - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual { - string memory errorMessage = "Governor: call reverted without message"; - for (uint256 i = 0; i < targets.length; ++i) { - (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); - AddressUpgradeable.verifyCallResult(success, returndata, errorMessage); - } - } - - /** - * @dev Hook before execution is triggered. - */ - function _beforeExecute( - uint256, /* proposalId */ - address[] memory targets, - uint256[] memory, /* values */ - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual { - if (_executor() != address(this)) { - for (uint256 i = 0; i < targets.length; ++i) { - if (targets[i] == address(this)) { - _governanceCall.pushBack(keccak256(calldatas[i])); - } - } - } - } - - /** - * @dev Hook after execution is triggered. - */ - function _afterExecute( - uint256, /* proposalId */ - address[] memory, /* targets */ - uint256[] memory, /* values */ - bytes[] memory, /* calldatas */ - bytes32 /*descriptionHash*/ - ) internal virtual { - if (_executor() != address(this)) { - if (!_governanceCall.empty()) { - _governanceCall.clear(); - } - } - } - - /** - * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as - * canceled to allow distinguishing it from executed proposals. - * - * Emits a {IGovernor-ProposalCanceled} event. - */ - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - ProposalState status = state(proposalId); - - require( - status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed, - "Governor: proposal not active" - ); - _proposals[proposalId].canceled = true; - - emit ProposalCanceled(proposalId); - - return proposalId; - } - - /** - * @dev See {IGovernor-getVotes}. - */ - function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { - return _getVotes(account, blockNumber, _defaultParams()); - } - - /** - * @dev See {IGovernor-getVotesWithParams}. - */ - function getVotesWithParams( - address account, - uint256 blockNumber, - bytes memory params - ) public view virtual override returns (uint256) { - return _getVotes(account, blockNumber, params); - } - - /** - * @dev See {IGovernor-castVote}. - */ - function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, ""); - } - - /** - * @dev See {IGovernor-castVoteWithReason}. - */ - function castVoteWithReason( - uint256 proposalId, - uint8 support, - string calldata reason - ) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, reason); - } - - /** - * @dev See {IGovernor-castVoteWithReasonAndParams}. - */ - function castVoteWithReasonAndParams( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params - ) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, reason, params); - } - - /** - * @dev See {IGovernor-castVoteBySig}. - */ - function castVoteBySig( - uint256 proposalId, - uint8 support, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override returns (uint256) { - address voter = ECDSAUpgradeable.recover( - _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), - v, - r, - s - ); - return _castVote(proposalId, voter, support, ""); - } - - /** - * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. - */ - function castVoteWithReasonAndParamsBySig( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override returns (uint256) { - address voter = ECDSAUpgradeable.recover( - _hashTypedDataV4( - keccak256( - abi.encode( - EXTENDED_BALLOT_TYPEHASH, - proposalId, - support, - keccak256(bytes(reason)), - keccak256(params) - ) - ) - ), - v, - r, - s - ); - - return _castVote(proposalId, voter, support, reason, params); - } - - /** - * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve - * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). - * - * Emits a {IGovernor-VoteCast} event. - */ - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason - ) internal virtual returns (uint256) { - return _castVote(proposalId, account, support, reason, _defaultParams()); - } - - /** - * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve - * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. - * - * Emits a {IGovernor-VoteCast} event. - */ - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal virtual returns (uint256) { - ProposalCore storage proposal = _proposals[proposalId]; - require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); - - uint256 weight = _getVotes(account, proposal.voteStart.getDeadline(), params); - _countVote(proposalId, account, support, weight, params); - - if (params.length == 0) { - emit VoteCast(account, proposalId, support, weight, reason); - } else { - emit VoteCastWithParams(account, proposalId, support, weight, reason, params); - } - - return weight; - } - - /** - * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor - * is some contract other than the governor itself, like when using a timelock, this function can be invoked - * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. - * Note that if the executor is simply the governor itself, use of `relay` is redundant. - */ - function relay( - address target, - uint256 value, - bytes calldata data - ) external payable virtual onlyGovernance { - (bool success, bytes memory returndata) = target.call{value: value}(data); - AddressUpgradeable.verifyCallResult(success, returndata, "Governor: relay reverted without message"); - } - - /** - * @dev Address through which the governor executes action. Will be overloaded by module that execute actions - * through another contract such as a timelock. - */ - function _executor() internal view virtual returns (address) { - return address(this); - } - - /** - * @dev See {IERC721Receiver-onERC721Received}. - */ - function onERC721Received( - address, - address, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC721Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155Received}. - */ - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155BatchReceived}. - */ - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[46] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/IGovernorUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/IGovernorUpgradeable.sol deleted file mode 100644 index 5ee40b4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/IGovernorUpgradeable.sol +++ /dev/null @@ -1,289 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (governance/IGovernor.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Interface of the {Governor} core. - * - * _Available since v4.3._ - */ -abstract contract IGovernorUpgradeable is Initializable, IERC165Upgradeable { - function __IGovernor_init() internal onlyInitializing { - } - - function __IGovernor_init_unchained() internal onlyInitializing { - } - enum ProposalState { - Pending, - Active, - Canceled, - Defeated, - Succeeded, - Queued, - Expired, - Executed - } - - /** - * @dev Emitted when a proposal is created. - */ - event ProposalCreated( - uint256 proposalId, - address proposer, - address[] targets, - uint256[] values, - string[] signatures, - bytes[] calldatas, - uint256 startBlock, - uint256 endBlock, - string description - ); - - /** - * @dev Emitted when a proposal is canceled. - */ - event ProposalCanceled(uint256 proposalId); - - /** - * @dev Emitted when a proposal is executed. - */ - event ProposalExecuted(uint256 proposalId); - - /** - * @dev Emitted when a vote is cast without params. - * - * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. - */ - event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); - - /** - * @dev Emitted when a vote is cast with params. - * - * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. - * `params` are additional encoded parameters. Their intepepretation also depends on the voting module used. - */ - event VoteCastWithParams( - address indexed voter, - uint256 proposalId, - uint8 support, - uint256 weight, - string reason, - bytes params - ); - - /** - * @notice module:core - * @dev Name of the governor instance (used in building the ERC712 domain separator). - */ - function name() public view virtual returns (string memory); - - /** - * @notice module:core - * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1" - */ - function version() public view virtual returns (string memory); - - /** - * @notice module:voting - * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to - * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of - * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`. - * - * There are 2 standard keys: `support` and `quorum`. - * - * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`. - * - `quorum=bravo` means that only For votes are counted towards quorum. - * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum. - * - * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique - * name that describes the behavior. For example: - * - * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain. - * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote. - * - * NOTE: The string can be decoded by the standard - * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`] - * JavaScript class. - */ - // solhint-disable-next-line func-name-mixedcase - function COUNTING_MODE() public pure virtual returns (string memory); - - /** - * @notice module:core - * @dev Hashing function used to (re)build the proposal id from the proposal details.. - */ - function hashProposal( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public pure virtual returns (uint256); - - /** - * @notice module:core - * @dev Current state of a proposal, following Compound's convention - */ - function state(uint256 proposalId) public view virtual returns (ProposalState); - - /** - * @notice module:core - * @dev Block number used to retrieve user's votes and quorum. As per Compound's Comp and OpenZeppelin's - * ERC20Votes, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the - * beginning of the following block. - */ - function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256); - - /** - * @notice module:core - * @dev Block number at which votes close. Votes close at the end of this block, so it is possible to cast a vote - * during this block. - */ - function proposalDeadline(uint256 proposalId) public view virtual returns (uint256); - - /** - * @notice module:user-config - * @dev Delay, in number of block, between the proposal is created and the vote starts. This can be increassed to - * leave time for users to buy voting power, or delegate it, before the voting of a proposal starts. - */ - function votingDelay() public view virtual returns (uint256); - - /** - * @notice module:user-config - * @dev Delay, in number of blocks, between the vote start and vote ends. - * - * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting - * duration compared to the voting delay. - */ - function votingPeriod() public view virtual returns (uint256); - - /** - * @notice module:user-config - * @dev Minimum number of cast voted required for a proposal to be successful. - * - * Note: The `blockNumber` parameter corresponds to the snapshot used for counting vote. This allows to scale the - * quorum depending on values such as the totalSupply of a token at this block (see {ERC20Votes}). - */ - function quorum(uint256 blockNumber) public view virtual returns (uint256); - - /** - * @notice module:reputation - * @dev Voting power of an `account` at a specific `blockNumber`. - * - * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or - * multiple), {ERC20Votes} tokens. - */ - function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256); - - /** - * @notice module:reputation - * @dev Voting power of an `account` at a specific `blockNumber` given additional encoded parameters. - */ - function getVotesWithParams( - address account, - uint256 blockNumber, - bytes memory params - ) public view virtual returns (uint256); - - /** - * @notice module:voting - * @dev Returns whether `account` has cast a vote on `proposalId`. - */ - function hasVoted(uint256 proposalId, address account) public view virtual returns (bool); - - /** - * @dev Create a new proposal. Vote start {IGovernor-votingDelay} blocks after the proposal is created and ends - * {IGovernor-votingPeriod} blocks after the voting starts. - * - * Emits a {ProposalCreated} event. - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual returns (uint256 proposalId); - - /** - * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the - * deadline to be reached. - * - * Emits a {ProposalExecuted} event. - * - * Note: some module can modify the requirements for execution, for example by adding an additional timelock. - */ - function execute( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public payable virtual returns (uint256 proposalId); - - /** - * @dev Cast a vote - * - * Emits a {VoteCast} event. - */ - function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance); - - /** - * @dev Cast a vote with a reason - * - * Emits a {VoteCast} event. - */ - function castVoteWithReason( - uint256 proposalId, - uint8 support, - string calldata reason - ) public virtual returns (uint256 balance); - - /** - * @dev Cast a vote with a reason and additional encoded parameters - * - * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. - */ - function castVoteWithReasonAndParams( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params - ) public virtual returns (uint256 balance); - - /** - * @dev Cast a vote using the user's cryptographic signature. - * - * Emits a {VoteCast} event. - */ - function castVoteBySig( - uint256 proposalId, - uint8 support, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual returns (uint256 balance); - - /** - * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature. - * - * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. - */ - function castVoteWithReasonAndParamsBySig( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual returns (uint256 balance); - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/README.adoc deleted file mode 100644 index f711c63..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/README.adoc +++ /dev/null @@ -1,176 +0,0 @@ -= Governance - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/governance - -This directory includes primitives for on-chain governance. - -== Governor - -This modular system of Governor contracts allows the deployment on-chain voting protocols similar to https://compound.finance/docs/governance[Compound's Governor Alpha & Bravo] and beyond, through the ability to easily customize multiple aspects of the protocol. - -[TIP] -==== -For a guided experience, set up your Governor contract using https://wizard.openzeppelin.com/#governor[Contracts Wizard]. - -For a written walkthrough, check out our guide on xref:ROOT:governance.adoc[How to set up on-chain governance]. -==== - -* {Governor}: The core contract that contains all the logic and primitives. It is abstract and requires choosing one of each of the modules below, or custom ones. - -Votes modules determine the source of voting power, and sometimes quorum number. - -* {GovernorVotes}: Extracts voting weight from an {ERC20Votes} token. - -* {GovernorVotesComp}: Extracts voting weight from a COMP-like or {ERC20VotesComp} token. - -* {GovernorVotesQuorumFraction}: Combines with `GovernorVotes` to set the quorum as a fraction of the total token supply. - -Counting modules determine valid voting options. - -* {GovernorCountingSimple}: Simple voting mechanism with 3 voting options: Against, For and Abstain. - -Timelock extensions add a delay for governance decisions to be executed. The workflow is extended to require a `queue` step before execution. With these modules, proposals are executed by the external timelock contract, thus it is the timelock that has to hold the assets that are being governed. - -* {GovernorTimelockControl}: Connects with an instance of {TimelockController}. Allows multiple proposers and executors, in addition to the Governor itself. - -* {GovernorTimelockCompound}: Connects with an instance of Compound's https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[`Timelock`] contract. - -Other extensions can customize the behavior or interface in multiple ways. - -* {GovernorCompatibilityBravo}: Extends the interface to be fully `GovernorBravo`-compatible. Note that events are compatible regardless of whether this extension is included or not. - -* {GovernorSettings}: Manages some of the settings (voting delay, voting period duration, and proposal threshold) in a way that can be updated through a governance proposal, without requiring an upgrade. - -* {GovernorPreventLateQuorum}: Ensures there is a minimum voting period after quorum is reached as a security protection against large voters. - -In addition to modules and extensions, the core contract requires a few virtual functions to be implemented to your particular specifications: - -* <>: Delay (in number of blocks) since the proposal is submitted until voting power is fixed and voting starts. This can be used to enforce a delay after a proposal is published for users to buy tokens, or delegate their votes. -* <>: Delay (in number of blocks) since the proposal starts until voting ends. -* <>: Quorum required for a proposal to be successful. This function includes a `blockNumber` argument so the quorum can adapt through time, for example, to follow a token's `totalSupply`. - -NOTE: Functions of the `Governor` contract do not include access control. If you want to restrict access, you should add these checks by overloading the particular functions. Among these, {Governor-_cancel} is internal by default, and you will have to expose it (with the right access control mechanism) yourself if this function is needed. - -=== Core - -{{IGovernor}} - -{{Governor}} - -=== Modules - -{{GovernorCountingSimple}} - -{{GovernorVotes}} - -{{GovernorVotesQuorumFraction}} - -{{GovernorVotesComp}} - -=== Extensions - -{{GovernorTimelockControl}} - -{{GovernorTimelockCompound}} - -{{GovernorSettings}} - -{{GovernorPreventLateQuorum}} - -{{GovernorCompatibilityBravo}} - -=== Deprecated - -{{GovernorProposalThreshold}} - -== Utils - -{{Votes}} - -== Timelock - -In a governance system, the {TimelockController} contract is in charge of introducing a delay between a proposal and its execution. It can be used with or without a {Governor}. - -{{TimelockController}} - -[[timelock-terminology]] -==== Terminology - -* *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see xref:access-control.adoc#operation_lifecycle[operation lifecycle]). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content. -* *Operation status:* -** *Unset:* An operation that is not part of the timelock mechanism. -** *Pending:* An operation that has been scheduled, before the timer expires. -** *Ready:* An operation that has been scheduled, after the timer expires. -** *Done:* An operation that has been executed. -* *Predecessor*: An (optional) dependency between operations. An operation can depend on another operation (its predecessor), forcing the execution order of these two operations. -* *Role*: -** *Admin:* An address (smart contract or EOA) that is in charge of granting the roles of Proposer and Executor. -** *Proposer:* An address (smart contract or EOA) that is in charge of scheduling (and cancelling) operations. -** *Executor:* An address (smart contract or EOA) that is in charge of executing operations once the timelock has expired. This role can be given to the zero address to allow anyone to execute operations. - -[[timelock-operation]] -==== Operation structure - -Operation executed by the xref:api:governance.adoc#TimelockController[`TimelockController`] can contain one or multiple subsequent calls. Depending on whether you need to multiple calls to be executed atomically, you can either use simple or batched operations. - -Both operations contain: - -* *Target*, the address of the smart contract that the timelock should operate on. -* *Value*, in wei, that should be sent with the transaction. Most of the time this will be 0. Ether can be deposited before-end or passed along when executing the transaction. -* *Data*, containing the encoded function selector and parameters of the call. This can be produced using a number of tools. For example, a maintenance operation granting role `ROLE` to `ACCOUNT` can be encoded using web3js as follows: - -```javascript -const data = timelock.contract.methods.grantRole(ROLE, ACCOUNT).encodeABI() -``` - -* *Predecessor*, that specifies a dependency between operations. This dependency is optional. Use `bytes32(0)` if the operation does not have any dependency. -* *Salt*, used to disambiguate two otherwise identical operations. This can be any random value. - -In the case of batched operations, `target`, `value` and `data` are specified as arrays, which must be of the same length. - -[[timelock-operation-lifecycle]] -==== Operation lifecycle - -Timelocked operations are identified by a unique id (their hash) and follow a specific lifecycle: - -`Unset` -> `Pending` -> `Pending` + `Ready` -> `Done` - -* By calling xref:api:governance.adoc#TimelockController-schedule-address-uint256-bytes-bytes32-bytes32-uint256-[`schedule`] (or xref:api:governance.adoc#TimelockController-scheduleBatch-address---uint256---bytes---bytes32-bytes32-uint256-[`scheduleBatch`]), a proposer moves the operation from the `Unset` to the `Pending` state. This starts a timer that must be longer than the minimum delay. The timer expires at a timestamp accessible through the xref:api:governance.adoc#TimelockController-getTimestamp-bytes32-[`getTimestamp`] method. -* Once the timer expires, the operation automatically gets the `Ready` state. At this point, it can be executed. -* By calling xref:api:governance.adoc#TimelockController-TimelockController-execute-address-uint256-bytes-bytes32-bytes32-[`execute`] (or xref:api:governance.adoc#TimelockController-executeBatch-address---uint256---bytes---bytes32-bytes32-[`executeBatch`]), an executor triggers the operation's underlying transactions and moves it to the `Done` state. If the operation has a predecessor, it has to be in the `Done` state for this transition to succeed. -* xref:api:governance.adoc#TimelockController-TimelockController-cancel-bytes32-[`cancel`] allows proposers to cancel any `Pending` operation. This resets the operation to the `Unset` state. It is thus possible for a proposer to re-schedule an operation that has been cancelled. In this case, the timer restarts when the operation is re-scheduled. - -Operations status can be queried using the functions: - -* xref:api:governance.adoc#TimelockController-isOperationPending-bytes32-[`isOperationPending(bytes32)`] -* xref:api:governance.adoc#TimelockController-isOperationReady-bytes32-[`isOperationReady(bytes32)`] -* xref:api:governance.adoc#TimelockController-isOperationDone-bytes32-[`isOperationDone(bytes32)`] - -[[timelock-roles]] -==== Roles - -[[timelock-admin]] -===== Admin - -The admins are in charge of managing proposers and executors. For the timelock to be self-governed, this role should only be given to the timelock itself. Upon deployment, the admin role can be granted to any address (in addition to the timelock itself). After further configuration and testing, this optional admin should renounce its role such that all further maintenance operations have to go through the timelock process. - -This role is identified by the *TIMELOCK_ADMIN_ROLE* value: `0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5` - -[[timelock-proposer]] -===== Proposer - -The proposers are in charge of scheduling (and cancelling) operations. This is a critical role, that should be given to governing entities. This could be an EOA, a multisig, or a DAO. - -WARNING: *Proposer fight:* Having multiple proposers, while providing redundancy in case one becomes unavailable, can be dangerous. As proposer have their say on all operations, they could cancel operations they disagree with, including operations to remove them for the proposers. - -This role is identified by the *PROPOSER_ROLE* value: `0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1` - -[[timelock-executor]] -===== Executor - -The executors are in charge of executing the operations scheduled by the proposers once the timelock expires. Logic dictates that multisig or DAO that are proposers should also be executors in order to guarantee operations that have been scheduled will eventually be executed. However, having additional executors can reduce the cost (the executing transaction does not require validation by the multisig or DAO that proposed it), while ensuring whoever is in charge of execution cannot trigger actions that have not been scheduled by the proposers. Alternatively, it is possible to allow _any_ address to execute a proposal once the timelock has expired by granting the executor role to the zero address. - -This role is identified by the *EXECUTOR_ROLE* value: `0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63` - -WARNING: A live contract without at least one proposer and one executor is locked. Make sure these roles are filled by reliable entities before the deployer renounces its administrative rights in favour of the timelock contract itself. See the {AccessControl} documentation to learn more about role management. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerUpgradeable.sol deleted file mode 100644 index 4c27eff..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerUpgradeable.sol +++ /dev/null @@ -1,443 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.2) (governance/TimelockController.sol) - -pragma solidity ^0.8.0; - -import "../access/AccessControlUpgradeable.sol"; -import "../token/ERC721/IERC721ReceiverUpgradeable.sol"; -import "../token/ERC1155/IERC1155ReceiverUpgradeable.sol"; -import "../utils/AddressUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Contract module which acts as a timelocked controller. When set as the - * owner of an `Ownable` smart contract, it enforces a timelock on all - * `onlyOwner` maintenance operations. This gives time for users of the - * controlled contract to exit before a potentially dangerous maintenance - * operation is applied. - * - * By default, this contract is self administered, meaning administration tasks - * have to go through the timelock process. The proposer (resp executor) role - * is in charge of proposing (resp executing) operations. A common use case is - * to position this {TimelockController} as the owner of a smart contract, with - * a multisig or a DAO as the sole proposer. - * - * _Available since v3.3._ - */ -contract TimelockControllerUpgradeable is Initializable, AccessControlUpgradeable, IERC721ReceiverUpgradeable, IERC1155ReceiverUpgradeable { - bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE"); - bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); - bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); - bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE"); - uint256 internal constant _DONE_TIMESTAMP = uint256(1); - - mapping(bytes32 => uint256) private _timestamps; - uint256 private _minDelay; - - /** - * @dev Emitted when a call is scheduled as part of operation `id`. - */ - event CallScheduled( - bytes32 indexed id, - uint256 indexed index, - address target, - uint256 value, - bytes data, - bytes32 predecessor, - uint256 delay - ); - - /** - * @dev Emitted when a call is performed as part of operation `id`. - */ - event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data); - - /** - * @dev Emitted when operation `id` is cancelled. - */ - event Cancelled(bytes32 indexed id); - - /** - * @dev Emitted when the minimum delay for future operations is modified. - */ - event MinDelayChange(uint256 oldDuration, uint256 newDuration); - - /** - * @dev Initializes the contract with the following parameters: - * - * - `minDelay`: initial minimum delay for operations - * - `proposers`: accounts to be granted proposer and canceller roles - * - `executors`: accounts to be granted executor role - * - `admin`: optional account to be granted admin role; disable with zero address - * - * IMPORTANT: The optional admin can aid with initial configuration of roles after deployment - * without being subject to delay, but this role should be subsequently renounced in favor of - * administration through timelocked proposals. Previous versions of this contract would assign - * this admin to the deployer automatically and should be renounced as well. - */ - function __TimelockController_init( - uint256 minDelay, - address[] memory proposers, - address[] memory executors, - address admin - ) internal onlyInitializing { - __TimelockController_init_unchained(minDelay, proposers, executors, admin); - } - - function __TimelockController_init_unchained( - uint256 minDelay, - address[] memory proposers, - address[] memory executors, - address admin - ) internal onlyInitializing { - _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE); - _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE); - _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE); - _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE); - - // self administration - _setupRole(TIMELOCK_ADMIN_ROLE, address(this)); - - // optional admin - if (admin != address(0)) { - _setupRole(TIMELOCK_ADMIN_ROLE, admin); - } - - // register proposers and cancellers - for (uint256 i = 0; i < proposers.length; ++i) { - _setupRole(PROPOSER_ROLE, proposers[i]); - _setupRole(CANCELLER_ROLE, proposers[i]); - } - - // register executors - for (uint256 i = 0; i < executors.length; ++i) { - _setupRole(EXECUTOR_ROLE, executors[i]); - } - - _minDelay = minDelay; - emit MinDelayChange(0, minDelay); - } - - /** - * @dev Modifier to make a function callable only by a certain role. In - * addition to checking the sender's role, `address(0)` 's role is also - * considered. Granting a role to `address(0)` is equivalent to enabling - * this role for everyone. - */ - modifier onlyRoleOrOpenRole(bytes32 role) { - if (!hasRole(role, address(0))) { - _checkRole(role, _msgSender()); - } - _; - } - - /** - * @dev Contract might receive/hold ETH as part of the maintenance process. - */ - receive() external payable {} - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, AccessControlUpgradeable) returns (bool) { - return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Returns whether an id correspond to a registered operation. This - * includes both Pending, Ready and Done operations. - */ - function isOperation(bytes32 id) public view virtual returns (bool registered) { - return getTimestamp(id) > 0; - } - - /** - * @dev Returns whether an operation is pending or not. - */ - function isOperationPending(bytes32 id) public view virtual returns (bool pending) { - return getTimestamp(id) > _DONE_TIMESTAMP; - } - - /** - * @dev Returns whether an operation is ready or not. - */ - function isOperationReady(bytes32 id) public view virtual returns (bool ready) { - uint256 timestamp = getTimestamp(id); - return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp; - } - - /** - * @dev Returns whether an operation is done or not. - */ - function isOperationDone(bytes32 id) public view virtual returns (bool done) { - return getTimestamp(id) == _DONE_TIMESTAMP; - } - - /** - * @dev Returns the timestamp at with an operation becomes ready (0 for - * unset operations, 1 for done operations). - */ - function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) { - return _timestamps[id]; - } - - /** - * @dev Returns the minimum delay for an operation to become valid. - * - * This value can be changed by executing an operation that calls `updateDelay`. - */ - function getMinDelay() public view virtual returns (uint256 duration) { - return _minDelay; - } - - /** - * @dev Returns the identifier of an operation containing a single - * transaction. - */ - function hashOperation( - address target, - uint256 value, - bytes calldata data, - bytes32 predecessor, - bytes32 salt - ) public pure virtual returns (bytes32 hash) { - return keccak256(abi.encode(target, value, data, predecessor, salt)); - } - - /** - * @dev Returns the identifier of an operation containing a batch of - * transactions. - */ - function hashOperationBatch( - address[] calldata targets, - uint256[] calldata values, - bytes[] calldata payloads, - bytes32 predecessor, - bytes32 salt - ) public pure virtual returns (bytes32 hash) { - return keccak256(abi.encode(targets, values, payloads, predecessor, salt)); - } - - /** - * @dev Schedule an operation containing a single transaction. - * - * Emits a {CallScheduled} event. - * - * Requirements: - * - * - the caller must have the 'proposer' role. - */ - function schedule( - address target, - uint256 value, - bytes calldata data, - bytes32 predecessor, - bytes32 salt, - uint256 delay - ) public virtual onlyRole(PROPOSER_ROLE) { - bytes32 id = hashOperation(target, value, data, predecessor, salt); - _schedule(id, delay); - emit CallScheduled(id, 0, target, value, data, predecessor, delay); - } - - /** - * @dev Schedule an operation containing a batch of transactions. - * - * Emits one {CallScheduled} event per transaction in the batch. - * - * Requirements: - * - * - the caller must have the 'proposer' role. - */ - function scheduleBatch( - address[] calldata targets, - uint256[] calldata values, - bytes[] calldata payloads, - bytes32 predecessor, - bytes32 salt, - uint256 delay - ) public virtual onlyRole(PROPOSER_ROLE) { - require(targets.length == values.length, "TimelockController: length mismatch"); - require(targets.length == payloads.length, "TimelockController: length mismatch"); - - bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); - _schedule(id, delay); - for (uint256 i = 0; i < targets.length; ++i) { - emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay); - } - } - - /** - * @dev Schedule an operation that is to becomes valid after a given delay. - */ - function _schedule(bytes32 id, uint256 delay) private { - require(!isOperation(id), "TimelockController: operation already scheduled"); - require(delay >= getMinDelay(), "TimelockController: insufficient delay"); - _timestamps[id] = block.timestamp + delay; - } - - /** - * @dev Cancel an operation. - * - * Requirements: - * - * - the caller must have the 'canceller' role. - */ - function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) { - require(isOperationPending(id), "TimelockController: operation cannot be cancelled"); - delete _timestamps[id]; - - emit Cancelled(id); - } - - /** - * @dev Execute an (ready) operation containing a single transaction. - * - * Emits a {CallExecuted} event. - * - * Requirements: - * - * - the caller must have the 'executor' role. - */ - // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending, - // thus any modifications to the operation during reentrancy should be caught. - // slither-disable-next-line reentrancy-eth - function execute( - address target, - uint256 value, - bytes calldata payload, - bytes32 predecessor, - bytes32 salt - ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { - bytes32 id = hashOperation(target, value, payload, predecessor, salt); - - _beforeCall(id, predecessor); - _execute(target, value, payload); - emit CallExecuted(id, 0, target, value, payload); - _afterCall(id); - } - - /** - * @dev Execute an (ready) operation containing a batch of transactions. - * - * Emits one {CallExecuted} event per transaction in the batch. - * - * Requirements: - * - * - the caller must have the 'executor' role. - */ - // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending, - // thus any modifications to the operation during reentrancy should be caught. - // slither-disable-next-line reentrancy-eth - function executeBatch( - address[] calldata targets, - uint256[] calldata values, - bytes[] calldata payloads, - bytes32 predecessor, - bytes32 salt - ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { - require(targets.length == values.length, "TimelockController: length mismatch"); - require(targets.length == payloads.length, "TimelockController: length mismatch"); - - bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); - - _beforeCall(id, predecessor); - for (uint256 i = 0; i < targets.length; ++i) { - address target = targets[i]; - uint256 value = values[i]; - bytes calldata payload = payloads[i]; - _execute(target, value, payload); - emit CallExecuted(id, i, target, value, payload); - } - _afterCall(id); - } - - /** - * @dev Execute an operation's call. - */ - function _execute( - address target, - uint256 value, - bytes calldata data - ) internal virtual { - (bool success, ) = target.call{value: value}(data); - require(success, "TimelockController: underlying transaction reverted"); - } - - /** - * @dev Checks before execution of an operation's calls. - */ - function _beforeCall(bytes32 id, bytes32 predecessor) private view { - require(isOperationReady(id), "TimelockController: operation is not ready"); - require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency"); - } - - /** - * @dev Checks after execution of an operation's calls. - */ - function _afterCall(bytes32 id) private { - require(isOperationReady(id), "TimelockController: operation is not ready"); - _timestamps[id] = _DONE_TIMESTAMP; - } - - /** - * @dev Changes the minimum timelock duration for future operations. - * - * Emits a {MinDelayChange} event. - * - * Requirements: - * - * - the caller must be the timelock itself. This can only be achieved by scheduling and later executing - * an operation where the timelock is the target and the data is the ABI-encoded call to this function. - */ - function updateDelay(uint256 newDelay) external virtual { - require(msg.sender == address(this), "TimelockController: caller must be timelock"); - emit MinDelayChange(_minDelay, newDelay); - _minDelay = newDelay; - } - - /** - * @dev See {IERC721Receiver-onERC721Received}. - */ - function onERC721Received( - address, - address, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC721Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155Received}. - */ - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155BatchReceived}. - */ - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerWith46MigrationUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerWith46MigrationUpgradeable.sol deleted file mode 100644 index 954afc5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerWith46MigrationUpgradeable.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.6.0 (governance/TimelockControllerWith46Migration.sol) - -pragma solidity ^0.8.0; - -import "./TimelockControllerUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of the TimelockController that includes an additional - * function to migrate from OpenZeppelin Upgradeable Contracts <4.6 to >=4.6. - * - * This migration is necessary to setup administration rights over the new - * `CANCELLER_ROLE`. - * - * The migration is trustless and can be performed by anyone. - * - * _Available since v4.6._ - */ -contract TimelockControllerWith46MigrationUpgradeable is Initializable, TimelockControllerUpgradeable { - function __TimelockControllerWith46Migration_init( - uint256 minDelay, - address[] memory proposers, - address[] memory executors, - address admin - ) internal onlyInitializing { - __TimelockController_init_unchained(minDelay, proposers, executors, admin); - } - - function __TimelockControllerWith46Migration_init_unchained( - uint256, - address[] memory, - address[] memory, - address - ) internal onlyInitializing {} - - /** - * @dev Migration function. Running it is necessary for upgradeable - * instances that were initially setup with code <4.6 and that upgraded - * to >=4.6. - */ - function migrateTo46() public virtual { - require( - getRoleAdmin(PROPOSER_ROLE) == TIMELOCK_ADMIN_ROLE && getRoleAdmin(CANCELLER_ROLE) == DEFAULT_ADMIN_ROLE, - "TimelockController: already migrated" - ); - _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol deleted file mode 100644 index ddbc589..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol +++ /dev/null @@ -1,302 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.3) (governance/compatibility/GovernorCompatibilityBravo.sol) - -pragma solidity ^0.8.0; - -import "../../utils/math/SafeCastUpgradeable.sol"; -import "../extensions/IGovernorTimelockUpgradeable.sol"; -import "../GovernorUpgradeable.sol"; -import "./IGovernorCompatibilityBravoUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Compatibility layer that implements GovernorBravo compatibility on to of {Governor}. - * - * This compatibility layer includes a voting system and requires a {IGovernorTimelock} compatible module to be added - * through inheritance. It does not include token bindings, not does it include any variable upgrade patterns. - * - * NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit. - * - * _Available since v4.3._ - */ -abstract contract GovernorCompatibilityBravoUpgradeable is Initializable, IGovernorTimelockUpgradeable, IGovernorCompatibilityBravoUpgradeable, GovernorUpgradeable { - function __GovernorCompatibilityBravo_init() internal onlyInitializing { - } - - function __GovernorCompatibilityBravo_init_unchained() internal onlyInitializing { - } - enum VoteType { - Against, - For, - Abstain - } - - struct ProposalDetails { - address proposer; - address[] targets; - uint256[] values; - string[] signatures; - bytes[] calldatas; - uint256 forVotes; - uint256 againstVotes; - uint256 abstainVotes; - mapping(address => Receipt) receipts; - bytes32 descriptionHash; - } - - mapping(uint256 => ProposalDetails) private _proposalDetails; - - // solhint-disable-next-line func-name-mixedcase - function COUNTING_MODE() public pure virtual override returns (string memory) { - return "support=bravo&quorum=bravo"; - } - - // ============================================== Proposal lifecycle ============================================== - /** - * @dev See {IGovernor-propose}. - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (uint256) { - _storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description); - return super.propose(targets, values, calldatas, description); - } - - /** - * @dev See {IGovernorCompatibilityBravo-propose}. - */ - function propose( - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas, - string memory description - ) public virtual override returns (uint256) { - require(signatures.length == calldatas.length, "GovernorBravo: invalid signatures length"); - // Stores the full proposal and fallback to the public (possibly overridden) propose. The fallback is done - // after the full proposal is stored, so the store operation included in the fallback will be skipped. Here we - // call `propose` and not `super.propose` to make sure if a child contract override `propose`, whatever code - // is added their is also executed when calling this alternative interface. - _storeProposal(_msgSender(), targets, values, signatures, calldatas, description); - return propose(targets, values, _encodeCalldata(signatures, calldatas), description); - } - - /** - * @dev See {IGovernorCompatibilityBravo-queue}. - */ - function queue(uint256 proposalId) public virtual override { - ProposalDetails storage details = _proposalDetails[proposalId]; - queue( - details.targets, - details.values, - _encodeCalldata(details.signatures, details.calldatas), - details.descriptionHash - ); - } - - /** - * @dev See {IGovernorCompatibilityBravo-execute}. - */ - function execute(uint256 proposalId) public payable virtual override { - ProposalDetails storage details = _proposalDetails[proposalId]; - execute( - details.targets, - details.values, - _encodeCalldata(details.signatures, details.calldatas), - details.descriptionHash - ); - } - - function cancel(uint256 proposalId) public virtual override { - ProposalDetails storage details = _proposalDetails[proposalId]; - - require( - _msgSender() == details.proposer || getVotes(details.proposer, block.number - 1) < proposalThreshold(), - "GovernorBravo: proposer above threshold" - ); - - _cancel( - details.targets, - details.values, - _encodeCalldata(details.signatures, details.calldatas), - details.descriptionHash - ); - } - - /** - * @dev Encodes calldatas with optional function signature. - */ - function _encodeCalldata(string[] memory signatures, bytes[] memory calldatas) - private - pure - returns (bytes[] memory) - { - bytes[] memory fullcalldatas = new bytes[](calldatas.length); - for (uint256 i = 0; i < fullcalldatas.length; ++i) { - fullcalldatas[i] = bytes(signatures[i]).length == 0 - ? calldatas[i] - : abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), calldatas[i]); - } - - return fullcalldatas; - } - - /** - * @dev Store proposal metadata for later lookup - */ - function _storeProposal( - address proposer, - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas, - string memory description - ) private { - bytes32 descriptionHash = keccak256(bytes(description)); - uint256 proposalId = hashProposal(targets, values, _encodeCalldata(signatures, calldatas), descriptionHash); - - ProposalDetails storage details = _proposalDetails[proposalId]; - if (details.descriptionHash == bytes32(0)) { - details.proposer = proposer; - details.targets = targets; - details.values = values; - details.signatures = signatures; - details.calldatas = calldatas; - details.descriptionHash = descriptionHash; - } - } - - // ==================================================== Views ===================================================== - /** - * @dev See {IGovernorCompatibilityBravo-proposals}. - */ - function proposals(uint256 proposalId) - public - view - virtual - override - returns ( - uint256 id, - address proposer, - uint256 eta, - uint256 startBlock, - uint256 endBlock, - uint256 forVotes, - uint256 againstVotes, - uint256 abstainVotes, - bool canceled, - bool executed - ) - { - id = proposalId; - eta = proposalEta(proposalId); - startBlock = proposalSnapshot(proposalId); - endBlock = proposalDeadline(proposalId); - - ProposalDetails storage details = _proposalDetails[proposalId]; - proposer = details.proposer; - forVotes = details.forVotes; - againstVotes = details.againstVotes; - abstainVotes = details.abstainVotes; - - ProposalState status = state(proposalId); - canceled = status == ProposalState.Canceled; - executed = status == ProposalState.Executed; - } - - /** - * @dev See {IGovernorCompatibilityBravo-getActions}. - */ - function getActions(uint256 proposalId) - public - view - virtual - override - returns ( - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas - ) - { - ProposalDetails storage details = _proposalDetails[proposalId]; - return (details.targets, details.values, details.signatures, details.calldatas); - } - - /** - * @dev See {IGovernorCompatibilityBravo-getReceipt}. - */ - function getReceipt(uint256 proposalId, address voter) public view virtual override returns (Receipt memory) { - return _proposalDetails[proposalId].receipts[voter]; - } - - /** - * @dev See {IGovernorCompatibilityBravo-quorumVotes}. - */ - function quorumVotes() public view virtual override returns (uint256) { - return quorum(block.number - 1); - } - - // ==================================================== Voting ==================================================== - /** - * @dev See {IGovernor-hasVoted}. - */ - function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { - return _proposalDetails[proposalId].receipts[account].hasVoted; - } - - /** - * @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum. - */ - function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { - ProposalDetails storage details = _proposalDetails[proposalId]; - return quorum(proposalSnapshot(proposalId)) <= details.forVotes; - } - - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be scritly over the againstVotes. - */ - function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { - ProposalDetails storage details = _proposalDetails[proposalId]; - return details.forVotes > details.againstVotes; - } - - /** - * @dev See {Governor-_countVote}. In this module, the support follows Governor Bravo. - */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory // params - ) internal virtual override { - ProposalDetails storage details = _proposalDetails[proposalId]; - Receipt storage receipt = details.receipts[account]; - - require(!receipt.hasVoted, "GovernorCompatibilityBravo: vote already cast"); - receipt.hasVoted = true; - receipt.support = support; - receipt.votes = SafeCastUpgradeable.toUint96(weight); - - if (support == uint8(VoteType.Against)) { - details.againstVotes += weight; - } else if (support == uint8(VoteType.For)) { - details.forVotes += weight; - } else if (support == uint8(VoteType.Abstain)) { - details.abstainVotes += weight; - } else { - revert("GovernorCompatibilityBravo: invalid vote type"); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/IGovernorCompatibilityBravoUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/IGovernorCompatibilityBravoUpgradeable.sol deleted file mode 100644 index 2fe34e3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/compatibility/IGovernorCompatibilityBravoUpgradeable.sol +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (governance/compatibility/IGovernorCompatibilityBravo.sol) - -pragma solidity ^0.8.0; - -import "../IGovernorUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Interface extension that adds missing functions to the {Governor} core to provide `GovernorBravo` compatibility. - * - * _Available since v4.3._ - */ -abstract contract IGovernorCompatibilityBravoUpgradeable is Initializable, IGovernorUpgradeable { - function __IGovernorCompatibilityBravo_init() internal onlyInitializing { - } - - function __IGovernorCompatibilityBravo_init_unchained() internal onlyInitializing { - } - /** - * @dev Proposal structure from Compound Governor Bravo. Not actually used by the compatibility layer, as - * {{proposal}} returns a very different structure. - */ - struct Proposal { - uint256 id; - address proposer; - uint256 eta; - address[] targets; - uint256[] values; - string[] signatures; - bytes[] calldatas; - uint256 startBlock; - uint256 endBlock; - uint256 forVotes; - uint256 againstVotes; - uint256 abstainVotes; - bool canceled; - bool executed; - mapping(address => Receipt) receipts; - } - - /** - * @dev Receipt structure from Compound Governor Bravo - */ - struct Receipt { - bool hasVoted; - uint8 support; - uint96 votes; - } - - /** - * @dev Part of the Governor Bravo's interface. - */ - function quorumVotes() public view virtual returns (uint256); - - /** - * @dev Part of the Governor Bravo's interface: _"The official record of all proposals ever proposed"_. - */ - function proposals(uint256) - public - view - virtual - returns ( - uint256 id, - address proposer, - uint256 eta, - uint256 startBlock, - uint256 endBlock, - uint256 forVotes, - uint256 againstVotes, - uint256 abstainVotes, - bool canceled, - bool executed - ); - - /** - * @dev Part of the Governor Bravo's interface: _"Function used to propose a new proposal"_. - */ - function propose( - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas, - string memory description - ) public virtual returns (uint256); - - /** - * @dev Part of the Governor Bravo's interface: _"Queues a proposal of state succeeded"_. - */ - function queue(uint256 proposalId) public virtual; - - /** - * @dev Part of the Governor Bravo's interface: _"Executes a queued proposal if eta has passed"_. - */ - function execute(uint256 proposalId) public payable virtual; - - /** - * @dev Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold. - */ - function cancel(uint256 proposalId) public virtual; - - /** - * @dev Part of the Governor Bravo's interface: _"Gets actions of a proposal"_. - */ - function getActions(uint256 proposalId) - public - view - virtual - returns ( - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas - ); - - /** - * @dev Part of the Governor Bravo's interface: _"Gets the receipt for a voter on a given proposal"_. - */ - function getReceipt(uint256 proposalId, address voter) public view virtual returns (Receipt memory); - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol deleted file mode 100644 index 32c570e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (governance/extensions/GovernorCountingSimple.sol) - -pragma solidity ^0.8.0; - -import "../GovernorUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {Governor} for simple, 3 options, vote counting. - * - * _Available since v4.3._ - */ -abstract contract GovernorCountingSimpleUpgradeable is Initializable, GovernorUpgradeable { - function __GovernorCountingSimple_init() internal onlyInitializing { - } - - function __GovernorCountingSimple_init_unchained() internal onlyInitializing { - } - /** - * @dev Supported vote types. Matches Governor Bravo ordering. - */ - enum VoteType { - Against, - For, - Abstain - } - - struct ProposalVote { - uint256 againstVotes; - uint256 forVotes; - uint256 abstainVotes; - mapping(address => bool) hasVoted; - } - - mapping(uint256 => ProposalVote) private _proposalVotes; - - /** - * @dev See {IGovernor-COUNTING_MODE}. - */ - // solhint-disable-next-line func-name-mixedcase - function COUNTING_MODE() public pure virtual override returns (string memory) { - return "support=bravo&quorum=for,abstain"; - } - - /** - * @dev See {IGovernor-hasVoted}. - */ - function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { - return _proposalVotes[proposalId].hasVoted[account]; - } - - /** - * @dev Accessor to the internal vote counts. - */ - function proposalVotes(uint256 proposalId) - public - view - virtual - returns ( - uint256 againstVotes, - uint256 forVotes, - uint256 abstainVotes - ) - { - ProposalVote storage proposalVote = _proposalVotes[proposalId]; - return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes); - } - - /** - * @dev See {Governor-_quorumReached}. - */ - function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { - ProposalVote storage proposalVote = _proposalVotes[proposalId]; - - return quorum(proposalSnapshot(proposalId)) <= proposalVote.forVotes + proposalVote.abstainVotes; - } - - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. - */ - function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { - ProposalVote storage proposalVote = _proposalVotes[proposalId]; - - return proposalVote.forVotes > proposalVote.againstVotes; - } - - /** - * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo). - */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory // params - ) internal virtual override { - ProposalVote storage proposalVote = _proposalVotes[proposalId]; - - require(!proposalVote.hasVoted[account], "GovernorVotingSimple: vote already cast"); - proposalVote.hasVoted[account] = true; - - if (support == uint8(VoteType.Against)) { - proposalVote.againstVotes += weight; - } else if (support == uint8(VoteType.For)) { - proposalVote.forVotes += weight; - } else if (support == uint8(VoteType.Abstain)) { - proposalVote.abstainVotes += weight; - } else { - revert("GovernorVotingSimple: invalid value for enum VoteType"); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol deleted file mode 100644 index 97d8b54..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorPreventLateQuorum.sol) - -pragma solidity ^0.8.0; - -import "../GovernorUpgradeable.sol"; -import "../../utils/math/MathUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev A module that ensures there is a minimum voting period after quorum is reached. This prevents a large voter from - * swaying a vote and triggering quorum at the last minute, by ensuring there is always time for other voters to react - * and try to oppose the decision. - * - * If a vote causes quorum to be reached, the proposal's voting period may be extended so that it does not end before at - * least a given number of blocks have passed (the "vote extension" parameter). This parameter can be set by the - * governance executor (e.g. through a governance proposal). - * - * _Available since v4.5._ - */ -abstract contract GovernorPreventLateQuorumUpgradeable is Initializable, GovernorUpgradeable { - using SafeCastUpgradeable for uint256; - using TimersUpgradeable for TimersUpgradeable.BlockNumber; - - uint64 private _voteExtension; - mapping(uint256 => TimersUpgradeable.BlockNumber) private _extendedDeadlines; - - /// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period. - event ProposalExtended(uint256 indexed proposalId, uint64 extendedDeadline); - - /// @dev Emitted when the {lateQuorumVoteExtension} parameter is changed. - event LateQuorumVoteExtensionSet(uint64 oldVoteExtension, uint64 newVoteExtension); - - /** - * @dev Initializes the vote extension parameter: the number of blocks that are required to pass since a proposal - * reaches quorum until its voting period ends. If necessary the voting period will be extended beyond the one set - * at proposal creation. - */ - function __GovernorPreventLateQuorum_init(uint64 initialVoteExtension) internal onlyInitializing { - __GovernorPreventLateQuorum_init_unchained(initialVoteExtension); - } - - function __GovernorPreventLateQuorum_init_unchained(uint64 initialVoteExtension) internal onlyInitializing { - _setLateQuorumVoteExtension(initialVoteExtension); - } - - /** - * @dev Returns the proposal deadline, which may have been extended beyond that set at proposal creation, if the - * proposal reached quorum late in the voting period. See {Governor-proposalDeadline}. - */ - function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { - return MathUpgradeable.max(super.proposalDeadline(proposalId), _extendedDeadlines[proposalId].getDeadline()); - } - - /** - * @dev Casts a vote and detects if it caused quorum to be reached, potentially extending the voting period. See - * {Governor-_castVote}. - * - * May emit a {ProposalExtended} event. - */ - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal virtual override returns (uint256) { - uint256 result = super._castVote(proposalId, account, support, reason, params); - - TimersUpgradeable.BlockNumber storage extendedDeadline = _extendedDeadlines[proposalId]; - - if (extendedDeadline.isUnset() && _quorumReached(proposalId)) { - uint64 extendedDeadlineValue = block.number.toUint64() + lateQuorumVoteExtension(); - - if (extendedDeadlineValue > proposalDeadline(proposalId)) { - emit ProposalExtended(proposalId, extendedDeadlineValue); - } - - extendedDeadline.setDeadline(extendedDeadlineValue); - } - - return result; - } - - /** - * @dev Returns the current value of the vote extension parameter: the number of blocks that are required to pass - * from the time a proposal reaches quorum until its voting period ends. - */ - function lateQuorumVoteExtension() public view virtual returns (uint64) { - return _voteExtension; - } - - /** - * @dev Changes the {lateQuorumVoteExtension}. This operation can only be performed by the governance executor, - * generally through a governance proposal. - * - * Emits a {LateQuorumVoteExtensionSet} event. - */ - function setLateQuorumVoteExtension(uint64 newVoteExtension) public virtual onlyGovernance { - _setLateQuorumVoteExtension(newVoteExtension); - } - - /** - * @dev Changes the {lateQuorumVoteExtension}. This is an internal function that can be exposed in a public function - * like {setLateQuorumVoteExtension} if another access control mechanism is needed. - * - * Emits a {LateQuorumVoteExtensionSet} event. - */ - function _setLateQuorumVoteExtension(uint64 newVoteExtension) internal virtual { - emit LateQuorumVoteExtensionSet(_voteExtension, newVoteExtension); - _voteExtension = newVoteExtension; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol deleted file mode 100644 index a42caeb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorProposalThresholdUpgradeable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorProposalThreshold.sol) - -pragma solidity ^0.8.0; - -import "../GovernorUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {Governor} for proposal restriction to token holders with a minimum balance. - * - * _Available since v4.3._ - * _Deprecated since v4.4._ - */ -abstract contract GovernorProposalThresholdUpgradeable is Initializable, GovernorUpgradeable { - function __GovernorProposalThreshold_init() internal onlyInitializing { - } - - function __GovernorProposalThreshold_init_unchained() internal onlyInitializing { - } - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorSettingsUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorSettingsUpgradeable.sol deleted file mode 100644 index a6acf49..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorSettingsUpgradeable.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorSettings.sol) - -pragma solidity ^0.8.0; - -import "../GovernorUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {Governor} for settings updatable through governance. - * - * _Available since v4.4._ - */ -abstract contract GovernorSettingsUpgradeable is Initializable, GovernorUpgradeable { - uint256 private _votingDelay; - uint256 private _votingPeriod; - uint256 private _proposalThreshold; - - event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay); - event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod); - event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold); - - /** - * @dev Initialize the governance parameters. - */ - function __GovernorSettings_init( - uint256 initialVotingDelay, - uint256 initialVotingPeriod, - uint256 initialProposalThreshold - ) internal onlyInitializing { - __GovernorSettings_init_unchained(initialVotingDelay, initialVotingPeriod, initialProposalThreshold); - } - - function __GovernorSettings_init_unchained( - uint256 initialVotingDelay, - uint256 initialVotingPeriod, - uint256 initialProposalThreshold - ) internal onlyInitializing { - _setVotingDelay(initialVotingDelay); - _setVotingPeriod(initialVotingPeriod); - _setProposalThreshold(initialProposalThreshold); - } - - /** - * @dev See {IGovernor-votingDelay}. - */ - function votingDelay() public view virtual override returns (uint256) { - return _votingDelay; - } - - /** - * @dev See {IGovernor-votingPeriod}. - */ - function votingPeriod() public view virtual override returns (uint256) { - return _votingPeriod; - } - - /** - * @dev See {Governor-proposalThreshold}. - */ - function proposalThreshold() public view virtual override returns (uint256) { - return _proposalThreshold; - } - - /** - * @dev Update the voting delay. This operation can only be performed through a governance proposal. - * - * Emits a {VotingDelaySet} event. - */ - function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance { - _setVotingDelay(newVotingDelay); - } - - /** - * @dev Update the voting period. This operation can only be performed through a governance proposal. - * - * Emits a {VotingPeriodSet} event. - */ - function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance { - _setVotingPeriod(newVotingPeriod); - } - - /** - * @dev Update the proposal threshold. This operation can only be performed through a governance proposal. - * - * Emits a {ProposalThresholdSet} event. - */ - function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance { - _setProposalThreshold(newProposalThreshold); - } - - /** - * @dev Internal setter for the voting delay. - * - * Emits a {VotingDelaySet} event. - */ - function _setVotingDelay(uint256 newVotingDelay) internal virtual { - emit VotingDelaySet(_votingDelay, newVotingDelay); - _votingDelay = newVotingDelay; - } - - /** - * @dev Internal setter for the voting period. - * - * Emits a {VotingPeriodSet} event. - */ - function _setVotingPeriod(uint256 newVotingPeriod) internal virtual { - // voting period must be at least one block long - require(newVotingPeriod > 0, "GovernorSettings: voting period too low"); - emit VotingPeriodSet(_votingPeriod, newVotingPeriod); - _votingPeriod = newVotingPeriod; - } - - /** - * @dev Internal setter for the proposal threshold. - * - * Emits a {ProposalThresholdSet} event. - */ - function _setProposalThreshold(uint256 newProposalThreshold) internal virtual { - emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold); - _proposalThreshold = newProposalThreshold; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol deleted file mode 100644 index d130dcb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockCompoundUpgradeable.sol +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorTimelockCompound.sol) - -pragma solidity ^0.8.0; - -import "./IGovernorTimelockUpgradeable.sol"; -import "../GovernorUpgradeable.sol"; -import "../../utils/math/SafeCastUpgradeable.sol"; -import "../../vendor/compound/ICompoundTimelockUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {Governor} that binds the execution process to a Compound Timelock. This adds a delay, enforced by - * the external timelock to all successful proposal (in addition to the voting duration). The {Governor} needs to be - * the admin of the timelock for any operation to be performed. A public, unrestricted, - * {GovernorTimelockCompound-__acceptAdmin} is available to accept ownership of the timelock. - * - * Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus, - * the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be - * inaccessible. - * - * _Available since v4.3._ - */ -abstract contract GovernorTimelockCompoundUpgradeable is Initializable, IGovernorTimelockUpgradeable, GovernorUpgradeable { - using SafeCastUpgradeable for uint256; - using TimersUpgradeable for TimersUpgradeable.Timestamp; - - struct ProposalTimelock { - TimersUpgradeable.Timestamp timer; - } - - ICompoundTimelockUpgradeable private _timelock; - - mapping(uint256 => ProposalTimelock) private _proposalTimelocks; - - /** - * @dev Emitted when the timelock controller used for proposal execution is modified. - */ - event TimelockChange(address oldTimelock, address newTimelock); - - /** - * @dev Set the timelock. - */ - function __GovernorTimelockCompound_init(ICompoundTimelockUpgradeable timelockAddress) internal onlyInitializing { - __GovernorTimelockCompound_init_unchained(timelockAddress); - } - - function __GovernorTimelockCompound_init_unchained(ICompoundTimelockUpgradeable timelockAddress) internal onlyInitializing { - _updateTimelock(timelockAddress); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, GovernorUpgradeable) returns (bool) { - return interfaceId == type(IGovernorTimelockUpgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Overridden version of the {Governor-state} function with added support for the `Queued` and `Expired` status. - */ - function state(uint256 proposalId) public view virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (ProposalState) { - ProposalState status = super.state(proposalId); - - if (status != ProposalState.Succeeded) { - return status; - } - - uint256 eta = proposalEta(proposalId); - if (eta == 0) { - return status; - } else if (block.timestamp >= eta + _timelock.GRACE_PERIOD()) { - return ProposalState.Expired; - } else { - return ProposalState.Queued; - } - } - - /** - * @dev Public accessor to check the address of the timelock - */ - function timelock() public view virtual override returns (address) { - return address(_timelock); - } - - /** - * @dev Public accessor to check the eta of a queued proposal - */ - function proposalEta(uint256 proposalId) public view virtual override returns (uint256) { - return _proposalTimelocks[proposalId].timer.getDeadline(); - } - - /** - * @dev Function to queue a proposal to the timelock. - */ - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public virtual override returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful"); - - uint256 eta = block.timestamp + _timelock.delay(); - _proposalTimelocks[proposalId].timer.setDeadline(eta.toUint64()); - for (uint256 i = 0; i < targets.length; ++i) { - require( - !_timelock.queuedTransactions(keccak256(abi.encode(targets[i], values[i], "", calldatas[i], eta))), - "GovernorTimelockCompound: identical proposal action already queued" - ); - _timelock.queueTransaction(targets[i], values[i], "", calldatas[i], eta); - } - - emit ProposalQueued(proposalId, eta); - - return proposalId; - } - - /** - * @dev Overridden execute function that run the already queued proposal through the timelock. - */ - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual override { - uint256 eta = proposalEta(proposalId); - require(eta > 0, "GovernorTimelockCompound: proposal not yet queued"); - AddressUpgradeable.sendValue(payable(_timelock), msg.value); - for (uint256 i = 0; i < targets.length; ++i) { - _timelock.executeTransaction(targets[i], values[i], "", calldatas[i], eta); - } - } - - /** - * @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already - * been queued. - */ - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override returns (uint256) { - uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash); - - uint256 eta = proposalEta(proposalId); - if (eta > 0) { - for (uint256 i = 0; i < targets.length; ++i) { - _timelock.cancelTransaction(targets[i], values[i], "", calldatas[i], eta); - } - _proposalTimelocks[proposalId].timer.reset(); - } - - return proposalId; - } - - /** - * @dev Address through which the governor executes action. In this case, the timelock. - */ - function _executor() internal view virtual override returns (address) { - return address(_timelock); - } - - /** - * @dev Accept admin right over the timelock. - */ - // solhint-disable-next-line private-vars-leading-underscore - function __acceptAdmin() public { - _timelock.acceptAdmin(); - } - - /** - * @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates - * must be proposed, scheduled, and executed through governance proposals. - * - * For security reasons, the timelock must be handed over to another admin before setting up a new one. The two - * operations (hand over the timelock) and do the update can be batched in a single proposal. - * - * Note that if the timelock admin has been handed over in a previous operation, we refuse updates made through the - * timelock if admin of the timelock has already been accepted and the operation is executed outside the scope of - * governance. - - * CAUTION: It is not recommended to change the timelock while there are other queued governance proposals. - */ - function updateTimelock(ICompoundTimelockUpgradeable newTimelock) external virtual onlyGovernance { - _updateTimelock(newTimelock); - } - - function _updateTimelock(ICompoundTimelockUpgradeable newTimelock) private { - emit TimelockChange(address(_timelock), address(newTimelock)); - _timelock = newTimelock; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol deleted file mode 100644 index c12f624..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol +++ /dev/null @@ -1,178 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorTimelockControl.sol) - -pragma solidity ^0.8.0; - -import "./IGovernorTimelockUpgradeable.sol"; -import "../GovernorUpgradeable.sol"; -import "../TimelockControllerUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a - * delay, enforced by the {TimelockController} to all successful proposal (in addition to the voting duration). The - * {Governor} needs the proposer (and ideally the executor) roles for the {Governor} to work properly. - * - * Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus, - * the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be - * inaccessible. - * - * WARNING: Setting up the TimelockController to have additional proposers besides the governor is very risky, as it - * grants them powers that they must be trusted or known not to use: 1) {onlyGovernance} functions like {relay} are - * available to them through the timelock, and 2) approved governance proposals can be blocked by them, effectively - * executing a Denial of Service attack. This risk will be mitigated in a future release. - * - * _Available since v4.3._ - */ -abstract contract GovernorTimelockControlUpgradeable is Initializable, IGovernorTimelockUpgradeable, GovernorUpgradeable { - TimelockControllerUpgradeable private _timelock; - mapping(uint256 => bytes32) private _timelockIds; - - /** - * @dev Emitted when the timelock controller used for proposal execution is modified. - */ - event TimelockChange(address oldTimelock, address newTimelock); - - /** - * @dev Set the timelock. - */ - function __GovernorTimelockControl_init(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing { - __GovernorTimelockControl_init_unchained(timelockAddress); - } - - function __GovernorTimelockControl_init_unchained(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing { - _updateTimelock(timelockAddress); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, GovernorUpgradeable) returns (bool) { - return interfaceId == type(IGovernorTimelockUpgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Overridden version of the {Governor-state} function with added support for the `Queued` status. - */ - function state(uint256 proposalId) public view virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (ProposalState) { - ProposalState status = super.state(proposalId); - - if (status != ProposalState.Succeeded) { - return status; - } - - // core tracks execution, so we just have to check if successful proposal have been queued. - bytes32 queueid = _timelockIds[proposalId]; - if (queueid == bytes32(0)) { - return status; - } else if (_timelock.isOperationDone(queueid)) { - return ProposalState.Executed; - } else if (_timelock.isOperationPending(queueid)) { - return ProposalState.Queued; - } else { - return ProposalState.Canceled; - } - } - - /** - * @dev Public accessor to check the address of the timelock - */ - function timelock() public view virtual override returns (address) { - return address(_timelock); - } - - /** - * @dev Public accessor to check the eta of a queued proposal - */ - function proposalEta(uint256 proposalId) public view virtual override returns (uint256) { - uint256 eta = _timelock.getTimestamp(_timelockIds[proposalId]); - return eta == 1 ? 0 : eta; // _DONE_TIMESTAMP (1) should be replaced with a 0 value - } - - /** - * @dev Function to queue a proposal to the timelock. - */ - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public virtual override returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful"); - - uint256 delay = _timelock.getMinDelay(); - _timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, descriptionHash); - _timelock.scheduleBatch(targets, values, calldatas, 0, descriptionHash, delay); - - emit ProposalQueued(proposalId, block.timestamp + delay); - - return proposalId; - } - - /** - * @dev Overridden execute function that run the already queued proposal through the timelock. - */ - function _execute( - uint256, /* proposalId */ - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override { - _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash); - } - - /** - * @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already - * been queued. - */ - // This function can reenter through the external call to the timelock, but we assume the timelock is trusted and - // well behaved (according to TimelockController) and this will not happen. - // slither-disable-next-line reentrancy-no-eth - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override returns (uint256) { - uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash); - - if (_timelockIds[proposalId] != 0) { - _timelock.cancel(_timelockIds[proposalId]); - delete _timelockIds[proposalId]; - } - - return proposalId; - } - - /** - * @dev Address through which the governor executes action. In this case, the timelock. - */ - function _executor() internal view virtual override returns (address) { - return address(_timelock); - } - - /** - * @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates - * must be proposed, scheduled, and executed through governance proposals. - * - * CAUTION: It is not recommended to change the timelock while there are other queued governance proposals. - */ - function updateTimelock(TimelockControllerUpgradeable newTimelock) external virtual onlyGovernance { - _updateTimelock(newTimelock); - } - - function _updateTimelock(TimelockControllerUpgradeable newTimelock) private { - emit TimelockChange(address(_timelock), address(newTimelock)); - _timelock = newTimelock; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol deleted file mode 100644 index 1db1410..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesCompUpgradeable.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorVotesComp.sol) - -pragma solidity ^0.8.0; - -import "../GovernorUpgradeable.sol"; -import "../../token/ERC20/extensions/ERC20VotesCompUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {Governor} for voting weight extraction from a Comp token. - * - * _Available since v4.3._ - * - * @custom:storage-size 51 - */ -abstract contract GovernorVotesCompUpgradeable is Initializable, GovernorUpgradeable { - ERC20VotesCompUpgradeable public token; - - function __GovernorVotesComp_init(ERC20VotesCompUpgradeable token_) internal onlyInitializing { - __GovernorVotesComp_init_unchained(token_); - } - - function __GovernorVotesComp_init_unchained(ERC20VotesCompUpgradeable token_) internal onlyInitializing { - token = token_; - } - - /** - * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). - */ - function _getVotes( - address account, - uint256 blockNumber, - bytes memory /*params*/ - ) internal view virtual override returns (uint256) { - return token.getPriorVotes(account, blockNumber); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol deleted file mode 100644 index bfda84e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (governance/extensions/GovernorVotesQuorumFraction.sol) - -pragma solidity ^0.8.0; - -import "./GovernorVotesUpgradeable.sol"; -import "../../utils/CheckpointsUpgradeable.sol"; -import "../../utils/math/SafeCastUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a - * fraction of the total supply. - * - * _Available since v4.3._ - */ -abstract contract GovernorVotesQuorumFractionUpgradeable is Initializable, GovernorVotesUpgradeable { - using CheckpointsUpgradeable for CheckpointsUpgradeable.History; - - uint256 private _quorumNumerator; // DEPRECATED - CheckpointsUpgradeable.History private _quorumNumeratorHistory; - - event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); - - /** - * @dev Initialize quorum as a fraction of the token's total supply. - * - * The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is - * specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be - * customized by overriding {quorumDenominator}. - */ - function __GovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue) internal onlyInitializing { - __GovernorVotesQuorumFraction_init_unchained(quorumNumeratorValue); - } - - function __GovernorVotesQuorumFraction_init_unchained(uint256 quorumNumeratorValue) internal onlyInitializing { - _updateQuorumNumerator(quorumNumeratorValue); - } - - /** - * @dev Returns the current quorum numerator. See {quorumDenominator}. - */ - function quorumNumerator() public view virtual returns (uint256) { - return _quorumNumeratorHistory._checkpoints.length == 0 ? _quorumNumerator : _quorumNumeratorHistory.latest(); - } - - /** - * @dev Returns the quorum numerator at a specific block number. See {quorumDenominator}. - */ - function quorumNumerator(uint256 blockNumber) public view virtual returns (uint256) { - // If history is empty, fallback to old storage - uint256 length = _quorumNumeratorHistory._checkpoints.length; - if (length == 0) { - return _quorumNumerator; - } - - // Optimistic search, check the latest checkpoint - CheckpointsUpgradeable.Checkpoint memory latest = _quorumNumeratorHistory._checkpoints[length - 1]; - if (latest._blockNumber <= blockNumber) { - return latest._value; - } - - // Otherwise, do the binary search - return _quorumNumeratorHistory.getAtBlock(blockNumber); - } - - /** - * @dev Returns the quorum denominator. Defaults to 100, but may be overridden. - */ - function quorumDenominator() public view virtual returns (uint256) { - return 100; - } - - /** - * @dev Returns the quorum for a block number, in terms of number of votes: `supply * numerator / denominator`. - */ - function quorum(uint256 blockNumber) public view virtual override returns (uint256) { - return (token.getPastTotalSupply(blockNumber) * quorumNumerator(blockNumber)) / quorumDenominator(); - } - - /** - * @dev Changes the quorum numerator. - * - * Emits a {QuorumNumeratorUpdated} event. - * - * Requirements: - * - * - Must be called through a governance proposal. - * - New numerator must be smaller or equal to the denominator. - */ - function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance { - _updateQuorumNumerator(newQuorumNumerator); - } - - /** - * @dev Changes the quorum numerator. - * - * Emits a {QuorumNumeratorUpdated} event. - * - * Requirements: - * - * - New numerator must be smaller or equal to the denominator. - */ - function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual { - require( - newQuorumNumerator <= quorumDenominator(), - "GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator" - ); - - uint256 oldQuorumNumerator = quorumNumerator(); - - // Make sure we keep track of the original numerator in contracts upgraded from a version without checkpoints. - if (oldQuorumNumerator != 0 && _quorumNumeratorHistory._checkpoints.length == 0) { - _quorumNumeratorHistory._checkpoints.push( - CheckpointsUpgradeable.Checkpoint({_blockNumber: 0, _value: SafeCastUpgradeable.toUint224(oldQuorumNumerator)}) - ); - } - - // Set new quorum for future proposals - _quorumNumeratorHistory.push(newQuorumNumerator); - - emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesUpgradeable.sol deleted file mode 100644 index 3c23608..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesUpgradeable.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorVotes.sol) - -pragma solidity ^0.8.0; - -import "../GovernorUpgradeable.sol"; -import "../utils/IVotesUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token. - * - * _Available since v4.3._ - * - * @custom:storage-size 51 - */ -abstract contract GovernorVotesUpgradeable is Initializable, GovernorUpgradeable { - IVotesUpgradeable public token; - - function __GovernorVotes_init(IVotesUpgradeable tokenAddress) internal onlyInitializing { - __GovernorVotes_init_unchained(tokenAddress); - } - - function __GovernorVotes_init_unchained(IVotesUpgradeable tokenAddress) internal onlyInitializing { - token = tokenAddress; - } - - /** - * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). - */ - function _getVotes( - address account, - uint256 blockNumber, - bytes memory /*params*/ - ) internal view virtual override returns (uint256) { - return token.getPastVotes(account, blockNumber); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/IGovernorTimelockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/IGovernorTimelockUpgradeable.sol deleted file mode 100644 index 821c3a0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/IGovernorTimelockUpgradeable.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol) - -pragma solidity ^0.8.0; - -import "../IGovernorUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of the {IGovernor} for timelock supporting modules. - * - * _Available since v4.3._ - */ -abstract contract IGovernorTimelockUpgradeable is Initializable, IGovernorUpgradeable { - function __IGovernorTimelock_init() internal onlyInitializing { - } - - function __IGovernorTimelock_init_unchained() internal onlyInitializing { - } - event ProposalQueued(uint256 proposalId, uint256 eta); - - function timelock() public view virtual returns (address); - - function proposalEta(uint256 proposalId) public view virtual returns (uint256); - - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public virtual returns (uint256 proposalId); - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/IVotesUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/IVotesUpgradeable.sol deleted file mode 100644 index 3faedeb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/IVotesUpgradeable.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) -pragma solidity ^0.8.0; - -/** - * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. - * - * _Available since v4.5._ - */ -interface IVotesUpgradeable { - /** - * @dev Emitted when an account changes their delegate. - */ - event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); - - /** - * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. - */ - event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); - - /** - * @dev Returns the current amount of votes that `account` has. - */ - function getVotes(address account) external view returns (uint256); - - /** - * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). - */ - function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); - - /** - * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). - * - * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. - * Votes that have not been delegated are still part of total supply, even though they would not participate in a - * vote. - */ - function getPastTotalSupply(uint256 blockNumber) external view returns (uint256); - - /** - * @dev Returns the delegate that `account` has chosen. - */ - function delegates(address account) external view returns (address); - - /** - * @dev Delegates votes from the sender to `delegatee`. - */ - function delegate(address delegatee) external; - - /** - * @dev Delegates votes from signer to `delegatee`. - */ - function delegateBySig( - address delegatee, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/VotesUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/VotesUpgradeable.sol deleted file mode 100644 index 99386d9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/governance/utils/VotesUpgradeable.sol +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (governance/utils/Votes.sol) -pragma solidity ^0.8.0; - -import "../../utils/ContextUpgradeable.sol"; -import "../../utils/CountersUpgradeable.sol"; -import "../../utils/CheckpointsUpgradeable.sol"; -import "../../utils/cryptography/EIP712Upgradeable.sol"; -import "./IVotesUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be - * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of - * "representative" that will pool delegated voting units from different accounts and can then use it to vote in - * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to - * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative. - * - * This contract is often combined with a token contract such that voting units correspond to token units. For an - * example, see {ERC721Votes}. - * - * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed - * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the - * cost of this history tracking optional. - * - * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return - * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the - * previous example, it would be included in {ERC721-_beforeTokenTransfer}). - * - * _Available since v4.5._ - */ -abstract contract VotesUpgradeable is Initializable, IVotesUpgradeable, ContextUpgradeable, EIP712Upgradeable { - function __Votes_init() internal onlyInitializing { - } - - function __Votes_init_unchained() internal onlyInitializing { - } - using CheckpointsUpgradeable for CheckpointsUpgradeable.History; - using CountersUpgradeable for CountersUpgradeable.Counter; - - bytes32 private constant _DELEGATION_TYPEHASH = - keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - mapping(address => address) private _delegation; - mapping(address => CheckpointsUpgradeable.History) private _delegateCheckpoints; - CheckpointsUpgradeable.History private _totalCheckpoints; - - mapping(address => CountersUpgradeable.Counter) private _nonces; - - /** - * @dev Returns the current amount of votes that `account` has. - */ - function getVotes(address account) public view virtual override returns (uint256) { - return _delegateCheckpoints[account].latest(); - } - - /** - * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { - return _delegateCheckpoints[account].getAtProbablyRecentBlock(blockNumber); - } - - /** - * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). - * - * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. - * Votes that have not been delegated are still part of total supply, even though they would not participate in a - * vote. - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { - require(blockNumber < block.number, "Votes: block not yet mined"); - return _totalCheckpoints.getAtProbablyRecentBlock(blockNumber); - } - - /** - * @dev Returns the current total supply of votes. - */ - function _getTotalSupply() internal view virtual returns (uint256) { - return _totalCheckpoints.latest(); - } - - /** - * @dev Returns the delegate that `account` has chosen. - */ - function delegates(address account) public view virtual override returns (address) { - return _delegation[account]; - } - - /** - * @dev Delegates votes from the sender to `delegatee`. - */ - function delegate(address delegatee) public virtual override { - address account = _msgSender(); - _delegate(account, delegatee); - } - - /** - * @dev Delegates votes from signer to `delegatee`. - */ - function delegateBySig( - address delegatee, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override { - require(block.timestamp <= expiry, "Votes: signature expired"); - address signer = ECDSAUpgradeable.recover( - _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), - v, - r, - s - ); - require(nonce == _useNonce(signer), "Votes: invalid nonce"); - _delegate(signer, delegatee); - } - - /** - * @dev Delegate all of `account`'s voting units to `delegatee`. - * - * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. - */ - function _delegate(address account, address delegatee) internal virtual { - address oldDelegate = delegates(account); - _delegation[account] = delegatee; - - emit DelegateChanged(account, oldDelegate, delegatee); - _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account)); - } - - /** - * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to` - * should be zero. Total supply of voting units will be adjusted with mints and burns. - */ - function _transferVotingUnits( - address from, - address to, - uint256 amount - ) internal virtual { - if (from == address(0)) { - _totalCheckpoints.push(_add, amount); - } - if (to == address(0)) { - _totalCheckpoints.push(_subtract, amount); - } - _moveDelegateVotes(delegates(from), delegates(to), amount); - } - - /** - * @dev Moves delegated votes from one delegate to another. - */ - function _moveDelegateVotes( - address from, - address to, - uint256 amount - ) private { - if (from != to && amount > 0) { - if (from != address(0)) { - (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_subtract, amount); - emit DelegateVotesChanged(from, oldValue, newValue); - } - if (to != address(0)) { - (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_add, amount); - emit DelegateVotesChanged(to, oldValue, newValue); - } - } - } - - function _add(uint256 a, uint256 b) private pure returns (uint256) { - return a + b; - } - - function _subtract(uint256 a, uint256 b) private pure returns (uint256) { - return a - b; - } - - /** - * @dev Consumes a nonce. - * - * Returns the current value and increments nonce. - */ - function _useNonce(address owner) internal virtual returns (uint256 current) { - CountersUpgradeable.Counter storage nonce = _nonces[owner]; - current = nonce.current(); - nonce.increment(); - } - - /** - * @dev Returns an address nonce. - */ - function nonces(address owner) public view virtual returns (uint256) { - return _nonces[owner].current(); - } - - /** - * @dev Returns the contract's {EIP712} domain separator. - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view returns (bytes32) { - return _domainSeparatorV4(); - } - - /** - * @dev Must return the voting units held by an account. - */ - function _getVotingUnits(address) internal view virtual returns (uint256); - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[46] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155MetadataURIUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155MetadataURIUpgradeable.sol deleted file mode 100644 index 35c3f85..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155MetadataURIUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155MetadataURI.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155ReceiverUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155ReceiverUpgradeable.sol deleted file mode 100644 index 1e9e6e3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155ReceiverUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155Receiver.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC1155/IERC1155ReceiverUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155Upgradeable.sol deleted file mode 100644 index 3df26dc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155Upgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC1155/IERC1155Upgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1271Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1271Upgradeable.sol deleted file mode 100644 index 631d222..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1271Upgradeable.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC1271 standard signature validation method for - * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. - * - * _Available since v4.1._ - */ -interface IERC1271Upgradeable { - /** - * @dev Should return whether the signature provided is valid for the provided data - * @param hash Hash of the data to be signed - * @param signature Signature byte array associated with _data - */ - function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363ReceiverUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363ReceiverUpgradeable.sol deleted file mode 100644 index 76cda4e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363ReceiverUpgradeable.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363Receiver.sol) - -pragma solidity ^0.8.0; - -interface IERC1363ReceiverUpgradeable { - /* - * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. - * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) - */ - - /** - * @notice Handle the receipt of ERC1363 tokens - * @dev Any ERC1363 smart contract calls this function on the recipient - * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the token contract address is always the message sender. - * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function - * @param from address The address which are token transferred from - * @param value uint256 The amount of tokens transferred - * @param data bytes Additional data with no specified format - * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` - * unless throwing - */ - function onTransferReceived( - address operator, - address from, - uint256 value, - bytes memory data - ) external returns (bytes4); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363SpenderUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363SpenderUpgradeable.sol deleted file mode 100644 index 997c029..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363SpenderUpgradeable.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363Spender.sol) - -pragma solidity ^0.8.0; - -interface IERC1363SpenderUpgradeable { - /* - * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. - * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) - */ - - /** - * @notice Handle the approval of ERC1363 tokens - * @dev Any ERC1363 smart contract calls this function on the recipient - * after an `approve`. This function MAY throw to revert and reject the - * approval. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the token contract address is always the message sender. - * @param owner address The address which called `approveAndCall` function - * @param value uint256 The amount of tokens to be spent - * @param data bytes Additional data with no specified format - * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` - * unless throwing - */ - function onApprovalReceived( - address owner, - uint256 value, - bytes memory data - ) external returns (bytes4); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363Upgradeable.sol deleted file mode 100644 index fe47947..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1363Upgradeable.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363.sol) - -pragma solidity ^0.8.0; - -import "./IERC20Upgradeable.sol"; -import "./IERC165Upgradeable.sol"; - -interface IERC1363Upgradeable is IERC165Upgradeable, IERC20Upgradeable { - /* - * Note: the ERC-165 identifier for this interface is 0x4bbee2df. - * 0x4bbee2df === - * bytes4(keccak256('transferAndCall(address,uint256)')) ^ - * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ - * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ - * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) - */ - - /* - * Note: the ERC-165 identifier for this interface is 0xfb9ec8ce. - * 0xfb9ec8ce === - * bytes4(keccak256('approveAndCall(address,uint256)')) ^ - * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) - */ - - /** - * @dev Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @return true unless throwing - */ - function transferAndCall(address to, uint256 value) external returns (bool); - - /** - * @dev Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @param data bytes Additional data with no specified format, sent in call to `to` - * @return true unless throwing - */ - function transferAndCall( - address to, - uint256 value, - bytes memory data - ) external returns (bool); - - /** - * @dev Transfer tokens from one address to another and then call `onTransferReceived` on receiver - * @param from address The address which you want to send tokens from - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @return true unless throwing - */ - function transferFromAndCall( - address from, - address to, - uint256 value - ) external returns (bool); - - /** - * @dev Transfer tokens from one address to another and then call `onTransferReceived` on receiver - * @param from address The address which you want to send tokens from - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @param data bytes Additional data with no specified format, sent in call to `to` - * @return true unless throwing - */ - function transferFromAndCall( - address from, - address to, - uint256 value, - bytes memory data - ) external returns (bool); - - /** - * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender - * and then call `onApprovalReceived` on spender. - * @param spender address The address which will spend the funds - * @param value uint256 The amount of tokens to be spent - */ - function approveAndCall(address spender, uint256 value) external returns (bool); - - /** - * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender - * and then call `onApprovalReceived` on spender. - * @param spender address The address which will spend the funds - * @param value uint256 The amount of tokens to be spent - * @param data bytes Additional data with no specified format, sent in call to `spender` - */ - function approveAndCall( - address spender, - uint256 value, - bytes memory data - ) external returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol deleted file mode 100644 index 08eb433..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/IERC165Upgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820ImplementerUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820ImplementerUpgradeable.sol deleted file mode 100644 index 1f5aeba..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820ImplementerUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1820Implementer.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/IERC1820ImplementerUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820RegistryUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820RegistryUpgradeable.sol deleted file mode 100644 index 088fbd6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1820RegistryUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1820Registry.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/IERC1820RegistryUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1967Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1967Upgradeable.sol deleted file mode 100644 index 05ca0f5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1967Upgradeable.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.3) (interfaces/IERC1967.sol) - -pragma solidity ^0.8.0; - -/** - * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. - * - * _Available since v4.9._ - */ -interface IERC1967Upgradeable { - /** - * @dev Emitted when the implementation is upgraded. - */ - event Upgraded(address indexed implementation); - - /** - * @dev Emitted when the admin account has changed. - */ - event AdminChanged(address previousAdmin, address newAdmin); - - /** - * @dev Emitted when the beacon is changed. - */ - event BeaconUpgraded(address indexed beacon); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20MetadataUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20MetadataUpgradeable.sol deleted file mode 100644 index c24417a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20MetadataUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20Metadata.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20Upgradeable.sol deleted file mode 100644 index a0d5cdb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC20Upgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/IERC20Upgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2309Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2309Upgradeable.sol deleted file mode 100644 index 9cb0aae..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2309Upgradeable.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (interfaces/IERC2309.sol) - -pragma solidity ^0.8.0; - -/** - * @dev ERC-2309: ERC-721 Consecutive Transfer Extension. - * - * _Available since v4.8._ - */ -interface IERC2309Upgradeable { - /** - * @dev Emitted when the tokens from `fromTokenId` to `toTokenId` are transferred from `fromAddress` to `toAddress`. - */ - event ConsecutiveTransfer( - uint256 indexed fromTokenId, - uint256 toTokenId, - address indexed fromAddress, - address indexed toAddress - ); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2981Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2981Upgradeable.sol deleted file mode 100644 index c798473..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC2981Upgradeable.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/IERC165Upgradeable.sol"; - -/** - * @dev Interface for the NFT Royalty Standard. - * - * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal - * support for royalty payments across all NFT marketplaces and ecosystem participants. - * - * _Available since v4.5._ - */ -interface IERC2981Upgradeable is IERC165Upgradeable { - /** - * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of - * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. - */ - function royaltyInfo(uint256 tokenId, uint256 salePrice) - external - view - returns (address receiver, uint256 royaltyAmount); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashBorrowerUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashBorrowerUpgradeable.sol deleted file mode 100644 index 3f75175..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashBorrowerUpgradeable.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC3156 FlashBorrower, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - * - * _Available since v4.1._ - */ -interface IERC3156FlashBorrowerUpgradeable { - /** - * @dev Receive a flash loan. - * @param initiator The initiator of the loan. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @param fee The additional amount of tokens to repay. - * @param data Arbitrary data structure, intended to contain user-defined parameters. - * @return The keccak256 hash of "IERC3156FlashBorrower.onFlashLoan" - */ - function onFlashLoan( - address initiator, - address token, - uint256 amount, - uint256 fee, - bytes calldata data - ) external returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashLenderUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashLenderUpgradeable.sol deleted file mode 100644 index d2543d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156FlashLenderUpgradeable.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol) - -pragma solidity ^0.8.0; - -import "./IERC3156FlashBorrowerUpgradeable.sol"; - -/** - * @dev Interface of the ERC3156 FlashLender, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - * - * _Available since v4.1._ - */ -interface IERC3156FlashLenderUpgradeable { - /** - * @dev The amount of currency available to be lended. - * @param token The loan currency. - * @return The amount of `token` that can be borrowed. - */ - function maxFlashLoan(address token) external view returns (uint256); - - /** - * @dev The fee to be charged for a given loan. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @return The amount of `token` to be charged for the loan, on top of the returned principal. - */ - function flashFee(address token, uint256 amount) external view returns (uint256); - - /** - * @dev Initiate a flash loan. - * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @param data Arbitrary data structure, intended to contain user-defined parameters. - */ - function flashLoan( - IERC3156FlashBorrowerUpgradeable receiver, - address token, - uint256 amount, - bytes calldata data - ) external returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156Upgradeable.sol deleted file mode 100644 index 1a9fd64..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC3156Upgradeable.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156.sol) - -pragma solidity ^0.8.0; - -import "./IERC3156FlashBorrowerUpgradeable.sol"; -import "./IERC3156FlashLenderUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC4626Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC4626Upgradeable.sol deleted file mode 100644 index a025d92..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC4626Upgradeable.sol +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (interfaces/IERC4626.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/IERC20Upgradeable.sol"; -import "../token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; - -/** - * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in - * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. - * - * _Available since v4.7._ - */ -interface IERC4626Upgradeable is IERC20Upgradeable, IERC20MetadataUpgradeable { - event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed sender, - address indexed receiver, - address indexed owner, - uint256 assets, - uint256 shares - ); - - /** - * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. - * - * - MUST be an ERC-20 token contract. - * - MUST NOT revert. - */ - function asset() external view returns (address assetTokenAddress); - - /** - * @dev Returns the total amount of the underlying asset that is “managed” by Vault. - * - * - SHOULD include any compounding that occurs from yield. - * - MUST be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT revert. - */ - function totalAssets() external view returns (uint256 totalManagedAssets); - - /** - * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal - * scenario where all the conditions are met. - * - * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - * - MUST NOT revert. - * - * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - * from. - */ - function convertToShares(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal - * scenario where all the conditions are met. - * - * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - * - MUST NOT revert. - * - * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - * from. - */ - function convertToAssets(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, - * through a deposit call. - * - * - MUST return a limited value if receiver is subject to some deposit limit. - * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. - * - MUST NOT revert. - */ - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given - * current on-chain conditions. - * - * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit - * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called - * in the same transaction. - * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the - * deposit would be accepted, regardless if the user has enough tokens approved, etc. - * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by depositing. - */ - function previewDeposit(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. - * - * - MUST emit the Deposit event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * deposit execution, and are accounted for during deposit. - * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not - * approving enough underlying tokens to the Vault contract, etc). - * - * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - */ - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - - /** - * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. - * - MUST return a limited value if receiver is subject to some mint limit. - * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. - * - MUST NOT revert. - */ - function maxMint(address receiver) external view returns (uint256 maxShares); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given - * current on-chain conditions. - * - * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call - * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the - * same transaction. - * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint - * would be accepted, regardless if the user has enough tokens approved, etc. - * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by minting. - */ - function previewMint(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. - * - * - MUST emit the Deposit event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint - * execution, and are accounted for during mint. - * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not - * approving enough underlying tokens to the Vault contract, etc). - * - * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - */ - function mint(uint256 shares, address receiver) external returns (uint256 assets); - - /** - * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the - * Vault, through a withdraw call. - * - * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - * - MUST NOT revert. - */ - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, - * given current on-chain conditions. - * - * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw - * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if - * called - * in the same transaction. - * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though - * the withdrawal would be accepted, regardless if the user has enough shares, etc. - * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by depositing. - */ - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. - * - * - MUST emit the Withdraw event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * withdraw execution, and are accounted for during withdraw. - * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner - * not having enough shares, etc). - * - * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - * Those methods should be performed separately. - */ - function withdraw( - uint256 assets, - address receiver, - address owner - ) external returns (uint256 shares); - - /** - * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, - * through a redeem call. - * - * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. - * - MUST NOT revert. - */ - function maxRedeem(address owner) external view returns (uint256 maxShares); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, - * given current on-chain conditions. - * - * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call - * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the - * same transaction. - * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the - * redemption would be accepted, regardless if the user has enough shares, etc. - * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by redeeming. - */ - function previewRedeem(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. - * - * - MUST emit the Withdraw event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * redeem execution, and are accounted for during redeem. - * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner - * not having enough shares, etc). - * - * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - * Those methods should be performed separately. - */ - function redeem( - uint256 shares, - address receiver, - address owner - ) external returns (uint256 assets); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721EnumerableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721EnumerableUpgradeable.sol deleted file mode 100644 index 06e732d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721EnumerableUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Enumerable.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/IERC721EnumerableUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721MetadataUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721MetadataUpgradeable.sol deleted file mode 100644 index 1ec3b80..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721MetadataUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721ReceiverUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721ReceiverUpgradeable.sol deleted file mode 100644 index bdbe94c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721ReceiverUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Receiver.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/IERC721ReceiverUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721Upgradeable.sol deleted file mode 100644 index 414e630..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC721Upgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/IERC721Upgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777RecipientUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777RecipientUpgradeable.sol deleted file mode 100644 index 219b28d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777RecipientUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777Recipient.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC777/IERC777RecipientUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777SenderUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777SenderUpgradeable.sol deleted file mode 100644 index 0e1440b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777SenderUpgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777Sender.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC777/IERC777SenderUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777Upgradeable.sol deleted file mode 100644 index 858d3f4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC777Upgradeable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC777/IERC777Upgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/README.adoc deleted file mode 100644 index 5b4cedf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/README.adoc +++ /dev/null @@ -1,56 +0,0 @@ -= Interfaces - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/interfaces - -== List of standardized interfaces -These interfaces are available as `.sol` files, and also as compiler `.json` ABI files (through the npm package). These -are useful to interact with third party contracts that implement them. - -- {IERC20} -- {IERC20Metadata} -- {IERC165} -- {IERC721} -- {IERC721Receiver} -- {IERC721Enumerable} -- {IERC721Metadata} -- {IERC777} -- {IERC777Recipient} -- {IERC777Sender} -- {IERC1155} -- {IERC1155Receiver} -- {IERC1155MetadataURI} -- {IERC1271} -- {IERC1363} -- {IERC1820Implementer} -- {IERC1820Registry} -- {IERC1822Proxiable} -- {IERC2612} -- {IERC2981} -- {IERC3156FlashLender} -- {IERC3156FlashBorrower} -- {IERC4626} - -== Detailed ABI - -{{IERC1271}} - -{{IERC1363}} - -{{IERC1363Receiver}} - -{{IERC1820Implementer}} - -{{IERC1820Registry}} - -{{IERC1822Proxiable}} - -{{IERC2612}} - -{{IERC2981}} - -{{IERC3156FlashLender}} - -{{IERC3156FlashBorrower}} - -{{IERC4626}} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC1822Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC1822Upgradeable.sol deleted file mode 100644 index e14596a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC1822Upgradeable.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) - -pragma solidity ^0.8.0; - -/** - * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified - * proxy whose upgrades are fully controlled by the current implementation. - */ -interface IERC1822ProxiableUpgradeable { - /** - * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation - * address. - * - * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks - * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this - * function revert if invoked through a proxy. - */ - function proxiableUUID() external view returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC2612Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC2612Upgradeable.sol deleted file mode 100644 index 0dda61e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/interfaces/draft-IERC2612Upgradeable.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/draft-IERC2612.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol"; - -interface IERC2612Upgradeable is IERC20PermitUpgradeable {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/ERC2771ContextUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/ERC2771ContextUpgradeable.sol deleted file mode 100644 index 3850112..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/ERC2771ContextUpgradeable.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol) - -pragma solidity ^0.8.9; - -import "../utils/ContextUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Context variant with ERC2771 support. - */ -abstract contract ERC2771ContextUpgradeable is Initializable, ContextUpgradeable { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _trustedForwarder; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address trustedForwarder) { - _trustedForwarder = trustedForwarder; - } - - function isTrustedForwarder(address forwarder) public view virtual returns (bool) { - return forwarder == _trustedForwarder; - } - - function _msgSender() internal view virtual override returns (address sender) { - if (isTrustedForwarder(msg.sender)) { - // The assembly code is more direct than the Solidity version using `abi.decode`. - /// @solidity memory-safe-assembly - assembly { - sender := shr(96, calldataload(sub(calldatasize(), 20))) - } - } else { - return super._msgSender(); - } - } - - function _msgData() internal view virtual override returns (bytes calldata) { - if (isTrustedForwarder(msg.sender)) { - return msg.data[:msg.data.length - 20]; - } else { - return super._msgData(); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/MinimalForwarderUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/MinimalForwarderUpgradeable.sol deleted file mode 100644 index 2652252..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/MinimalForwarderUpgradeable.sol +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (metatx/MinimalForwarder.sol) - -pragma solidity ^0.8.0; - -import "../utils/cryptography/ECDSAUpgradeable.sol"; -import "../utils/cryptography/EIP712Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Simple minimal forwarder to be used together with an ERC2771 compatible contract. See {ERC2771Context}. - * - * MinimalForwarder is mainly meant for testing, as it is missing features to be a good production-ready forwarder. This - * contract does not intend to have all the properties that are needed for a sound forwarding system. A fully - * functioning forwarding system with good properties requires more complexity. We suggest you look at other projects - * such as the GSN which do have the goal of building a system like that. - */ -contract MinimalForwarderUpgradeable is Initializable, EIP712Upgradeable { - using ECDSAUpgradeable for bytes32; - - struct ForwardRequest { - address from; - address to; - uint256 value; - uint256 gas; - uint256 nonce; - bytes data; - } - - bytes32 private constant _TYPEHASH = - keccak256("ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data)"); - - mapping(address => uint256) private _nonces; - - function __MinimalForwarder_init() internal onlyInitializing { - __EIP712_init_unchained("MinimalForwarder", "0.0.1"); - } - - function __MinimalForwarder_init_unchained() internal onlyInitializing {} - - function getNonce(address from) public view returns (uint256) { - return _nonces[from]; - } - - function verify(ForwardRequest calldata req, bytes calldata signature) public view returns (bool) { - address signer = _hashTypedDataV4( - keccak256(abi.encode(_TYPEHASH, req.from, req.to, req.value, req.gas, req.nonce, keccak256(req.data))) - ).recover(signature); - return _nonces[req.from] == req.nonce && signer == req.from; - } - - function execute(ForwardRequest calldata req, bytes calldata signature) - public - payable - returns (bool, bytes memory) - { - require(verify(req, signature), "MinimalForwarder: signature does not match request"); - _nonces[req.from] = req.nonce + 1; - - (bool success, bytes memory returndata) = req.to.call{gas: req.gas, value: req.value}( - abi.encodePacked(req.data, req.from) - ); - - // Validate that the relayer has sent enough gas for the call. - // See https://ronan.eth.limo/blog/ethereum-gas-dangers/ - if (gasleft() <= req.gas / 63) { - // We explicitly trigger invalid opcode to consume all gas and bubble-up the effects, since - // neither revert or assert consume all gas since Solidity 0.8.0 - // https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require - /// @solidity memory-safe-assembly - assembly { - invalid() - } - } - - return (success, returndata); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/README.adoc deleted file mode 100644 index eccdeaf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/metatx/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= Meta Transactions - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/metatx - -== Core - -{{ERC2771Context}} - -== Utils - -{{MinimalForwarder}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlCrossChainMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlCrossChainMockUpgradeable.sol deleted file mode 100644 index 959b4af..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlCrossChainMockUpgradeable.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.4; - -import "../access/AccessControlCrossChainUpgradeable.sol"; -import "../crosschain/arbitrum/CrossChainEnabledArbitrumL2Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract AccessControlCrossChainMockUpgradeable is Initializable, AccessControlCrossChainUpgradeable, CrossChainEnabledArbitrumL2Upgradeable { - function __AccessControlCrossChainMock_init() internal onlyInitializing { - __AccessControlCrossChainMock_init_unchained(); - } - - function __AccessControlCrossChainMock_init_unchained() internal onlyInitializing { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public { - _setRoleAdmin(roleId, adminRoleId); - } - - function senderProtected(bytes32 roleId) public onlyRole(roleId) {} - - function crossChainRoleAlias(bytes32 role) public pure returns (bytes32) { - return _crossChainRoleAlias(role); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlEnumerableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlEnumerableMockUpgradeable.sol deleted file mode 100644 index 7959eee..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlEnumerableMockUpgradeable.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/AccessControlEnumerableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract AccessControlEnumerableMockUpgradeable is Initializable, AccessControlEnumerableUpgradeable { - function __AccessControlEnumerableMock_init() internal onlyInitializing { - __AccessControlEnumerableMock_init_unchained(); - } - - function __AccessControlEnumerableMock_init_unchained() internal onlyInitializing { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public { - _setRoleAdmin(roleId, adminRoleId); - } - - function senderProtected(bytes32 roleId) public onlyRole(roleId) {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlMockUpgradeable.sol deleted file mode 100644 index a770f5d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AccessControlMockUpgradeable.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/AccessControlUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract AccessControlMockUpgradeable is Initializable, AccessControlUpgradeable { - function __AccessControlMock_init() internal onlyInitializing { - __AccessControlMock_init_unchained(); - } - - function __AccessControlMock_init_unchained() internal onlyInitializing { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public { - _setRoleAdmin(roleId, adminRoleId); - } - - function senderProtected(bytes32 roleId) public onlyRole(roleId) {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AddressImplUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AddressImplUpgradeable.sol deleted file mode 100644 index 8013c2f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/AddressImplUpgradeable.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/AddressUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract AddressImplUpgradeable is Initializable { - function __AddressImpl_init() internal onlyInitializing { - } - - function __AddressImpl_init_unchained() internal onlyInitializing { - } - string public sharedAnswer; - - event CallReturnValue(string data); - - function isContract(address account) external view returns (bool) { - return AddressUpgradeable.isContract(account); - } - - function sendValue(address payable receiver, uint256 amount) external { - AddressUpgradeable.sendValue(receiver, amount); - } - - function functionCall(address target, bytes calldata data) external { - bytes memory returnData = AddressUpgradeable.functionCall(target, data); - emit CallReturnValue(abi.decode(returnData, (string))); - } - - function functionCallWithValue( - address target, - bytes calldata data, - uint256 value - ) external payable { - bytes memory returnData = AddressUpgradeable.functionCallWithValue(target, data, value); - emit CallReturnValue(abi.decode(returnData, (string))); - } - - function functionStaticCall(address target, bytes calldata data) external { - bytes memory returnData = AddressUpgradeable.functionStaticCall(target, data); - emit CallReturnValue(abi.decode(returnData, (string))); - } - - // sendValue's tests require the contract to hold Ether - receive() external payable {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ArraysMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ArraysMockUpgradeable.sol deleted file mode 100644 index e4e7c99..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ArraysMockUpgradeable.sol +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/ArraysUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract Uint256ArraysMockUpgradeable is Initializable { - using ArraysUpgradeable for uint256[]; - - uint256[] private _array; - - function __Uint256ArraysMock_init(uint256[] memory array) internal onlyInitializing { - __Uint256ArraysMock_init_unchained(array); - } - - function __Uint256ArraysMock_init_unchained(uint256[] memory array) internal onlyInitializing { - _array = array; - } - - function findUpperBound(uint256 element) external view returns (uint256) { - return _array.findUpperBound(element); - } - - function unsafeAccess(uint256 pos) external view returns (uint256) { - return _array.unsafeAccess(pos).value; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} - -contract AddressArraysMockUpgradeable is Initializable { - using ArraysUpgradeable for address[]; - - address[] private _array; - - function __AddressArraysMock_init(address[] memory array) internal onlyInitializing { - __AddressArraysMock_init_unchained(array); - } - - function __AddressArraysMock_init_unchained(address[] memory array) internal onlyInitializing { - _array = array; - } - - function unsafeAccess(uint256 pos) external view returns (address) { - return _array.unsafeAccess(pos).value; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} - -contract Bytes32ArraysMockUpgradeable is Initializable { - using ArraysUpgradeable for bytes32[]; - - bytes32[] private _array; - - function __Bytes32ArraysMock_init(bytes32[] memory array) internal onlyInitializing { - __Bytes32ArraysMock_init_unchained(array); - } - - function __Bytes32ArraysMock_init_unchained(bytes32[] memory array) internal onlyInitializing { - _array = array; - } - - function unsafeAccess(uint256 pos) external view returns (bytes32) { - return _array.unsafeAccess(pos).value; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BadBeaconUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BadBeaconUpgradeable.sol deleted file mode 100644 index f795145..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BadBeaconUpgradeable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; -import "../proxy/utils/Initializable.sol"; - -contract BadBeaconNoImplUpgradeable is Initializable { function __BadBeaconNoImpl_init() internal onlyInitializing { - } - - function __BadBeaconNoImpl_init_unchained() internal onlyInitializing { - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract BadBeaconNotContractUpgradeable is Initializable { - function __BadBeaconNotContract_init() internal onlyInitializing { - } - - function __BadBeaconNotContract_init_unchained() internal onlyInitializing { - } - function implementation() external pure returns (address) { - return address(0x1); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Base64MockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Base64MockUpgradeable.sol deleted file mode 100644 index 5c7e6df..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Base64MockUpgradeable.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Base64Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract Base64MockUpgradeable is Initializable { - function __Base64Mock_init() internal onlyInitializing { - } - - function __Base64Mock_init_unchained() internal onlyInitializing { - } - function encode(bytes memory value) external pure returns (string memory) { - return Base64Upgradeable.encode(value); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BitmapMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BitmapMockUpgradeable.sol deleted file mode 100644 index bf5bcb1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/BitmapMockUpgradeable.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/structs/BitMapsUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract BitMapMockUpgradeable is Initializable { - function __BitMapMock_init() internal onlyInitializing { - } - - function __BitMapMock_init_unchained() internal onlyInitializing { - } - using BitMapsUpgradeable for BitMapsUpgradeable.BitMap; - - BitMapsUpgradeable.BitMap private _bitmap; - - function get(uint256 index) public view returns (bool) { - return _bitmap.get(index); - } - - function setTo(uint256 index, bool value) public { - _bitmap.setTo(index, value); - } - - function set(uint256 index) public { - _bitmap.set(index); - } - - function unset(uint256 index) public { - _bitmap.unset(index); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CallReceiverMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CallReceiverMockUpgradeable.sol deleted file mode 100644 index 724979c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CallReceiverMockUpgradeable.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; -import "../proxy/utils/Initializable.sol"; - -contract CallReceiverMockUpgradeable is Initializable { - function __CallReceiverMock_init() internal onlyInitializing { - } - - function __CallReceiverMock_init_unchained() internal onlyInitializing { - } - string public sharedAnswer; - - event MockFunctionCalled(); - event MockFunctionCalledWithArgs(uint256 a, uint256 b); - - uint256[] private _array; - - function mockFunction() public payable returns (string memory) { - emit MockFunctionCalled(); - - return "0x1234"; - } - - function mockFunctionWithArgs(uint256 a, uint256 b) public payable returns (string memory) { - emit MockFunctionCalledWithArgs(a, b); - - return "0x1234"; - } - - function mockFunctionNonPayable() public returns (string memory) { - emit MockFunctionCalled(); - - return "0x1234"; - } - - function mockStaticFunction() public pure returns (string memory) { - return "0x1234"; - } - - function mockFunctionRevertsNoReason() public payable { - revert(); - } - - function mockFunctionRevertsReason() public payable { - revert("CallReceiverMock: reverting"); - } - - function mockFunctionThrows() public payable { - assert(false); - } - - function mockFunctionOutOfGas() public payable { - for (uint256 i = 0; ; ++i) { - _array.push(i); - } - } - - function mockFunctionWritesStorage() public returns (string memory) { - sharedAnswer = "42"; - return "0x1234"; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CheckpointsMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CheckpointsMockUpgradeable.sol deleted file mode 100644 index e4b0e32..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CheckpointsMockUpgradeable.sol +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/CheckpointsMock.js. - -pragma solidity ^0.8.0; - -import "../utils/CheckpointsUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract CheckpointsMockUpgradeable is Initializable { - function __CheckpointsMock_init() internal onlyInitializing { - } - - function __CheckpointsMock_init_unchained() internal onlyInitializing { - } - using CheckpointsUpgradeable for CheckpointsUpgradeable.History; - - CheckpointsUpgradeable.History private _totalCheckpoints; - - function latest() public view returns (uint256) { - return _totalCheckpoints.latest(); - } - - function latestCheckpoint() - public - view - returns ( - bool, - uint256, - uint256 - ) - { - return _totalCheckpoints.latestCheckpoint(); - } - - function length() public view returns (uint256) { - return _totalCheckpoints.length(); - } - - function push(uint256 value) public returns (uint256, uint256) { - return _totalCheckpoints.push(value); - } - - function getAtBlock(uint256 blockNumber) public view returns (uint256) { - return _totalCheckpoints.getAtBlock(blockNumber); - } - - function getAtProbablyRecentBlock(uint256 blockNumber) public view returns (uint256) { - return _totalCheckpoints.getAtProbablyRecentBlock(blockNumber); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} - -contract Checkpoints224MockUpgradeable is Initializable { - function __Checkpoints224Mock_init() internal onlyInitializing { - } - - function __Checkpoints224Mock_init_unchained() internal onlyInitializing { - } - using CheckpointsUpgradeable for CheckpointsUpgradeable.Trace224; - - CheckpointsUpgradeable.Trace224 private _totalCheckpoints; - - function latest() public view returns (uint224) { - return _totalCheckpoints.latest(); - } - - function latestCheckpoint() - public - view - returns ( - bool, - uint32, - uint224 - ) - { - return _totalCheckpoints.latestCheckpoint(); - } - - function length() public view returns (uint256) { - return _totalCheckpoints.length(); - } - - function push(uint32 key, uint224 value) public returns (uint224, uint224) { - return _totalCheckpoints.push(key, value); - } - - function lowerLookup(uint32 key) public view returns (uint224) { - return _totalCheckpoints.lowerLookup(key); - } - - function upperLookup(uint32 key) public view returns (uint224) { - return _totalCheckpoints.upperLookup(key); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} - -contract Checkpoints160MockUpgradeable is Initializable { - function __Checkpoints160Mock_init() internal onlyInitializing { - } - - function __Checkpoints160Mock_init_unchained() internal onlyInitializing { - } - using CheckpointsUpgradeable for CheckpointsUpgradeable.Trace160; - - CheckpointsUpgradeable.Trace160 private _totalCheckpoints; - - function latest() public view returns (uint160) { - return _totalCheckpoints.latest(); - } - - function latestCheckpoint() - public - view - returns ( - bool, - uint96, - uint160 - ) - { - return _totalCheckpoints.latestCheckpoint(); - } - - function length() public view returns (uint256) { - return _totalCheckpoints.length(); - } - - function push(uint96 key, uint160 value) public returns (uint160, uint160) { - return _totalCheckpoints.push(key, value); - } - - function lowerLookup(uint96 key) public view returns (uint160) { - return _totalCheckpoints.lowerLookup(key); - } - - function upperLookup(uint96 key) public view returns (uint160) { - return _totalCheckpoints.upperLookup(key); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClashingImplementationUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClashingImplementationUpgradeable.sol deleted file mode 100644 index ec847bf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClashingImplementationUpgradeable.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation contract with a payable admin() function made to clash with TransparentUpgradeableProxy's to - * test correct functioning of the Transparent Proxy feature. - */ -contract ClashingImplementationUpgradeable is Initializable { - function __ClashingImplementation_init() internal onlyInitializing { - } - - function __ClashingImplementation_init_unchained() internal onlyInitializing { - } - function admin() external payable returns (address) { - return 0x0000000000000000000000000000000011111142; - } - - function delegatedFunction() external pure returns (bool) { - return true; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClonesMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClonesMockUpgradeable.sol deleted file mode 100644 index d51f606..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ClonesMockUpgradeable.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/ClonesUpgradeable.sol"; -import "../utils/AddressUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ClonesMockUpgradeable is Initializable { - function __ClonesMock_init() internal onlyInitializing { - } - - function __ClonesMock_init_unchained() internal onlyInitializing { - } - using AddressUpgradeable for address; - using ClonesUpgradeable for address; - - event NewInstance(address instance); - - function clone(address implementation, bytes calldata initdata) public payable { - _initAndEmit(implementation.clone(), initdata); - } - - function cloneDeterministic( - address implementation, - bytes32 salt, - bytes calldata initdata - ) public payable { - _initAndEmit(implementation.cloneDeterministic(salt), initdata); - } - - function predictDeterministicAddress(address implementation, bytes32 salt) public view returns (address predicted) { - return implementation.predictDeterministicAddress(salt); - } - - function _initAndEmit(address instance, bytes memory initdata) private { - if (initdata.length > 0) { - instance.functionCallWithValue(initdata, msg.value); - } - emit NewInstance(instance); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ConditionalEscrowMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ConditionalEscrowMockUpgradeable.sol deleted file mode 100644 index 4cf9ac7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ConditionalEscrowMockUpgradeable.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/escrow/ConditionalEscrowUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -// mock class using ConditionalEscrow -contract ConditionalEscrowMockUpgradeable is Initializable, ConditionalEscrowUpgradeable { - function __ConditionalEscrowMock_init() internal onlyInitializing { - __Ownable_init_unchained(); - } - - function __ConditionalEscrowMock_init_unchained() internal onlyInitializing { - } - mapping(address => bool) private _allowed; - - function setAllowed(address payee, bool allowed) public { - _allowed[payee] = allowed; - } - - function withdrawalAllowed(address payee) public view override returns (bool) { - return _allowed[payee]; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ContextMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ContextMockUpgradeable.sol deleted file mode 100644 index 6ec35c8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ContextMockUpgradeable.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/ContextUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ContextMockUpgradeable is Initializable, ContextUpgradeable { - function __ContextMock_init() internal onlyInitializing { - } - - function __ContextMock_init_unchained() internal onlyInitializing { - } - event Sender(address sender); - - function msgSender() public { - emit Sender(_msgSender()); - } - - event Data(bytes data, uint256 integerValue, string stringValue); - - function msgData(uint256 integerValue, string memory stringValue) public { - emit Data(_msgData(), integerValue, stringValue); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract ContextMockCallerUpgradeable is Initializable { - function __ContextMockCaller_init() internal onlyInitializing { - } - - function __ContextMockCaller_init_unchained() internal onlyInitializing { - } - function callSender(ContextMockUpgradeable context) public { - context.msgSender(); - } - - function callData( - ContextMockUpgradeable context, - uint256 integerValue, - string memory stringValue - ) public { - context.msgData(integerValue, stringValue); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CountersImplUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CountersImplUpgradeable.sol deleted file mode 100644 index 5575308..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/CountersImplUpgradeable.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/CountersUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract CountersImplUpgradeable is Initializable { - function __CountersImpl_init() internal onlyInitializing { - } - - function __CountersImpl_init_unchained() internal onlyInitializing { - } - using CountersUpgradeable for CountersUpgradeable.Counter; - - CountersUpgradeable.Counter private _counter; - - function current() public view returns (uint256) { - return _counter.current(); - } - - function increment() public { - _counter.increment(); - } - - function decrement() public { - _counter.decrement(); - } - - function reset() public { - _counter.reset(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Create2ImplUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Create2ImplUpgradeable.sol deleted file mode 100644 index 4d7f5d9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Create2ImplUpgradeable.sol +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Create2Upgradeable.sol"; -import "../utils/introspection/ERC1820ImplementerUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract Create2ImplUpgradeable is Initializable { - function __Create2Impl_init() internal onlyInitializing { - } - - function __Create2Impl_init_unchained() internal onlyInitializing { - } - function deploy( - uint256 value, - bytes32 salt, - bytes memory code - ) public { - Create2Upgradeable.deploy(value, salt, code); - } - - function deployERC1820Implementer(uint256 value, bytes32 salt) public { - Create2Upgradeable.deploy(value, salt, type(ERC1820ImplementerUpgradeable).creationCode); - } - - function computeAddress(bytes32 salt, bytes32 codeHash) public view returns (address) { - return Create2Upgradeable.computeAddress(salt, codeHash); - } - - function computeAddressWithDeployer( - bytes32 salt, - bytes32 codeHash, - address deployer - ) public pure returns (address) { - return Create2Upgradeable.computeAddress(salt, codeHash, deployer); - } - - receive() external payable {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DoubleEndedQueueMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DoubleEndedQueueMockUpgradeable.sol deleted file mode 100644 index f0ca4c5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DoubleEndedQueueMockUpgradeable.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/structs/DoubleEndedQueueUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -// Bytes32Deque -contract Bytes32DequeMockUpgradeable is Initializable { - function __Bytes32DequeMock_init() internal onlyInitializing { - } - - function __Bytes32DequeMock_init_unchained() internal onlyInitializing { - } - using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque; - - event OperationResult(bytes32 value); - - DoubleEndedQueueUpgradeable.Bytes32Deque private _vector; - - function pushBack(bytes32 value) public { - _vector.pushBack(value); - } - - function pushFront(bytes32 value) public { - _vector.pushFront(value); - } - - function popFront() public returns (bytes32) { - bytes32 value = _vector.popFront(); - emit OperationResult(value); - return value; - } - - function popBack() public returns (bytes32) { - bytes32 value = _vector.popBack(); - emit OperationResult(value); - return value; - } - - function front() public view returns (bytes32) { - return _vector.front(); - } - - function back() public view returns (bytes32) { - return _vector.back(); - } - - function at(uint256 i) public view returns (bytes32) { - return _vector.at(i); - } - - function clear() public { - _vector.clear(); - } - - function length() public view returns (uint256) { - return _vector.length(); - } - - function empty() public view returns (bool) { - return _vector.empty(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DummyImplementationUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DummyImplementationUpgradeable.sol deleted file mode 100644 index 8d8aceb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/DummyImplementationUpgradeable.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; -import "../proxy/utils/Initializable.sol"; - -abstract contract ImplUpgradeable is Initializable { - function __Impl_init() internal onlyInitializing { - } - - function __Impl_init_unchained() internal onlyInitializing { - } - function version() public pure virtual returns (string memory); - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract DummyImplementationUpgradeable is Initializable { - function __DummyImplementation_init() internal onlyInitializing { - } - - function __DummyImplementation_init_unchained() internal onlyInitializing { - } - uint256 public value; - string public text; - uint256[] public values; - - function initializeNonPayable() public { - value = 10; - } - - function initializePayable() public payable { - value = 100; - } - - function initializeNonPayableWithValue(uint256 _value) public { - value = _value; - } - - function initializePayableWithValue(uint256 _value) public payable { - value = _value; - } - - function initialize( - uint256 _value, - string memory _text, - uint256[] memory _values - ) public { - value = _value; - text = _text; - values = _values; - } - - function get() public pure returns (bool) { - return true; - } - - function version() public pure virtual returns (string memory) { - return "V1"; - } - - function reverts() public pure { - require(false, "DummyImplementation reverted"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} - -contract DummyImplementationV2Upgradeable is Initializable, DummyImplementationUpgradeable { - function __DummyImplementationV2_init() internal onlyInitializing { - } - - function __DummyImplementationV2_init_unchained() internal onlyInitializing { - } - function migrate(uint256 newVal) public payable { - value = newVal; - } - - function version() public pure override returns (string memory) { - return "V2"; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ECDSAMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ECDSAMockUpgradeable.sol deleted file mode 100644 index 63db89c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ECDSAMockUpgradeable.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/cryptography/ECDSAUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ECDSAMockUpgradeable is Initializable { - function __ECDSAMock_init() internal onlyInitializing { - } - - function __ECDSAMock_init_unchained() internal onlyInitializing { - } - using ECDSAUpgradeable for bytes32; - using ECDSAUpgradeable for bytes; - - function recover(bytes32 hash, bytes memory signature) public pure returns (address) { - return hash.recover(signature); - } - - // solhint-disable-next-line func-name-mixedcase - function recover_v_r_s( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) public pure returns (address) { - return hash.recover(v, r, s); - } - - // solhint-disable-next-line func-name-mixedcase - function recover_r_vs( - bytes32 hash, - bytes32 r, - bytes32 vs - ) public pure returns (address) { - return hash.recover(r, vs); - } - - function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) { - return hash.toEthSignedMessageHash(); - } - - function toEthSignedMessageHash(bytes memory s) public pure returns (bytes32) { - return s.toEthSignedMessageHash(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EIP712ExternalUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EIP712ExternalUpgradeable.sol deleted file mode 100644 index 0172b86..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EIP712ExternalUpgradeable.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/cryptography/ECDSAUpgradeable.sol"; -import "../utils/cryptography/EIP712Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract EIP712ExternalUpgradeable is Initializable, EIP712Upgradeable { - function __EIP712External_init(string memory name, string memory version) internal onlyInitializing { - __EIP712_init_unchained(name, version); - } - - function __EIP712External_init_unchained(string memory, string memory) internal onlyInitializing {} - - function domainSeparator() external view returns (bytes32) { - return _domainSeparatorV4(); - } - - function verify( - bytes memory signature, - address signer, - address mailTo, - string memory mailContents - ) external view { - bytes32 digest = _hashTypedDataV4( - keccak256(abi.encode(keccak256("Mail(address to,string contents)"), mailTo, keccak256(bytes(mailContents)))) - ); - address recoveredSigner = ECDSAUpgradeable.recover(digest, signature); - require(recoveredSigner == signer); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155BurnableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155BurnableMockUpgradeable.sol deleted file mode 100644 index d6f4d48..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155BurnableMockUpgradeable.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC1155BurnableMockUpgradeable is Initializable, ERC1155BurnableUpgradeable { - function __ERC1155BurnableMock_init(string memory uri) internal onlyInitializing { - __ERC1155_init_unchained(uri); - } - - function __ERC1155BurnableMock_init_unchained(string memory) internal onlyInitializing {} - - function mint( - address to, - uint256 id, - uint256 value, - bytes memory data - ) public { - _mint(to, id, value, data); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155MockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155MockUpgradeable.sol deleted file mode 100644 index 773cf78..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155MockUpgradeable.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC1155/ERC1155Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @title ERC1155Mock - * This mock just publicizes internal functions for testing purposes - */ -contract ERC1155MockUpgradeable is Initializable, ERC1155Upgradeable { - function __ERC1155Mock_init(string memory uri) internal onlyInitializing { - __ERC1155_init_unchained(uri); - } - - function __ERC1155Mock_init_unchained(string memory) internal onlyInitializing {} - - function setURI(string memory newuri) public { - _setURI(newuri); - } - - function mint( - address to, - uint256 id, - uint256 value, - bytes memory data - ) public { - _mint(to, id, value, data); - } - - function mintBatch( - address to, - uint256[] memory ids, - uint256[] memory values, - bytes memory data - ) public { - _mintBatch(to, ids, values, data); - } - - function burn( - address owner, - uint256 id, - uint256 value - ) public { - _burn(owner, id, value); - } - - function burnBatch( - address owner, - uint256[] memory ids, - uint256[] memory values - ) public { - _burnBatch(owner, ids, values); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155PausableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155PausableMockUpgradeable.sol deleted file mode 100644 index 7d7bcde..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155PausableMockUpgradeable.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./ERC1155MockUpgradeable.sol"; -import "../token/ERC1155/extensions/ERC1155PausableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC1155PausableMockUpgradeable is Initializable, ERC1155MockUpgradeable, ERC1155PausableUpgradeable { - function __ERC1155PausableMock_init(string memory uri) internal onlyInitializing { - __ERC1155_init_unchained(uri); - __ERC1155Mock_init_unchained(uri); - __Pausable_init_unchained(); - } - - function __ERC1155PausableMock_init_unchained(string memory) internal onlyInitializing {} - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal override(ERC1155Upgradeable, ERC1155PausableUpgradeable) { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155ReceiverMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155ReceiverMockUpgradeable.sol deleted file mode 100644 index bb639e7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155ReceiverMockUpgradeable.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC1155/IERC1155ReceiverUpgradeable.sol"; -import "../utils/introspection/ERC165Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC1155ReceiverMockUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable { - bytes4 private _recRetval; - bool private _recReverts; - bytes4 private _batRetval; - bool private _batReverts; - - event Received(address operator, address from, uint256 id, uint256 value, bytes data, uint256 gas); - event BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data, uint256 gas); - - function __ERC1155ReceiverMock_init( - bytes4 recRetval, - bool recReverts, - bytes4 batRetval, - bool batReverts - ) internal onlyInitializing { - __ERC1155ReceiverMock_init_unchained(recRetval, recReverts, batRetval, batReverts); - } - - function __ERC1155ReceiverMock_init_unchained( - bytes4 recRetval, - bool recReverts, - bytes4 batRetval, - bool batReverts - ) internal onlyInitializing { - _recRetval = recRetval; - _recReverts = recReverts; - _batRetval = batRetval; - _batReverts = batReverts; - } - - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) external override returns (bytes4) { - require(!_recReverts, "ERC1155ReceiverMock: reverting on receive"); - emit Received(operator, from, id, value, data, gasleft()); - return _recRetval; - } - - function onERC1155BatchReceived( - address operator, - address from, - uint256[] calldata ids, - uint256[] calldata values, - bytes calldata data - ) external override returns (bytes4) { - require(!_batReverts, "ERC1155ReceiverMock: reverting on batch receive"); - emit BatchReceived(operator, from, ids, values, data, gasleft()); - return _batRetval; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155SupplyMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155SupplyMockUpgradeable.sol deleted file mode 100644 index 6684b5c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155SupplyMockUpgradeable.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./ERC1155MockUpgradeable.sol"; -import "../token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC1155SupplyMockUpgradeable is Initializable, ERC1155MockUpgradeable, ERC1155SupplyUpgradeable { - function __ERC1155SupplyMock_init(string memory uri) internal onlyInitializing { - __ERC1155_init_unchained(uri); - __ERC1155Mock_init_unchained(uri); - } - - function __ERC1155SupplyMock_init_unchained(string memory) internal onlyInitializing {} - - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155URIStorageMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155URIStorageMockUpgradeable.sol deleted file mode 100644 index e12d9c0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1155URIStorageMockUpgradeable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./ERC1155MockUpgradeable.sol"; -import "../token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC1155URIStorageMockUpgradeable is Initializable, ERC1155MockUpgradeable, ERC1155URIStorageUpgradeable { - function __ERC1155URIStorageMock_init(string memory _uri) internal onlyInitializing { - __ERC1155_init_unchained(_uri); - __ERC1155Mock_init_unchained(_uri); - __ERC1155URIStorage_init_unchained(); - } - - function __ERC1155URIStorageMock_init_unchained(string memory) internal onlyInitializing {} - - function uri(uint256 tokenId) public view override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable) returns (string memory) { - return ERC1155URIStorageUpgradeable.uri(tokenId); - } - - function setURI(uint256 tokenId, string memory _tokenURI) public { - _setURI(tokenId, _tokenURI); - } - - function setBaseURI(string memory baseURI) public { - _setBaseURI(baseURI); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1271WalletMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1271WalletMockUpgradeable.sol deleted file mode 100644 index d37d5c1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1271WalletMockUpgradeable.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/OwnableUpgradeable.sol"; -import "../interfaces/IERC1271Upgradeable.sol"; -import "../utils/cryptography/ECDSAUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC1271WalletMockUpgradeable is Initializable, OwnableUpgradeable, IERC1271Upgradeable { - function __ERC1271WalletMock_init(address originalOwner) internal onlyInitializing { - __Ownable_init_unchained(); - __ERC1271WalletMock_init_unchained(originalOwner); - } - - function __ERC1271WalletMock_init_unchained(address originalOwner) internal onlyInitializing { - transferOwnership(originalOwner); - } - - function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) { - return ECDSAUpgradeable.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract ERC1271MaliciousMockUpgradeable is Initializable, IERC1271Upgradeable { - function __ERC1271MaliciousMock_init() internal onlyInitializing { - } - - function __ERC1271MaliciousMock_init_unchained() internal onlyInitializing { - } - function isValidSignature(bytes32, bytes memory) public pure override returns (bytes4) { - assembly { - mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - return(0, 32) - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165InterfacesSupportedUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165InterfacesSupportedUpgradeable.sol deleted file mode 100644 index 34a0954..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165InterfacesSupportedUpgradeable.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * https://eips.ethereum.org/EIPS/eip-214#specification - * From the specification: - * > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead - * throw an exception. - * > These operations include [...], LOG0, LOG1, LOG2, [...] - * - * therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works) - * solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it - */ -contract SupportsInterfaceWithLookupMockUpgradeable is Initializable, IERC165Upgradeable { - /* - * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 - */ - bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7; - - /** - * @dev A mapping of interface id to whether or not it's supported. - */ - mapping(bytes4 => bool) private _supportedInterfaces; - - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implement ERC165 itself. - */ - function __SupportsInterfaceWithLookupMock_init() internal onlyInitializing { - __SupportsInterfaceWithLookupMock_init_unchained(); - } - - function __SupportsInterfaceWithLookupMock_init_unchained() internal onlyInitializing { - _registerInterface(INTERFACE_ID_ERC165); - } - - /** - * @dev Implement supportsInterface(bytes4) using a lookup table. - */ - function supportsInterface(bytes4 interfaceId) public view override returns (bool) { - return _supportedInterfaces[interfaceId]; - } - - /** - * @dev Private method for registering an interface. - */ - function _registerInterface(bytes4 interfaceId) internal { - require(interfaceId != 0xffffffff, "ERC165InterfacesSupported: invalid interface id"); - _supportedInterfaces[interfaceId] = true; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} - -contract ERC165InterfacesSupportedUpgradeable is Initializable, SupportsInterfaceWithLookupMockUpgradeable { - function __ERC165InterfacesSupported_init(bytes4[] memory interfaceIds) internal onlyInitializing { - __SupportsInterfaceWithLookupMock_init_unchained(); - __ERC165InterfacesSupported_init_unchained(interfaceIds); - } - - function __ERC165InterfacesSupported_init_unchained(bytes4[] memory interfaceIds) internal onlyInitializing { - for (uint256 i = 0; i < interfaceIds.length; i++) { - _registerInterface(interfaceIds[i]); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MaliciousDataUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MaliciousDataUpgradeable.sol deleted file mode 100644 index 781cc46..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MaliciousDataUpgradeable.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; -import "../../proxy/utils/Initializable.sol"; - -contract ERC165MaliciousDataUpgradeable is Initializable { - function __ERC165MaliciousData_init() internal onlyInitializing { - } - - function __ERC165MaliciousData_init_unchained() internal onlyInitializing { - } - function supportsInterface(bytes4) public pure returns (bool) { - assembly { - mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - return(0, 32) - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MissingDataUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MissingDataUpgradeable.sol deleted file mode 100644 index 4f5cc99..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165MissingDataUpgradeable.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; -import "../../proxy/utils/Initializable.sol"; - -contract ERC165MissingDataUpgradeable is Initializable { - function __ERC165MissingData_init() internal onlyInitializing { - } - - function __ERC165MissingData_init_unchained() internal onlyInitializing { - } - function supportsInterface(bytes4 interfaceId) public view {} // missing return - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165NotSupportedUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165NotSupportedUpgradeable.sol deleted file mode 100644 index 8aca64b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165NotSupportedUpgradeable.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; -import "../../proxy/utils/Initializable.sol"; - -contract ERC165NotSupportedUpgradeable is Initializable { function __ERC165NotSupported_init() internal onlyInitializing { - } - - function __ERC165NotSupported_init_unchained() internal onlyInitializing { - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165ReturnBombUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165ReturnBombUpgradeable.sol deleted file mode 100644 index d97e3ea..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165/ERC165ReturnBombUpgradeable.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -contract ERC165ReturnBombMockUpgradeable is Initializable, IERC165Upgradeable { - function __ERC165ReturnBombMock_init() internal onlyInitializing { - } - - function __ERC165ReturnBombMock_init_unchained() internal onlyInitializing { - } - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - if (interfaceId == type(IERC165Upgradeable).interfaceId) { - assembly { - mstore(0, 1) - } - } - assembly { - return(0, 101500) - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165CheckerMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165CheckerMockUpgradeable.sol deleted file mode 100644 index 5a90cf3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165CheckerMockUpgradeable.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165CheckerUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC165CheckerMockUpgradeable is Initializable { - function __ERC165CheckerMock_init() internal onlyInitializing { - } - - function __ERC165CheckerMock_init_unchained() internal onlyInitializing { - } - using ERC165CheckerUpgradeable for address; - - function supportsERC165(address account) public view returns (bool) { - return account.supportsERC165(); - } - - function supportsInterface(address account, bytes4 interfaceId) public view returns (bool) { - return account.supportsInterface(interfaceId); - } - - function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) { - return account.supportsAllInterfaces(interfaceIds); - } - - function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool[] memory) { - return account.getSupportedInterfaces(interfaceIds); - } - - function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) public view returns (bool) { - return account.supportsERC165InterfaceUnchecked(interfaceId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165MockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165MockUpgradeable.sol deleted file mode 100644 index 56618a2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165MockUpgradeable.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC165MockUpgradeable is Initializable, ERC165Upgradeable { function __ERC165Mock_init() internal onlyInitializing { - } - - function __ERC165Mock_init_unchained() internal onlyInitializing { - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165StorageMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165StorageMockUpgradeable.sol deleted file mode 100644 index c59fdf5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC165StorageMockUpgradeable.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165StorageUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC165StorageMockUpgradeable is Initializable, ERC165StorageUpgradeable { - function __ERC165StorageMock_init() internal onlyInitializing { - } - - function __ERC165StorageMock_init_unchained() internal onlyInitializing { - } - function registerInterface(bytes4 interfaceId) public { - _registerInterface(interfaceId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1820ImplementerMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1820ImplementerMockUpgradeable.sol deleted file mode 100644 index e0d529d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC1820ImplementerMockUpgradeable.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC1820ImplementerUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC1820ImplementerMockUpgradeable is Initializable, ERC1820ImplementerUpgradeable { - function __ERC1820ImplementerMock_init() internal onlyInitializing { - } - - function __ERC1820ImplementerMock_init_unchained() internal onlyInitializing { - } - function registerInterfaceForAddress(bytes32 interfaceHash, address account) public { - _registerInterfaceForAddress(interfaceHash, account); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20BurnableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20BurnableMockUpgradeable.sol deleted file mode 100644 index 2245185..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20BurnableMockUpgradeable.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20BurnableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20BurnableMockUpgradeable is Initializable, ERC20BurnableUpgradeable { - function __ERC20BurnableMock_init( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC20BurnableMock_init_unchained(name, symbol, initialAccount, initialBalance); - } - - function __ERC20BurnableMock_init_unchained( - string memory, - string memory, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - _mint(initialAccount, initialBalance); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20CappedMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20CappedMockUpgradeable.sol deleted file mode 100644 index e3945b2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20CappedMockUpgradeable.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20CappedUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20CappedMockUpgradeable is Initializable, ERC20CappedUpgradeable { - function __ERC20CappedMock_init( - string memory name, - string memory symbol, - uint256 cap - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC20Capped_init_unchained(cap); - } - - function __ERC20CappedMock_init_unchained( - string memory, - string memory, - uint256 - ) internal onlyInitializing {} - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20DecimalsMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20DecimalsMockUpgradeable.sol deleted file mode 100644 index 32b6702..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20DecimalsMockUpgradeable.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/ERC20Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20DecimalsMockUpgradeable is Initializable, ERC20Upgradeable { - uint8 private _decimals; - - function __ERC20DecimalsMock_init( - string memory name_, - string memory symbol_, - uint8 decimals_ - ) internal onlyInitializing { - __ERC20_init_unchained(name_, symbol_); - __ERC20DecimalsMock_init_unchained(name_, symbol_, decimals_); - } - - function __ERC20DecimalsMock_init_unchained( - string memory, - string memory, - uint8 decimals_ - ) internal onlyInitializing { - _decimals = decimals_; - } - - function decimals() public view override returns (uint8) { - return _decimals; - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20FlashMintMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20FlashMintMockUpgradeable.sol deleted file mode 100644 index 75e120d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20FlashMintMockUpgradeable.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20FlashMintUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20FlashMintMockUpgradeable is Initializable, ERC20FlashMintUpgradeable { - uint256 _flashFeeAmount; - address _flashFeeReceiverAddress; - - function __ERC20FlashMintMock_init( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC20FlashMintMock_init_unchained(name, symbol, initialAccount, initialBalance); - } - - function __ERC20FlashMintMock_init_unchained( - string memory, - string memory, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - _mint(initialAccount, initialBalance); - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function setFlashFee(uint256 amount) public { - _flashFeeAmount = amount; - } - - function _flashFee(address, uint256) internal view override returns (uint256) { - return _flashFeeAmount; - } - - function setFlashFeeReceiver(address receiver) public { - _flashFeeReceiverAddress = receiver; - } - - function flashFeeReceiver() public view returns (address) { - return _flashFeeReceiver(); - } - - function _flashFeeReceiver() internal view override returns (address) { - return _flashFeeReceiverAddress; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20MockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20MockUpgradeable.sol deleted file mode 100644 index ec5247f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20MockUpgradeable.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/ERC20Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -// mock class using ERC20 -contract ERC20MockUpgradeable is Initializable, ERC20Upgradeable { - function __ERC20Mock_init( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC20Mock_init_unchained(name, symbol, initialAccount, initialBalance); - } - - function __ERC20Mock_init_unchained( - string memory, - string memory, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - _mint(initialAccount, initialBalance); - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - function transferInternal( - address from, - address to, - uint256 value - ) public { - _transfer(from, to, value); - } - - function approveInternal( - address owner, - address spender, - uint256 value - ) public { - _approve(owner, spender, value); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PausableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PausableMockUpgradeable.sol deleted file mode 100644 index 78aeeba..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PausableMockUpgradeable.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20PausableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -// mock class using ERC20Pausable -contract ERC20PausableMockUpgradeable is Initializable, ERC20PausableUpgradeable { - function __ERC20PausableMock_init( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __Pausable_init_unchained(); - __ERC20PausableMock_init_unchained(name, symbol, initialAccount, initialBalance); - } - - function __ERC20PausableMock_init_unchained( - string memory, - string memory, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - _mint(initialAccount, initialBalance); - } - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - function mint(address to, uint256 amount) public { - _mint(to, amount); - } - - function burn(address from, uint256 amount) public { - _burn(from, amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PermitMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PermitMockUpgradeable.sol deleted file mode 100644 index 9a80668..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20PermitMockUpgradeable.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20PermitMockUpgradeable is Initializable, ERC20PermitUpgradeable { - function __ERC20PermitMock_init( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __EIP712_init_unchained(name, "1"); - __ERC20Permit_init_unchained(name); - __ERC20PermitMock_init_unchained(name, symbol, initialAccount, initialBalance); - } - - function __ERC20PermitMock_init_unchained( - string memory, - string memory, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - _mint(initialAccount, initialBalance); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20SnapshotMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20SnapshotMockUpgradeable.sol deleted file mode 100644 index 40fba6c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20SnapshotMockUpgradeable.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20SnapshotUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20SnapshotMockUpgradeable is Initializable, ERC20SnapshotUpgradeable { - function __ERC20SnapshotMock_init( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC20SnapshotMock_init_unchained(name, symbol, initialAccount, initialBalance); - } - - function __ERC20SnapshotMock_init_unchained( - string memory, - string memory, - address initialAccount, - uint256 initialBalance - ) internal onlyInitializing { - _mint(initialAccount, initialBalance); - } - - function snapshot() public { - _snapshot(); - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesCompMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesCompMockUpgradeable.sol deleted file mode 100644 index 7e6e5c8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesCompMockUpgradeable.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20VotesCompUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20VotesCompMockUpgradeable is Initializable, ERC20VotesCompUpgradeable { - function __ERC20VotesCompMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __EIP712_init_unchained(name, "1"); - __ERC20Permit_init_unchained(name); - } - - function __ERC20VotesCompMock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesMockUpgradeable.sol deleted file mode 100644 index 2edea9d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20VotesMockUpgradeable.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20VotesUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20VotesMockUpgradeable is Initializable, ERC20VotesUpgradeable { - function __ERC20VotesMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __EIP712_init_unchained(name, "1"); - __ERC20Permit_init_unchained(name); - } - - function __ERC20VotesMock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20WrapperMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20WrapperMockUpgradeable.sol deleted file mode 100644 index f2cdf4d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC20WrapperMockUpgradeable.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20WrapperUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20WrapperMockUpgradeable is Initializable, ERC20WrapperUpgradeable { - function __ERC20WrapperMock_init( - IERC20Upgradeable _underlyingToken, - string memory name, - string memory symbol - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC20Wrapper_init_unchained(_underlyingToken); - } - - function __ERC20WrapperMock_init_unchained( - IERC20Upgradeable, - string memory, - string memory - ) internal onlyInitializing {} - - function recover(address account) public returns (uint256) { - return _recover(account); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC2771ContextMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC2771ContextMockUpgradeable.sol deleted file mode 100644 index 7df5c31..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC2771ContextMockUpgradeable.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.9; - -import "./ContextMockUpgradeable.sol"; -import "../metatx/ERC2771ContextUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -// By inheriting from ERC2771Context, Context's internal functions are overridden automatically -contract ERC2771ContextMockUpgradeable is Initializable, ContextMockUpgradeable, ERC2771ContextUpgradeable { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address trustedForwarder) ERC2771ContextUpgradeable(trustedForwarder) { - emit Sender(_msgSender()); // _msgSender() should be accessible during construction - } - - function _msgSender() internal view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address) { - return ERC2771ContextUpgradeable._msgSender(); - } - - function _msgData() internal view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) { - return ERC2771ContextUpgradeable._msgData(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC3156FlashBorrowerMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC3156FlashBorrowerMockUpgradeable.sol deleted file mode 100644 index 6e8e883..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC3156FlashBorrowerMockUpgradeable.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/IERC20Upgradeable.sol"; -import "../interfaces/IERC3156Upgradeable.sol"; -import "../utils/AddressUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev WARNING: this IERC3156FlashBorrower mock implementation is for testing purposes ONLY. - * Writing a secure flash lock borrower is not an easy task, and should be done with the utmost care. - * This is not an example of how it should be done, and no pattern present in this mock should be considered secure. - * Following best practices, always have your contract properly audited before using them to manipulate important funds on - * live networks. - */ -contract ERC3156FlashBorrowerMockUpgradeable is Initializable, IERC3156FlashBorrowerUpgradeable { - bytes32 internal constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan"); - - bool _enableApprove; - bool _enableReturn; - - event BalanceOf(address token, address account, uint256 value); - event TotalSupply(address token, uint256 value); - - function __ERC3156FlashBorrowerMock_init(bool enableReturn, bool enableApprove) internal onlyInitializing { - __ERC3156FlashBorrowerMock_init_unchained(enableReturn, enableApprove); - } - - function __ERC3156FlashBorrowerMock_init_unchained(bool enableReturn, bool enableApprove) internal onlyInitializing { - _enableApprove = enableApprove; - _enableReturn = enableReturn; - } - - function onFlashLoan( - address, /*initiator*/ - address token, - uint256 amount, - uint256 fee, - bytes calldata data - ) public override returns (bytes32) { - require(msg.sender == token); - - emit BalanceOf(token, address(this), IERC20Upgradeable(token).balanceOf(address(this))); - emit TotalSupply(token, IERC20Upgradeable(token).totalSupply()); - - if (data.length > 0) { - // WARNING: This code is for testing purposes only! Do not use. - AddressUpgradeable.functionCall(token, data); - } - - if (_enableApprove) { - IERC20Upgradeable(token).approve(token, amount + fee); - } - - return _enableReturn ? _RETURN_VALUE : bytes32(0); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC4626MockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC4626MockUpgradeable.sol deleted file mode 100644 index 1afe4ee..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC4626MockUpgradeable.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC4626Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC4626MockUpgradeable is Initializable, ERC4626Upgradeable { - function __ERC4626Mock_init( - IERC20MetadataUpgradeable asset, - string memory name, - string memory symbol - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC4626_init_unchained(asset); - } - - function __ERC4626Mock_init_unchained( - IERC20MetadataUpgradeable, - string memory, - string memory - ) internal onlyInitializing {} - - function mockMint(address account, uint256 amount) public { - _mint(account, amount); - } - - function mockBurn(address account, uint256 amount) public { - _burn(account, amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract ERC4626DecimalMockUpgradeable is Initializable, ERC4626MockUpgradeable { - using MathUpgradeable for uint256; - - uint8 private _decimals; - - function __ERC4626DecimalMock_init( - IERC20MetadataUpgradeable asset, - string memory name, - string memory symbol, - uint8 decimalsOverride - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC4626_init_unchained(asset); - __ERC4626Mock_init_unchained(asset, name, symbol); - __ERC4626DecimalMock_init_unchained(asset, name, symbol, decimalsOverride); - } - - function __ERC4626DecimalMock_init_unchained( - IERC20MetadataUpgradeable, - string memory, - string memory, - uint8 decimalsOverride - ) internal onlyInitializing { - _decimals = decimalsOverride; - } - - function decimals() public view virtual override returns (uint8) { - return _decimals; - } - - function _initialConvertToShares(uint256 assets, MathUpgradeable.Rounding rounding) - internal - view - virtual - override - returns (uint256 shares) - { - return assets.mulDiv(10**decimals(), 10**super.decimals(), rounding); - } - - function _initialConvertToAssets(uint256 shares, MathUpgradeable.Rounding rounding) - internal - view - virtual - override - returns (uint256 assets) - { - return shares.mulDiv(10**super.decimals(), 10**decimals(), rounding); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721BurnableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721BurnableMockUpgradeable.sol deleted file mode 100644 index cfeca43..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721BurnableMockUpgradeable.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC721BurnableMockUpgradeable is Initializable, ERC721BurnableUpgradeable { - function __ERC721BurnableMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - } - - function __ERC721BurnableMock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ConsecutiveEnumerableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ConsecutiveEnumerableMockUpgradeable.sol deleted file mode 100644 index c2a165e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ConsecutiveEnumerableMockUpgradeable.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721ConsecutiveUpgradeable.sol"; -import "../token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC721ConsecutiveEnumerableMockUpgradeable is Initializable, ERC721ConsecutiveUpgradeable, ERC721EnumerableUpgradeable { - function __ERC721ConsecutiveEnumerableMock_init( - string memory name, - string memory symbol, - address[] memory receivers, - uint96[] memory amounts - ) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - __ERC721ConsecutiveEnumerableMock_init_unchained(name, symbol, receivers, amounts); - } - - function __ERC721ConsecutiveEnumerableMock_init_unchained( - string memory, - string memory, - address[] memory receivers, - uint96[] memory amounts - ) internal onlyInitializing { - for (uint256 i = 0; i < receivers.length; ++i) { - _mintConsecutive(receivers[i], amounts[i]); - } - } - - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(ERC721Upgradeable, ERC721EnumerableUpgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function _ownerOf(uint256 tokenId) internal view virtual override(ERC721Upgradeable, ERC721ConsecutiveUpgradeable) returns (address) { - return super._ownerOf(tokenId); - } - - function _mint(address to, uint256 tokenId) internal virtual override(ERC721Upgradeable, ERC721ConsecutiveUpgradeable) { - super._mint(to, tokenId); - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override(ERC721Upgradeable, ERC721EnumerableUpgradeable) { - super._beforeTokenTransfer(from, to, firstTokenId, batchSize); - } - - function _afterTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override(ERC721Upgradeable, ERC721ConsecutiveUpgradeable) { - super._afterTokenTransfer(from, to, firstTokenId, batchSize); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ConsecutiveMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ConsecutiveMockUpgradeable.sol deleted file mode 100644 index 32931f8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ConsecutiveMockUpgradeable.sol +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; -import "../token/ERC721/extensions/ERC721ConsecutiveUpgradeable.sol"; -import "../token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; -import "../token/ERC721/extensions/ERC721PausableUpgradeable.sol"; -import "../token/ERC721/extensions/ERC721VotesUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @title ERC721ConsecutiveMock - */ -contract ERC721ConsecutiveMockUpgradeable is Initializable, ERC721BurnableUpgradeable, ERC721ConsecutiveUpgradeable, ERC721PausableUpgradeable, ERC721VotesUpgradeable { - function __ERC721ConsecutiveMock_init( - string memory name, - string memory symbol, - address[] memory delegates, - address[] memory receivers, - uint96[] memory amounts - ) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - __Pausable_init_unchained(); - __EIP712_init_unchained(name, "1"); - __ERC721ConsecutiveMock_init_unchained(name, symbol, delegates, receivers, amounts); - } - - function __ERC721ConsecutiveMock_init_unchained( - string memory, - string memory, - address[] memory delegates, - address[] memory receivers, - uint96[] memory amounts - ) internal onlyInitializing { - for (uint256 i = 0; i < delegates.length; ++i) { - _delegate(delegates[i], delegates[i]); - } - - for (uint256 i = 0; i < receivers.length; ++i) { - _mintConsecutive(receivers[i], amounts[i]); - } - } - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function mintConsecutive(address to, uint96 amount) public { - _mintConsecutive(to, amount); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function _ownerOf(uint256 tokenId) internal view virtual override(ERC721Upgradeable, ERC721ConsecutiveUpgradeable) returns (address) { - return super._ownerOf(tokenId); - } - - function _mint(address to, uint256 tokenId) internal virtual override(ERC721Upgradeable, ERC721ConsecutiveUpgradeable) { - super._mint(to, tokenId); - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override(ERC721Upgradeable, ERC721PausableUpgradeable) { - super._beforeTokenTransfer(from, to, firstTokenId, batchSize); - } - - function _afterTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override(ERC721Upgradeable, ERC721VotesUpgradeable, ERC721ConsecutiveUpgradeable) { - super._afterTokenTransfer(from, to, firstTokenId, batchSize); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract ERC721ConsecutiveNoConstructorMintMockUpgradeable is Initializable, ERC721ConsecutiveUpgradeable { - function __ERC721ConsecutiveNoConstructorMintMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - __ERC721ConsecutiveNoConstructorMintMock_init_unchained(name, symbol); - } - - function __ERC721ConsecutiveNoConstructorMintMock_init_unchained(string memory, string memory) internal onlyInitializing { - _mint(msg.sender, 0); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721EnumerableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721EnumerableMockUpgradeable.sol deleted file mode 100644 index a1e8e18..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721EnumerableMockUpgradeable.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @title ERC721Mock - * This mock just provides a public safeMint, mint, and burn functions for testing purposes - */ -contract ERC721EnumerableMockUpgradeable is Initializable, ERC721EnumerableUpgradeable { - string private _baseTokenURI; - - function __ERC721EnumerableMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - } - - function __ERC721EnumerableMock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function _baseURI() internal view override returns (string memory) { - return _baseTokenURI; - } - - function setBaseURI(string calldata newBaseTokenURI) public { - _baseTokenURI = newBaseTokenURI; - } - - function baseURI() public view returns (string memory) { - return _baseURI(); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721MockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721MockUpgradeable.sol deleted file mode 100644 index 94c90ee..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721MockUpgradeable.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/ERC721Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @title ERC721Mock - * This mock just provides a public safeMint, mint, and burn functions for testing purposes - */ -contract ERC721MockUpgradeable is Initializable, ERC721Upgradeable { - function __ERC721Mock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - } - - function __ERC721Mock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function baseURI() public view returns (string memory) { - return _baseURI(); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721PausableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721PausableMockUpgradeable.sol deleted file mode 100644 index 2ecd621..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721PausableMockUpgradeable.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721PausableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @title ERC721PausableMock - * This mock just provides a public mint, burn and exists functions for testing purposes - */ -contract ERC721PausableMockUpgradeable is Initializable, ERC721PausableUpgradeable { - function __ERC721PausableMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - __Pausable_init_unchained(); - } - - function __ERC721PausableMock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ReceiverMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ReceiverMockUpgradeable.sol deleted file mode 100644 index 4696d5d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721ReceiverMockUpgradeable.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/IERC721ReceiverUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC721ReceiverMockUpgradeable is Initializable, IERC721ReceiverUpgradeable { - enum Error { - None, - RevertWithMessage, - RevertWithoutMessage, - Panic - } - - bytes4 private _retval; - Error private _error; - - event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas); - - function __ERC721ReceiverMock_init(bytes4 retval, Error error) internal onlyInitializing { - __ERC721ReceiverMock_init_unchained(retval, error); - } - - function __ERC721ReceiverMock_init_unchained(bytes4 retval, Error error) internal onlyInitializing { - _retval = retval; - _error = error; - } - - function onERC721Received( - address operator, - address from, - uint256 tokenId, - bytes memory data - ) public override returns (bytes4) { - if (_error == Error.RevertWithMessage) { - revert("ERC721ReceiverMock: reverting"); - } else if (_error == Error.RevertWithoutMessage) { - revert(); - } else if (_error == Error.Panic) { - uint256 a = uint256(0) / uint256(0); - a; - } - emit Received(operator, from, tokenId, data, gasleft()); - return _retval; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721RoyaltyMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721RoyaltyMockUpgradeable.sol deleted file mode 100644 index 9fb7133..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721RoyaltyMockUpgradeable.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC721RoyaltyMockUpgradeable is Initializable, ERC721RoyaltyUpgradeable { - function __ERC721RoyaltyMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - } - - function __ERC721RoyaltyMock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function setTokenRoyalty( - uint256 tokenId, - address recipient, - uint96 fraction - ) public { - _setTokenRoyalty(tokenId, recipient, fraction); - } - - function setDefaultRoyalty(address recipient, uint96 fraction) public { - _setDefaultRoyalty(recipient, fraction); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } - - function deleteDefaultRoyalty() public { - _deleteDefaultRoyalty(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721URIStorageMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721URIStorageMockUpgradeable.sol deleted file mode 100644 index 753f22f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721URIStorageMockUpgradeable.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @title ERC721Mock - * This mock just provides a public safeMint, mint, and burn functions for testing purposes - */ -contract ERC721URIStorageMockUpgradeable is Initializable, ERC721URIStorageUpgradeable { - string private _baseTokenURI; - - function __ERC721URIStorageMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - } - - function __ERC721URIStorageMock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function _baseURI() internal view override returns (string memory) { - return _baseTokenURI; - } - - function setBaseURI(string calldata newBaseTokenURI) public { - _baseTokenURI = newBaseTokenURI; - } - - function baseURI() public view returns (string memory) { - return _baseURI(); - } - - function setTokenURI(uint256 tokenId, string memory _tokenURI) public { - _setTokenURI(tokenId, _tokenURI); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721VotesMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721VotesMockUpgradeable.sol deleted file mode 100644 index 6cfa7e8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC721VotesMockUpgradeable.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721VotesUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC721VotesMockUpgradeable is Initializable, ERC721VotesUpgradeable { - function __ERC721VotesMock_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - __EIP712_init_unchained(name, "1"); - } - - function __ERC721VotesMock_init_unchained(string memory, string memory) internal onlyInitializing {} - - function getTotalSupply() public view returns (uint256) { - return _getTotalSupply(); - } - - function mint(address account, uint256 tokenId) public { - _mint(account, tokenId); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777MockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777MockUpgradeable.sol deleted file mode 100644 index d437571..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777MockUpgradeable.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/ContextUpgradeable.sol"; -import "../token/ERC777/ERC777Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC777MockUpgradeable is Initializable, ContextUpgradeable, ERC777Upgradeable { - event BeforeTokenTransfer(); - - function __ERC777Mock_init( - address initialHolder, - uint256 initialBalance, - string memory name, - string memory symbol, - address[] memory defaultOperators - ) internal onlyInitializing { - __ERC777_init_unchained(name, symbol, defaultOperators); - __ERC777Mock_init_unchained(initialHolder, initialBalance, name, symbol, defaultOperators); - } - - function __ERC777Mock_init_unchained( - address initialHolder, - uint256 initialBalance, - string memory, - string memory, - address[] memory - ) internal onlyInitializing { - _mint(initialHolder, initialBalance, "", ""); - } - - function mintInternal( - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) public { - _mint(to, amount, userData, operatorData); - } - - function mintInternalExtended( - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData, - bool requireReceptionAck - ) public { - _mint(to, amount, userData, operatorData, requireReceptionAck); - } - - function approveInternal( - address holder, - address spender, - uint256 value - ) public { - _approve(holder, spender, value); - } - - function _beforeTokenTransfer( - address, - address, - address, - uint256 - ) internal override { - emit BeforeTokenTransfer(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777SenderRecipientMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777SenderRecipientMockUpgradeable.sol deleted file mode 100644 index a79dd12..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ERC777SenderRecipientMockUpgradeable.sol +++ /dev/null @@ -1,176 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC777/IERC777Upgradeable.sol"; -import "../token/ERC777/IERC777SenderUpgradeable.sol"; -import "../token/ERC777/IERC777RecipientUpgradeable.sol"; -import "../utils/ContextUpgradeable.sol"; -import "../utils/introspection/IERC1820RegistryUpgradeable.sol"; -import "../utils/introspection/ERC1820ImplementerUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC777SenderRecipientMockUpgradeable is Initializable, ContextUpgradeable, IERC777SenderUpgradeable, IERC777RecipientUpgradeable, ERC1820ImplementerUpgradeable { - function __ERC777SenderRecipientMock_init() internal onlyInitializing { - __ERC777SenderRecipientMock_init_unchained(); - } - - function __ERC777SenderRecipientMock_init_unchained() internal onlyInitializing { - _erc1820 = IERC1820RegistryUpgradeable(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); - } - event TokensToSendCalled( - address operator, - address from, - address to, - uint256 amount, - bytes data, - bytes operatorData, - address token, - uint256 fromBalance, - uint256 toBalance - ); - - event TokensReceivedCalled( - address operator, - address from, - address to, - uint256 amount, - bytes data, - bytes operatorData, - address token, - uint256 fromBalance, - uint256 toBalance - ); - - // Emitted in ERC777Mock. Here for easier decoding - event BeforeTokenTransfer(); - - bool private _shouldRevertSend; - bool private _shouldRevertReceive; - - IERC1820RegistryUpgradeable private _erc1820; - - bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender"); - bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); - - function tokensToSend( - address operator, - address from, - address to, - uint256 amount, - bytes calldata userData, - bytes calldata operatorData - ) external override { - if (_shouldRevertSend) { - revert(); - } - - IERC777Upgradeable token = IERC777Upgradeable(_msgSender()); - - uint256 fromBalance = token.balanceOf(from); - // when called due to burn, to will be the zero address, which will have a balance of 0 - uint256 toBalance = token.balanceOf(to); - - emit TokensToSendCalled( - operator, - from, - to, - amount, - userData, - operatorData, - address(token), - fromBalance, - toBalance - ); - } - - function tokensReceived( - address operator, - address from, - address to, - uint256 amount, - bytes calldata userData, - bytes calldata operatorData - ) external override { - if (_shouldRevertReceive) { - revert(); - } - - IERC777Upgradeable token = IERC777Upgradeable(_msgSender()); - - uint256 fromBalance = token.balanceOf(from); - // when called due to burn, to will be the zero address, which will have a balance of 0 - uint256 toBalance = token.balanceOf(to); - - emit TokensReceivedCalled( - operator, - from, - to, - amount, - userData, - operatorData, - address(token), - fromBalance, - toBalance - ); - } - - function senderFor(address account) public { - _registerInterfaceForAddress(_TOKENS_SENDER_INTERFACE_HASH, account); - - address self = address(this); - if (account == self) { - registerSender(self); - } - } - - function registerSender(address sender) public { - _erc1820.setInterfaceImplementer(address(this), _TOKENS_SENDER_INTERFACE_HASH, sender); - } - - function recipientFor(address account) public { - _registerInterfaceForAddress(_TOKENS_RECIPIENT_INTERFACE_HASH, account); - - address self = address(this); - if (account == self) { - registerRecipient(self); - } - } - - function registerRecipient(address recipient) public { - _erc1820.setInterfaceImplementer(address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, recipient); - } - - function setShouldRevertSend(bool shouldRevert) public { - _shouldRevertSend = shouldRevert; - } - - function setShouldRevertReceive(bool shouldRevert) public { - _shouldRevertReceive = shouldRevert; - } - - function send( - IERC777Upgradeable token, - address to, - uint256 amount, - bytes memory data - ) public { - // This is 777's send function, not the Solidity send function - token.send(to, amount, data); // solhint-disable-line check-send-result - } - - function burn( - IERC777Upgradeable token, - uint256 amount, - bytes memory data - ) public { - token.burn(amount, data); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableMapMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableMapMockUpgradeable.sol deleted file mode 100644 index 8f41925..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableMapMockUpgradeable.sol +++ /dev/null @@ -1,282 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/EnumerableMapMock.js. - -pragma solidity ^0.8.0; - -import "../utils/structs/EnumerableMapUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -// UintToAddressMap -contract UintToAddressMapMockUpgradeable is Initializable { - function __UintToAddressMapMock_init() internal onlyInitializing { - } - - function __UintToAddressMapMock_init_unchained() internal onlyInitializing { - } - using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap; - - event OperationResult(bool result); - - EnumerableMapUpgradeable.UintToAddressMap private _map; - - function contains(uint256 key) public view returns (bool) { - return _map.contains(key); - } - - function set(uint256 key, address value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(uint256 key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (uint256 key, address value) { - return _map.at(index); - } - - function tryGet(uint256 key) public view returns (bool, address) { - return _map.tryGet(key); - } - - function get(uint256 key) public view returns (address) { - return _map.get(key); - } - - function getWithMessage(uint256 key, string calldata errorMessage) public view returns (address) { - return _map.get(key, errorMessage); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} - -// AddressToUintMap -contract AddressToUintMapMockUpgradeable is Initializable { - function __AddressToUintMapMock_init() internal onlyInitializing { - } - - function __AddressToUintMapMock_init_unchained() internal onlyInitializing { - } - using EnumerableMapUpgradeable for EnumerableMapUpgradeable.AddressToUintMap; - - event OperationResult(bool result); - - EnumerableMapUpgradeable.AddressToUintMap private _map; - - function contains(address key) public view returns (bool) { - return _map.contains(key); - } - - function set(address key, uint256 value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(address key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (address key, uint256 value) { - return _map.at(index); - } - - function tryGet(address key) public view returns (bool, uint256) { - return _map.tryGet(key); - } - - function get(address key) public view returns (uint256) { - return _map.get(key); - } - - function getWithMessage(address key, string calldata errorMessage) public view returns (uint256) { - return _map.get(key, errorMessage); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} - -// Bytes32ToBytes32Map -contract Bytes32ToBytes32MapMockUpgradeable is Initializable { - function __Bytes32ToBytes32MapMock_init() internal onlyInitializing { - } - - function __Bytes32ToBytes32MapMock_init_unchained() internal onlyInitializing { - } - using EnumerableMapUpgradeable for EnumerableMapUpgradeable.Bytes32ToBytes32Map; - - event OperationResult(bool result); - - EnumerableMapUpgradeable.Bytes32ToBytes32Map private _map; - - function contains(bytes32 key) public view returns (bool) { - return _map.contains(key); - } - - function set(bytes32 key, bytes32 value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(bytes32 key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (bytes32 key, bytes32 value) { - return _map.at(index); - } - - function tryGet(bytes32 key) public view returns (bool, bytes32) { - return _map.tryGet(key); - } - - function get(bytes32 key) public view returns (bytes32) { - return _map.get(key); - } - - function getWithMessage(bytes32 key, string calldata errorMessage) public view returns (bytes32) { - return _map.get(key, errorMessage); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} - -// UintToUintMap -contract UintToUintMapMockUpgradeable is Initializable { - function __UintToUintMapMock_init() internal onlyInitializing { - } - - function __UintToUintMapMock_init_unchained() internal onlyInitializing { - } - using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToUintMap; - - event OperationResult(bool result); - - EnumerableMapUpgradeable.UintToUintMap private _map; - - function contains(uint256 key) public view returns (bool) { - return _map.contains(key); - } - - function set(uint256 key, uint256 value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(uint256 key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (uint256 key, uint256 value) { - return _map.at(index); - } - - function tryGet(uint256 key) public view returns (bool, uint256) { - return _map.tryGet(key); - } - - function get(uint256 key) public view returns (uint256) { - return _map.get(key); - } - - function getWithMessage(uint256 key, string calldata errorMessage) public view returns (uint256) { - return _map.get(key, errorMessage); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} - -// Bytes32ToUintMap -contract Bytes32ToUintMapMockUpgradeable is Initializable { - function __Bytes32ToUintMapMock_init() internal onlyInitializing { - } - - function __Bytes32ToUintMapMock_init_unchained() internal onlyInitializing { - } - using EnumerableMapUpgradeable for EnumerableMapUpgradeable.Bytes32ToUintMap; - - event OperationResult(bool result); - - EnumerableMapUpgradeable.Bytes32ToUintMap private _map; - - function contains(bytes32 key) public view returns (bool) { - return _map.contains(key); - } - - function set(bytes32 key, uint256 value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(bytes32 key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (bytes32 key, uint256 value) { - return _map.at(index); - } - - function tryGet(bytes32 key) public view returns (bool, uint256) { - return _map.tryGet(key); - } - - function get(bytes32 key) public view returns (uint256) { - return _map.get(key); - } - - function getWithMessage(bytes32 key, string calldata errorMessage) public view returns (uint256) { - return _map.get(key, errorMessage); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableSetMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableSetMockUpgradeable.sol deleted file mode 100644 index 06f2816..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EnumerableSetMockUpgradeable.sol +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/EnumerableSetMock.js. - -pragma solidity ^0.8.0; - -import "../utils/structs/EnumerableSetUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -// Bytes32Set -contract EnumerableBytes32SetMockUpgradeable is Initializable { - function __EnumerableBytes32SetMock_init() internal onlyInitializing { - } - - function __EnumerableBytes32SetMock_init_unchained() internal onlyInitializing { - } - using EnumerableSetUpgradeable for EnumerableSetUpgradeable.Bytes32Set; - - event OperationResult(bool result); - - EnumerableSetUpgradeable.Bytes32Set private _set; - - function contains(bytes32 value) public view returns (bool) { - return _set.contains(value); - } - - function add(bytes32 value) public { - bool result = _set.add(value); - emit OperationResult(result); - } - - function remove(bytes32 value) public { - bool result = _set.remove(value); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _set.length(); - } - - function at(uint256 index) public view returns (bytes32) { - return _set.at(index); - } - - function values() public view returns (bytes32[] memory) { - return _set.values(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} - -// AddressSet -contract EnumerableAddressSetMockUpgradeable is Initializable { - function __EnumerableAddressSetMock_init() internal onlyInitializing { - } - - function __EnumerableAddressSetMock_init_unchained() internal onlyInitializing { - } - using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; - - event OperationResult(bool result); - - EnumerableSetUpgradeable.AddressSet private _set; - - function contains(address value) public view returns (bool) { - return _set.contains(value); - } - - function add(address value) public { - bool result = _set.add(value); - emit OperationResult(result); - } - - function remove(address value) public { - bool result = _set.remove(value); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _set.length(); - } - - function at(uint256 index) public view returns (address) { - return _set.at(index); - } - - function values() public view returns (address[] memory) { - return _set.values(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} - -// UintSet -contract EnumerableUintSetMockUpgradeable is Initializable { - function __EnumerableUintSetMock_init() internal onlyInitializing { - } - - function __EnumerableUintSetMock_init_unchained() internal onlyInitializing { - } - using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet; - - event OperationResult(bool result); - - EnumerableSetUpgradeable.UintSet private _set; - - function contains(uint256 value) public view returns (bool) { - return _set.contains(value); - } - - function add(uint256 value) public { - bool result = _set.add(value); - emit OperationResult(result); - } - - function remove(uint256 value) public { - bool result = _set.remove(value); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _set.length(); - } - - function at(uint256 index) public view returns (uint256) { - return _set.at(index); - } - - function values() public view returns (uint256[] memory) { - return _set.values(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EtherReceiverMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EtherReceiverMockUpgradeable.sol deleted file mode 100644 index c52be5d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/EtherReceiverMockUpgradeable.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; -import "../proxy/utils/Initializable.sol"; - -contract EtherReceiverMockUpgradeable is Initializable { - function __EtherReceiverMock_init() internal onlyInitializing { - } - - function __EtherReceiverMock_init_unchained() internal onlyInitializing { - } - bool private _acceptEther; - - function setAcceptEther(bool acceptEther) public { - _acceptEther = acceptEther; - } - - receive() external payable { - if (!_acceptEther) { - revert(); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompMockUpgradeable.sol deleted file mode 100644 index 5a8e3f7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompMockUpgradeable.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../governance/extensions/GovernorVotesCompUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract GovernorCompMockUpgradeable is Initializable, GovernorVotesCompUpgradeable, GovernorCountingSimpleUpgradeable { - function __GovernorCompMock_init(string memory name_, ERC20VotesCompUpgradeable token_) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - __GovernorVotesComp_init_unchained(token_); - } - - function __GovernorCompMock_init_unchained(string memory, ERC20VotesCompUpgradeable) internal onlyInitializing {} - - function quorum(uint256) public pure override returns (uint256) { - return 0; - } - - function votingDelay() public pure override returns (uint256) { - return 4; - } - - function votingPeriod() public pure override returns (uint256) { - return 16; - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompatibilityBravoMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompatibilityBravoMockUpgradeable.sol deleted file mode 100644 index b9b91fc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorCompatibilityBravoMockUpgradeable.sol +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol"; -import "../governance/extensions/GovernorTimelockCompoundUpgradeable.sol"; -import "../governance/extensions/GovernorSettingsUpgradeable.sol"; -import "../governance/extensions/GovernorVotesCompUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract GovernorCompatibilityBravoMockUpgradeable is - Initializable, GovernorCompatibilityBravoUpgradeable, - GovernorSettingsUpgradeable, - GovernorTimelockCompoundUpgradeable, - GovernorVotesCompUpgradeable -{ - function __GovernorCompatibilityBravoMock_init( - string memory name_, - ERC20VotesCompUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 proposalThreshold_, - ICompoundTimelockUpgradeable timelock_ - ) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - __GovernorSettings_init_unchained(votingDelay_, votingPeriod_, proposalThreshold_); - __GovernorTimelockCompound_init_unchained(timelock_); - __GovernorVotesComp_init_unchained(token_); - } - - function __GovernorCompatibilityBravoMock_init_unchained( - string memory, - ERC20VotesCompUpgradeable, - uint256, - uint256, - uint256, - ICompoundTimelockUpgradeable - ) internal onlyInitializing {} - - function supportsInterface(bytes4 interfaceId) - public - view - override(IERC165Upgradeable, GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function quorum(uint256) public pure override returns (uint256) { - return 0; - } - - function state(uint256 proposalId) - public - view - override(IGovernorUpgradeable, GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) - returns (ProposalState) - { - return super.state(proposalId); - } - - function proposalEta(uint256 proposalId) - public - view - override(IGovernorTimelockUpgradeable, GovernorTimelockCompoundUpgradeable) - returns (uint256) - { - return super.proposalEta(proposalId); - } - - function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) { - return super.proposalThreshold(); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(IGovernorUpgradeable, GovernorUpgradeable, GovernorCompatibilityBravoUpgradeable) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public override(IGovernorTimelockUpgradeable, GovernorTimelockCompoundUpgradeable) returns (uint256) { - return super.queue(targets, values, calldatas, salt); - } - - function execute( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public payable override(IGovernorUpgradeable, GovernorUpgradeable) returns (uint256) { - return super.execute(targets, values, calldatas, salt); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - /** - * @notice WARNING: this is for mock purposes only. Ability to the _cancel function should be restricted for live - * deployments. - */ - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) internal override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) returns (uint256 proposalId) { - return super._cancel(targets, values, calldatas, salt); - } - - function _executor() internal view override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) returns (address) { - return super._executor(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorMockUpgradeable.sol deleted file mode 100644 index 5cc5b23..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorMockUpgradeable.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorProposalThresholdUpgradeable.sol"; -import "../governance/extensions/GovernorSettingsUpgradeable.sol"; -import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract GovernorMockUpgradeable is - Initializable, GovernorProposalThresholdUpgradeable, - GovernorSettingsUpgradeable, - GovernorVotesQuorumFractionUpgradeable, - GovernorCountingSimpleUpgradeable -{ - function __GovernorMock_init( - string memory name_, - IVotesUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 quorumNumerator_ - ) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - __GovernorSettings_init_unchained(votingDelay_, votingPeriod_, 0); - __GovernorVotes_init_unchained(token_); - __GovernorVotesQuorumFraction_init_unchained(quorumNumerator_); - } - - function __GovernorMock_init_unchained( - string memory, - IVotesUpgradeable, - uint256, - uint256, - uint256 - ) internal onlyInitializing {} - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) { - return super.proposalThreshold(); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(GovernorUpgradeable, GovernorProposalThresholdUpgradeable) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorPreventLateQuorumMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorPreventLateQuorumMockUpgradeable.sol deleted file mode 100644 index c612352..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorPreventLateQuorumMockUpgradeable.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorPreventLateQuorumUpgradeable.sol"; -import "../governance/extensions/GovernorSettingsUpgradeable.sol"; -import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../governance/extensions/GovernorVotesUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract GovernorPreventLateQuorumMockUpgradeable is - Initializable, GovernorSettingsUpgradeable, - GovernorVotesUpgradeable, - GovernorCountingSimpleUpgradeable, - GovernorPreventLateQuorumUpgradeable -{ - uint256 private _quorum; - - function __GovernorPreventLateQuorumMock_init( - string memory name_, - IVotesUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 quorum_, - uint64 voteExtension_ - ) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - __GovernorSettings_init_unchained(votingDelay_, votingPeriod_, 0); - __GovernorVotes_init_unchained(token_); - __GovernorPreventLateQuorum_init_unchained(voteExtension_); - __GovernorPreventLateQuorumMock_init_unchained(name_, token_, votingDelay_, votingPeriod_, quorum_, voteExtension_); - } - - function __GovernorPreventLateQuorumMock_init_unchained( - string memory, - IVotesUpgradeable, - uint256, - uint256, - uint256 quorum_, - uint64 - ) internal onlyInitializing { - _quorum = quorum_; - } - - function quorum(uint256) public view override returns (uint256) { - return _quorum; - } - - function proposalDeadline(uint256 proposalId) - public - view - override(GovernorUpgradeable, GovernorPreventLateQuorumUpgradeable) - returns (uint256) - { - return super.proposalDeadline(proposalId); - } - - function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) { - return super.proposalThreshold(); - } - - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal override(GovernorUpgradeable, GovernorPreventLateQuorumUpgradeable) returns (uint256) { - return super._castVote(proposalId, account, support, reason, params); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockCompoundMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockCompoundMockUpgradeable.sol deleted file mode 100644 index f7c51f1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockCompoundMockUpgradeable.sol +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorTimelockCompoundUpgradeable.sol"; -import "../governance/extensions/GovernorSettingsUpgradeable.sol"; -import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract GovernorTimelockCompoundMockUpgradeable is - Initializable, GovernorSettingsUpgradeable, - GovernorTimelockCompoundUpgradeable, - GovernorVotesQuorumFractionUpgradeable, - GovernorCountingSimpleUpgradeable -{ - function __GovernorTimelockCompoundMock_init( - string memory name_, - IVotesUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - ICompoundTimelockUpgradeable timelock_, - uint256 quorumNumerator_ - ) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - __GovernorSettings_init_unchained(votingDelay_, votingPeriod_, 0); - __GovernorTimelockCompound_init_unchained(timelock_); - __GovernorVotes_init_unchained(token_); - __GovernorVotesQuorumFraction_init_unchained(quorumNumerator_); - } - - function __GovernorTimelockCompoundMock_init_unchained( - string memory, - IVotesUpgradeable, - uint256, - uint256, - ICompoundTimelockUpgradeable, - uint256 - ) internal onlyInitializing {} - - function supportsInterface(bytes4 interfaceId) - public - view - override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function quorum(uint256 blockNumber) - public - view - override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - /** - * Overriding nightmare - */ - function state(uint256 proposalId) - public - view - override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) - returns (ProposalState) - { - return super.state(proposalId); - } - - function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) { - return super.proposalThreshold(); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) internal override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) returns (uint256 proposalId) { - return super._cancel(targets, values, calldatas, salt); - } - - function _executor() internal view override(GovernorUpgradeable, GovernorTimelockCompoundUpgradeable) returns (address) { - return super._executor(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockControlMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockControlMockUpgradeable.sol deleted file mode 100644 index df55802..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorTimelockControlMockUpgradeable.sol +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorTimelockControlUpgradeable.sol"; -import "../governance/extensions/GovernorSettingsUpgradeable.sol"; -import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract GovernorTimelockControlMockUpgradeable is - Initializable, GovernorSettingsUpgradeable, - GovernorTimelockControlUpgradeable, - GovernorVotesQuorumFractionUpgradeable, - GovernorCountingSimpleUpgradeable -{ - function __GovernorTimelockControlMock_init( - string memory name_, - IVotesUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - TimelockControllerUpgradeable timelock_, - uint256 quorumNumerator_ - ) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - __GovernorSettings_init_unchained(votingDelay_, votingPeriod_, 0); - __GovernorTimelockControl_init_unchained(timelock_); - __GovernorVotes_init_unchained(token_); - __GovernorVotesQuorumFraction_init_unchained(quorumNumerator_); - } - - function __GovernorTimelockControlMock_init_unchained( - string memory, - IVotesUpgradeable, - uint256, - uint256, - TimelockControllerUpgradeable, - uint256 - ) internal onlyInitializing {} - - function supportsInterface(bytes4 interfaceId) - public - view - override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function quorum(uint256 blockNumber) - public - view - override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, descriptionHash); - } - - /** - * Overriding nightmare - */ - function state(uint256 proposalId) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (ProposalState) { - return super.state(proposalId); - } - - function proposalThreshold() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) { - return super.proposalThreshold(); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256 proposalId) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() internal view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (address) { - return super._executor(); - } - - function nonGovernanceFunction() external {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorVoteMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorVoteMockUpgradeable.sol deleted file mode 100644 index eac277a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorVoteMockUpgradeable.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../governance/extensions/GovernorVotesUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract GovernorVoteMocksUpgradeable is Initializable, GovernorVotesUpgradeable, GovernorCountingSimpleUpgradeable { - function __GovernorVoteMocks_init(string memory name_, IVotesUpgradeable token_) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - __GovernorVotes_init_unchained(token_); - } - - function __GovernorVoteMocks_init_unchained(string memory, IVotesUpgradeable) internal onlyInitializing {} - - function quorum(uint256) public pure override returns (uint256) { - return 0; - } - - function votingDelay() public pure override returns (uint256) { - return 4; - } - - function votingPeriod() public pure override returns (uint256) { - return 16; - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorWithParamsMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorWithParamsMockUpgradeable.sol deleted file mode 100644 index 479326c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/GovernorWithParamsMockUpgradeable.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../governance/extensions/GovernorVotesUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract GovernorWithParamsMockUpgradeable is Initializable, GovernorVotesUpgradeable, GovernorCountingSimpleUpgradeable { - event CountParams(uint256 uintParam, string strParam); - - function __GovernorWithParamsMock_init(string memory name_, IVotesUpgradeable token_) internal onlyInitializing { - __EIP712_init_unchained(name_, version()); - __Governor_init_unchained(name_); - __GovernorVotes_init_unchained(token_); - } - - function __GovernorWithParamsMock_init_unchained(string memory, IVotesUpgradeable) internal onlyInitializing {} - - function quorum(uint256) public pure override returns (uint256) { - return 0; - } - - function votingDelay() public pure override returns (uint256) { - return 4; - } - - function votingPeriod() public pure override returns (uint256) { - return 16; - } - - function _getVotes( - address account, - uint256 blockNumber, - bytes memory params - ) internal view override(GovernorUpgradeable, GovernorVotesUpgradeable) returns (uint256) { - uint256 reduction = 0; - // If the user provides parameters, we reduce the voting weight by the amount of the integer param - if (params.length > 0) { - (reduction, ) = abi.decode(params, (uint256, string)); - } - // reverts on overflow - return super._getVotes(account, blockNumber, params) - reduction; - } - - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory params - ) internal override(GovernorUpgradeable, GovernorCountingSimpleUpgradeable) { - if (params.length > 0) { - (uint256 _uintParam, string memory _strParam) = abi.decode(params, (uint256, string)); - emit CountParams(_uintParam, _strParam); - } - return super._countVote(proposalId, account, support, weight, params); - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/InitializableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/InitializableMock.sol deleted file mode 100644 index 34040b6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/InitializableMock.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/utils/Initializable.sol"; - -/** - * @title InitializableMock - * @dev This contract is a mock to test initializable functionality - */ -contract InitializableMock is Initializable { - bool public initializerRan; - bool public onlyInitializingRan; - uint256 public x; - - function isInitializing() public view returns (bool) { - return _isInitializing(); - } - - function initialize() public initializer { - initializerRan = true; - } - - function initializeOnlyInitializing() public onlyInitializing { - onlyInitializingRan = true; - } - - function initializerNested() public initializer { - initialize(); - } - - function onlyInitializingNested() public initializer { - initializeOnlyInitializing(); - } - - function initializeWithX(uint256 _x) public payable initializer { - x = _x; - } - - function nonInitializable(uint256 _x) public payable { - x = _x; - } - - function fail() public pure { - require(false, "InitializableMock forced failure"); - } -} - -contract ConstructorInitializableMock is Initializable { - bool public initializerRan; - bool public onlyInitializingRan; - - constructor() initializer { - initialize(); - initializeOnlyInitializing(); - } - - function initialize() public initializer { - initializerRan = true; - } - - function initializeOnlyInitializing() public onlyInitializing { - onlyInitializingRan = true; - } -} - -contract ChildConstructorInitializableMock is ConstructorInitializableMock { - bool public childInitializerRan; - - constructor() initializer { - childInitialize(); - } - - function childInitialize() public initializer { - childInitializerRan = true; - } -} - -contract ReinitializerMock is Initializable { - uint256 public counter; - - function getInitializedVersion() public view returns (uint8) { - return _getInitializedVersion(); - } - - function initialize() public initializer { - doStuff(); - } - - function reinitialize(uint8 i) public reinitializer(i) { - doStuff(); - } - - function nestedReinitialize(uint8 i, uint8 j) public reinitializer(i) { - reinitialize(j); - } - - function chainReinitialize(uint8 i, uint8 j) public { - reinitialize(i); - reinitialize(j); - } - - function disableInitializers() public { - _disableInitializers(); - } - - function doStuff() public onlyInitializing { - counter++; - } -} - -contract DisableNew is Initializable { - constructor() { - _disableInitializers(); - } -} - -contract DisableOld is Initializable { - constructor() initializer {} -} - -contract DisableBad1 is DisableNew, DisableOld {} - -contract DisableBad2 is Initializable { - constructor() initializer { - _disableInitializers(); - } -} - -contract DisableOk is DisableOld, DisableNew {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MathMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MathMockUpgradeable.sol deleted file mode 100644 index 526ebc9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MathMockUpgradeable.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/MathUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract MathMockUpgradeable is Initializable { - function __MathMock_init() internal onlyInitializing { - } - - function __MathMock_init_unchained() internal onlyInitializing { - } - function max(uint256 a, uint256 b) public pure returns (uint256) { - return MathUpgradeable.max(a, b); - } - - function min(uint256 a, uint256 b) public pure returns (uint256) { - return MathUpgradeable.min(a, b); - } - - function average(uint256 a, uint256 b) public pure returns (uint256) { - return MathUpgradeable.average(a, b); - } - - function ceilDiv(uint256 a, uint256 b) public pure returns (uint256) { - return MathUpgradeable.ceilDiv(a, b); - } - - function mulDiv( - uint256 a, - uint256 b, - uint256 denominator, - MathUpgradeable.Rounding direction - ) public pure returns (uint256) { - return MathUpgradeable.mulDiv(a, b, denominator, direction); - } - - function sqrt(uint256 a, MathUpgradeable.Rounding direction) public pure returns (uint256) { - return MathUpgradeable.sqrt(a, direction); - } - - function log2(uint256 a, MathUpgradeable.Rounding direction) public pure returns (uint256) { - return MathUpgradeable.log2(a, direction); - } - - function log10(uint256 a, MathUpgradeable.Rounding direction) public pure returns (uint256) { - return MathUpgradeable.log10(a, direction); - } - - function log256(uint256 a, MathUpgradeable.Rounding direction) public pure returns (uint256) { - return MathUpgradeable.log256(a, direction); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MerkleProofWrapperUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MerkleProofWrapperUpgradeable.sol deleted file mode 100644 index c45120a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MerkleProofWrapperUpgradeable.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/cryptography/MerkleProofUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract MerkleProofWrapperUpgradeable is Initializable { - function __MerkleProofWrapper_init() internal onlyInitializing { - } - - function __MerkleProofWrapper_init_unchained() internal onlyInitializing { - } - function verify( - bytes32[] memory proof, - bytes32 root, - bytes32 leaf - ) public pure returns (bool) { - return MerkleProofUpgradeable.verify(proof, root, leaf); - } - - function verifyCalldata( - bytes32[] calldata proof, - bytes32 root, - bytes32 leaf - ) public pure returns (bool) { - return MerkleProofUpgradeable.verifyCalldata(proof, root, leaf); - } - - function processProof(bytes32[] memory proof, bytes32 leaf) public pure returns (bytes32) { - return MerkleProofUpgradeable.processProof(proof, leaf); - } - - function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) public pure returns (bytes32) { - return MerkleProofUpgradeable.processProofCalldata(proof, leaf); - } - - function multiProofVerify( - bytes32[] memory proofs, - bool[] memory proofFlag, - bytes32 root, - bytes32[] memory leaves - ) public pure returns (bool) { - return MerkleProofUpgradeable.multiProofVerify(proofs, proofFlag, root, leaves); - } - - function multiProofVerifyCalldata( - bytes32[] calldata proofs, - bool[] calldata proofFlag, - bytes32 root, - bytes32[] memory leaves - ) public pure returns (bool) { - return MerkleProofUpgradeable.multiProofVerifyCalldata(proofs, proofFlag, root, leaves); - } - - function processMultiProof( - bytes32[] memory proofs, - bool[] memory proofFlag, - bytes32[] memory leaves - ) public pure returns (bytes32) { - return MerkleProofUpgradeable.processMultiProof(proofs, proofFlag, leaves); - } - - function processMultiProofCalldata( - bytes32[] calldata proofs, - bool[] calldata proofFlag, - bytes32[] memory leaves - ) public pure returns (bytes32) { - return MerkleProofUpgradeable.processMultiProofCalldata(proofs, proofFlag, leaves); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTestUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTestUpgradeable.sol deleted file mode 100644 index 440bcfd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTestUpgradeable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./MulticallTokenMockUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract MulticallTestUpgradeable is Initializable { - function __MulticallTest_init() internal onlyInitializing { - } - - function __MulticallTest_init_unchained() internal onlyInitializing { - } - function checkReturnValues( - MulticallTokenMockUpgradeable multicallToken, - address[] calldata recipients, - uint256[] calldata amounts - ) external { - bytes[] memory calls = new bytes[](recipients.length); - for (uint256 i = 0; i < recipients.length; i++) { - calls[i] = abi.encodeWithSignature("transfer(address,uint256)", recipients[i], amounts[i]); - } - - bytes[] memory results = multicallToken.multicall(calls); - for (uint256 i = 0; i < results.length; i++) { - require(abi.decode(results[i], (bool))); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTokenMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTokenMockUpgradeable.sol deleted file mode 100644 index fc12597..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MulticallTokenMockUpgradeable.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/MulticallUpgradeable.sol"; -import "./ERC20MockUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract MulticallTokenMockUpgradeable is Initializable, ERC20MockUpgradeable, MulticallUpgradeable { - function __MulticallTokenMock_init(uint256 initialBalance) internal onlyInitializing { - __ERC20_init_unchained("MulticallToken", "BCT"); - __ERC20Mock_init_unchained("MulticallToken", "BCT", msg.sender, initialBalance); - } - - function __MulticallTokenMock_init_unchained(uint256) internal onlyInitializing {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MultipleInheritanceInitializableMocks.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MultipleInheritanceInitializableMocks.sol deleted file mode 100644 index f6d6440..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/MultipleInheritanceInitializableMocks.sol +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/utils/Initializable.sol"; - -// Sample contracts showing upgradeability with multiple inheritance. -// Child contract inherits from Father and Mother contracts, and Father extends from Gramps. -// -// Human -// / \ -// | Gramps -// | | -// Mother Father -// | | -// -- Child -- - -/** - * Sample base intializable contract that is a human - */ -contract SampleHuman is Initializable { - bool public isHuman; - - function initialize() public initializer { - __SampleHuman_init(); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleHuman_init() internal onlyInitializing { - __SampleHuman_init_unchained(); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleHuman_init_unchained() internal onlyInitializing { - isHuman = true; - } -} - -/** - * Sample base intializable contract that defines a field mother - */ -contract SampleMother is Initializable, SampleHuman { - uint256 public mother; - - function initialize(uint256 value) public initializer { - __SampleMother_init(value); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleMother_init(uint256 value) internal onlyInitializing { - __SampleHuman_init(); - __SampleMother_init_unchained(value); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleMother_init_unchained(uint256 value) internal onlyInitializing { - mother = value; - } -} - -/** - * Sample base intializable contract that defines a field gramps - */ -contract SampleGramps is Initializable, SampleHuman { - string public gramps; - - function initialize(string memory value) public initializer { - __SampleGramps_init(value); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleGramps_init(string memory value) internal onlyInitializing { - __SampleHuman_init(); - __SampleGramps_init_unchained(value); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleGramps_init_unchained(string memory value) internal onlyInitializing { - gramps = value; - } -} - -/** - * Sample base intializable contract that defines a field father and extends from gramps - */ -contract SampleFather is Initializable, SampleGramps { - uint256 public father; - - function initialize(string memory _gramps, uint256 _father) public initializer { - __SampleFather_init(_gramps, _father); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleFather_init(string memory _gramps, uint256 _father) internal onlyInitializing { - __SampleGramps_init(_gramps); - __SampleFather_init_unchained(_father); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleFather_init_unchained(uint256 _father) internal onlyInitializing { - father = _father; - } -} - -/** - * Child extends from mother, father (gramps) - */ -contract SampleChild is Initializable, SampleMother, SampleFather { - uint256 public child; - - function initialize( - uint256 _mother, - string memory _gramps, - uint256 _father, - uint256 _child - ) public initializer { - __SampleChild_init(_mother, _gramps, _father, _child); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleChild_init( - uint256 _mother, - string memory _gramps, - uint256 _father, - uint256 _child - ) internal onlyInitializing { - __SampleMother_init(_mother); - __SampleFather_init(_gramps, _father); - __SampleChild_init_unchained(_child); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleChild_init_unchained(uint256 _child) internal onlyInitializing { - child = _child; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Ownable2StepMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Ownable2StepMockUpgradeable.sol deleted file mode 100644 index 89d4181..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/Ownable2StepMockUpgradeable.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/Ownable2StepUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract Ownable2StepMockUpgradeable is Initializable, Ownable2StepUpgradeable { function __Ownable2StepMock_init() internal onlyInitializing { - __Ownable_init_unchained(); - } - - function __Ownable2StepMock_init_unchained() internal onlyInitializing { - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/OwnableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/OwnableMockUpgradeable.sol deleted file mode 100644 index 8bcf45d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/OwnableMockUpgradeable.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/OwnableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract OwnableMockUpgradeable is Initializable, OwnableUpgradeable { function __OwnableMock_init() internal onlyInitializing { - __Ownable_init_unchained(); - } - - function __OwnableMock_init_unchained() internal onlyInitializing { - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PausableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PausableMockUpgradeable.sol deleted file mode 100644 index 2937ec2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PausableMockUpgradeable.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../security/PausableUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract PausableMockUpgradeable is Initializable, PausableUpgradeable { - bool public drasticMeasureTaken; - uint256 public count; - - function __PausableMock_init() internal onlyInitializing { - __Pausable_init_unchained(); - __PausableMock_init_unchained(); - } - - function __PausableMock_init_unchained() internal onlyInitializing { - drasticMeasureTaken = false; - count = 0; - } - - function normalProcess() external whenNotPaused { - count++; - } - - function drasticMeasure() external whenPaused { - drasticMeasureTaken = true; - } - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PullPaymentMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PullPaymentMockUpgradeable.sol deleted file mode 100644 index 637c164..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/PullPaymentMockUpgradeable.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../security/PullPaymentUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -// mock class using PullPayment -contract PullPaymentMockUpgradeable is Initializable, PullPaymentUpgradeable { - function __PullPaymentMock_init() internal onlyInitializing { - __PullPayment_init_unchained(); - } - - function __PullPaymentMock_init_unchained() internal onlyInitializing {} - - // test helper function to call asyncTransfer - function callTransfer(address dest, uint256 amount) public { - _asyncTransfer(dest, amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyAttackUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyAttackUpgradeable.sol deleted file mode 100644 index fb8141b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyAttackUpgradeable.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/ContextUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ReentrancyAttackUpgradeable is Initializable, ContextUpgradeable { - function __ReentrancyAttack_init() internal onlyInitializing { - } - - function __ReentrancyAttack_init_unchained() internal onlyInitializing { - } - function callSender(bytes4 data) public { - (bool success, ) = _msgSender().call(abi.encodeWithSelector(data)); - require(success, "ReentrancyAttack: failed call"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyMockUpgradeable.sol deleted file mode 100644 index dd8e405..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/ReentrancyMockUpgradeable.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../security/ReentrancyGuardUpgradeable.sol"; -import "./ReentrancyAttackUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ReentrancyMockUpgradeable is Initializable, ReentrancyGuardUpgradeable { - uint256 public counter; - - function __ReentrancyMock_init() internal onlyInitializing { - __ReentrancyGuard_init_unchained(); - __ReentrancyMock_init_unchained(); - } - - function __ReentrancyMock_init_unchained() internal onlyInitializing { - counter = 0; - } - - function callback() external nonReentrant { - _count(); - } - - function countLocalRecursive(uint256 n) public nonReentrant { - if (n > 0) { - _count(); - countLocalRecursive(n - 1); - } - } - - function countThisRecursive(uint256 n) public nonReentrant { - if (n > 0) { - _count(); - (bool success, ) = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1)); - require(success, "ReentrancyMock: failed call"); - } - } - - function countAndCall(ReentrancyAttackUpgradeable attacker) public nonReentrant { - _count(); - bytes4 func = bytes4(keccak256("callback()")); - attacker.callSender(func); - } - - function _count() private { - counter += 1; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/RegressionImplementation.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/RegressionImplementation.sol deleted file mode 100644 index be6b501..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/RegressionImplementation.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/utils/Initializable.sol"; - -contract Implementation1 is Initializable { - uint256 internal _value; - - function initialize() public initializer {} - - function setValue(uint256 _number) public { - _value = _number; - } -} - -contract Implementation2 is Initializable { - uint256 internal _value; - - function initialize() public initializer {} - - function setValue(uint256 _number) public { - _value = _number; - } - - function getValue() public view returns (uint256) { - return _value; - } -} - -contract Implementation3 is Initializable { - uint256 internal _value; - - function initialize() public initializer {} - - function setValue(uint256 _number) public { - _value = _number; - } - - function getValue(uint256 _number) public view returns (uint256) { - return _value + _number; - } -} - -contract Implementation4 is Initializable { - uint256 internal _value; - - function initialize() public initializer {} - - function setValue(uint256 _number) public { - _value = _number; - } - - function getValue() public view returns (uint256) { - return _value; - } - - fallback() external { - _value = 1; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeCastMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeCastMockUpgradeable.sol deleted file mode 100644 index 0421331..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeCastMockUpgradeable.sol +++ /dev/null @@ -1,280 +0,0 @@ -// SPDX-License-Identifier: MIT -// This file was procedurally generated from scripts/generate/templates/SafeCastMock.js. - -pragma solidity ^0.8.0; - -import "../utils/math/SafeCastUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract SafeCastMockUpgradeable is Initializable { - function __SafeCastMock_init() internal onlyInitializing { - } - - function __SafeCastMock_init_unchained() internal onlyInitializing { - } - using SafeCastUpgradeable for uint256; - using SafeCastUpgradeable for int256; - - function toUint256(int256 a) public pure returns (uint256) { - return a.toUint256(); - } - - function toUint248(uint256 a) public pure returns (uint248) { - return a.toUint248(); - } - - function toUint240(uint256 a) public pure returns (uint240) { - return a.toUint240(); - } - - function toUint232(uint256 a) public pure returns (uint232) { - return a.toUint232(); - } - - function toUint224(uint256 a) public pure returns (uint224) { - return a.toUint224(); - } - - function toUint216(uint256 a) public pure returns (uint216) { - return a.toUint216(); - } - - function toUint208(uint256 a) public pure returns (uint208) { - return a.toUint208(); - } - - function toUint200(uint256 a) public pure returns (uint200) { - return a.toUint200(); - } - - function toUint192(uint256 a) public pure returns (uint192) { - return a.toUint192(); - } - - function toUint184(uint256 a) public pure returns (uint184) { - return a.toUint184(); - } - - function toUint176(uint256 a) public pure returns (uint176) { - return a.toUint176(); - } - - function toUint168(uint256 a) public pure returns (uint168) { - return a.toUint168(); - } - - function toUint160(uint256 a) public pure returns (uint160) { - return a.toUint160(); - } - - function toUint152(uint256 a) public pure returns (uint152) { - return a.toUint152(); - } - - function toUint144(uint256 a) public pure returns (uint144) { - return a.toUint144(); - } - - function toUint136(uint256 a) public pure returns (uint136) { - return a.toUint136(); - } - - function toUint128(uint256 a) public pure returns (uint128) { - return a.toUint128(); - } - - function toUint120(uint256 a) public pure returns (uint120) { - return a.toUint120(); - } - - function toUint112(uint256 a) public pure returns (uint112) { - return a.toUint112(); - } - - function toUint104(uint256 a) public pure returns (uint104) { - return a.toUint104(); - } - - function toUint96(uint256 a) public pure returns (uint96) { - return a.toUint96(); - } - - function toUint88(uint256 a) public pure returns (uint88) { - return a.toUint88(); - } - - function toUint80(uint256 a) public pure returns (uint80) { - return a.toUint80(); - } - - function toUint72(uint256 a) public pure returns (uint72) { - return a.toUint72(); - } - - function toUint64(uint256 a) public pure returns (uint64) { - return a.toUint64(); - } - - function toUint56(uint256 a) public pure returns (uint56) { - return a.toUint56(); - } - - function toUint48(uint256 a) public pure returns (uint48) { - return a.toUint48(); - } - - function toUint40(uint256 a) public pure returns (uint40) { - return a.toUint40(); - } - - function toUint32(uint256 a) public pure returns (uint32) { - return a.toUint32(); - } - - function toUint24(uint256 a) public pure returns (uint24) { - return a.toUint24(); - } - - function toUint16(uint256 a) public pure returns (uint16) { - return a.toUint16(); - } - - function toUint8(uint256 a) public pure returns (uint8) { - return a.toUint8(); - } - - function toInt256(uint256 a) public pure returns (int256) { - return a.toInt256(); - } - - function toInt248(int256 a) public pure returns (int248) { - return a.toInt248(); - } - - function toInt240(int256 a) public pure returns (int240) { - return a.toInt240(); - } - - function toInt232(int256 a) public pure returns (int232) { - return a.toInt232(); - } - - function toInt224(int256 a) public pure returns (int224) { - return a.toInt224(); - } - - function toInt216(int256 a) public pure returns (int216) { - return a.toInt216(); - } - - function toInt208(int256 a) public pure returns (int208) { - return a.toInt208(); - } - - function toInt200(int256 a) public pure returns (int200) { - return a.toInt200(); - } - - function toInt192(int256 a) public pure returns (int192) { - return a.toInt192(); - } - - function toInt184(int256 a) public pure returns (int184) { - return a.toInt184(); - } - - function toInt176(int256 a) public pure returns (int176) { - return a.toInt176(); - } - - function toInt168(int256 a) public pure returns (int168) { - return a.toInt168(); - } - - function toInt160(int256 a) public pure returns (int160) { - return a.toInt160(); - } - - function toInt152(int256 a) public pure returns (int152) { - return a.toInt152(); - } - - function toInt144(int256 a) public pure returns (int144) { - return a.toInt144(); - } - - function toInt136(int256 a) public pure returns (int136) { - return a.toInt136(); - } - - function toInt128(int256 a) public pure returns (int128) { - return a.toInt128(); - } - - function toInt120(int256 a) public pure returns (int120) { - return a.toInt120(); - } - - function toInt112(int256 a) public pure returns (int112) { - return a.toInt112(); - } - - function toInt104(int256 a) public pure returns (int104) { - return a.toInt104(); - } - - function toInt96(int256 a) public pure returns (int96) { - return a.toInt96(); - } - - function toInt88(int256 a) public pure returns (int88) { - return a.toInt88(); - } - - function toInt80(int256 a) public pure returns (int80) { - return a.toInt80(); - } - - function toInt72(int256 a) public pure returns (int72) { - return a.toInt72(); - } - - function toInt64(int256 a) public pure returns (int64) { - return a.toInt64(); - } - - function toInt56(int256 a) public pure returns (int56) { - return a.toInt56(); - } - - function toInt48(int256 a) public pure returns (int48) { - return a.toInt48(); - } - - function toInt40(int256 a) public pure returns (int40) { - return a.toInt40(); - } - - function toInt32(int256 a) public pure returns (int32) { - return a.toInt32(); - } - - function toInt24(int256 a) public pure returns (int24) { - return a.toInt24(); - } - - function toInt16(int256 a) public pure returns (int16) { - return a.toInt16(); - } - - function toInt8(int256 a) public pure returns (int8) { - return a.toInt8(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeERC20HelperUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeERC20HelperUpgradeable.sol deleted file mode 100644 index b70d7bf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeERC20HelperUpgradeable.sol +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/ContextUpgradeable.sol"; -import "../token/ERC20/IERC20Upgradeable.sol"; -import "../token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; -import "../token/ERC20/utils/SafeERC20Upgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract ERC20ReturnFalseMockUpgradeable is Initializable, ContextUpgradeable { - function __ERC20ReturnFalseMock_init() internal onlyInitializing { - } - - function __ERC20ReturnFalseMock_init_unchained() internal onlyInitializing { - } - uint256 private _allowance; - - // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, - // we write to a dummy state variable. - uint256 private _dummy; - - function transfer(address, uint256) public returns (bool) { - _dummy = 0; - return false; - } - - function transferFrom( - address, - address, - uint256 - ) public returns (bool) { - _dummy = 0; - return false; - } - - function approve(address, uint256) public returns (bool) { - _dummy = 0; - return false; - } - - function allowance(address, address) public view returns (uint256) { - require(_dummy == 0); // Dummy read from a state variable so that the function is view - return 0; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} - -contract ERC20ReturnTrueMockUpgradeable is Initializable, ContextUpgradeable { - function __ERC20ReturnTrueMock_init() internal onlyInitializing { - } - - function __ERC20ReturnTrueMock_init_unchained() internal onlyInitializing { - } - mapping(address => uint256) private _allowances; - - // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, - // we write to a dummy state variable. - uint256 private _dummy; - - function transfer(address, uint256) public returns (bool) { - _dummy = 0; - return true; - } - - function transferFrom( - address, - address, - uint256 - ) public returns (bool) { - _dummy = 0; - return true; - } - - function approve(address, uint256) public returns (bool) { - _dummy = 0; - return true; - } - - function setAllowance(uint256 allowance_) public { - _allowances[_msgSender()] = allowance_; - } - - function allowance(address owner, address) public view returns (uint256) { - return _allowances[owner]; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} - -contract ERC20NoReturnMockUpgradeable is Initializable, ContextUpgradeable { - function __ERC20NoReturnMock_init() internal onlyInitializing { - } - - function __ERC20NoReturnMock_init_unchained() internal onlyInitializing { - } - mapping(address => uint256) private _allowances; - - // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, - // we write to a dummy state variable. - uint256 private _dummy; - - function transfer(address, uint256) public { - _dummy = 0; - } - - function transferFrom( - address, - address, - uint256 - ) public { - _dummy = 0; - } - - function approve(address, uint256) public { - _dummy = 0; - } - - function setAllowance(uint256 allowance_) public { - _allowances[_msgSender()] = allowance_; - } - - function allowance(address owner, address) public view returns (uint256) { - return _allowances[owner]; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} - -contract ERC20PermitNoRevertMockUpgradeable is - Initializable, ERC20Upgradeable, - ERC20PermitUpgradeable -{ - function __ERC20PermitNoRevertMock_init() internal onlyInitializing { - __ERC20_init_unchained("ERC20PermitNoRevertMock", "ERC20PermitNoRevertMock"); - __EIP712_init_unchained("ERC20PermitNoRevertMock", "1"); - __ERC20Permit_init_unchained("ERC20PermitNoRevertMock"); - } - - function __ERC20PermitNoRevertMock_init_unchained() internal onlyInitializing { - } - function getChainId() external view returns (uint256) { - return block.chainid; - } - - function permitThatMayRevert( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public { - super.permit(owner, spender, value, deadline, v, r, s); - } - - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public override { - try this.permitThatMayRevert(owner, spender, value, deadline, v, r, s) { - // do nothing - } catch { - // do nothing - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract SafeERC20WrapperUpgradeable is Initializable, ContextUpgradeable { - using SafeERC20Upgradeable for IERC20Upgradeable; - - IERC20Upgradeable private _token; - - function __SafeERC20Wrapper_init(IERC20Upgradeable token) internal onlyInitializing { - __SafeERC20Wrapper_init_unchained(token); - } - - function __SafeERC20Wrapper_init_unchained(IERC20Upgradeable token) internal onlyInitializing { - _token = token; - } - - function transfer() public { - _token.safeTransfer(address(0), 0); - } - - function transferFrom() public { - _token.safeTransferFrom(address(0), address(0), 0); - } - - function approve(uint256 amount) public { - _token.safeApprove(address(0), amount); - } - - function increaseAllowance(uint256 amount) public { - _token.safeIncreaseAllowance(address(0), amount); - } - - function decreaseAllowance(uint256 amount) public { - _token.safeDecreaseAllowance(address(0), amount); - } - - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public { - SafeERC20Upgradeable.safePermit(IERC20PermitUpgradeable(address(_token)), owner, spender, value, deadline, v, r, s); - } - - function setAllowance(uint256 allowance_) public { - ERC20ReturnTrueMockUpgradeable(address(_token)).setAllowance(allowance_); - } - - function allowance() public view returns (uint256) { - return _token.allowance(address(0), address(0)); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeMathMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeMathMockUpgradeable.sol deleted file mode 100644 index ab62bd8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SafeMathMockUpgradeable.sol +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/SafeMathUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract SafeMathMockUpgradeable is Initializable { - function __SafeMathMock_init() internal onlyInitializing { - } - - function __SafeMathMock_init_unchained() internal onlyInitializing { - } - function tryAdd(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMathUpgradeable.tryAdd(a, b); - } - - function trySub(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMathUpgradeable.trySub(a, b); - } - - function tryMul(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMathUpgradeable.tryMul(a, b); - } - - function tryDiv(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMathUpgradeable.tryDiv(a, b); - } - - function tryMod(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMathUpgradeable.tryMod(a, b); - } - - // using the do* naming convention to avoid warnings due to clashing opcode names - - function doAdd(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMathUpgradeable.add(a, b); - } - - function doSub(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMathUpgradeable.sub(a, b); - } - - function doMul(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMathUpgradeable.mul(a, b); - } - - function doDiv(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMathUpgradeable.div(a, b); - } - - function doMod(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMathUpgradeable.mod(a, b); - } - - function subWithMessage( - uint256 a, - uint256 b, - string memory errorMessage - ) public pure returns (uint256) { - return SafeMathUpgradeable.sub(a, b, errorMessage); - } - - function divWithMessage( - uint256 a, - uint256 b, - string memory errorMessage - ) public pure returns (uint256) { - return SafeMathUpgradeable.div(a, b, errorMessage); - } - - function modWithMessage( - uint256 a, - uint256 b, - string memory errorMessage - ) public pure returns (uint256) { - return SafeMathUpgradeable.mod(a, b, errorMessage); - } - - function addMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMathUpgradeable.add(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - function subMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMathUpgradeable.sub(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - function mulMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMathUpgradeable.mul(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - function divMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMathUpgradeable.div(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - function modMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMathUpgradeable.mod(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignatureCheckerMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignatureCheckerMockUpgradeable.sol deleted file mode 100644 index ba7ceeb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignatureCheckerMockUpgradeable.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/cryptography/SignatureCheckerUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract SignatureCheckerMockUpgradeable is Initializable { - function __SignatureCheckerMock_init() internal onlyInitializing { - } - - function __SignatureCheckerMock_init_unchained() internal onlyInitializing { - } - using SignatureCheckerUpgradeable for address; - - function isValidSignatureNow( - address signer, - bytes32 hash, - bytes memory signature - ) public view returns (bool) { - return signer.isValidSignatureNow(hash, signature); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedMathMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedMathMockUpgradeable.sol deleted file mode 100644 index 318cf2b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedMathMockUpgradeable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/SignedMathUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract SignedMathMockUpgradeable is Initializable { - function __SignedMathMock_init() internal onlyInitializing { - } - - function __SignedMathMock_init_unchained() internal onlyInitializing { - } - function max(int256 a, int256 b) public pure returns (int256) { - return SignedMathUpgradeable.max(a, b); - } - - function min(int256 a, int256 b) public pure returns (int256) { - return SignedMathUpgradeable.min(a, b); - } - - function average(int256 a, int256 b) public pure returns (int256) { - return SignedMathUpgradeable.average(a, b); - } - - function abs(int256 n) public pure returns (uint256) { - return SignedMathUpgradeable.abs(n); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedSafeMathMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedSafeMathMockUpgradeable.sol deleted file mode 100644 index 85d7bf4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SignedSafeMathMockUpgradeable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/SignedSafeMathUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract SignedSafeMathMockUpgradeable is Initializable { - function __SignedSafeMathMock_init() internal onlyInitializing { - } - - function __SignedSafeMathMock_init_unchained() internal onlyInitializing { - } - function mul(int256 a, int256 b) public pure returns (int256) { - return SignedSafeMathUpgradeable.mul(a, b); - } - - function div(int256 a, int256 b) public pure returns (int256) { - return SignedSafeMathUpgradeable.div(a, b); - } - - function sub(int256 a, int256 b) public pure returns (int256) { - return SignedSafeMathUpgradeable.sub(a, b); - } - - function add(int256 a, int256 b) public pure returns (int256) { - return SignedSafeMathUpgradeable.add(a, b); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SingleInheritanceInitializableMocks.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SingleInheritanceInitializableMocks.sol deleted file mode 100644 index 6c82dd2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/SingleInheritanceInitializableMocks.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/utils/Initializable.sol"; - -/** - * @title MigratableMockV1 - * @dev This contract is a mock to test initializable functionality through migrations - */ -contract MigratableMockV1 is Initializable { - uint256 public x; - - function initialize(uint256 value) public payable initializer { - x = value; - } -} - -/** - * @title MigratableMockV2 - * @dev This contract is a mock to test migratable functionality with params - */ -contract MigratableMockV2 is MigratableMockV1 { - bool internal _migratedV2; - uint256 public y; - - function migrate(uint256 value, uint256 anotherValue) public payable { - require(!_migratedV2); - x = value; - y = anotherValue; - _migratedV2 = true; - } -} - -/** - * @title MigratableMockV3 - * @dev This contract is a mock to test migratable functionality without params - */ -contract MigratableMockV3 is MigratableMockV2 { - bool internal _migratedV3; - - function migrate() public payable { - require(!_migratedV3); - uint256 oldX = x; - x = y; - y = oldX; - _migratedV3 = true; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StorageSlotMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StorageSlotMockUpgradeable.sol deleted file mode 100644 index 95698c0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StorageSlotMockUpgradeable.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/StorageSlotUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract StorageSlotMockUpgradeable is Initializable { - function __StorageSlotMock_init() internal onlyInitializing { - } - - function __StorageSlotMock_init_unchained() internal onlyInitializing { - } - using StorageSlotUpgradeable for bytes32; - - function setBoolean(bytes32 slot, bool value) public { - slot.getBooleanSlot().value = value; - } - - function setAddress(bytes32 slot, address value) public { - slot.getAddressSlot().value = value; - } - - function setBytes32(bytes32 slot, bytes32 value) public { - slot.getBytes32Slot().value = value; - } - - function setUint256(bytes32 slot, uint256 value) public { - slot.getUint256Slot().value = value; - } - - function getBoolean(bytes32 slot) public view returns (bool) { - return slot.getBooleanSlot().value; - } - - function getAddress(bytes32 slot) public view returns (address) { - return slot.getAddressSlot().value; - } - - function getBytes32(bytes32 slot) public view returns (bytes32) { - return slot.getBytes32Slot().value; - } - - function getUint256(bytes32 slot) public view returns (uint256) { - return slot.getUint256Slot().value; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StringsMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StringsMockUpgradeable.sol deleted file mode 100644 index 0a612c0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/StringsMockUpgradeable.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/StringsUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract StringsMockUpgradeable is Initializable { - function __StringsMock_init() internal onlyInitializing { - } - - function __StringsMock_init_unchained() internal onlyInitializing { - } - function toString(uint256 value) public pure returns (string memory) { - return StringsUpgradeable.toString(value); - } - - function toHexString(uint256 value) public pure returns (string memory) { - return StringsUpgradeable.toHexString(value); - } - - function toHexString(uint256 value, uint256 length) public pure returns (string memory) { - return StringsUpgradeable.toHexString(value, length); - } - - function toHexString(address addr) public pure returns (string memory) { - return StringsUpgradeable.toHexString(addr); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersBlockNumberImplUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersBlockNumberImplUpgradeable.sol deleted file mode 100644 index b657a7f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersBlockNumberImplUpgradeable.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/TimersUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract TimersBlockNumberImplUpgradeable is Initializable { - function __TimersBlockNumberImpl_init() internal onlyInitializing { - } - - function __TimersBlockNumberImpl_init_unchained() internal onlyInitializing { - } - using TimersUpgradeable for TimersUpgradeable.BlockNumber; - - TimersUpgradeable.BlockNumber private _timer; - - function getDeadline() public view returns (uint64) { - return _timer.getDeadline(); - } - - function setDeadline(uint64 timestamp) public { - _timer.setDeadline(timestamp); - } - - function reset() public { - _timer.reset(); - } - - function isUnset() public view returns (bool) { - return _timer.isUnset(); - } - - function isStarted() public view returns (bool) { - return _timer.isStarted(); - } - - function isPending() public view returns (bool) { - return _timer.isPending(); - } - - function isExpired() public view returns (bool) { - return _timer.isExpired(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersTimestampImplUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersTimestampImplUpgradeable.sol deleted file mode 100644 index f28f301..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/TimersTimestampImplUpgradeable.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/TimersUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract TimersTimestampImplUpgradeable is Initializable { - function __TimersTimestampImpl_init() internal onlyInitializing { - } - - function __TimersTimestampImpl_init_unchained() internal onlyInitializing { - } - using TimersUpgradeable for TimersUpgradeable.Timestamp; - - TimersUpgradeable.Timestamp private _timer; - - function getDeadline() public view returns (uint64) { - return _timer.getDeadline(); - } - - function setDeadline(uint64 timestamp) public { - _timer.setDeadline(timestamp); - } - - function reset() public { - _timer.reset(); - } - - function isUnset() public view returns (bool) { - return _timer.isUnset(); - } - - function isStarted() public view returns (bool) { - return _timer.isStarted(); - } - - function isPending() public view returns (bool) { - return _timer.isPending(); - } - - function isExpired() public view returns (bool) { - return _timer.isExpired(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/UUPSLegacyUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/UUPSLegacyUpgradeable.sol deleted file mode 100644 index 2377863..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/UUPSLegacyUpgradeable.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./UUPSUpgradeableMockUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -// This contract implements the pre-4.5 UUPS upgrade function with a rollback test. -// It's used to test that newer UUPS contracts are considered valid upgrades by older UUPS contracts. -contract UUPSUpgradeableLegacyMockUpgradeable is Initializable, UUPSUpgradeableMockUpgradeable { - function __UUPSUpgradeableLegacyMock_init() internal onlyInitializing { - } - - function __UUPSUpgradeableLegacyMock_init_unchained() internal onlyInitializing { - } - // Inlined from ERC1967Upgrade - bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; - - // ERC1967Upgrade._setImplementation is private so we reproduce it here. - // An extra underscore prevents a name clash error. - function __setImplementation(address newImplementation) private { - require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); - StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; - } - - function _upgradeToAndCallSecureLegacyV1( - address newImplementation, - bytes memory data, - bool forceCall - ) internal { - address oldImplementation = _getImplementation(); - - // Initial upgrade and setup call - __setImplementation(newImplementation); - if (data.length > 0 || forceCall) { - __functionDelegateCall(newImplementation, data); - } - - // Perform rollback test if not already in progress - StorageSlotUpgradeable.BooleanSlot storage rollbackTesting = StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT); - if (!rollbackTesting.value) { - // Trigger rollback using upgradeTo from the new implementation - rollbackTesting.value = true; - __functionDelegateCall( - newImplementation, - abi.encodeWithSignature("upgradeTo(address)", oldImplementation) - ); - rollbackTesting.value = false; - // Check rollback was effective - require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades"); - // Finally reset to the new implementation and log the upgrade - _upgradeTo(newImplementation); - } - } - - // hooking into the old mechanism - function upgradeTo(address newImplementation) external override { - _upgradeToAndCallSecureLegacyV1(newImplementation, bytes(""), false); - } - - function upgradeToAndCall(address newImplementation, bytes memory data) external payable override { - _upgradeToAndCallSecureLegacyV1(newImplementation, data, false); - } - - // ERC1967Upgrade._functionDelegateCall is private so we reproduce it here. - // An extra underscore prevents a name clash error. - function __functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { - require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); - - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory returndata) = target.delegatecall(data); - return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/UUPSUpgradeableMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/UUPSUpgradeableMockUpgradeable.sol deleted file mode 100644 index 47f3bdb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/UUPS/UUPSUpgradeableMockUpgradeable.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../CountersImplUpgradeable.sol"; -import "../../proxy/utils/UUPSUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -contract UUPSUpgradeableMockUpgradeable is Initializable, CountersImplUpgradeable, UUPSUpgradeable { - function __UUPSUpgradeableMock_init() internal onlyInitializing { - } - - function __UUPSUpgradeableMock_init_unchained() internal onlyInitializing { - } - // Not having any checks in this function is dangerous! Do not do this outside tests! - function _authorizeUpgrade(address) internal override {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract UUPSUpgradeableUnsafeMockUpgradeable is Initializable, UUPSUpgradeableMockUpgradeable { - function __UUPSUpgradeableUnsafeMock_init() internal onlyInitializing { - } - - function __UUPSUpgradeableUnsafeMock_init_unchained() internal onlyInitializing { - } - function upgradeTo(address newImplementation) external override { - ERC1967UpgradeUpgradeable._upgradeToAndCall(newImplementation, bytes(""), false); - } - - function upgradeToAndCall(address newImplementation, bytes memory data) external payable override { - ERC1967UpgradeUpgradeable._upgradeToAndCall(newImplementation, data, false); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/VotesMockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/VotesMockUpgradeable.sol deleted file mode 100644 index f5b08d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/VotesMockUpgradeable.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/utils/VotesUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -contract VotesMockUpgradeable is Initializable, VotesUpgradeable { - mapping(address => uint256) private _balances; - mapping(uint256 => address) private _owners; - - function __VotesMock_init(string memory name) internal onlyInitializing { - __EIP712_init_unchained(name, "1"); - } - - function __VotesMock_init_unchained(string memory) internal onlyInitializing {} - - function getTotalSupply() public view returns (uint256) { - return _getTotalSupply(); - } - - function delegate(address account, address newDelegation) public { - return _delegate(account, newDelegation); - } - - function _getVotingUnits(address account) internal view override returns (uint256) { - return _balances[account]; - } - - function mint(address account, uint256 voteId) external { - _balances[account] += 1; - _owners[voteId] = account; - _transferVotingUnits(address(0), account, 1); - } - - function burn(uint256 voteId) external { - address owner = _owners[voteId]; - _balances[owner] -= 1; - _transferVotingUnits(owner, address(0), 1); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/WithInit.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/WithInit.sol deleted file mode 100644 index fa07afd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/WithInit.sol +++ /dev/null @@ -1,1373 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.7 <0.9; -pragma experimental ABIEncoderV2; - -import "../access/AccessControlUpgradeable.sol"; - -contract AccessControlUpgradeableWithInit is AccessControlUpgradeable { - constructor() payable initializer { - __AccessControl_init(); - } -} -import "../utils/ContextUpgradeable.sol"; - -contract ContextUpgradeableWithInit is ContextUpgradeable { - constructor() payable initializer { - __Context_init(); - } -} -import "../utils/introspection/ERC165Upgradeable.sol"; - -contract ERC165UpgradeableWithInit is ERC165Upgradeable { - constructor() payable initializer { - __ERC165_init(); - } -} -import "./AccessControlMockUpgradeable.sol"; - -contract AccessControlMockUpgradeableWithInit is AccessControlMockUpgradeable { - constructor() payable initializer { - __AccessControlMock_init(); - } -} -import "../governance/TimelockControllerUpgradeable.sol"; - -contract TimelockControllerUpgradeableWithInit is TimelockControllerUpgradeable { - constructor( - uint256 minDelay, - address[] memory proposers, - address[] memory executors, - address admin - ) payable initializer { - __TimelockController_init(minDelay, proposers, executors, admin); - } -} -import "../utils/cryptography/EIP712Upgradeable.sol"; - -contract EIP712UpgradeableWithInit is EIP712Upgradeable { - constructor(string memory name, string memory version) payable initializer { - __EIP712_init(name, version); - } -} -import "./wizard/MyGovernor3Upgradeable.sol"; - -contract MyGovernorUpgradeableWithInit is MyGovernorUpgradeable { - constructor(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) payable initializer { - __MyGovernor_init(_token, _timelock); - } -} -import "./wizard/MyGovernor2Upgradeable.sol"; - -contract MyGovernor2UpgradeableWithInit is MyGovernor2Upgradeable { - constructor(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) payable initializer { - __MyGovernor2_init(_token, _timelock); - } -} -import "./wizard/MyGovernor1Upgradeable.sol"; - -contract MyGovernor1UpgradeableWithInit is MyGovernor1Upgradeable { - constructor(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) payable initializer { - __MyGovernor1_init(_token, _timelock); - } -} -import "./GovernorWithParamsMockUpgradeable.sol"; - -contract GovernorWithParamsMockUpgradeableWithInit is GovernorWithParamsMockUpgradeable { - constructor(string memory name_, IVotesUpgradeable token_) payable initializer { - __GovernorWithParamsMock_init(name_, token_); - } -} -import "./GovernorVoteMockUpgradeable.sol"; - -contract GovernorVoteMocksUpgradeableWithInit is GovernorVoteMocksUpgradeable { - constructor(string memory name_, IVotesUpgradeable token_) payable initializer { - __GovernorVoteMocks_init(name_, token_); - } -} -import "./GovernorTimelockControlMockUpgradeable.sol"; - -contract GovernorTimelockControlMockUpgradeableWithInit is GovernorTimelockControlMockUpgradeable { - constructor( - string memory name_, - IVotesUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - TimelockControllerUpgradeable timelock_, - uint256 quorumNumerator_ - ) payable initializer { - __GovernorTimelockControlMock_init(name_, token_, votingDelay_, votingPeriod_, timelock_, quorumNumerator_); - } -} -import "./GovernorTimelockCompoundMockUpgradeable.sol"; - -contract GovernorTimelockCompoundMockUpgradeableWithInit is GovernorTimelockCompoundMockUpgradeable { - constructor( - string memory name_, - IVotesUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - ICompoundTimelockUpgradeable timelock_, - uint256 quorumNumerator_ - ) payable initializer { - __GovernorTimelockCompoundMock_init(name_, token_, votingDelay_, votingPeriod_, timelock_, quorumNumerator_); - } -} -import "./GovernorCompatibilityBravoMockUpgradeable.sol"; - -contract GovernorCompatibilityBravoMockUpgradeableWithInit is GovernorCompatibilityBravoMockUpgradeable { - constructor( - string memory name_, - ERC20VotesCompUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 proposalThreshold_, - ICompoundTimelockUpgradeable timelock_ - ) payable initializer { - __GovernorCompatibilityBravoMock_init(name_, token_, votingDelay_, votingPeriod_, proposalThreshold_, timelock_); - } -} -import "../token/ERC20/ERC20Upgradeable.sol"; - -contract ERC20UpgradeableWithInit is ERC20Upgradeable { - constructor(string memory name_, string memory symbol_) payable initializer { - __ERC20_init(name_, symbol_); - } -} -import "./GovernorCompMockUpgradeable.sol"; - -contract GovernorCompMockUpgradeableWithInit is GovernorCompMockUpgradeable { - constructor(string memory name_, ERC20VotesCompUpgradeable token_) payable initializer { - __GovernorCompMock_init(name_, token_); - } -} -import "./ERC1271WalletMockUpgradeable.sol"; - -contract ERC1271WalletMockUpgradeableWithInit is ERC1271WalletMockUpgradeable { - constructor(address originalOwner) payable initializer { - __ERC1271WalletMock_init(originalOwner); - } -} -import "./ERC1271WalletMockUpgradeable.sol"; - -contract ERC1271MaliciousMockUpgradeableWithInit is ERC1271MaliciousMockUpgradeable { - constructor() payable initializer { - __ERC1271MaliciousMock_init(); - } -} -import "../access/OwnableUpgradeable.sol"; - -contract OwnableUpgradeableWithInit is OwnableUpgradeable { - constructor() payable initializer { - __Ownable_init(); - } -} -import "../utils/escrow/EscrowUpgradeable.sol"; - -contract EscrowUpgradeableWithInit is EscrowUpgradeable { - constructor() payable initializer { - __Escrow_init(); - } -} -import "../utils/MulticallUpgradeable.sol"; - -contract MulticallUpgradeableWithInit is MulticallUpgradeable { - constructor() payable initializer { - __Multicall_init(); - } -} -import "./MulticallTokenMockUpgradeable.sol"; - -contract MulticallTokenMockUpgradeableWithInit is MulticallTokenMockUpgradeable { - constructor(uint256 initialBalance) payable initializer { - __MulticallTokenMock_init(initialBalance); - } -} -import "./ERC20MockUpgradeable.sol"; - -contract ERC20MockUpgradeableWithInit is ERC20MockUpgradeable { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) payable initializer { - __ERC20Mock_init(name, symbol, initialAccount, initialBalance); - } -} -import "../token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol"; - -contract ERC20PresetMinterPauserUpgradeableWithInit is ERC20PresetMinterPauserUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC20PresetMinterPauser_init(name, symbol); - } -} -import "../access/AccessControlEnumerableUpgradeable.sol"; - -contract AccessControlEnumerableUpgradeableWithInit is AccessControlEnumerableUpgradeable { - constructor() payable initializer { - __AccessControlEnumerable_init(); - } -} -import "../security/PausableUpgradeable.sol"; - -contract PausableUpgradeableWithInit is PausableUpgradeable { - constructor() payable initializer { - __Pausable_init(); - } -} -import "../token/ERC777/ERC777Upgradeable.sol"; - -contract ERC777UpgradeableWithInit is ERC777Upgradeable { - constructor( - string memory name_, - string memory symbol_, - address[] memory defaultOperators_ - ) payable initializer { - __ERC777_init(name_, symbol_, defaultOperators_); - } -} -import "../token/ERC777/presets/ERC777PresetFixedSupplyUpgradeable.sol"; - -contract ERC777PresetFixedSupplyUpgradeableWithInit is ERC777PresetFixedSupplyUpgradeable { - constructor( - string memory name, - string memory symbol, - address[] memory defaultOperators, - uint256 initialSupply, - address owner - ) payable initializer { - __ERC777PresetFixedSupply_init(name, symbol, defaultOperators, initialSupply, owner); - } -} -import "./ERC777SenderRecipientMockUpgradeable.sol"; - -contract ERC777SenderRecipientMockUpgradeableWithInit is ERC777SenderRecipientMockUpgradeable { - constructor() payable initializer { - __ERC777SenderRecipientMock_init(); - } -} -import "../utils/introspection/ERC1820ImplementerUpgradeable.sol"; - -contract ERC1820ImplementerUpgradeableWithInit is ERC1820ImplementerUpgradeable { - constructor() payable initializer { - __ERC1820Implementer_init(); - } -} -import "./ERC1820ImplementerMockUpgradeable.sol"; - -contract ERC1820ImplementerMockUpgradeableWithInit is ERC1820ImplementerMockUpgradeable { - constructor() payable initializer { - __ERC1820ImplementerMock_init(); - } -} -import "./Create2ImplUpgradeable.sol"; - -contract Create2ImplUpgradeableWithInit is Create2ImplUpgradeable { - constructor() payable initializer { - __Create2Impl_init(); - } -} -import "../token/ERC20/utils/TokenTimelockUpgradeable.sol"; - -contract TokenTimelockUpgradeableWithInit is TokenTimelockUpgradeable { - constructor( - IERC20Upgradeable token_, - address beneficiary_, - uint256 releaseTime_ - ) payable initializer { - __TokenTimelock_init(token_, beneficiary_, releaseTime_); - } -} -import "../token/ERC721/presets/ERC721PresetMinterPauserAutoIdUpgradeable.sol"; - -contract ERC721PresetMinterPauserAutoIdUpgradeableWithInit is ERC721PresetMinterPauserAutoIdUpgradeable { - constructor( - string memory name, - string memory symbol, - string memory baseTokenURI - ) payable initializer { - __ERC721PresetMinterPauserAutoId_init(name, symbol, baseTokenURI); - } -} -import "../token/ERC721/ERC721Upgradeable.sol"; - -contract ERC721UpgradeableWithInit is ERC721Upgradeable { - constructor(string memory name_, string memory symbol_) payable initializer { - __ERC721_init(name_, symbol_); - } -} -import "../token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol"; - -contract ERC1155PresetMinterPauserUpgradeableWithInit is ERC1155PresetMinterPauserUpgradeable { - constructor(string memory uri) payable initializer { - __ERC1155PresetMinterPauser_init(uri); - } -} -import "../token/ERC1155/ERC1155Upgradeable.sol"; - -contract ERC1155UpgradeableWithInit is ERC1155Upgradeable { - constructor(string memory uri_) payable initializer { - __ERC1155_init(uri_); - } -} -import "./VotesMockUpgradeable.sol"; - -contract VotesMockUpgradeableWithInit is VotesMockUpgradeable { - constructor(string memory name) payable initializer { - __VotesMock_init(name); - } -} -import "./EIP712ExternalUpgradeable.sol"; - -contract EIP712ExternalUpgradeableWithInit is EIP712ExternalUpgradeable { - constructor(string memory name, string memory version) payable initializer { - __EIP712External_init(name, version); - } -} -import "../metatx/MinimalForwarderUpgradeable.sol"; - -contract MinimalForwarderUpgradeableWithInit is MinimalForwarderUpgradeable { - constructor() payable initializer { - __MinimalForwarder_init(); - } -} -import "./GovernorMockUpgradeable.sol"; - -contract GovernorMockUpgradeableWithInit is GovernorMockUpgradeable { - constructor( - string memory name_, - IVotesUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 quorumNumerator_ - ) payable initializer { - __GovernorMock_init(name_, token_, votingDelay_, votingPeriod_, quorumNumerator_); - } -} -import "./GovernorPreventLateQuorumMockUpgradeable.sol"; - -contract GovernorPreventLateQuorumMockUpgradeableWithInit is GovernorPreventLateQuorumMockUpgradeable { - constructor( - string memory name_, - IVotesUpgradeable token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 quorum_, - uint64 voteExtension_ - ) payable initializer { - __GovernorPreventLateQuorumMock_init(name_, token_, votingDelay_, votingPeriod_, quorum_, voteExtension_); - } -} -import "./ERC1155SupplyMockUpgradeable.sol"; - -contract ERC1155SupplyMockUpgradeableWithInit is ERC1155SupplyMockUpgradeable { - constructor(string memory uri) payable initializer { - __ERC1155SupplyMock_init(uri); - } -} -import "./ERC1155MockUpgradeable.sol"; - -contract ERC1155MockUpgradeableWithInit is ERC1155MockUpgradeable { - constructor(string memory uri) payable initializer { - __ERC1155Mock_init(uri); - } -} -import "./ERC1155URIStorageMockUpgradeable.sol"; - -contract ERC1155URIStorageMockUpgradeableWithInit is ERC1155URIStorageMockUpgradeable { - constructor(string memory _uri) payable initializer { - __ERC1155URIStorageMock_init(_uri); - } -} -import "./ERC1155PausableMockUpgradeable.sol"; - -contract ERC1155PausableMockUpgradeableWithInit is ERC1155PausableMockUpgradeable { - constructor(string memory uri) payable initializer { - __ERC1155PausableMock_init(uri); - } -} -import "./ERC1155BurnableMockUpgradeable.sol"; - -contract ERC1155BurnableMockUpgradeableWithInit is ERC1155BurnableMockUpgradeable { - constructor(string memory uri) payable initializer { - __ERC1155BurnableMock_init(uri); - } -} -import "../utils/introspection/ERC165StorageUpgradeable.sol"; - -contract ERC165StorageUpgradeableWithInit is ERC165StorageUpgradeable { - constructor() payable initializer { - __ERC165Storage_init(); - } -} -import "./ERC165StorageMockUpgradeable.sol"; - -contract ERC165StorageMockUpgradeableWithInit is ERC165StorageMockUpgradeable { - constructor() payable initializer { - __ERC165StorageMock_init(); - } -} -import "./ERC165CheckerMockUpgradeable.sol"; - -contract ERC165CheckerMockUpgradeableWithInit is ERC165CheckerMockUpgradeable { - constructor() payable initializer { - __ERC165CheckerMock_init(); - } -} -import "./ERC721EnumerableMockUpgradeable.sol"; - -contract ERC721EnumerableMockUpgradeableWithInit is ERC721EnumerableMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC721EnumerableMock_init(name, symbol); - } -} -import "./ERC721ConsecutiveMockUpgradeable.sol"; - -contract ERC721ConsecutiveMockUpgradeableWithInit is ERC721ConsecutiveMockUpgradeable { - constructor( - string memory name, - string memory symbol, - address[] memory delegates, - address[] memory receivers, - uint96[] memory amounts - ) payable initializer { - __ERC721ConsecutiveMock_init(name, symbol, delegates, receivers, amounts); - } -} -import "./ERC721ConsecutiveMockUpgradeable.sol"; - -contract ERC721ConsecutiveNoConstructorMintMockUpgradeableWithInit is ERC721ConsecutiveNoConstructorMintMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC721ConsecutiveNoConstructorMintMock_init(name, symbol); - } -} -import "./BitmapMockUpgradeable.sol"; - -contract BitMapMockUpgradeableWithInit is BitMapMockUpgradeable { - constructor() payable initializer { - __BitMapMock_init(); - } -} -import "./DoubleEndedQueueMockUpgradeable.sol"; - -contract Bytes32DequeMockUpgradeableWithInit is Bytes32DequeMockUpgradeable { - constructor() payable initializer { - __Bytes32DequeMock_init(); - } -} -import "./SafeCastMockUpgradeable.sol"; - -contract SafeCastMockUpgradeableWithInit is SafeCastMockUpgradeable { - constructor() payable initializer { - __SafeCastMock_init(); - } -} -import "./CheckpointsMockUpgradeable.sol"; - -contract CheckpointsMockUpgradeableWithInit is CheckpointsMockUpgradeable { - constructor() payable initializer { - __CheckpointsMock_init(); - } -} -import "./CheckpointsMockUpgradeable.sol"; - -contract Checkpoints224MockUpgradeableWithInit is Checkpoints224MockUpgradeable { - constructor() payable initializer { - __Checkpoints224Mock_init(); - } -} -import "./CheckpointsMockUpgradeable.sol"; - -contract Checkpoints160MockUpgradeableWithInit is Checkpoints160MockUpgradeable { - constructor() payable initializer { - __Checkpoints160Mock_init(); - } -} -import "./ERC721ConsecutiveEnumerableMockUpgradeable.sol"; - -contract ERC721ConsecutiveEnumerableMockUpgradeableWithInit is ERC721ConsecutiveEnumerableMockUpgradeable { - constructor( - string memory name, - string memory symbol, - address[] memory receivers, - uint96[] memory amounts - ) payable initializer { - __ERC721ConsecutiveEnumerableMock_init(name, symbol, receivers, amounts); - } -} -import "./ERC721BurnableMockUpgradeable.sol"; - -contract ERC721BurnableMockUpgradeableWithInit is ERC721BurnableMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC721BurnableMock_init(name, symbol); - } -} -import "../token/ERC1155/utils/ERC1155HolderUpgradeable.sol"; - -contract ERC1155HolderUpgradeableWithInit is ERC1155HolderUpgradeable { - constructor() payable initializer { - __ERC1155Holder_init(); - } -} -import "./ERC1155ReceiverMockUpgradeable.sol"; - -contract ERC1155ReceiverMockUpgradeableWithInit is ERC1155ReceiverMockUpgradeable { - constructor( - bytes4 recRetval, - bool recReverts, - bytes4 batRetval, - bool batReverts - ) payable initializer { - __ERC1155ReceiverMock_init(recRetval, recReverts, batRetval, batReverts); - } -} -import "./ERC165/ERC165ReturnBombUpgradeable.sol"; - -contract ERC165ReturnBombMockUpgradeableWithInit is ERC165ReturnBombMockUpgradeable { - constructor() payable initializer { - __ERC165ReturnBombMock_init(); - } -} -import "./ERC165/ERC165InterfacesSupportedUpgradeable.sol"; - -contract SupportsInterfaceWithLookupMockUpgradeableWithInit is SupportsInterfaceWithLookupMockUpgradeable { - constructor() payable initializer { - __SupportsInterfaceWithLookupMock_init(); - } -} -import "./ERC165/ERC165InterfacesSupportedUpgradeable.sol"; - -contract ERC165InterfacesSupportedUpgradeableWithInit is ERC165InterfacesSupportedUpgradeable { - constructor(bytes4[] memory interfaceIds) payable initializer { - __ERC165InterfacesSupported_init(interfaceIds); - } -} -import "../token/common/ERC2981Upgradeable.sol"; - -contract ERC2981UpgradeableWithInit is ERC2981Upgradeable { - constructor() payable initializer { - __ERC2981_init(); - } -} -import "./ERC721RoyaltyMockUpgradeable.sol"; - -contract ERC721RoyaltyMockUpgradeableWithInit is ERC721RoyaltyMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC721RoyaltyMock_init(name, symbol); - } -} -import "./ERC165MockUpgradeable.sol"; - -contract ERC165MockUpgradeableWithInit is ERC165MockUpgradeable { - constructor() payable initializer { - __ERC165Mock_init(); - } -} -import "./StringsMockUpgradeable.sol"; - -contract StringsMockUpgradeableWithInit is StringsMockUpgradeable { - constructor() payable initializer { - __StringsMock_init(); - } -} -import "../proxy/ERC1967/ERC1967UpgradeUpgradeable.sol"; - -contract ERC1967UpgradeUpgradeableWithInit is ERC1967UpgradeUpgradeable { - constructor() payable initializer { - __ERC1967Upgrade_init(); - } -} -import "./UUPS/UUPSUpgradeableMockUpgradeable.sol"; - -contract UUPSUpgradeableMockUpgradeableWithInit is UUPSUpgradeableMockUpgradeable { - constructor() payable initializer { - __UUPSUpgradeableMock_init(); - } -} -import "./UUPS/UUPSUpgradeableMockUpgradeable.sol"; - -contract UUPSUpgradeableUnsafeMockUpgradeableWithInit is UUPSUpgradeableUnsafeMockUpgradeable { - constructor() payable initializer { - __UUPSUpgradeableUnsafeMock_init(); - } -} -import "./CountersImplUpgradeable.sol"; - -contract CountersImplUpgradeableWithInit is CountersImplUpgradeable { - constructor() payable initializer { - __CountersImpl_init(); - } -} -import "./UUPS/UUPSLegacyUpgradeable.sol"; - -contract UUPSUpgradeableLegacyMockUpgradeableWithInit is UUPSUpgradeableLegacyMockUpgradeable { - constructor() payable initializer { - __UUPSUpgradeableLegacyMock_init(); - } -} -import "./StorageSlotMockUpgradeable.sol"; - -contract StorageSlotMockUpgradeableWithInit is StorageSlotMockUpgradeable { - constructor() payable initializer { - __StorageSlotMock_init(); - } -} -import "./ERC20SnapshotMockUpgradeable.sol"; - -contract ERC20SnapshotMockUpgradeableWithInit is ERC20SnapshotMockUpgradeable { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) payable initializer { - __ERC20SnapshotMock_init(name, symbol, initialAccount, initialBalance); - } -} -import "./ArraysMockUpgradeable.sol"; - -contract Uint256ArraysMockUpgradeableWithInit is Uint256ArraysMockUpgradeable { - constructor(uint256[] memory array) payable initializer { - __Uint256ArraysMock_init(array); - } -} -import "./ArraysMockUpgradeable.sol"; - -contract AddressArraysMockUpgradeableWithInit is AddressArraysMockUpgradeable { - constructor(address[] memory array) payable initializer { - __AddressArraysMock_init(array); - } -} -import "./ArraysMockUpgradeable.sol"; - -contract Bytes32ArraysMockUpgradeableWithInit is Bytes32ArraysMockUpgradeable { - constructor(bytes32[] memory array) payable initializer { - __Bytes32ArraysMock_init(array); - } -} -import "./ERC4626MockUpgradeable.sol"; - -contract ERC4626MockUpgradeableWithInit is ERC4626MockUpgradeable { - constructor( - IERC20MetadataUpgradeable asset, - string memory name, - string memory symbol - ) payable initializer { - __ERC4626Mock_init(asset, name, symbol); - } -} -import "./ERC4626MockUpgradeable.sol"; - -contract ERC4626DecimalMockUpgradeableWithInit is ERC4626DecimalMockUpgradeable { - constructor( - IERC20MetadataUpgradeable asset, - string memory name, - string memory symbol, - uint8 decimalsOverride - ) payable initializer { - __ERC4626DecimalMock_init(asset, name, symbol, decimalsOverride); - } -} -import "./MathMockUpgradeable.sol"; - -contract MathMockUpgradeableWithInit is MathMockUpgradeable { - constructor() payable initializer { - __MathMock_init(); - } -} -import "./TimersTimestampImplUpgradeable.sol"; - -contract TimersTimestampImplUpgradeableWithInit is TimersTimestampImplUpgradeable { - constructor() payable initializer { - __TimersTimestampImpl_init(); - } -} -import "./TimersBlockNumberImplUpgradeable.sol"; - -contract TimersBlockNumberImplUpgradeableWithInit is TimersBlockNumberImplUpgradeable { - constructor() payable initializer { - __TimersBlockNumberImpl_init(); - } -} -import "../token/ERC721/utils/ERC721HolderUpgradeable.sol"; - -contract ERC721HolderUpgradeableWithInit is ERC721HolderUpgradeable { - constructor() payable initializer { - __ERC721Holder_init(); - } -} -import "./ERC721ReceiverMockUpgradeable.sol"; - -contract ERC721ReceiverMockUpgradeableWithInit is ERC721ReceiverMockUpgradeable { - constructor(bytes4 retval, Error error) payable initializer { - __ERC721ReceiverMock_init(retval, error); - } -} -import "./ERC721VotesMockUpgradeable.sol"; - -contract ERC721VotesMockUpgradeableWithInit is ERC721VotesMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC721VotesMock_init(name, symbol); - } -} -import "./ERC721URIStorageMockUpgradeable.sol"; - -contract ERC721URIStorageMockUpgradeableWithInit is ERC721URIStorageMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC721URIStorageMock_init(name, symbol); - } -} -import "./ERC721MockUpgradeable.sol"; - -contract ERC721MockUpgradeableWithInit is ERC721MockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC721Mock_init(name, symbol); - } -} -import "./ERC721PausableMockUpgradeable.sol"; - -contract ERC721PausableMockUpgradeableWithInit is ERC721PausableMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC721PausableMock_init(name, symbol); - } -} -import "./ERC20PausableMockUpgradeable.sol"; - -contract ERC20PausableMockUpgradeableWithInit is ERC20PausableMockUpgradeable { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) payable initializer { - __ERC20PausableMock_init(name, symbol, initialAccount, initialBalance); - } -} -import "./PausableMockUpgradeable.sol"; - -contract PausableMockUpgradeableWithInit is PausableMockUpgradeable { - constructor() payable initializer { - __PausableMock_init(); - } -} -import "./AccessControlEnumerableMockUpgradeable.sol"; - -contract AccessControlEnumerableMockUpgradeableWithInit is AccessControlEnumerableMockUpgradeable { - constructor() payable initializer { - __AccessControlEnumerableMock_init(); - } -} -import "./EnumerableMapMockUpgradeable.sol"; - -contract UintToAddressMapMockUpgradeableWithInit is UintToAddressMapMockUpgradeable { - constructor() payable initializer { - __UintToAddressMapMock_init(); - } -} -import "./EnumerableMapMockUpgradeable.sol"; - -contract AddressToUintMapMockUpgradeableWithInit is AddressToUintMapMockUpgradeable { - constructor() payable initializer { - __AddressToUintMapMock_init(); - } -} -import "./EnumerableMapMockUpgradeable.sol"; - -contract Bytes32ToBytes32MapMockUpgradeableWithInit is Bytes32ToBytes32MapMockUpgradeable { - constructor() payable initializer { - __Bytes32ToBytes32MapMock_init(); - } -} -import "./EnumerableMapMockUpgradeable.sol"; - -contract UintToUintMapMockUpgradeableWithInit is UintToUintMapMockUpgradeable { - constructor() payable initializer { - __UintToUintMapMock_init(); - } -} -import "./EnumerableMapMockUpgradeable.sol"; - -contract Bytes32ToUintMapMockUpgradeableWithInit is Bytes32ToUintMapMockUpgradeable { - constructor() payable initializer { - __Bytes32ToUintMapMock_init(); - } -} -import "./EnumerableSetMockUpgradeable.sol"; - -contract EnumerableBytes32SetMockUpgradeableWithInit is EnumerableBytes32SetMockUpgradeable { - constructor() payable initializer { - __EnumerableBytes32SetMock_init(); - } -} -import "./EnumerableSetMockUpgradeable.sol"; - -contract EnumerableAddressSetMockUpgradeableWithInit is EnumerableAddressSetMockUpgradeable { - constructor() payable initializer { - __EnumerableAddressSetMock_init(); - } -} -import "./EnumerableSetMockUpgradeable.sol"; - -contract EnumerableUintSetMockUpgradeableWithInit is EnumerableUintSetMockUpgradeable { - constructor() payable initializer { - __EnumerableUintSetMock_init(); - } -} -import "./SafeERC20HelperUpgradeable.sol"; - -contract ERC20ReturnFalseMockUpgradeableWithInit is ERC20ReturnFalseMockUpgradeable { - constructor() payable initializer { - __ERC20ReturnFalseMock_init(); - } -} -import "./SafeERC20HelperUpgradeable.sol"; - -contract ERC20ReturnTrueMockUpgradeableWithInit is ERC20ReturnTrueMockUpgradeable { - constructor() payable initializer { - __ERC20ReturnTrueMock_init(); - } -} -import "./SafeERC20HelperUpgradeable.sol"; - -contract ERC20NoReturnMockUpgradeableWithInit is ERC20NoReturnMockUpgradeable { - constructor() payable initializer { - __ERC20NoReturnMock_init(); - } -} -import "./SafeERC20HelperUpgradeable.sol"; - -contract ERC20PermitNoRevertMockUpgradeableWithInit is ERC20PermitNoRevertMockUpgradeable { - constructor() payable initializer { - __ERC20PermitNoRevertMock_init(); - } -} -import "./SafeERC20HelperUpgradeable.sol"; - -contract SafeERC20WrapperUpgradeableWithInit is SafeERC20WrapperUpgradeable { - constructor(IERC20Upgradeable token) payable initializer { - __SafeERC20Wrapper_init(token); - } -} -import "./ERC20PermitMockUpgradeable.sol"; - -contract ERC20PermitMockUpgradeableWithInit is ERC20PermitMockUpgradeable { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) payable initializer { - __ERC20PermitMock_init(name, symbol, initialAccount, initialBalance); - } -} -import "./ERC20WrapperMockUpgradeable.sol"; - -contract ERC20WrapperMockUpgradeableWithInit is ERC20WrapperMockUpgradeable { - constructor( - IERC20Upgradeable _underlyingToken, - string memory name, - string memory symbol - ) payable initializer { - __ERC20WrapperMock_init(_underlyingToken, name, symbol); - } -} -import "../finance/VestingWalletUpgradeable.sol"; - -contract VestingWalletUpgradeableWithInit is VestingWalletUpgradeable { - constructor( - address beneficiaryAddress, - uint64 startTimestamp, - uint64 durationSeconds - ) payable initializer { - __VestingWallet_init(beneficiaryAddress, startTimestamp, durationSeconds); - } -} -import "../finance/PaymentSplitterUpgradeable.sol"; - -contract PaymentSplitterUpgradeableWithInit is PaymentSplitterUpgradeable { - constructor(address[] memory payees, uint256[] memory shares_) payable initializer { - __PaymentSplitter_init(payees, shares_); - } -} -import "./ERC3156FlashBorrowerMockUpgradeable.sol"; - -contract ERC3156FlashBorrowerMockUpgradeableWithInit is ERC3156FlashBorrowerMockUpgradeable { - constructor(bool enableReturn, bool enableApprove) payable initializer { - __ERC3156FlashBorrowerMock_init(enableReturn, enableApprove); - } -} -import "./ERC20FlashMintMockUpgradeable.sol"; - -contract ERC20FlashMintMockUpgradeableWithInit is ERC20FlashMintMockUpgradeable { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) payable initializer { - __ERC20FlashMintMock_init(name, symbol, initialAccount, initialBalance); - } -} -import "./ERC777MockUpgradeable.sol"; - -contract ERC777MockUpgradeableWithInit is ERC777MockUpgradeable { - constructor( - address initialHolder, - uint256 initialBalance, - string memory name, - string memory symbol, - address[] memory defaultOperators - ) payable initializer { - __ERC777Mock_init(initialHolder, initialBalance, name, symbol, defaultOperators); - } -} -import "../token/ERC20/presets/ERC20PresetFixedSupplyUpgradeable.sol"; - -contract ERC20PresetFixedSupplyUpgradeableWithInit is ERC20PresetFixedSupplyUpgradeable { - constructor( - string memory name, - string memory symbol, - uint256 initialSupply, - address owner - ) payable initializer { - __ERC20PresetFixedSupply_init(name, symbol, initialSupply, owner); - } -} -import "./ERC20BurnableMockUpgradeable.sol"; - -contract ERC20BurnableMockUpgradeableWithInit is ERC20BurnableMockUpgradeable { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) payable initializer { - __ERC20BurnableMock_init(name, symbol, initialAccount, initialBalance); - } -} -import "./ReentrancyAttackUpgradeable.sol"; - -contract ReentrancyAttackUpgradeableWithInit is ReentrancyAttackUpgradeable { - constructor() payable initializer { - __ReentrancyAttack_init(); - } -} -import "./ReentrancyMockUpgradeable.sol"; - -contract ReentrancyMockUpgradeableWithInit is ReentrancyMockUpgradeable { - constructor() payable initializer { - __ReentrancyMock_init(); - } -} -import "../security/ReentrancyGuardUpgradeable.sol"; - -contract ReentrancyGuardUpgradeableWithInit is ReentrancyGuardUpgradeable { - constructor() payable initializer { - __ReentrancyGuard_init(); - } -} -import "../crosschain/polygon/CrossChainEnabledPolygonChildUpgradeable.sol"; - -contract CrossChainEnabledPolygonChildUpgradeableWithInit is CrossChainEnabledPolygonChildUpgradeable { - constructor(address fxChild) CrossChainEnabledPolygonChildUpgradeable(fxChild) payable initializer { - - } -} -import "./crosschain/receiversUpgradeable.sol"; - -contract CrossChainEnabledAMBMockUpgradeableWithInit is CrossChainEnabledAMBMockUpgradeable { - constructor(address bridge) CrossChainEnabledAMBMockUpgradeable(bridge) payable initializer { - - } -} -import "./crosschain/receiversUpgradeable.sol"; - -contract CrossChainEnabledArbitrumL1MockUpgradeableWithInit is CrossChainEnabledArbitrumL1MockUpgradeable { - constructor(address bridge) CrossChainEnabledArbitrumL1MockUpgradeable(bridge) payable initializer { - - } -} -import "./crosschain/receiversUpgradeable.sol"; - -contract CrossChainEnabledArbitrumL2MockUpgradeableWithInit is CrossChainEnabledArbitrumL2MockUpgradeable { - constructor() payable initializer { - __CrossChainEnabledArbitrumL2Mock_init(); - } -} -import "./crosschain/receiversUpgradeable.sol"; - -contract CrossChainEnabledOptimismMockUpgradeableWithInit is CrossChainEnabledOptimismMockUpgradeable { - constructor(address bridge) CrossChainEnabledOptimismMockUpgradeable(bridge) payable initializer { - - } -} -import "./crosschain/receiversUpgradeable.sol"; - -contract CrossChainEnabledPolygonChildMockUpgradeableWithInit is CrossChainEnabledPolygonChildMockUpgradeable { - constructor(address bridge) CrossChainEnabledPolygonChildMockUpgradeable(bridge) payable initializer { - - } -} -import "../crosschain/amb/CrossChainEnabledAMBUpgradeable.sol"; - -contract CrossChainEnabledAMBUpgradeableWithInit is CrossChainEnabledAMBUpgradeable { - constructor(address bridge) CrossChainEnabledAMBUpgradeable(bridge) payable initializer { - - } -} -import "../crosschain/arbitrum/CrossChainEnabledArbitrumL1Upgradeable.sol"; - -contract CrossChainEnabledArbitrumL1UpgradeableWithInit is CrossChainEnabledArbitrumL1Upgradeable { - constructor(address bridge) CrossChainEnabledArbitrumL1Upgradeable(bridge) payable initializer { - - } -} -import "../crosschain/arbitrum/CrossChainEnabledArbitrumL2Upgradeable.sol"; - -contract CrossChainEnabledArbitrumL2UpgradeableWithInit is CrossChainEnabledArbitrumL2Upgradeable { - constructor() payable initializer { - __CrossChainEnabledArbitrumL2_init(); - } -} -import "../crosschain/optimism/CrossChainEnabledOptimismUpgradeable.sol"; - -contract CrossChainEnabledOptimismUpgradeableWithInit is CrossChainEnabledOptimismUpgradeable { - constructor(address messenger) CrossChainEnabledOptimismUpgradeable(messenger) payable initializer { - - } -} -import "./AccessControlCrossChainMockUpgradeable.sol"; - -contract AccessControlCrossChainMockUpgradeableWithInit is AccessControlCrossChainMockUpgradeable { - constructor() payable initializer { - __AccessControlCrossChainMock_init(); - } -} -import "./crosschain/bridgesUpgradeable.sol"; - -contract BaseRelayMockUpgradeableWithInit is BaseRelayMockUpgradeable { - constructor() payable initializer { - __BaseRelayMock_init(); - } -} -import "./crosschain/bridgesUpgradeable.sol"; - -contract BridgeAMBMockUpgradeableWithInit is BridgeAMBMockUpgradeable { - constructor() payable initializer { - __BridgeAMBMock_init(); - } -} -import "./crosschain/bridgesUpgradeable.sol"; - -contract BridgeArbitrumL1MockUpgradeableWithInit is BridgeArbitrumL1MockUpgradeable { - constructor() payable initializer { - __BridgeArbitrumL1Mock_init(); - } -} -import "./crosschain/bridgesUpgradeable.sol"; - -contract BridgeArbitrumL1InboxUpgradeableWithInit is BridgeArbitrumL1InboxUpgradeable { - constructor() payable initializer { - __BridgeArbitrumL1Inbox_init(); - } -} -import "./crosschain/bridgesUpgradeable.sol"; - -contract BridgeArbitrumL1OutboxUpgradeableWithInit is BridgeArbitrumL1OutboxUpgradeable { - constructor() payable initializer { - __BridgeArbitrumL1Outbox_init(); - } -} -import "./crosschain/bridgesUpgradeable.sol"; - -contract BridgeArbitrumL2MockUpgradeableWithInit is BridgeArbitrumL2MockUpgradeable { - constructor() payable initializer { - __BridgeArbitrumL2Mock_init(); - } -} -import "./crosschain/bridgesUpgradeable.sol"; - -contract BridgeOptimismMockUpgradeableWithInit is BridgeOptimismMockUpgradeable { - constructor() payable initializer { - __BridgeOptimismMock_init(); - } -} -import "./crosschain/bridgesUpgradeable.sol"; - -contract BridgePolygonChildMockUpgradeableWithInit is BridgePolygonChildMockUpgradeable { - constructor() payable initializer { - __BridgePolygonChildMock_init(); - } -} -import "./ContextMockUpgradeable.sol"; - -contract ContextMockUpgradeableWithInit is ContextMockUpgradeable { - constructor() payable initializer { - __ContextMock_init(); - } -} -import "./ContextMockUpgradeable.sol"; - -contract ContextMockCallerUpgradeableWithInit is ContextMockCallerUpgradeable { - constructor() payable initializer { - __ContextMockCaller_init(); - } -} -import "./ERC2771ContextMockUpgradeable.sol"; - -contract ERC2771ContextMockUpgradeableWithInit is ERC2771ContextMockUpgradeable { - constructor(address trustedForwarder) ERC2771ContextMockUpgradeable(trustedForwarder) payable initializer { - - } -} -import "../metatx/ERC2771ContextUpgradeable.sol"; - -contract ERC2771ContextUpgradeableWithInit is ERC2771ContextUpgradeable { - constructor(address trustedForwarder) ERC2771ContextUpgradeable(trustedForwarder) payable initializer { - - } -} -import "./ERC20CappedMockUpgradeable.sol"; - -contract ERC20CappedMockUpgradeableWithInit is ERC20CappedMockUpgradeable { - constructor( - string memory name, - string memory symbol, - uint256 cap - ) payable initializer { - __ERC20CappedMock_init(name, symbol, cap); - } -} -import "./ERC20DecimalsMockUpgradeable.sol"; - -contract ERC20DecimalsMockUpgradeableWithInit is ERC20DecimalsMockUpgradeable { - constructor( - string memory name_, - string memory symbol_, - uint8 decimals_ - ) payable initializer { - __ERC20DecimalsMock_init(name_, symbol_, decimals_); - } -} -import "./MulticallTestUpgradeable.sol"; - -contract MulticallTestUpgradeableWithInit is MulticallTestUpgradeable { - constructor() payable initializer { - __MulticallTest_init(); - } -} -import "./ClonesMockUpgradeable.sol"; - -contract ClonesMockUpgradeableWithInit is ClonesMockUpgradeable { - constructor() payable initializer { - __ClonesMock_init(); - } -} -import "./AddressImplUpgradeable.sol"; - -contract AddressImplUpgradeableWithInit is AddressImplUpgradeable { - constructor() payable initializer { - __AddressImpl_init(); - } -} -import "../utils/escrow/RefundEscrowUpgradeable.sol"; - -contract RefundEscrowUpgradeableWithInit is RefundEscrowUpgradeable { - constructor(address payable beneficiary_) payable initializer { - __RefundEscrow_init(beneficiary_); - } -} -import "./ConditionalEscrowMockUpgradeable.sol"; - -contract ConditionalEscrowMockUpgradeableWithInit is ConditionalEscrowMockUpgradeable { - constructor() payable initializer { - __ConditionalEscrowMock_init(); - } -} -import "../security/PullPaymentUpgradeable.sol"; - -contract PullPaymentUpgradeableWithInit is PullPaymentUpgradeable { - constructor() payable initializer { - __PullPayment_init(); - } -} -import "./PullPaymentMockUpgradeable.sol"; - -contract PullPaymentMockUpgradeableWithInit is PullPaymentMockUpgradeable { - constructor() payable initializer { - __PullPaymentMock_init(); - } -} -import "./OwnableMockUpgradeable.sol"; - -contract OwnableMockUpgradeableWithInit is OwnableMockUpgradeable { - constructor() payable initializer { - __OwnableMock_init(); - } -} -import "../access/Ownable2StepUpgradeable.sol"; - -contract Ownable2StepUpgradeableWithInit is Ownable2StepUpgradeable { - constructor() payable initializer { - __Ownable2Step_init(); - } -} -import "./Ownable2StepMockUpgradeable.sol"; - -contract Ownable2StepMockUpgradeableWithInit is Ownable2StepMockUpgradeable { - constructor() payable initializer { - __Ownable2StepMock_init(); - } -} -import "./SignatureCheckerMockUpgradeable.sol"; - -contract SignatureCheckerMockUpgradeableWithInit is SignatureCheckerMockUpgradeable { - constructor() payable initializer { - __SignatureCheckerMock_init(); - } -} -import "./ECDSAMockUpgradeable.sol"; - -contract ECDSAMockUpgradeableWithInit is ECDSAMockUpgradeable { - constructor() payable initializer { - __ECDSAMock_init(); - } -} -import "./ERC20VotesMockUpgradeable.sol"; - -contract ERC20VotesMockUpgradeableWithInit is ERC20VotesMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC20VotesMock_init(name, symbol); - } -} -import "./ERC20VotesCompMockUpgradeable.sol"; - -contract ERC20VotesCompMockUpgradeableWithInit is ERC20VotesCompMockUpgradeable { - constructor(string memory name, string memory symbol) payable initializer { - __ERC20VotesCompMock_init(name, symbol); - } -} -import "../governance/TimelockControllerWith46MigrationUpgradeable.sol"; - -contract TimelockControllerWith46MigrationUpgradeableWithInit is TimelockControllerWith46MigrationUpgradeable { - constructor( - uint256 minDelay, - address[] memory proposers, - address[] memory executors, - address admin - ) payable initializer { - __TimelockControllerWith46Migration_init(minDelay, proposers, executors, admin); - } -} -import "./BadBeaconUpgradeable.sol"; - -contract BadBeaconNoImplUpgradeableWithInit is BadBeaconNoImplUpgradeable { - constructor() payable initializer { - __BadBeaconNoImpl_init(); - } -} -import "./BadBeaconUpgradeable.sol"; - -contract BadBeaconNotContractUpgradeableWithInit is BadBeaconNotContractUpgradeable { - constructor() payable initializer { - __BadBeaconNotContract_init(); - } -} -import "./Base64MockUpgradeable.sol"; - -contract Base64MockUpgradeableWithInit is Base64MockUpgradeable { - constructor() payable initializer { - __Base64Mock_init(); - } -} -import "./CallReceiverMockUpgradeable.sol"; - -contract CallReceiverMockUpgradeableWithInit is CallReceiverMockUpgradeable { - constructor() payable initializer { - __CallReceiverMock_init(); - } -} -import "./ClashingImplementationUpgradeable.sol"; - -contract ClashingImplementationUpgradeableWithInit is ClashingImplementationUpgradeable { - constructor() payable initializer { - __ClashingImplementation_init(); - } -} -import "./DummyImplementationUpgradeable.sol"; - -contract DummyImplementationUpgradeableWithInit is DummyImplementationUpgradeable { - constructor() payable initializer { - __DummyImplementation_init(); - } -} -import "./DummyImplementationUpgradeable.sol"; - -contract DummyImplementationV2UpgradeableWithInit is DummyImplementationV2Upgradeable { - constructor() payable initializer { - __DummyImplementationV2_init(); - } -} -import "./ERC165/ERC165MaliciousDataUpgradeable.sol"; - -contract ERC165MaliciousDataUpgradeableWithInit is ERC165MaliciousDataUpgradeable { - constructor() payable initializer { - __ERC165MaliciousData_init(); - } -} -import "./ERC165/ERC165MissingDataUpgradeable.sol"; - -contract ERC165MissingDataUpgradeableWithInit is ERC165MissingDataUpgradeable { - constructor() payable initializer { - __ERC165MissingData_init(); - } -} -import "./ERC165/ERC165NotSupportedUpgradeable.sol"; - -contract ERC165NotSupportedUpgradeableWithInit is ERC165NotSupportedUpgradeable { - constructor() payable initializer { - __ERC165NotSupported_init(); - } -} -import "./EtherReceiverMockUpgradeable.sol"; - -contract EtherReceiverMockUpgradeableWithInit is EtherReceiverMockUpgradeable { - constructor() payable initializer { - __EtherReceiverMock_init(); - } -} -import "./MerkleProofWrapperUpgradeable.sol"; - -contract MerkleProofWrapperUpgradeableWithInit is MerkleProofWrapperUpgradeable { - constructor() payable initializer { - __MerkleProofWrapper_init(); - } -} -import "./SafeMathMockUpgradeable.sol"; - -contract SafeMathMockUpgradeableWithInit is SafeMathMockUpgradeable { - constructor() payable initializer { - __SafeMathMock_init(); - } -} -import "./SignedMathMockUpgradeable.sol"; - -contract SignedMathMockUpgradeableWithInit is SignedMathMockUpgradeable { - constructor() payable initializer { - __SignedMathMock_init(); - } -} -import "./SignedSafeMathMockUpgradeable.sol"; - -contract SignedSafeMathMockUpgradeableWithInit is SignedSafeMathMockUpgradeable { - constructor() payable initializer { - __SignedSafeMathMock_init(); - } -} -import "./compound/CompTimelockUpgradeable.sol"; - -contract CompTimelockUpgradeableWithInit is CompTimelockUpgradeable { - constructor(address admin_, uint256 delay_) payable initializer { - __CompTimelock_init(admin_, delay_); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/compound/CompTimelockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/compound/CompTimelockUpgradeable.sol deleted file mode 100644 index 43ed215..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/compound/CompTimelockUpgradeable.sol +++ /dev/null @@ -1,186 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// solhint-disable private-vars-leading-underscore -/** - * Copyright 2020 Compound Labs, Inc. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -pragma solidity ^0.8.0; -import "../../proxy/utils/Initializable.sol"; - -contract CompTimelockUpgradeable is Initializable { - event NewAdmin(address indexed newAdmin); - event NewPendingAdmin(address indexed newPendingAdmin); - event NewDelay(uint256 indexed newDelay); - event CancelTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - event ExecuteTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - event QueueTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - - uint256 public constant GRACE_PERIOD = 14 days; - uint256 public constant MINIMUM_DELAY = 2 days; - uint256 public constant MAXIMUM_DELAY = 30 days; - - address public admin; - address public pendingAdmin; - uint256 public delay; - - mapping(bytes32 => bool) public queuedTransactions; - - function __CompTimelock_init(address admin_, uint256 delay_) internal onlyInitializing { - __CompTimelock_init_unchained(admin_, delay_); - } - - function __CompTimelock_init_unchained(address admin_, uint256 delay_) internal onlyInitializing { - require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay."); - require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay."); - - admin = admin_; - delay = delay_; - } - - receive() external payable {} - - function setDelay(uint256 delay_) public { - require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock."); - require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay."); - require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay."); - delay = delay_; - - emit NewDelay(delay); - } - - function acceptAdmin() public { - require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin."); - admin = msg.sender; - pendingAdmin = address(0); - - emit NewAdmin(admin); - } - - function setPendingAdmin(address pendingAdmin_) public { - require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock."); - pendingAdmin = pendingAdmin_; - - emit NewPendingAdmin(pendingAdmin); - } - - function queueTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) public returns (bytes32) { - require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin."); - require( - eta >= getBlockTimestamp() + delay, - "Timelock::queueTransaction: Estimated execution block must satisfy delay." - ); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - queuedTransactions[txHash] = true; - - emit QueueTransaction(txHash, target, value, signature, data, eta); - return txHash; - } - - function cancelTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) public { - require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin."); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - queuedTransactions[txHash] = false; - - emit CancelTransaction(txHash, target, value, signature, data, eta); - } - - function executeTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) public payable returns (bytes memory) { - require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin."); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued."); - require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock."); - require(getBlockTimestamp() <= eta + GRACE_PERIOD, "Timelock::executeTransaction: Transaction is stale."); - - queuedTransactions[txHash] = false; - - bytes memory callData; - - if (bytes(signature).length == 0) { - callData = data; - } else { - callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data); - } - - // solium-disable-next-line security/no-call-value - (bool success, bytes memory returnData) = target.call{value: value}(callData); - require(success, "Timelock::executeTransaction: Transaction execution reverted."); - - emit ExecuteTransaction(txHash, target, value, signature, data, eta); - - return returnData; - } - - function getBlockTimestamp() internal view returns (uint256) { - // solium-disable-next-line security/no-block-members - return block.timestamp; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[46] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/crosschain/bridgesUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/crosschain/bridgesUpgradeable.sol deleted file mode 100644 index 09afc17..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/crosschain/bridgesUpgradeable.sol +++ /dev/null @@ -1,199 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../../utils/AddressUpgradeable.sol"; -import "../../vendor/polygon/IFxMessageProcessorUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -abstract contract BaseRelayMockUpgradeable is Initializable { - function __BaseRelayMock_init() internal onlyInitializing { - } - - function __BaseRelayMock_init_unchained() internal onlyInitializing { - } - // needed to parse custom errors - error NotCrossChainCall(); - error InvalidCrossChainSender(address sender, address expected); - - address internal _currentSender; - - function relayAs( - address target, - bytes calldata data, - address sender - ) external virtual { - address previousSender = _currentSender; - - _currentSender = sender; - - (bool success, bytes memory returndata) = target.call(data); - AddressUpgradeable.verifyCallResultFromTarget(target, success, returndata, "low-level call reverted"); - - _currentSender = previousSender; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} - -/** - * AMB - */ -contract BridgeAMBMockUpgradeable is Initializable, BaseRelayMockUpgradeable { - function __BridgeAMBMock_init() internal onlyInitializing { - } - - function __BridgeAMBMock_init_unchained() internal onlyInitializing { - } - function messageSender() public view returns (address) { - return _currentSender; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -/** - * Arbitrum - */ -contract BridgeArbitrumL1MockUpgradeable is Initializable, BaseRelayMockUpgradeable { - function __BridgeArbitrumL1Mock_init() internal onlyInitializing { - } - - function __BridgeArbitrumL1Mock_init_unchained() internal onlyInitializing { - } - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable inbox = address(new BridgeArbitrumL1InboxUpgradeable()); - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable outbox = address(new BridgeArbitrumL1OutboxUpgradeable()); - - function activeOutbox() public view returns (address) { - return outbox; - } - - function currentSender() public view returns (address) { - return _currentSender; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract BridgeArbitrumL1InboxUpgradeable is Initializable { - function __BridgeArbitrumL1Inbox_init() internal onlyInitializing { - } - - function __BridgeArbitrumL1Inbox_init_unchained() internal onlyInitializing { - } - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable bridge = msg.sender; - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract BridgeArbitrumL1OutboxUpgradeable is Initializable { - function __BridgeArbitrumL1Outbox_init() internal onlyInitializing { - } - - function __BridgeArbitrumL1Outbox_init_unchained() internal onlyInitializing { - } - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable bridge = msg.sender; - - function l2ToL1Sender() public view returns (address) { - return BridgeArbitrumL1MockUpgradeable(bridge).currentSender(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract BridgeArbitrumL2MockUpgradeable is Initializable, BaseRelayMockUpgradeable { - function __BridgeArbitrumL2Mock_init() internal onlyInitializing { - } - - function __BridgeArbitrumL2Mock_init_unchained() internal onlyInitializing { - } - function wasMyCallersAddressAliased() public view returns (bool) { - return _currentSender != address(0); - } - - function myCallersAddressWithoutAliasing() public view returns (address) { - return _currentSender; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -/** - * Optimism - */ -contract BridgeOptimismMockUpgradeable is Initializable, BaseRelayMockUpgradeable { - function __BridgeOptimismMock_init() internal onlyInitializing { - } - - function __BridgeOptimismMock_init_unchained() internal onlyInitializing { - } - function xDomainMessageSender() public view returns (address) { - return _currentSender; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -/** - * Polygon - */ -contract BridgePolygonChildMockUpgradeable is Initializable, BaseRelayMockUpgradeable { - function __BridgePolygonChildMock_init() internal onlyInitializing { - } - - function __BridgePolygonChildMock_init_unchained() internal onlyInitializing { - } - function relayAs( - address target, - bytes calldata data, - address sender - ) external override { - IFxMessageProcessorUpgradeable(target).processMessageFromRoot(0, sender, data); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/crosschain/receiversUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/crosschain/receiversUpgradeable.sol deleted file mode 100644 index c76d321..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/crosschain/receiversUpgradeable.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.4; - -import "../../access/OwnableUpgradeable.sol"; -import "../../crosschain/amb/CrossChainEnabledAMBUpgradeable.sol"; -import "../../crosschain/arbitrum/CrossChainEnabledArbitrumL1Upgradeable.sol"; -import "../../crosschain/arbitrum/CrossChainEnabledArbitrumL2Upgradeable.sol"; -import "../../crosschain/optimism/CrossChainEnabledOptimismUpgradeable.sol"; -import "../../crosschain/polygon/CrossChainEnabledPolygonChildUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -abstract contract ReceiverUpgradeable is Initializable, CrossChainEnabledUpgradeable { - function __Receiver_init() internal onlyInitializing { - } - - function __Receiver_init_unchained() internal onlyInitializing { - } - // we don't use Ownable because it messes up testing for the upgradeable contracts - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable owner = msg.sender; - - function crossChainRestricted() external onlyCrossChain {} - - function crossChainOwnerRestricted() external onlyCrossChainSender(owner) {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -/** - * AMB - */ -contract CrossChainEnabledAMBMockUpgradeable is Initializable, ReceiverUpgradeable, CrossChainEnabledAMBUpgradeable { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) CrossChainEnabledAMBUpgradeable(bridge) {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -/** - * Arbitrum - */ -contract CrossChainEnabledArbitrumL1MockUpgradeable is Initializable, ReceiverUpgradeable, CrossChainEnabledArbitrumL1Upgradeable { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) CrossChainEnabledArbitrumL1Upgradeable(bridge) {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -contract CrossChainEnabledArbitrumL2MockUpgradeable is Initializable, ReceiverUpgradeable, CrossChainEnabledArbitrumL2Upgradeable { function __CrossChainEnabledArbitrumL2Mock_init() internal onlyInitializing { - } - - function __CrossChainEnabledArbitrumL2Mock_init_unchained() internal onlyInitializing { - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -/** - * Optimism - */ -contract CrossChainEnabledOptimismMockUpgradeable is Initializable, ReceiverUpgradeable, CrossChainEnabledOptimismUpgradeable { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) CrossChainEnabledOptimismUpgradeable(bridge) {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -/** - * Polygon - */ -contract CrossChainEnabledPolygonChildMockUpgradeable is Initializable, ReceiverUpgradeable, CrossChainEnabledPolygonChildUpgradeable { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) CrossChainEnabledPolygonChildUpgradeable(bridge) {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor1Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor1Upgradeable.sol deleted file mode 100644 index 1507671..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor1Upgradeable.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../../governance/GovernorUpgradeable.sol"; -import "../../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../../governance/extensions/GovernorVotesUpgradeable.sol"; -import "../../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol"; -import "../../governance/extensions/GovernorTimelockControlUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -contract MyGovernor1Upgradeable is - Initializable, GovernorUpgradeable, - GovernorTimelockControlUpgradeable, - GovernorVotesUpgradeable, - GovernorVotesQuorumFractionUpgradeable, - GovernorCountingSimpleUpgradeable -{ - function __MyGovernor1_init(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing { - __EIP712_init_unchained("MyGovernor", version()); - __Governor_init_unchained("MyGovernor"); - __GovernorTimelockControl_init_unchained(_timelock); - __GovernorVotes_init_unchained(_token); - __GovernorVotesQuorumFraction_init_unchained(4); - } - - function __MyGovernor1_init_unchained(IVotesUpgradeable, TimelockControllerUpgradeable) internal onlyInitializing {} - - function votingDelay() public pure override returns (uint256) { - return 1; // 1 block - } - - function votingPeriod() public pure override returns (uint256) { - return 45818; // 1 week - } - - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (ProposalState) { - return super.state(proposalId); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(GovernorUpgradeable, IGovernorUpgradeable) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() internal view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (address) { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor2Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor2Upgradeable.sol deleted file mode 100644 index c6c2df4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor2Upgradeable.sol +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../../governance/GovernorUpgradeable.sol"; -import "../../governance/extensions/GovernorProposalThresholdUpgradeable.sol"; -import "../../governance/extensions/GovernorCountingSimpleUpgradeable.sol"; -import "../../governance/extensions/GovernorVotesUpgradeable.sol"; -import "../../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol"; -import "../../governance/extensions/GovernorTimelockControlUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -contract MyGovernor2Upgradeable is - Initializable, GovernorUpgradeable, - GovernorTimelockControlUpgradeable, - GovernorProposalThresholdUpgradeable, - GovernorVotesUpgradeable, - GovernorVotesQuorumFractionUpgradeable, - GovernorCountingSimpleUpgradeable -{ - function __MyGovernor2_init(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing { - __EIP712_init_unchained("MyGovernor", version()); - __Governor_init_unchained("MyGovernor"); - __GovernorTimelockControl_init_unchained(_timelock); - __GovernorVotes_init_unchained(_token); - __GovernorVotesQuorumFraction_init_unchained(4); - } - - function __MyGovernor2_init_unchained(IVotesUpgradeable, TimelockControllerUpgradeable) internal onlyInitializing {} - - function votingDelay() public pure override returns (uint256) { - return 1; // 1 block - } - - function votingPeriod() public pure override returns (uint256) { - return 45818; // 1 week - } - - function proposalThreshold() public pure override returns (uint256) { - return 1000e18; - } - - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (ProposalState) { - return super.state(proposalId); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(GovernorUpgradeable, GovernorProposalThresholdUpgradeable, IGovernorUpgradeable) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() internal view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (address) { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor3Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor3Upgradeable.sol deleted file mode 100644 index d2ddc6b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/mocks/wizard/MyGovernor3Upgradeable.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../../governance/GovernorUpgradeable.sol"; -import "../../governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol"; -import "../../governance/extensions/GovernorVotesUpgradeable.sol"; -import "../../governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol"; -import "../../governance/extensions/GovernorTimelockControlUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -contract MyGovernorUpgradeable is - Initializable, GovernorUpgradeable, - GovernorTimelockControlUpgradeable, - GovernorCompatibilityBravoUpgradeable, - GovernorVotesUpgradeable, - GovernorVotesQuorumFractionUpgradeable -{ - function __MyGovernor_init(IVotesUpgradeable _token, TimelockControllerUpgradeable _timelock) internal onlyInitializing { - __EIP712_init_unchained("MyGovernor", version()); - __Governor_init_unchained("MyGovernor"); - __GovernorTimelockControl_init_unchained(_timelock); - __GovernorVotes_init_unchained(_token); - __GovernorVotesQuorumFraction_init_unchained(4); - } - - function __MyGovernor_init_unchained(IVotesUpgradeable, TimelockControllerUpgradeable) internal onlyInitializing {} - - function votingDelay() public pure override returns (uint256) { - return 1; // 1 block - } - - function votingPeriod() public pure override returns (uint256) { - return 45818; // 1 week - } - - function proposalThreshold() public pure override returns (uint256) { - return 1000e18; - } - - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) - public - view - override(GovernorUpgradeable, IGovernorUpgradeable, GovernorTimelockControlUpgradeable) - returns (ProposalState) - { - return super.state(proposalId); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(GovernorUpgradeable, GovernorCompatibilityBravoUpgradeable, IGovernorUpgradeable) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() internal view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (address) { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(GovernorUpgradeable, IERC165Upgradeable, GovernorTimelockControlUpgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/package.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/package.json deleted file mode 100644 index e72cb58..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@openzeppelin/contracts-upgradeable", - "description": "Secure Smart Contract library for Solidity", - "version": "4.8.3", - "files": [ - "**/*.sol", - "/build/contracts/*.json", - "!/mocks/**/*" - ], - "scripts": { - "prepare": "bash ../scripts/prepare-contracts-package.sh", - "prepare-docs": "cd ..; npm run prepare-docs" - }, - "repository": { - "type": "git", - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable.git" - }, - "keywords": [ - "solidity", - "ethereum", - "smart", - "contracts", - "security", - "zeppelin" - ], - "author": "OpenZeppelin Community ", - "license": "MIT", - "bugs": { - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/issues" - }, - "homepage": "https://openzeppelin.com/contracts/" -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ClonesUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ClonesUpgradeable.sol deleted file mode 100644 index 6dcb5c5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ClonesUpgradeable.sol +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (proxy/Clones.sol) - -pragma solidity ^0.8.0; - -/** - * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for - * deploying minimal proxy contracts, also known as "clones". - * - * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies - * > a minimal bytecode implementation that delegates all calls to a known, fixed address. - * - * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` - * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the - * deterministic method. - * - * _Available since v3.4._ - */ -library ClonesUpgradeable { - /** - * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. - * - * This function uses the create opcode, which should never revert. - */ - function clone(address implementation) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes - // of the `implementation` address with the bytecode before the address. - mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) - // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. - mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) - instance := create(0, 0x09, 0x37) - } - require(instance != address(0), "ERC1167: create failed"); - } - - /** - * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. - * - * This function uses the create2 opcode and a `salt` to deterministically deploy - * the clone. Using the same `implementation` and `salt` multiple time will revert, since - * the clones cannot be deployed twice at the same address. - */ - function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes - // of the `implementation` address with the bytecode before the address. - mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) - // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. - mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) - instance := create2(0, 0x09, 0x37, salt) - } - require(instance != address(0), "ERC1167: create2 failed"); - } - - /** - * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. - */ - function predictDeterministicAddress( - address implementation, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - /// @solidity memory-safe-assembly - assembly { - let ptr := mload(0x40) - mstore(add(ptr, 0x38), deployer) - mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) - mstore(add(ptr, 0x14), implementation) - mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) - mstore(add(ptr, 0x58), salt) - mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) - predicted := keccak256(add(ptr, 0x43), 0x55) - } - } - - /** - * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. - */ - function predictDeterministicAddress(address implementation, bytes32 salt) - internal - view - returns (address predicted) - { - return predictDeterministicAddress(implementation, salt, address(this)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol deleted file mode 100644 index 186a3a2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.3) (proxy/ERC1967/ERC1967Upgrade.sol) - -pragma solidity ^0.8.2; - -import "../beacon/IBeaconUpgradeable.sol"; -import "../../interfaces/IERC1967Upgradeable.sol"; -import "../../interfaces/draft-IERC1822Upgradeable.sol"; -import "../../utils/AddressUpgradeable.sol"; -import "../../utils/StorageSlotUpgradeable.sol"; -import "../utils/Initializable.sol"; - -/** - * @dev This abstract contract provides getters and event emitting update functions for - * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. - * - * _Available since v4.1._ - * - * @custom:oz-upgrades-unsafe-allow delegatecall - */ -abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable { - function __ERC1967Upgrade_init() internal onlyInitializing { - } - - function __ERC1967Upgrade_init_unchained() internal onlyInitializing { - } - // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 - bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; - - /** - * @dev Storage slot with the address of the current implementation. - * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /** - * @dev Returns the current implementation address. - */ - function _getImplementation() internal view returns (address) { - return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; - } - - /** - * @dev Stores a new address in the EIP1967 implementation slot. - */ - function _setImplementation(address newImplementation) private { - require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); - StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; - } - - /** - * @dev Perform implementation upgrade - * - * Emits an {Upgraded} event. - */ - function _upgradeTo(address newImplementation) internal { - _setImplementation(newImplementation); - emit Upgraded(newImplementation); - } - - /** - * @dev Perform implementation upgrade with additional setup call. - * - * Emits an {Upgraded} event. - */ - function _upgradeToAndCall( - address newImplementation, - bytes memory data, - bool forceCall - ) internal { - _upgradeTo(newImplementation); - if (data.length > 0 || forceCall) { - _functionDelegateCall(newImplementation, data); - } - } - - /** - * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. - * - * Emits an {Upgraded} event. - */ - function _upgradeToAndCallUUPS( - address newImplementation, - bytes memory data, - bool forceCall - ) internal { - // Upgrades from old implementations will perform a rollback test. This test requires the new - // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing - // this special case will break upgrade paths from old UUPS implementation to new ones. - if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { - _setImplementation(newImplementation); - } else { - try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { - require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); - } catch { - revert("ERC1967Upgrade: new implementation is not UUPS"); - } - _upgradeToAndCall(newImplementation, data, forceCall); - } - } - - /** - * @dev Storage slot with the admin of the contract. - * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - - /** - * @dev Returns the current admin. - */ - function _getAdmin() internal view returns (address) { - return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; - } - - /** - * @dev Stores a new address in the EIP1967 admin slot. - */ - function _setAdmin(address newAdmin) private { - require(newAdmin != address(0), "ERC1967: new admin is the zero address"); - StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; - } - - /** - * @dev Changes the admin of the proxy. - * - * Emits an {AdminChanged} event. - */ - function _changeAdmin(address newAdmin) internal { - emit AdminChanged(_getAdmin(), newAdmin); - _setAdmin(newAdmin); - } - - /** - * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. - * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. - */ - bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; - - /** - * @dev Returns the current beacon. - */ - function _getBeacon() internal view returns (address) { - return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; - } - - /** - * @dev Stores a new beacon in the EIP1967 beacon slot. - */ - function _setBeacon(address newBeacon) private { - require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); - require( - AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), - "ERC1967: beacon implementation is not a contract" - ); - StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; - } - - /** - * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does - * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). - * - * Emits a {BeaconUpgraded} event. - */ - function _upgradeBeaconToAndCall( - address newBeacon, - bytes memory data, - bool forceCall - ) internal { - _setBeacon(newBeacon); - emit BeaconUpgraded(newBeacon); - if (data.length > 0 || forceCall) { - _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); - } - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], - * but performing a delegate call. - * - * _Available since v3.4._ - */ - function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { - require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); - - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory returndata) = target.delegatecall(data); - return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/README.adoc deleted file mode 100644 index 89717a7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/README.adoc +++ /dev/null @@ -1,87 +0,0 @@ -= Proxies - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/proxy - -This is a low-level set of contracts implementing different proxy patterns with and without upgradeability. For an in-depth overview of this pattern check out the xref:upgrades-plugins::proxies.adoc[Proxy Upgrade Pattern] page. - -Most of the proxies below are built on an abstract base contract. - -- {Proxy}: Abstract contract implementing the core delegation functionality. - -In order to avoid clashes with the storage variables of the implementation contract behind a proxy, we use https://eips.ethereum.org/EIPS/eip-1967[EIP1967] storage slots. - -- {ERC1967Upgrade}: Internal functions to get and set the storage slots defined in EIP1967. -- {ERC1967Proxy}: A proxy using EIP1967 storage slots. Not upgradeable by default. - -There are two alternative ways to add upgradeability to an ERC1967 proxy. Their differences are explained below in <>. - -- {TransparentUpgradeableProxy}: A proxy with a built in admin and upgrade interface. -- {UUPSUpgradeable}: An upgradeability mechanism to be included in the implementation contract. - -CAUTION: Using upgradeable proxies correctly and securely is a difficult task that requires deep knowledge of the proxy pattern, Solidity, and the EVM. Unless you want a lot of low level control, we recommend using the xref:upgrades-plugins::index.adoc[OpenZeppelin Upgrades Plugins] for Truffle and Hardhat. - -A different family of proxies are beacon proxies. This pattern, popularized by Dharma, allows multiple proxies to be upgraded to a different implementation in a single transaction. - -- {BeaconProxy}: A proxy that retrieves its implementation from a beacon contract. -- {UpgradeableBeacon}: A beacon contract with a built in admin that can upgrade the {BeaconProxy} pointing to it. - -In this pattern, the proxy contract doesn't hold the implementation address in storage like an ERC1967 proxy. Instead, the address is stored in a separate beacon contract. The `upgrade` operations are sent to the beacon instead of to the proxy contract, and all proxies that follow that beacon are automatically upgraded. - -Outside the realm of upgradeability, proxies can also be useful to make cheap contract clones, such as those created by an on-chain factory contract that creates many instances of the same contract. These instances are designed to be both cheap to deploy, and cheap to call. - -- {Clones}: A library that can deploy cheap minimal non-upgradeable proxies. - -[[transparent-vs-uups]] -== Transparent vs UUPS Proxies - -The original proxies included in OpenZeppelin followed the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[Transparent Proxy Pattern]. While this pattern is still provided, our recommendation is now shifting towards UUPS proxies, which are both lightweight and versatile. The name UUPS comes from https://eips.ethereum.org/EIPS/eip-1822[EIP1822], which first documented the pattern. - -While both of these share the same interface for upgrades, in UUPS proxies the upgrade is handled by the implementation, and can eventually be removed. Transparent proxies, on the other hand, include the upgrade and admin logic in the proxy itself. This means {TransparentUpgradeableProxy} is more expensive to deploy than what is possible with UUPS proxies. - -UUPS proxies are implemented using an {ERC1967Proxy}. Note that this proxy is not by itself upgradeable. It is the role of the implementation to include, alongside the contract's logic, all the code necessary to update the implementation's address that is stored at a specific slot in the proxy's storage space. This is where the {UUPSUpgradeable} contract comes in. Inheriting from it (and overriding the {xref-UUPSUpgradeable-_authorizeUpgrade-address-}[`_authorizeUpgrade`] function with the relevant access control mechanism) will turn your contract into a UUPS compliant implementation. - -Note that since both proxies use the same storage slot for the implementation address, using a UUPS compliant implementation with a {TransparentUpgradeableProxy} might allow non-admins to perform upgrade operations. - -By default, the upgrade functionality included in {UUPSUpgradeable} contains a security mechanism that will prevent any upgrades to a non UUPS compliant implementation. This prevents upgrades to an implementation contract that wouldn't contain the necessary upgrade mechanism, as it would lock the upgradeability of the proxy forever. This security mechanism can be bypassed by either of: - -- Adding a flag mechanism in the implementation that will disable the upgrade function when triggered. -- Upgrading to an implementation that features an upgrade mechanism without the additional security check, and then upgrading again to another implementation without the upgrade mechanism. - -The current implementation of this security mechanism uses https://eips.ethereum.org/EIPS/eip-1822[EIP1822] to detect the storage slot used by the implementation. A previous implementation, now deprecated, relied on a rollback check. It is possible to upgrade from a contract using the old mechanism to a new one. The inverse is however not possible, as old implementations (before version 4.5) did not include the `ERC1822` interface. - -== Core - -{{Proxy}} - -== ERC1967 - -{{IERC1967}} - -{{ERC1967Proxy}} - -{{ERC1967Upgrade}} - -== Transparent Proxy - -{{TransparentUpgradeableProxy}} - -{{ProxyAdmin}} - -== Beacon - -{{BeaconProxy}} - -{{IBeacon}} - -{{UpgradeableBeacon}} - -== Minimal Clones - -{{Clones}} - -== Utils - -{{Initializable}} - -{{UUPSUpgradeable}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/beacon/IBeaconUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/beacon/IBeaconUpgradeable.sol deleted file mode 100644 index 7a17d4f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/beacon/IBeaconUpgradeable.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) - -pragma solidity ^0.8.0; - -/** - * @dev This is the interface that {BeaconProxy} expects of its beacon. - */ -interface IBeaconUpgradeable { - /** - * @dev Must return an address that can be used as a delegate call target. - * - * {BeaconProxy} will check that this address is a contract. - */ - function implementation() external view returns (address); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol deleted file mode 100644 index 111d8d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol) - -pragma solidity ^0.8.2; - -import "../../utils/AddressUpgradeable.sol"; - -/** - * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed - * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an - * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer - * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. - * - * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be - * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in - * case an upgrade adds a module that needs to be initialized. - * - * For example: - * - * [.hljs-theme-light.nopadding] - * ``` - * contract MyToken is ERC20Upgradeable { - * function initialize() initializer public { - * __ERC20_init("MyToken", "MTK"); - * } - * } - * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { - * function initializeV2() reinitializer(2) public { - * __ERC20Permit_init("MyToken"); - * } - * } - * ``` - * - * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as - * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. - * - * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure - * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. - * - * [CAUTION] - * ==== - * Avoid leaving a contract uninitialized. - * - * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation - * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke - * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: - * - * [.hljs-theme-light.nopadding] - * ``` - * /// @custom:oz-upgrades-unsafe-allow constructor - * constructor() { - * _disableInitializers(); - * } - * ``` - * ==== - */ -abstract contract Initializable { - /** - * @dev Indicates that the contract has been initialized. - * @custom:oz-retyped-from bool - */ - uint8 private _initialized; - - /** - * @dev Indicates that the contract is in the process of being initialized. - */ - bool private _initializing; - - /** - * @dev Triggered when the contract has been initialized or reinitialized. - */ - event Initialized(uint8 version); - - /** - * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, - * `onlyInitializing` functions can be used to initialize parent contracts. - * - * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a - * constructor. - * - * Emits an {Initialized} event. - */ - modifier initializer() { - bool isTopLevelCall = !_initializing; - require( - (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), - "Initializable: contract is already initialized" - ); - _initialized = 1; - if (isTopLevelCall) { - _initializing = true; - } - _; - if (isTopLevelCall) { - _initializing = false; - emit Initialized(1); - } - } - - /** - * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the - * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be - * used to initialize parent contracts. - * - * A reinitializer may be used after the original initialization step. This is essential to configure modules that - * are added through upgrades and that require initialization. - * - * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` - * cannot be nested. If one is invoked in the context of another, execution will revert. - * - * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in - * a contract, executing them in the right order is up to the developer or operator. - * - * WARNING: setting the version to 255 will prevent any future reinitialization. - * - * Emits an {Initialized} event. - */ - modifier reinitializer(uint8 version) { - require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); - _initialized = version; - _initializing = true; - _; - _initializing = false; - emit Initialized(version); - } - - /** - * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the - * {initializer} and {reinitializer} modifiers, directly or indirectly. - */ - modifier onlyInitializing() { - require(_initializing, "Initializable: contract is not initializing"); - _; - } - - /** - * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. - * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized - * to any version. It is recommended to use this to lock implementation contracts that are designed to be called - * through proxies. - * - * Emits an {Initialized} event the first time it is successfully executed. - */ - function _disableInitializers() internal virtual { - require(!_initializing, "Initializable: contract is initializing"); - if (_initialized < type(uint8).max) { - _initialized = type(uint8).max; - emit Initialized(type(uint8).max); - } - } - - /** - * @dev Returns the highest version that has been initialized. See {reinitializer}. - */ - function _getInitializedVersion() internal view returns (uint8) { - return _initialized; - } - - /** - * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. - */ - function _isInitializing() internal view returns (bool) { - return _initializing; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol deleted file mode 100644 index 5f372cd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol) - -pragma solidity ^0.8.0; - -import "../../interfaces/draft-IERC1822Upgradeable.sol"; -import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; -import "./Initializable.sol"; - -/** - * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an - * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. - * - * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is - * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing - * `UUPSUpgradeable` with a custom implementation of upgrades. - * - * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. - * - * _Available since v4.1._ - */ -abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { - function __UUPSUpgradeable_init() internal onlyInitializing { - } - - function __UUPSUpgradeable_init_unchained() internal onlyInitializing { - } - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address private immutable __self = address(this); - - /** - * @dev Check that the execution is being performed through a delegatecall call and that the execution context is - * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case - * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a - * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to - * fail. - */ - modifier onlyProxy() { - require(address(this) != __self, "Function must be called through delegatecall"); - require(_getImplementation() == __self, "Function must be called through active proxy"); - _; - } - - /** - * @dev Check that the execution is not being performed through a delegate call. This allows a function to be - * callable on the implementing contract but not through proxies. - */ - modifier notDelegated() { - require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); - _; - } - - /** - * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the - * implementation. It is used to validate the implementation's compatibility when performing an upgrade. - * - * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks - * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this - * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. - */ - function proxiableUUID() external view virtual override notDelegated returns (bytes32) { - return _IMPLEMENTATION_SLOT; - } - - /** - * @dev Upgrade the implementation of the proxy to `newImplementation`. - * - * Calls {_authorizeUpgrade}. - * - * Emits an {Upgraded} event. - */ - function upgradeTo(address newImplementation) external virtual onlyProxy { - _authorizeUpgrade(newImplementation); - _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); - } - - /** - * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call - * encoded in `data`. - * - * Calls {_authorizeUpgrade}. - * - * Emits an {Upgraded} event. - */ - function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { - _authorizeUpgrade(newImplementation); - _upgradeToAndCallUUPS(newImplementation, data, true); - } - - /** - * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by - * {upgradeTo} and {upgradeToAndCall}. - * - * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. - * - * ```solidity - * function _authorizeUpgrade(address) internal override onlyOwner {} - * ``` - */ - function _authorizeUpgrade(address newImplementation) internal virtual; - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol deleted file mode 100644 index 445648c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) - -pragma solidity ^0.8.0; - -import "../utils/ContextUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Contract module which allows children to implement an emergency stop - * mechanism that can be triggered by an authorized account. - * - * This module is used through inheritance. It will make available the - * modifiers `whenNotPaused` and `whenPaused`, which can be applied to - * the functions of your contract. Note that they will not be pausable by - * simply including this module, only once the modifiers are put in place. - */ -abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { - /** - * @dev Emitted when the pause is triggered by `account`. - */ - event Paused(address account); - - /** - * @dev Emitted when the pause is lifted by `account`. - */ - event Unpaused(address account); - - bool private _paused; - - /** - * @dev Initializes the contract in unpaused state. - */ - function __Pausable_init() internal onlyInitializing { - __Pausable_init_unchained(); - } - - function __Pausable_init_unchained() internal onlyInitializing { - _paused = false; - } - - /** - * @dev Modifier to make a function callable only when the contract is not paused. - * - * Requirements: - * - * - The contract must not be paused. - */ - modifier whenNotPaused() { - _requireNotPaused(); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is paused. - * - * Requirements: - * - * - The contract must be paused. - */ - modifier whenPaused() { - _requirePaused(); - _; - } - - /** - * @dev Returns true if the contract is paused, and false otherwise. - */ - function paused() public view virtual returns (bool) { - return _paused; - } - - /** - * @dev Throws if the contract is paused. - */ - function _requireNotPaused() internal view virtual { - require(!paused(), "Pausable: paused"); - } - - /** - * @dev Throws if the contract is not paused. - */ - function _requirePaused() internal view virtual { - require(paused(), "Pausable: not paused"); - } - - /** - * @dev Triggers stopped state. - * - * Requirements: - * - * - The contract must not be paused. - */ - function _pause() internal virtual whenNotPaused { - _paused = true; - emit Paused(_msgSender()); - } - - /** - * @dev Returns to normal state. - * - * Requirements: - * - * - The contract must be paused. - */ - function _unpause() internal virtual whenPaused { - _paused = false; - emit Unpaused(_msgSender()); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/PullPaymentUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/PullPaymentUpgradeable.sol deleted file mode 100644 index dd81f7a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/PullPaymentUpgradeable.sol +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (security/PullPayment.sol) - -pragma solidity ^0.8.0; - -import "../utils/escrow/EscrowUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Simple implementation of a - * https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/external-calls/#favor-pull-over-push-for-external-calls[pull-payment] - * strategy, where the paying contract doesn't interact directly with the - * receiver account, which must withdraw its payments itself. - * - * Pull-payments are often considered the best practice when it comes to sending - * Ether, security-wise. It prevents recipients from blocking execution, and - * eliminates reentrancy concerns. - * - * TIP: If you would like to learn more about reentrancy and alternative ways - * to protect against it, check out our blog post - * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. - * - * To use, derive from the `PullPayment` contract, and use {_asyncTransfer} - * instead of Solidity's `transfer` function. Payees can query their due - * payments with {payments}, and retrieve them with {withdrawPayments}. - * - * @custom:storage-size 51 - */ -abstract contract PullPaymentUpgradeable is Initializable { - EscrowUpgradeable private _escrow; - - function __PullPayment_init() internal onlyInitializing { - __PullPayment_init_unchained(); - } - - function __PullPayment_init_unchained() internal onlyInitializing { - _escrow = new EscrowUpgradeable(); - _escrow.initialize(); - } - - /** - * @dev Withdraw accumulated payments, forwarding all gas to the recipient. - * - * Note that _any_ account can call this function, not just the `payee`. - * This means that contracts unaware of the `PullPayment` protocol can still - * receive funds this way, by having a separate account call - * {withdrawPayments}. - * - * WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities. - * Make sure you trust the recipient, or are either following the - * checks-effects-interactions pattern or using {ReentrancyGuard}. - * - * @param payee Whose payments will be withdrawn. - * - * Causes the `escrow` to emit a {Withdrawn} event. - */ - function withdrawPayments(address payable payee) public virtual { - _escrow.withdraw(payee); - } - - /** - * @dev Returns the payments owed to an address. - * @param dest The creditor's address. - */ - function payments(address dest) public view returns (uint256) { - return _escrow.depositsOf(dest); - } - - /** - * @dev Called by the payer to store the sent amount as credit to be pulled. - * Funds sent in this way are stored in an intermediate {Escrow} contract, so - * there is no danger of them being spent before withdrawal. - * - * @param dest The destination address of the funds. - * @param amount The amount to transfer. - * - * Causes the `escrow` to emit a {Deposited} event. - */ - function _asyncTransfer(address dest, uint256 amount) internal virtual { - _escrow.deposit{value: amount}(dest); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/README.adoc deleted file mode 100644 index 66f398f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/README.adoc +++ /dev/null @@ -1,20 +0,0 @@ -= Security - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/security - -These contracts aim to cover common security practices. - -* {PullPayment}: A pattern that can be used to avoid reentrancy attacks. -* {ReentrancyGuard}: A modifier that can prevent reentrancy during certain functions. -* {Pausable}: A common emergency response mechanism that can pause functionality while a remediation is pending. - -TIP: For an overview on reentrancy and the possible mechanisms to prevent it, read our article https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. - -== Contracts - -{{PullPayment}} - -{{ReentrancyGuard}} - -{{Pausable}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol deleted file mode 100644 index 3ecc54c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) - -pragma solidity ^0.8.0; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Contract module that helps prevent reentrant calls to a function. - * - * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier - * available, which can be applied to functions to make sure there are no nested - * (reentrant) calls to them. - * - * Note that because there is a single `nonReentrant` guard, functions marked as - * `nonReentrant` may not call one another. This can be worked around by making - * those functions `private`, and then adding `external` `nonReentrant` entry - * points to them. - * - * TIP: If you would like to learn more about reentrancy and alternative ways - * to protect against it, check out our blog post - * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. - */ -abstract contract ReentrancyGuardUpgradeable is Initializable { - // Booleans are more expensive than uint256 or any type that takes up a full - // word because each write operation emits an extra SLOAD to first read the - // slot's contents, replace the bits taken up by the boolean, and then write - // back. This is the compiler's defense against contract upgrades and - // pointer aliasing, and it cannot be disabled. - - // The values being non-zero value makes deployment a bit more expensive, - // but in exchange the refund on every call to nonReentrant will be lower in - // amount. Since refunds are capped to a percentage of the total - // transaction's gas, it is best to keep them low in cases like this one, to - // increase the likelihood of the full refund coming into effect. - uint256 private constant _NOT_ENTERED = 1; - uint256 private constant _ENTERED = 2; - - uint256 private _status; - - function __ReentrancyGuard_init() internal onlyInitializing { - __ReentrancyGuard_init_unchained(); - } - - function __ReentrancyGuard_init_unchained() internal onlyInitializing { - _status = _NOT_ENTERED; - } - - /** - * @dev Prevents a contract from calling itself, directly or indirectly. - * Calling a `nonReentrant` function from another `nonReentrant` - * function is not supported. It is possible to prevent this from happening - * by making the `nonReentrant` function external, and making it call a - * `private` function that does the actual work. - */ - modifier nonReentrant() { - _nonReentrantBefore(); - _; - _nonReentrantAfter(); - } - - function _nonReentrantBefore() private { - // On the first call to nonReentrant, _status will be _NOT_ENTERED - require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); - - // Any calls to nonReentrant after this point will fail - _status = _ENTERED; - } - - function _nonReentrantAfter() private { - // By storing the original value once again, a refund is triggered (see - // https://eips.ethereum.org/EIPS/eip-2200) - _status = _NOT_ENTERED; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol deleted file mode 100644 index 5aeb488..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol +++ /dev/null @@ -1,529 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol) - -pragma solidity ^0.8.0; - -import "./IERC1155Upgradeable.sol"; -import "./IERC1155ReceiverUpgradeable.sol"; -import "./extensions/IERC1155MetadataURIUpgradeable.sol"; -import "../../utils/AddressUpgradeable.sol"; -import "../../utils/ContextUpgradeable.sol"; -import "../../utils/introspection/ERC165Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the basic standard multi-token. - * See https://eips.ethereum.org/EIPS/eip-1155 - * Originally based on code by Enjin: https://github.com/enjin/erc-1155 - * - * _Available since v3.1._ - */ -contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable { - using AddressUpgradeable for address; - - // Mapping from token ID to account balances - mapping(uint256 => mapping(address => uint256)) private _balances; - - // Mapping from account to operator approvals - mapping(address => mapping(address => bool)) private _operatorApprovals; - - // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json - string private _uri; - - /** - * @dev See {_setURI}. - */ - function __ERC1155_init(string memory uri_) internal onlyInitializing { - __ERC1155_init_unchained(uri_); - } - - function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing { - _setURI(uri_); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { - return - interfaceId == type(IERC1155Upgradeable).interfaceId || - interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @dev See {IERC1155MetadataURI-uri}. - * - * This implementation returns the same URI for *all* token types. It relies - * on the token type ID substitution mechanism - * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. - * - * Clients calling this function must replace the `\{id\}` substring with the - * actual token type ID. - */ - function uri(uint256) public view virtual override returns (string memory) { - return _uri; - } - - /** - * @dev See {IERC1155-balanceOf}. - * - * Requirements: - * - * - `account` cannot be the zero address. - */ - function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { - require(account != address(0), "ERC1155: address zero is not a valid owner"); - return _balances[id][account]; - } - - /** - * @dev See {IERC1155-balanceOfBatch}. - * - * Requirements: - * - * - `accounts` and `ids` must have the same length. - */ - function balanceOfBatch(address[] memory accounts, uint256[] memory ids) - public - view - virtual - override - returns (uint256[] memory) - { - require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch"); - - uint256[] memory batchBalances = new uint256[](accounts.length); - - for (uint256 i = 0; i < accounts.length; ++i) { - batchBalances[i] = balanceOf(accounts[i], ids[i]); - } - - return batchBalances; - } - - /** - * @dev See {IERC1155-setApprovalForAll}. - */ - function setApprovalForAll(address operator, bool approved) public virtual override { - _setApprovalForAll(_msgSender(), operator, approved); - } - - /** - * @dev See {IERC1155-isApprovedForAll}. - */ - function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { - return _operatorApprovals[account][operator]; - } - - /** - * @dev See {IERC1155-safeTransferFrom}. - */ - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual override { - require( - from == _msgSender() || isApprovedForAll(from, _msgSender()), - "ERC1155: caller is not token owner or approved" - ); - _safeTransferFrom(from, to, id, amount, data); - } - - /** - * @dev See {IERC1155-safeBatchTransferFrom}. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual override { - require( - from == _msgSender() || isApprovedForAll(from, _msgSender()), - "ERC1155: caller is not token owner or approved" - ); - _safeBatchTransferFrom(from, to, ids, amounts, data); - } - - /** - * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - `from` must have a balance of tokens of type `id` of at least `amount`. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the - * acceptance magic value. - */ - function _safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: transfer to the zero address"); - - address operator = _msgSender(); - uint256[] memory ids = _asSingletonArray(id); - uint256[] memory amounts = _asSingletonArray(amount); - - _beforeTokenTransfer(operator, from, to, ids, amounts, data); - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - _balances[id][to] += amount; - - emit TransferSingle(operator, from, to, id, amount); - - _afterTokenTransfer(operator, from, to, ids, amounts, data); - - _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the - * acceptance magic value. - */ - function _safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - require(to != address(0), "ERC1155: transfer to the zero address"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, from, to, ids, amounts, data); - - for (uint256 i = 0; i < ids.length; ++i) { - uint256 id = ids[i]; - uint256 amount = amounts[i]; - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - _balances[id][to] += amount; - } - - emit TransferBatch(operator, from, to, ids, amounts); - - _afterTokenTransfer(operator, from, to, ids, amounts, data); - - _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); - } - - /** - * @dev Sets a new URI for all token types, by relying on the token type ID - * substitution mechanism - * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. - * - * By this mechanism, any occurrence of the `\{id\}` substring in either the - * URI or any of the amounts in the JSON file at said URI will be replaced by - * clients with the token type ID. - * - * For example, the `https://token-cdn-domain/\{id\}.json` URI would be - * interpreted by clients as - * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` - * for token type ID 0x4cce0. - * - * See {uri}. - * - * Because these URIs cannot be meaningfully represented by the {URI} event, - * this function emits no events. - */ - function _setURI(string memory newuri) internal virtual { - _uri = newuri; - } - - /** - * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the - * acceptance magic value. - */ - function _mint( - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: mint to the zero address"); - - address operator = _msgSender(); - uint256[] memory ids = _asSingletonArray(id); - uint256[] memory amounts = _asSingletonArray(amount); - - _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); - - _balances[id][to] += amount; - emit TransferSingle(operator, address(0), to, id, amount); - - _afterTokenTransfer(operator, address(0), to, ids, amounts, data); - - _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `amounts` must have the same length. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the - * acceptance magic value. - */ - function _mintBatch( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: mint to the zero address"); - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); - - for (uint256 i = 0; i < ids.length; i++) { - _balances[ids[i]][to] += amounts[i]; - } - - emit TransferBatch(operator, address(0), to, ids, amounts); - - _afterTokenTransfer(operator, address(0), to, ids, amounts, data); - - _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); - } - - /** - * @dev Destroys `amount` tokens of token type `id` from `from` - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `from` must have at least `amount` tokens of token type `id`. - */ - function _burn( - address from, - uint256 id, - uint256 amount - ) internal virtual { - require(from != address(0), "ERC1155: burn from the zero address"); - - address operator = _msgSender(); - uint256[] memory ids = _asSingletonArray(id); - uint256[] memory amounts = _asSingletonArray(amount); - - _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - - emit TransferSingle(operator, from, address(0), id, amount); - - _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `amounts` must have the same length. - */ - function _burnBatch( - address from, - uint256[] memory ids, - uint256[] memory amounts - ) internal virtual { - require(from != address(0), "ERC1155: burn from the zero address"); - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); - - for (uint256 i = 0; i < ids.length; i++) { - uint256 id = ids[i]; - uint256 amount = amounts[i]; - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - } - - emit TransferBatch(operator, from, address(0), ids, amounts); - - _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); - } - - /** - * @dev Approve `operator` to operate on all of `owner` tokens - * - * Emits an {ApprovalForAll} event. - */ - function _setApprovalForAll( - address owner, - address operator, - bool approved - ) internal virtual { - require(owner != operator, "ERC1155: setting approval status for self"); - _operatorApprovals[owner][operator] = approved; - emit ApprovalForAll(owner, operator, approved); - } - - /** - * @dev Hook that is called before any token transfer. This includes minting - * and burning, as well as batched variants. - * - * The same hook is called on both single and batched variants. For single - * transfers, the length of the `ids` and `amounts` arrays will be 1. - * - * Calling conditions (for each `id` and `amount` pair): - * - * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * of token type `id` will be transferred to `to`. - * - When `from` is zero, `amount` tokens of token type `id` will be minted - * for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` - * will be burned. - * - `from` and `to` are never both zero. - * - `ids` and `amounts` have the same, non-zero length. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - /** - * @dev Hook that is called after any token transfer. This includes minting - * and burning, as well as batched variants. - * - * The same hook is called on both single and batched variants. For single - * transfers, the length of the `id` and `amount` arrays will be 1. - * - * Calling conditions (for each `id` and `amount` pair): - * - * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * of token type `id` will be transferred to `to`. - * - When `from` is zero, `amount` tokens of token type `id` will be minted - * for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` - * will be burned. - * - `from` and `to` are never both zero. - * - `ids` and `amounts` have the same, non-zero length. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _afterTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - function _doSafeTransferAcceptanceCheck( - address operator, - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) private { - if (to.isContract()) { - try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { - if (response != IERC1155ReceiverUpgradeable.onERC1155Received.selector) { - revert("ERC1155: ERC1155Receiver rejected tokens"); - } - } catch Error(string memory reason) { - revert(reason); - } catch { - revert("ERC1155: transfer to non-ERC1155Receiver implementer"); - } - } - } - - function _doSafeBatchTransferAcceptanceCheck( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) private { - if (to.isContract()) { - try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( - bytes4 response - ) { - if (response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector) { - revert("ERC1155: ERC1155Receiver rejected tokens"); - } - } catch Error(string memory reason) { - revert(reason); - } catch { - revert("ERC1155: transfer to non-ERC1155Receiver implementer"); - } - } - } - - function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { - uint256[] memory array = new uint256[](1); - array[0] = element; - - return array; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155ReceiverUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155ReceiverUpgradeable.sol deleted file mode 100644 index 2a40cc5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155ReceiverUpgradeable.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165Upgradeable.sol"; - -/** - * @dev _Available since v3.1._ - */ -interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { - /** - * @dev Handles the receipt of a single ERC1155 token type. This function is - * called at the end of a `safeTransferFrom` after the balance has been updated. - * - * NOTE: To accept the transfer, this must return - * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` - * (i.e. 0xf23a6e61, or its own function selector). - * - * @param operator The address which initiated the transfer (i.e. msg.sender) - * @param from The address which previously owned the token - * @param id The ID of the token being transferred - * @param value The amount of tokens being transferred - * @param data Additional data with no specified format - * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed - */ - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) external returns (bytes4); - - /** - * @dev Handles the receipt of a multiple ERC1155 token types. This function - * is called at the end of a `safeBatchTransferFrom` after the balances have - * been updated. - * - * NOTE: To accept the transfer(s), this must return - * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` - * (i.e. 0xbc197c81, or its own function selector). - * - * @param operator The address which initiated the batch transfer (i.e. msg.sender) - * @param from The address which previously owned the token - * @param ids An array containing ids of each token being transferred (order and length must match values array) - * @param values An array containing amounts of each token being transferred (order and length must match ids array) - * @param data Additional data with no specified format - * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed - */ - function onERC1155BatchReceived( - address operator, - address from, - uint256[] calldata ids, - uint256[] calldata values, - bytes calldata data - ) external returns (bytes4); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155Upgradeable.sol deleted file mode 100644 index 817fb52..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/IERC1155Upgradeable.sol +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165Upgradeable.sol"; - -/** - * @dev Required interface of an ERC1155 compliant contract, as defined in the - * https://eips.ethereum.org/EIPS/eip-1155[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155Upgradeable is IERC165Upgradeable { - /** - * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. - */ - event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); - - /** - * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all - * transfers. - */ - event TransferBatch( - address indexed operator, - address indexed from, - address indexed to, - uint256[] ids, - uint256[] values - ); - - /** - * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to - * `approved`. - */ - event ApprovalForAll(address indexed account, address indexed operator, bool approved); - - /** - * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. - * - * If an {URI} event was emitted for `id`, the standard - * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value - * returned by {IERC1155MetadataURI-uri}. - */ - event URI(string value, uint256 indexed id); - - /** - * @dev Returns the amount of tokens of token type `id` owned by `account`. - * - * Requirements: - * - * - `account` cannot be the zero address. - */ - function balanceOf(address account, uint256 id) external view returns (uint256); - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. - * - * Requirements: - * - * - `accounts` and `ids` must have the same length. - */ - function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) - external - view - returns (uint256[] memory); - - /** - * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, - * - * Emits an {ApprovalForAll} event. - * - * Requirements: - * - * - `operator` cannot be the caller. - */ - function setApprovalForAll(address operator, bool approved) external; - - /** - * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. - * - * See {setApprovalForAll}. - */ - function isApprovedForAll(address account, address operator) external view returns (bool); - - /** - * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. - * - `from` must have a balance of tokens of type `id` of at least `amount`. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the - * acceptance magic value. - */ - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) external; - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `amounts` must have the same length. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the - * acceptance magic value. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/README.adoc deleted file mode 100644 index 13ffbdb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/README.adoc +++ /dev/null @@ -1,49 +0,0 @@ -= ERC 1155 - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc1155 - -This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-1155[ERC1155 Multi Token Standard]. - -The EIP consists of three interfaces which fulfill different roles, found here as {IERC1155}, {IERC1155MetadataURI} and {IERC1155Receiver}. - -{ERC1155} implements the mandatory {IERC1155} interface, as well as the optional extension {IERC1155MetadataURI}, by relying on the substitution mechanism to use the same URI for all token types, dramatically reducing gas costs. - -Additionally there are multiple custom extensions, including: - -* designation of addresses that can pause token transfers for all users ({ERC1155Pausable}). -* destruction of own tokens ({ERC1155Burnable}). - -NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC1155 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc1155.adoc#Presets[ERC1155 Presets] (such as {ERC1155PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts. - -== Core - -{{IERC1155}} - -{{IERC1155MetadataURI}} - -{{ERC1155}} - -{{IERC1155Receiver}} - -{{ERC1155Receiver}} - -== Extensions - -{{ERC1155Pausable}} - -{{ERC1155Burnable}} - -{{ERC1155Supply}} - -{{ERC1155URIStorage}} - -== Presets - -These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code. - -{{ERC1155PresetMinterPauser}} - -== Utilities - -{{ERC1155Holder}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol deleted file mode 100644 index 2a26b32..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/extensions/ERC1155Burnable.sol) - -pragma solidity ^0.8.0; - -import "../ERC1155Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {ERC1155} that allows token holders to destroy both their - * own tokens and those that they have been approved to use. - * - * _Available since v3.1._ - */ -abstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable { - function __ERC1155Burnable_init() internal onlyInitializing { - } - - function __ERC1155Burnable_init_unchained() internal onlyInitializing { - } - function burn( - address account, - uint256 id, - uint256 value - ) public virtual { - require( - account == _msgSender() || isApprovedForAll(account, _msgSender()), - "ERC1155: caller is not token owner or approved" - ); - - _burn(account, id, value); - } - - function burnBatch( - address account, - uint256[] memory ids, - uint256[] memory values - ) public virtual { - require( - account == _msgSender() || isApprovedForAll(account, _msgSender()), - "ERC1155: caller is not token owner or approved" - ); - - _burnBatch(account, ids, values); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155PausableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155PausableUpgradeable.sol deleted file mode 100644 index ef6e3fd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155PausableUpgradeable.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC1155/extensions/ERC1155Pausable.sol) - -pragma solidity ^0.8.0; - -import "../ERC1155Upgradeable.sol"; -import "../../../security/PausableUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev ERC1155 token with pausable token transfers, minting and burning. - * - * Useful for scenarios such as preventing trades until the end of an evaluation - * period, or having an emergency switch for freezing all token transfers in the - * event of a large bug. - * - * IMPORTANT: This contract does not include public pause and unpause functions. In - * addition to inheriting this contract, you must define both functions, invoking the - * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate - * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will - * make the contract unpausable. - * - * _Available since v3.1._ - */ -abstract contract ERC1155PausableUpgradeable is Initializable, ERC1155Upgradeable, PausableUpgradeable { - function __ERC1155Pausable_init() internal onlyInitializing { - __Pausable_init_unchained(); - } - - function __ERC1155Pausable_init_unchained() internal onlyInitializing { - } - /** - * @dev See {ERC1155-_beforeTokenTransfer}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual override { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - - require(!paused(), "ERC1155Pausable: token transfer while paused"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol deleted file mode 100644 index c96fe2d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol) - -pragma solidity ^0.8.0; - -import "../ERC1155Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of ERC1155 that adds tracking of total supply per id. - * - * Useful for scenarios where Fungible and Non-fungible tokens have to be - * clearly identified. Note: While a totalSupply of 1 might mean the - * corresponding is an NFT, there is no guarantees that no other token with the - * same id are not going to be minted. - */ -abstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable { - function __ERC1155Supply_init() internal onlyInitializing { - } - - function __ERC1155Supply_init_unchained() internal onlyInitializing { - } - mapping(uint256 => uint256) private _totalSupply; - - /** - * @dev Total amount of tokens in with a given id. - */ - function totalSupply(uint256 id) public view virtual returns (uint256) { - return _totalSupply[id]; - } - - /** - * @dev Indicates whether any token exist with a given id, or not. - */ - function exists(uint256 id) public view virtual returns (bool) { - return ERC1155SupplyUpgradeable.totalSupply(id) > 0; - } - - /** - * @dev See {ERC1155-_beforeTokenTransfer}. - */ - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual override { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - - if (from == address(0)) { - for (uint256 i = 0; i < ids.length; ++i) { - _totalSupply[ids[i]] += amounts[i]; - } - } - - if (to == address(0)) { - for (uint256 i = 0; i < ids.length; ++i) { - uint256 id = ids[i]; - uint256 amount = amounts[i]; - uint256 supply = _totalSupply[id]; - require(supply >= amount, "ERC1155: burn amount exceeds totalSupply"); - unchecked { - _totalSupply[id] = supply - amount; - } - } - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol deleted file mode 100644 index ccb912a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol) - -pragma solidity ^0.8.0; - -import "../../../utils/StringsUpgradeable.sol"; -import "../ERC1155Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev ERC1155 token with storage based token URI management. - * Inspired by the ERC721URIStorage extension - * - * _Available since v4.6._ - */ -abstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable { - function __ERC1155URIStorage_init() internal onlyInitializing { - __ERC1155URIStorage_init_unchained(); - } - - function __ERC1155URIStorage_init_unchained() internal onlyInitializing { - _baseURI = ""; - } - using StringsUpgradeable for uint256; - - // Optional base URI - string private _baseURI; - - // Optional mapping for token URIs - mapping(uint256 => string) private _tokenURIs; - - /** - * @dev See {IERC1155MetadataURI-uri}. - * - * This implementation returns the concatenation of the `_baseURI` - * and the token-specific uri if the latter is set - * - * This enables the following behaviors: - * - * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation - * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI` - * is empty per default); - * - * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()` - * which in most cases will contain `ERC1155._uri`; - * - * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a - * uri value set, then the result is empty. - */ - function uri(uint256 tokenId) public view virtual override returns (string memory) { - string memory tokenURI = _tokenURIs[tokenId]; - - // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked). - return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId); - } - - /** - * @dev Sets `tokenURI` as the tokenURI of `tokenId`. - */ - function _setURI(uint256 tokenId, string memory tokenURI) internal virtual { - _tokenURIs[tokenId] = tokenURI; - emit URI(uri(tokenId), tokenId); - } - - /** - * @dev Sets `baseURI` as the `_baseURI` for all tokens - */ - function _setBaseURI(string memory baseURI) internal virtual { - _baseURI = baseURI; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol deleted file mode 100644 index e47f021..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) - -pragma solidity ^0.8.0; - -import "../IERC1155Upgradeable.sol"; - -/** - * @dev Interface of the optional ERC1155MetadataExtension interface, as defined - * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable { - /** - * @dev Returns the URI for token type `id`. - * - * If the `\{id\}` substring is present in the URI, it must be replaced by - * clients with the actual token type ID. - */ - function uri(uint256 id) external view returns (string memory); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol deleted file mode 100644 index 5fcb96f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/ERC1155PresetMinterPauserUpgradeable.sol +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/presets/ERC1155PresetMinterPauser.sol) - -pragma solidity ^0.8.0; - -import "../ERC1155Upgradeable.sol"; -import "../extensions/ERC1155BurnableUpgradeable.sol"; -import "../extensions/ERC1155PausableUpgradeable.sol"; -import "../../../access/AccessControlEnumerableUpgradeable.sol"; -import "../../../utils/ContextUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev {ERC1155} token, including: - * - * - ability for holders to burn (destroy) their tokens - * - a minter role that allows for token minting (creation) - * - a pauser role that allows to stop all token transfers - * - * This contract uses {AccessControl} to lock permissioned functions using the - * different roles - head to its documentation for details. - * - * The account that deploys the contract will be granted the minter and pauser - * roles, as well as the default admin role, which will let it grant both minter - * and pauser roles to other accounts. - * - * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._ - */ -contract ERC1155PresetMinterPauserUpgradeable is Initializable, ContextUpgradeable, AccessControlEnumerableUpgradeable, ERC1155BurnableUpgradeable, ERC1155PausableUpgradeable { - function initialize(string memory uri) public virtual initializer { - __ERC1155PresetMinterPauser_init(uri); - } - bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); - bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); - - /** - * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, and `PAUSER_ROLE` to the account that - * deploys the contract. - */ - function __ERC1155PresetMinterPauser_init(string memory uri) internal onlyInitializing { - __ERC1155_init_unchained(uri); - __Pausable_init_unchained(); - __ERC1155PresetMinterPauser_init_unchained(uri); - } - - function __ERC1155PresetMinterPauser_init_unchained(string memory) internal onlyInitializing { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - - _setupRole(MINTER_ROLE, _msgSender()); - _setupRole(PAUSER_ROLE, _msgSender()); - } - - /** - * @dev Creates `amount` new tokens for `to`, of token type `id`. - * - * See {ERC1155-_mint}. - * - * Requirements: - * - * - the caller must have the `MINTER_ROLE`. - */ - function mint( - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint"); - - _mint(to, id, amount, data); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] variant of {mint}. - */ - function mintBatch( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint"); - - _mintBatch(to, ids, amounts, data); - } - - /** - * @dev Pauses all token transfers. - * - * See {ERC1155Pausable} and {Pausable-_pause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function pause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have pauser role to pause"); - _pause(); - } - - /** - * @dev Unpauses all token transfers. - * - * See {ERC1155Pausable} and {Pausable-_unpause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function unpause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have pauser role to unpause"); - _unpause(); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(AccessControlEnumerableUpgradeable, ERC1155Upgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual override(ERC1155Upgradeable, ERC1155PausableUpgradeable) { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/README.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/README.md deleted file mode 100644 index 468200b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/presets/README.md +++ /dev/null @@ -1 +0,0 @@ -Contract presets are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com/) as a more powerful alternative. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155HolderUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155HolderUpgradeable.sol deleted file mode 100644 index c21db22..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155HolderUpgradeable.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol) - -pragma solidity ^0.8.0; - -import "./ERC1155ReceiverUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens. - * - * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be - * stuck. - * - * @dev _Available since v3.1._ - */ -contract ERC1155HolderUpgradeable is Initializable, ERC1155ReceiverUpgradeable { - function __ERC1155Holder_init() internal onlyInitializing { - } - - function __ERC1155Holder_init_unchained() internal onlyInitializing { - } - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol deleted file mode 100644 index a516a14..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/utils/ERC1155ReceiverUpgradeable.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol) - -pragma solidity ^0.8.0; - -import "../IERC1155ReceiverUpgradeable.sol"; -import "../../../utils/introspection/ERC165Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev _Available since v3.1._ - */ -abstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable { - function __ERC1155Receiver_init() internal onlyInitializing { - } - - function __ERC1155Receiver_init_unchained() internal onlyInitializing { - } - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { - return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol deleted file mode 100644 index 6bef1d4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol +++ /dev/null @@ -1,401 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) - -pragma solidity ^0.8.0; - -import "./IERC20Upgradeable.sol"; -import "./extensions/IERC20MetadataUpgradeable.sol"; -import "../../utils/ContextUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the {IERC20} interface. - * - * This implementation is agnostic to the way tokens are created. This means - * that a supply mechanism has to be added in a derived contract using {_mint}. - * For a generic mechanism see {ERC20PresetMinterPauser}. - * - * TIP: For a detailed writeup see our guide - * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How - * to implement supply mechanisms]. - * - * We have followed general OpenZeppelin Contracts guidelines: functions revert - * instead returning `false` on failure. This behavior is nonetheless - * conventional and does not conflict with the expectations of ERC20 - * applications. - * - * Additionally, an {Approval} event is emitted on calls to {transferFrom}. - * This allows applications to reconstruct the allowance for all accounts just - * by listening to said events. Other implementations of the EIP may not emit - * these events, as it isn't required by the specification. - * - * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} - * functions have been added to mitigate the well-known issues around setting - * allowances. See {IERC20-approve}. - */ -contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { - mapping(address => uint256) private _balances; - - mapping(address => mapping(address => uint256)) private _allowances; - - uint256 private _totalSupply; - - string private _name; - string private _symbol; - - /** - * @dev Sets the values for {name} and {symbol}. - * - * The default value of {decimals} is 18. To select a different value for - * {decimals} you should overload it. - * - * All two of these values are immutable: they can only be set once during - * construction. - */ - function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { - __ERC20_init_unchained(name_, symbol_); - } - - function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { - _name = name_; - _symbol = symbol_; - } - - /** - * @dev Returns the name of the token. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - /** - * @dev Returns the number of decimals used to get its user representation. - * For example, if `decimals` equals `2`, a balance of `505` tokens should - * be displayed to a user as `5.05` (`505 / 10 ** 2`). - * - * Tokens usually opt for a value of 18, imitating the relationship between - * Ether and Wei. This is the value {ERC20} uses, unless this function is - * overridden; - * - * NOTE: This information is only used for _display_ purposes: it in - * no way affects any of the arithmetic of the contract, including - * {IERC20-balanceOf} and {IERC20-transfer}. - */ - function decimals() public view virtual override returns (uint8) { - return 18; - } - - /** - * @dev See {IERC20-totalSupply}. - */ - function totalSupply() public view virtual override returns (uint256) { - return _totalSupply; - } - - /** - * @dev See {IERC20-balanceOf}. - */ - function balanceOf(address account) public view virtual override returns (uint256) { - return _balances[account]; - } - - /** - * @dev See {IERC20-transfer}. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - the caller must have a balance of at least `amount`. - */ - function transfer(address to, uint256 amount) public virtual override returns (bool) { - address owner = _msgSender(); - _transfer(owner, to, amount); - return true; - } - - /** - * @dev See {IERC20-allowance}. - */ - function allowance(address owner, address spender) public view virtual override returns (uint256) { - return _allowances[owner][spender]; - } - - /** - * @dev See {IERC20-approve}. - * - * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on - * `transferFrom`. This is semantically equivalent to an infinite approval. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function approve(address spender, uint256 amount) public virtual override returns (bool) { - address owner = _msgSender(); - _approve(owner, spender, amount); - return true; - } - - /** - * @dev See {IERC20-transferFrom}. - * - * Emits an {Approval} event indicating the updated allowance. This is not - * required by the EIP. See the note at the beginning of {ERC20}. - * - * NOTE: Does not update the allowance if the current allowance - * is the maximum `uint256`. - * - * Requirements: - * - * - `from` and `to` cannot be the zero address. - * - `from` must have a balance of at least `amount`. - * - the caller must have allowance for ``from``'s tokens of at least - * `amount`. - */ - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual override returns (bool) { - address spender = _msgSender(); - _spendAllowance(from, spender, amount); - _transfer(from, to, amount); - return true; - } - - /** - * @dev Atomically increases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { - address owner = _msgSender(); - _approve(owner, spender, allowance(owner, spender) + addedValue); - return true; - } - - /** - * @dev Atomically decreases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `spender` must have allowance for the caller of at least - * `subtractedValue`. - */ - function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { - address owner = _msgSender(); - uint256 currentAllowance = allowance(owner, spender); - require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); - unchecked { - _approve(owner, spender, currentAllowance - subtractedValue); - } - - return true; - } - - /** - * @dev Moves `amount` of tokens from `from` to `to`. - * - * This internal function is equivalent to {transfer}, and can be used to - * e.g. implement automatic token fees, slashing mechanisms, etc. - * - * Emits a {Transfer} event. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `from` must have a balance of at least `amount`. - */ - function _transfer( - address from, - address to, - uint256 amount - ) internal virtual { - require(from != address(0), "ERC20: transfer from the zero address"); - require(to != address(0), "ERC20: transfer to the zero address"); - - _beforeTokenTransfer(from, to, amount); - - uint256 fromBalance = _balances[from]; - require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); - unchecked { - _balances[from] = fromBalance - amount; - // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by - // decrementing then incrementing. - _balances[to] += amount; - } - - emit Transfer(from, to, amount); - - _afterTokenTransfer(from, to, amount); - } - - /** @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. - * - * Emits a {Transfer} event with `from` set to the zero address. - * - * Requirements: - * - * - `account` cannot be the zero address. - */ - function _mint(address account, uint256 amount) internal virtual { - require(account != address(0), "ERC20: mint to the zero address"); - - _beforeTokenTransfer(address(0), account, amount); - - _totalSupply += amount; - unchecked { - // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. - _balances[account] += amount; - } - emit Transfer(address(0), account, amount); - - _afterTokenTransfer(address(0), account, amount); - } - - /** - * @dev Destroys `amount` tokens from `account`, reducing the - * total supply. - * - * Emits a {Transfer} event with `to` set to the zero address. - * - * Requirements: - * - * - `account` cannot be the zero address. - * - `account` must have at least `amount` tokens. - */ - function _burn(address account, uint256 amount) internal virtual { - require(account != address(0), "ERC20: burn from the zero address"); - - _beforeTokenTransfer(account, address(0), amount); - - uint256 accountBalance = _balances[account]; - require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); - unchecked { - _balances[account] = accountBalance - amount; - // Overflow not possible: amount <= accountBalance <= totalSupply. - _totalSupply -= amount; - } - - emit Transfer(account, address(0), amount); - - _afterTokenTransfer(account, address(0), amount); - } - - /** - * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. - * - * This internal function is equivalent to `approve`, and can be used to - * e.g. set automatic allowances for certain subsystems, etc. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `owner` cannot be the zero address. - * - `spender` cannot be the zero address. - */ - function _approve( - address owner, - address spender, - uint256 amount - ) internal virtual { - require(owner != address(0), "ERC20: approve from the zero address"); - require(spender != address(0), "ERC20: approve to the zero address"); - - _allowances[owner][spender] = amount; - emit Approval(owner, spender, amount); - } - - /** - * @dev Updates `owner` s allowance for `spender` based on spent `amount`. - * - * Does not update the allowance amount in case of infinite allowance. - * Revert if not enough allowance is available. - * - * Might emit an {Approval} event. - */ - function _spendAllowance( - address owner, - address spender, - uint256 amount - ) internal virtual { - uint256 currentAllowance = allowance(owner, spender); - if (currentAllowance != type(uint256).max) { - require(currentAllowance >= amount, "ERC20: insufficient allowance"); - unchecked { - _approve(owner, spender, currentAllowance - amount); - } - } - } - - /** - * @dev Hook that is called before any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} - - /** - * @dev Hook that is called after any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * has been transferred to `to`. - * - when `from` is zero, `amount` tokens have been minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens have been burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[45] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol deleted file mode 100644 index f72ebe9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/IERC20Upgradeable.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC20 standard as defined in the EIP. - */ -interface IERC20Upgradeable { - /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). - * - * Note that `value` may be zero. - */ - event Transfer(address indexed from, address indexed to, uint256 value); - - /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` is the new allowance. - */ - event Approval(address indexed owner, address indexed spender, uint256 value); - - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by `account`. - */ - function balanceOf(address account) external view returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `to`. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transfer(address to, uint256 amount) external returns (bool); - - /** - * @dev Returns the remaining number of tokens that `spender` will be - * allowed to spend on behalf of `owner` through {transferFrom}. This is - * zero by default. - * - * This value changes when {approve} or {transferFrom} are called. - */ - function allowance(address owner, address spender) external view returns (uint256); - - /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * IMPORTANT: Beware that changing an allowance with this method brings the risk - * that someone may use both the old and the new allowance by unfortunate - * transaction ordering. One possible solution to mitigate this race - * condition is to first reduce the spender's allowance to 0 and set the - * desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * - * Emits an {Approval} event. - */ - function approve(address spender, uint256 amount) external returns (bool); - - /** - * @dev Moves `amount` tokens from `from` to `to` using the - * allowance mechanism. `amount` is then deducted from the caller's - * allowance. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transferFrom( - address from, - address to, - uint256 amount - ) external returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/README.adoc deleted file mode 100644 index ae2ce36..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/README.adoc +++ /dev/null @@ -1,86 +0,0 @@ -= ERC 20 - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc20 - -This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-20[ERC20 Token Standard]. - -TIP: For an overview of ERC20 tokens and a walk through on how to create a token contract read our xref:ROOT:erc20.adoc[ERC20 guide]. - -There are a few core contracts that implement the behavior specified in the EIP: - -* {IERC20}: the interface all ERC20 implementations should conform to. -* {IERC20Metadata}: the extended ERC20 interface including the <>, <> and <> functions. -* {ERC20}: the implementation of the ERC20 interface, including the <>, <> and <> optional standard extension to the base interface. - -Additionally there are multiple custom extensions, including: - -* {ERC20Burnable}: destruction of own tokens. -* {ERC20Capped}: enforcement of a cap to the total supply when minting tokens. -* {ERC20Pausable}: ability to pause token transfers. -* {ERC20Snapshot}: efficient storage of past token balances to be later queried at any point in time. -* {ERC20Permit}: gasless approval of tokens (standardized as ERC2612). -* {ERC20FlashMint}: token level support for flash loans through the minting and burning of ephemeral tokens (standardized as ERC3156). -* {ERC20Votes}: support for voting and vote delegation. -* {ERC20VotesComp}: support for voting and vote delegation (compatible with Compound's token, with uint96 restrictions). -* {ERC20Wrapper}: wrapper to create an ERC20 backed by another ERC20, with deposit and withdraw methods. Useful in conjunction with {ERC20Votes}. -* {ERC4626}: tokenized vault that manages shares (represented as ERC20) that are backed by assets (another ERC20). - -Finally, there are some utilities to interact with ERC20 contracts in various ways. - -* {SafeERC20}: a wrapper around the interface that eliminates the need to handle boolean return values. -* {TokenTimelock}: hold tokens for a beneficiary until a specified time. - -The following related EIPs are in draft status. - -- {ERC20Permit} - -NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC20 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc20.adoc#Presets[ERC20 Presets] (such as {ERC20PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts. - -== Core - -{{IERC20}} - -{{IERC20Metadata}} - -{{ERC20}} - -== Extensions - -{{ERC20Burnable}} - -{{ERC20Capped}} - -{{ERC20Pausable}} - -{{ERC20Snapshot}} - -{{ERC20Votes}} - -{{ERC20VotesComp}} - -{{ERC20Wrapper}} - -{{ERC20FlashMint}} - -{{ERC4626}} - -== Draft EIPs - -The following EIPs are still in Draft status. Due to their nature as drafts, the details of these contracts may change and we cannot guarantee their xref:ROOT:releases-stability.adoc[stability]. Minor releases of OpenZeppelin Contracts may contain breaking changes for the contracts in this directory, which will be duly announced in the https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md[changelog]. The EIPs included here are used by projects in production and this may make them less likely to change significantly. - -{{ERC20Permit}} - -== Presets - -These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code. - -{{ERC20PresetMinterPauser}} - -{{ERC20PresetFixedSupply}} - -== Utilities - -{{SafeERC20}} - -{{TokenTimelock}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20BurnableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20BurnableUpgradeable.sol deleted file mode 100644 index 98766b8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20BurnableUpgradeable.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) - -pragma solidity ^0.8.0; - -import "../ERC20Upgradeable.sol"; -import "../../../utils/ContextUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {ERC20} that allows token holders to destroy both their own - * tokens and those that they have an allowance for, in a way that can be - * recognized off-chain (via event analysis). - */ -abstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable { - function __ERC20Burnable_init() internal onlyInitializing { - } - - function __ERC20Burnable_init_unchained() internal onlyInitializing { - } - /** - * @dev Destroys `amount` tokens from the caller. - * - * See {ERC20-_burn}. - */ - function burn(uint256 amount) public virtual { - _burn(_msgSender(), amount); - } - - /** - * @dev Destroys `amount` tokens from `account`, deducting from the caller's - * allowance. - * - * See {ERC20-_burn} and {ERC20-allowance}. - * - * Requirements: - * - * - the caller must have allowance for ``accounts``'s tokens of at least - * `amount`. - */ - function burnFrom(address account, uint256 amount) public virtual { - _spendAllowance(account, _msgSender(), amount); - _burn(account, amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20CappedUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20CappedUpgradeable.sol deleted file mode 100644 index 3935b65..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20CappedUpgradeable.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol) - -pragma solidity ^0.8.0; - -import "../ERC20Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of {ERC20} that adds a cap to the supply of tokens. - * - * @custom:storage-size 51 - */ -abstract contract ERC20CappedUpgradeable is Initializable, ERC20Upgradeable { - uint256 private _cap; - - /** - * @dev Sets the value of the `cap`. This value is immutable, it can only be - * set once during construction. - */ - function __ERC20Capped_init(uint256 cap_) internal onlyInitializing { - __ERC20Capped_init_unchained(cap_); - } - - function __ERC20Capped_init_unchained(uint256 cap_) internal onlyInitializing { - require(cap_ > 0, "ERC20Capped: cap is 0"); - _cap = cap_; - } - - /** - * @dev Returns the cap on the token's total supply. - */ - function cap() public view virtual returns (uint256) { - return _cap; - } - - /** - * @dev See {ERC20-_mint}. - */ - function _mint(address account, uint256 amount) internal virtual override { - require(ERC20Upgradeable.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded"); - super._mint(account, amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol deleted file mode 100644 index 008c628..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/ERC20FlashMint.sol) - -pragma solidity ^0.8.0; - -import "../../../interfaces/IERC3156FlashBorrowerUpgradeable.sol"; -import "../../../interfaces/IERC3156FlashLenderUpgradeable.sol"; -import "../ERC20Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the ERC3156 Flash loans extension, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - * - * Adds the {flashLoan} method, which provides flash loan support at the token - * level. By default there is no fee, but this can be changed by overriding {flashFee}. - * - * _Available since v4.1._ - */ -abstract contract ERC20FlashMintUpgradeable is Initializable, ERC20Upgradeable, IERC3156FlashLenderUpgradeable { - function __ERC20FlashMint_init() internal onlyInitializing { - } - - function __ERC20FlashMint_init_unchained() internal onlyInitializing { - } - bytes32 private constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan"); - - /** - * @dev Returns the maximum amount of tokens available for loan. - * @param token The address of the token that is requested. - * @return The amount of token that can be loaned. - */ - function maxFlashLoan(address token) public view virtual override returns (uint256) { - return token == address(this) ? type(uint256).max - ERC20Upgradeable.totalSupply() : 0; - } - - /** - * @dev Returns the fee applied when doing flash loans. This function calls - * the {_flashFee} function which returns the fee applied when doing flash - * loans. - * @param token The token to be flash loaned. - * @param amount The amount of tokens to be loaned. - * @return The fees applied to the corresponding flash loan. - */ - function flashFee(address token, uint256 amount) public view virtual override returns (uint256) { - require(token == address(this), "ERC20FlashMint: wrong token"); - return _flashFee(token, amount); - } - - /** - * @dev Returns the fee applied when doing flash loans. By default this - * implementation has 0 fees. This function can be overloaded to make - * the flash loan mechanism deflationary. - * @param token The token to be flash loaned. - * @param amount The amount of tokens to be loaned. - * @return The fees applied to the corresponding flash loan. - */ - function _flashFee(address token, uint256 amount) internal view virtual returns (uint256) { - // silence warning about unused variable without the addition of bytecode. - token; - amount; - return 0; - } - - /** - * @dev Returns the receiver address of the flash fee. By default this - * implementation returns the address(0) which means the fee amount will be burnt. - * This function can be overloaded to change the fee receiver. - * @return The address for which the flash fee will be sent to. - */ - function _flashFeeReceiver() internal view virtual returns (address) { - return address(0); - } - - /** - * @dev Performs a flash loan. New tokens are minted and sent to the - * `receiver`, who is required to implement the {IERC3156FlashBorrower} - * interface. By the end of the flash loan, the receiver is expected to own - * amount + fee tokens and have them approved back to the token contract itself so - * they can be burned. - * @param receiver The receiver of the flash loan. Should implement the - * {IERC3156FlashBorrower-onFlashLoan} interface. - * @param token The token to be flash loaned. Only `address(this)` is - * supported. - * @param amount The amount of tokens to be loaned. - * @param data An arbitrary datafield that is passed to the receiver. - * @return `true` if the flash loan was successful. - */ - // This function can reenter, but it doesn't pose a risk because it always preserves the property that the amount - // minted at the beginning is always recovered and burned at the end, or else the entire function will revert. - // slither-disable-next-line reentrancy-no-eth - function flashLoan( - IERC3156FlashBorrowerUpgradeable receiver, - address token, - uint256 amount, - bytes calldata data - ) public virtual override returns (bool) { - require(amount <= maxFlashLoan(token), "ERC20FlashMint: amount exceeds maxFlashLoan"); - uint256 fee = flashFee(token, amount); - _mint(address(receiver), amount); - require( - receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE, - "ERC20FlashMint: invalid return value" - ); - address flashFeeReceiver = _flashFeeReceiver(); - _spendAllowance(address(receiver), address(this), amount + fee); - if (fee == 0 || flashFeeReceiver == address(0)) { - _burn(address(receiver), amount + fee); - } else { - _burn(address(receiver), amount); - _transfer(address(receiver), flashFeeReceiver, fee); - } - return true; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PausableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PausableUpgradeable.sol deleted file mode 100644 index 170f424..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20PausableUpgradeable.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC20/extensions/ERC20Pausable.sol) - -pragma solidity ^0.8.0; - -import "../ERC20Upgradeable.sol"; -import "../../../security/PausableUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev ERC20 token with pausable token transfers, minting and burning. - * - * Useful for scenarios such as preventing trades until the end of an evaluation - * period, or having an emergency switch for freezing all token transfers in the - * event of a large bug. - * - * IMPORTANT: This contract does not include public pause and unpause functions. In - * addition to inheriting this contract, you must define both functions, invoking the - * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate - * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will - * make the contract unpausable. - */ -abstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable { - function __ERC20Pausable_init() internal onlyInitializing { - __Pausable_init_unchained(); - } - - function __ERC20Pausable_init_unchained() internal onlyInitializing { - } - /** - * @dev See {ERC20-_beforeTokenTransfer}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - super._beforeTokenTransfer(from, to, amount); - - require(!paused(), "ERC20Pausable: token transfer while paused"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol deleted file mode 100644 index 657ab2e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol +++ /dev/null @@ -1,208 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol) - -pragma solidity ^0.8.0; - -import "../ERC20Upgradeable.sol"; -import "../../../utils/ArraysUpgradeable.sol"; -import "../../../utils/CountersUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and - * total supply at the time are recorded for later access. - * - * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. - * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different - * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be - * used to create an efficient ERC20 forking mechanism. - * - * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a - * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot - * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id - * and the account address. - * - * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it - * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this - * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract. - * - * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient - * alternative consider {ERC20Votes}. - * - * ==== Gas Costs - * - * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log - * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much - * smaller since identical balances in subsequent snapshots are stored as a single entry. - * - * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is - * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent - * transfers will have normal cost until the next snapshot, and so on. - */ - -abstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable { - function __ERC20Snapshot_init() internal onlyInitializing { - } - - function __ERC20Snapshot_init_unchained() internal onlyInitializing { - } - // Inspired by Jordi Baylina's MiniMeToken to record historical balances: - // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol - - using ArraysUpgradeable for uint256[]; - using CountersUpgradeable for CountersUpgradeable.Counter; - - // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a - // Snapshot struct, but that would impede usage of functions that work on an array. - struct Snapshots { - uint256[] ids; - uint256[] values; - } - - mapping(address => Snapshots) private _accountBalanceSnapshots; - Snapshots private _totalSupplySnapshots; - - // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid. - CountersUpgradeable.Counter private _currentSnapshotId; - - /** - * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created. - */ - event Snapshot(uint256 id); - - /** - * @dev Creates a new snapshot and returns its snapshot id. - * - * Emits a {Snapshot} event that contains the same id. - * - * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a - * set of accounts, for example using {AccessControl}, or it may be open to the public. - * - * [WARNING] - * ==== - * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking, - * you must consider that it can potentially be used by attackers in two ways. - * - * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow - * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target - * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs - * section above. - * - * We haven't measured the actual numbers; if this is something you're interested in please reach out to us. - * ==== - */ - function _snapshot() internal virtual returns (uint256) { - _currentSnapshotId.increment(); - - uint256 currentId = _getCurrentSnapshotId(); - emit Snapshot(currentId); - return currentId; - } - - /** - * @dev Get the current snapshotId - */ - function _getCurrentSnapshotId() internal view virtual returns (uint256) { - return _currentSnapshotId.current(); - } - - /** - * @dev Retrieves the balance of `account` at the time `snapshotId` was created. - */ - function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) { - (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]); - - return snapshotted ? value : balanceOf(account); - } - - /** - * @dev Retrieves the total supply at the time `snapshotId` was created. - */ - function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) { - (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots); - - return snapshotted ? value : totalSupply(); - } - - // Update balance and/or total supply snapshots before the values are modified. This is implemented - // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - super._beforeTokenTransfer(from, to, amount); - - if (from == address(0)) { - // mint - _updateAccountSnapshot(to); - _updateTotalSupplySnapshot(); - } else if (to == address(0)) { - // burn - _updateAccountSnapshot(from); - _updateTotalSupplySnapshot(); - } else { - // transfer - _updateAccountSnapshot(from); - _updateAccountSnapshot(to); - } - } - - function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) { - require(snapshotId > 0, "ERC20Snapshot: id is 0"); - require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id"); - - // When a valid snapshot is queried, there are three possibilities: - // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never - // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds - // to this id is the current one. - // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the - // requested id, and its value is the one to return. - // c) More snapshots were created after the requested one, and the queried value was later modified. There will be - // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is - // larger than the requested one. - // - // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if - // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does - // exactly this. - - uint256 index = snapshots.ids.findUpperBound(snapshotId); - - if (index == snapshots.ids.length) { - return (false, 0); - } else { - return (true, snapshots.values[index]); - } - } - - function _updateAccountSnapshot(address account) private { - _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account)); - } - - function _updateTotalSupplySnapshot() private { - _updateSnapshot(_totalSupplySnapshots, totalSupply()); - } - - function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { - uint256 currentId = _getCurrentSnapshotId(); - if (_lastSnapshotId(snapshots.ids) < currentId) { - snapshots.ids.push(currentId); - snapshots.values.push(currentValue); - } - } - - function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) { - if (ids.length == 0) { - return 0; - } else { - return ids[ids.length - 1]; - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[46] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol deleted file mode 100644 index 5a6eb2a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesCompUpgradeable.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20VotesComp.sol) - -pragma solidity ^0.8.0; - -import "./ERC20VotesUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of ERC20 to support Compound's voting and delegation. This version exactly matches Compound's - * interface, with the drawback of only supporting supply up to (2^96^ - 1). - * - * NOTE: You should use this contract if you need exact compatibility with COMP (for example in order to use your token - * with Governor Alpha or Bravo) and if you are sure the supply cap of 2^96^ is enough for you. Otherwise, use the - * {ERC20Votes} variant of this module. - * - * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either - * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting - * power can be queried through the public accessors {getCurrentVotes} and {getPriorVotes}. - * - * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it - * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. - * - * _Available since v4.2._ - */ -abstract contract ERC20VotesCompUpgradeable is Initializable, ERC20VotesUpgradeable { - function __ERC20VotesComp_init() internal onlyInitializing { - } - - function __ERC20VotesComp_init_unchained() internal onlyInitializing { - } - /** - * @dev Comp version of the {getVotes} accessor, with `uint96` return type. - */ - function getCurrentVotes(address account) external view virtual returns (uint96) { - return SafeCastUpgradeable.toUint96(getVotes(account)); - } - - /** - * @dev Comp version of the {getPastVotes} accessor, with `uint96` return type. - */ - function getPriorVotes(address account, uint256 blockNumber) external view virtual returns (uint96) { - return SafeCastUpgradeable.toUint96(getPastVotes(account, blockNumber)); - } - - /** - * @dev Maximum token supply. Reduced to `type(uint96).max` (2^96^ - 1) to fit COMP interface. - */ - function _maxSupply() internal view virtual override returns (uint224) { - return type(uint96).max; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol deleted file mode 100644 index 7a83864..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20VotesUpgradeable.sol +++ /dev/null @@ -1,288 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.1) (token/ERC20/extensions/ERC20Votes.sol) - -pragma solidity ^0.8.0; - -import "./draft-ERC20PermitUpgradeable.sol"; -import "../../../utils/math/MathUpgradeable.sol"; -import "../../../governance/utils/IVotesUpgradeable.sol"; -import "../../../utils/math/SafeCastUpgradeable.sol"; -import "../../../utils/cryptography/ECDSAUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's, - * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1. - * - * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module. - * - * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either - * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting - * power can be queried through the public accessors {getVotes} and {getPastVotes}. - * - * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it - * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. - * - * _Available since v4.2._ - */ -abstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable { - function __ERC20Votes_init() internal onlyInitializing { - } - - function __ERC20Votes_init_unchained() internal onlyInitializing { - } - struct Checkpoint { - uint32 fromBlock; - uint224 votes; - } - - bytes32 private constant _DELEGATION_TYPEHASH = - keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - mapping(address => address) private _delegates; - mapping(address => Checkpoint[]) private _checkpoints; - Checkpoint[] private _totalSupplyCheckpoints; - - /** - * @dev Get the `pos`-th checkpoint for `account`. - */ - function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) { - return _checkpoints[account][pos]; - } - - /** - * @dev Get number of checkpoints for `account`. - */ - function numCheckpoints(address account) public view virtual returns (uint32) { - return SafeCastUpgradeable.toUint32(_checkpoints[account].length); - } - - /** - * @dev Get the address `account` is currently delegating to. - */ - function delegates(address account) public view virtual override returns (address) { - return _delegates[account]; - } - - /** - * @dev Gets the current votes balance for `account` - */ - function getVotes(address account) public view virtual override returns (uint256) { - uint256 pos = _checkpoints[account].length; - return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes; - } - - /** - * @dev Retrieve the number of votes for `account` at the end of `blockNumber`. - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { - require(blockNumber < block.number, "ERC20Votes: block not yet mined"); - return _checkpointsLookup(_checkpoints[account], blockNumber); - } - - /** - * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. - * It is but NOT the sum of all the delegated votes! - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { - require(blockNumber < block.number, "ERC20Votes: block not yet mined"); - return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber); - } - - /** - * @dev Lookup a value in a list of (sorted) checkpoints. - */ - function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) { - // We run a binary search to look for the earliest checkpoint taken after `blockNumber`. - // - // Initially we check if the block is recent to narrow the search range. - // During the loop, the index of the wanted checkpoint remains in the range [low-1, high). - // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant. - // - If the middle checkpoint is after `blockNumber`, we look in [low, mid) - // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high) - // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not - // out of bounds (in which case we're looking too far in the past and the result is 0). - // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is - // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out - // the same. - uint256 length = ckpts.length; - - uint256 low = 0; - uint256 high = length; - - if (length > 5) { - uint256 mid = length - MathUpgradeable.sqrt(length); - if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) { - high = mid; - } else { - low = mid + 1; - } - } - - while (low < high) { - uint256 mid = MathUpgradeable.average(low, high); - if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) { - high = mid; - } else { - low = mid + 1; - } - } - - return high == 0 ? 0 : _unsafeAccess(ckpts, high - 1).votes; - } - - /** - * @dev Delegate votes from the sender to `delegatee`. - */ - function delegate(address delegatee) public virtual override { - _delegate(_msgSender(), delegatee); - } - - /** - * @dev Delegates votes from signer to `delegatee` - */ - function delegateBySig( - address delegatee, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override { - require(block.timestamp <= expiry, "ERC20Votes: signature expired"); - address signer = ECDSAUpgradeable.recover( - _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), - v, - r, - s - ); - require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce"); - _delegate(signer, delegatee); - } - - /** - * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1). - */ - function _maxSupply() internal view virtual returns (uint224) { - return type(uint224).max; - } - - /** - * @dev Snapshots the totalSupply after it has been increased. - */ - function _mint(address account, uint256 amount) internal virtual override { - super._mint(account, amount); - require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes"); - - _writeCheckpoint(_totalSupplyCheckpoints, _add, amount); - } - - /** - * @dev Snapshots the totalSupply after it has been decreased. - */ - function _burn(address account, uint256 amount) internal virtual override { - super._burn(account, amount); - - _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount); - } - - /** - * @dev Move voting power when tokens are transferred. - * - * Emits a {IVotes-DelegateVotesChanged} event. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - super._afterTokenTransfer(from, to, amount); - - _moveVotingPower(delegates(from), delegates(to), amount); - } - - /** - * @dev Change delegation for `delegator` to `delegatee`. - * - * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. - */ - function _delegate(address delegator, address delegatee) internal virtual { - address currentDelegate = delegates(delegator); - uint256 delegatorBalance = balanceOf(delegator); - _delegates[delegator] = delegatee; - - emit DelegateChanged(delegator, currentDelegate, delegatee); - - _moveVotingPower(currentDelegate, delegatee, delegatorBalance); - } - - function _moveVotingPower( - address src, - address dst, - uint256 amount - ) private { - if (src != dst && amount > 0) { - if (src != address(0)) { - (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); - emit DelegateVotesChanged(src, oldWeight, newWeight); - } - - if (dst != address(0)) { - (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount); - emit DelegateVotesChanged(dst, oldWeight, newWeight); - } - } - } - - function _writeCheckpoint( - Checkpoint[] storage ckpts, - function(uint256, uint256) view returns (uint256) op, - uint256 delta - ) private returns (uint256 oldWeight, uint256 newWeight) { - uint256 pos = ckpts.length; - - Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1); - - oldWeight = oldCkpt.votes; - newWeight = op(oldWeight, delta); - - if (pos > 0 && oldCkpt.fromBlock == block.number) { - _unsafeAccess(ckpts, pos - 1).votes = SafeCastUpgradeable.toUint224(newWeight); - } else { - ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)})); - } - } - - function _add(uint256 a, uint256 b) private pure returns (uint256) { - return a + b; - } - - function _subtract(uint256 a, uint256 b) private pure returns (uint256) { - return a - b; - } - - /** - * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. - */ - function _unsafeAccess(Checkpoint[] storage ckpts, uint256 pos) private pure returns (Checkpoint storage result) { - assembly { - mstore(0, ckpts.slot) - result.slot := add(keccak256(0, 0x20), pos) - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[47] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20WrapperUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20WrapperUpgradeable.sol deleted file mode 100644 index 5088b94..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC20WrapperUpgradeable.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20Wrapper.sol) - -pragma solidity ^0.8.0; - -import "../ERC20Upgradeable.sol"; -import "../utils/SafeERC20Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of the ERC20 token contract to support token wrapping. - * - * Users can deposit and withdraw "underlying tokens" and receive a matching number of "wrapped tokens". This is useful - * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the - * wrapping of an existing "basic" ERC20 into a governance token. - * - * _Available since v4.2._ - * - * @custom:storage-size 51 - */ -abstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable { - IERC20Upgradeable public underlying; - - function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing { - __ERC20Wrapper_init_unchained(underlyingToken); - } - - function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing { - underlying = underlyingToken; - } - - /** - * @dev See {ERC20-decimals}. - */ - function decimals() public view virtual override returns (uint8) { - try IERC20MetadataUpgradeable(address(underlying)).decimals() returns (uint8 value) { - return value; - } catch { - return super.decimals(); - } - } - - /** - * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens. - */ - function depositFor(address account, uint256 amount) public virtual returns (bool) { - SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount); - _mint(account, amount); - return true; - } - - /** - * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens. - */ - function withdrawTo(address account, uint256 amount) public virtual returns (bool) { - _burn(_msgSender(), amount); - SafeERC20Upgradeable.safeTransfer(underlying, account, amount); - return true; - } - - /** - * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal - * function that can be exposed with access control if desired. - */ - function _recover(address account) internal virtual returns (uint256) { - uint256 value = underlying.balanceOf(address(this)) - totalSupply(); - _mint(account, value); - return value; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol deleted file mode 100644 index 67bf8b1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol +++ /dev/null @@ -1,296 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.1) (token/ERC20/extensions/ERC4626.sol) - -pragma solidity ^0.8.0; - -import "../ERC20Upgradeable.sol"; -import "../utils/SafeERC20Upgradeable.sol"; -import "../../../interfaces/IERC4626Upgradeable.sol"; -import "../../../utils/math/MathUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the ERC4626 "Tokenized Vault Standard" as defined in - * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626]. - * - * This extension allows the minting and burning of "shares" (represented using the ERC20 inheritance) in exchange for - * underlying "assets" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends - * the ERC20 standard. Any additional extensions included along it would affect the "shares" token represented by this - * contract and not the "assets" token which is an independent contract. - * - * CAUTION: When the vault is empty or nearly empty, deposits are at high risk of being stolen through frontrunning with - * a "donation" to the vault that inflates the price of a share. This is variously known as a donation or inflation - * attack and is essentially a problem of slippage. Vault deployers can protect against this attack by making an initial - * deposit of a non-trivial amount of the asset, such that price manipulation becomes infeasible. Withdrawals may - * similarly be affected by slippage. Users can protect against this attack as well unexpected slippage in general by - * verifying the amount received is as expected, using a wrapper that performs these checks such as - * https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router]. - * - * _Available since v4.7._ - */ -abstract contract ERC4626Upgradeable is Initializable, ERC20Upgradeable, IERC4626Upgradeable { - using MathUpgradeable for uint256; - - IERC20Upgradeable private _asset; - uint8 private _decimals; - - /** - * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777). - */ - function __ERC4626_init(IERC20Upgradeable asset_) internal onlyInitializing { - __ERC4626_init_unchained(asset_); - } - - function __ERC4626_init_unchained(IERC20Upgradeable asset_) internal onlyInitializing { - (bool success, uint8 assetDecimals) = _tryGetAssetDecimals(asset_); - _decimals = success ? assetDecimals : super.decimals(); - _asset = asset_; - } - - /** - * @dev Attempts to fetch the asset decimals. A return value of false indicates that the attempt failed in some way. - */ - function _tryGetAssetDecimals(IERC20Upgradeable asset_) private view returns (bool, uint8) { - (bool success, bytes memory encodedDecimals) = address(asset_).staticcall( - abi.encodeWithSelector(IERC20MetadataUpgradeable.decimals.selector) - ); - if (success && encodedDecimals.length >= 32) { - uint256 returnedDecimals = abi.decode(encodedDecimals, (uint256)); - if (returnedDecimals <= type(uint8).max) { - return (true, uint8(returnedDecimals)); - } - } - return (false, 0); - } - - /** - * @dev Decimals are read from the underlying asset in the constructor and cached. If this fails (e.g., the asset - * has not been created yet), the cached value is set to a default obtained by `super.decimals()` (which depends on - * inheritance but is most likely 18). Override this function in order to set a guaranteed hardcoded value. - * See {IERC20Metadata-decimals}. - */ - function decimals() public view virtual override(IERC20MetadataUpgradeable, ERC20Upgradeable) returns (uint8) { - return _decimals; - } - - /** @dev See {IERC4626-asset}. */ - function asset() public view virtual override returns (address) { - return address(_asset); - } - - /** @dev See {IERC4626-totalAssets}. */ - function totalAssets() public view virtual override returns (uint256) { - return _asset.balanceOf(address(this)); - } - - /** @dev See {IERC4626-convertToShares}. */ - function convertToShares(uint256 assets) public view virtual override returns (uint256 shares) { - return _convertToShares(assets, MathUpgradeable.Rounding.Down); - } - - /** @dev See {IERC4626-convertToAssets}. */ - function convertToAssets(uint256 shares) public view virtual override returns (uint256 assets) { - return _convertToAssets(shares, MathUpgradeable.Rounding.Down); - } - - /** @dev See {IERC4626-maxDeposit}. */ - function maxDeposit(address) public view virtual override returns (uint256) { - return _isVaultCollateralized() ? type(uint256).max : 0; - } - - /** @dev See {IERC4626-maxMint}. */ - function maxMint(address) public view virtual override returns (uint256) { - return type(uint256).max; - } - - /** @dev See {IERC4626-maxWithdraw}. */ - function maxWithdraw(address owner) public view virtual override returns (uint256) { - return _convertToAssets(balanceOf(owner), MathUpgradeable.Rounding.Down); - } - - /** @dev See {IERC4626-maxRedeem}. */ - function maxRedeem(address owner) public view virtual override returns (uint256) { - return balanceOf(owner); - } - - /** @dev See {IERC4626-previewDeposit}. */ - function previewDeposit(uint256 assets) public view virtual override returns (uint256) { - return _convertToShares(assets, MathUpgradeable.Rounding.Down); - } - - /** @dev See {IERC4626-previewMint}. */ - function previewMint(uint256 shares) public view virtual override returns (uint256) { - return _convertToAssets(shares, MathUpgradeable.Rounding.Up); - } - - /** @dev See {IERC4626-previewWithdraw}. */ - function previewWithdraw(uint256 assets) public view virtual override returns (uint256) { - return _convertToShares(assets, MathUpgradeable.Rounding.Up); - } - - /** @dev See {IERC4626-previewRedeem}. */ - function previewRedeem(uint256 shares) public view virtual override returns (uint256) { - return _convertToAssets(shares, MathUpgradeable.Rounding.Down); - } - - /** @dev See {IERC4626-deposit}. */ - function deposit(uint256 assets, address receiver) public virtual override returns (uint256) { - require(assets <= maxDeposit(receiver), "ERC4626: deposit more than max"); - - uint256 shares = previewDeposit(assets); - _deposit(_msgSender(), receiver, assets, shares); - - return shares; - } - - /** @dev See {IERC4626-mint}. - * - * As opposed to {deposit}, minting is allowed even if the vault is in a state where the price of a share is zero. - * In this case, the shares will be minted without requiring any assets to be deposited. - */ - function mint(uint256 shares, address receiver) public virtual override returns (uint256) { - require(shares <= maxMint(receiver), "ERC4626: mint more than max"); - - uint256 assets = previewMint(shares); - _deposit(_msgSender(), receiver, assets, shares); - - return assets; - } - - /** @dev See {IERC4626-withdraw}. */ - function withdraw( - uint256 assets, - address receiver, - address owner - ) public virtual override returns (uint256) { - require(assets <= maxWithdraw(owner), "ERC4626: withdraw more than max"); - - uint256 shares = previewWithdraw(assets); - _withdraw(_msgSender(), receiver, owner, assets, shares); - - return shares; - } - - /** @dev See {IERC4626-redeem}. */ - function redeem( - uint256 shares, - address receiver, - address owner - ) public virtual override returns (uint256) { - require(shares <= maxRedeem(owner), "ERC4626: redeem more than max"); - - uint256 assets = previewRedeem(shares); - _withdraw(_msgSender(), receiver, owner, assets, shares); - - return assets; - } - - /** - * @dev Internal conversion function (from assets to shares) with support for rounding direction. - * - * Will revert if assets > 0, totalSupply > 0 and totalAssets = 0. That corresponds to a case where any asset - * would represent an infinite amount of shares. - */ - function _convertToShares(uint256 assets, MathUpgradeable.Rounding rounding) internal view virtual returns (uint256 shares) { - uint256 supply = totalSupply(); - return - (assets == 0 || supply == 0) - ? _initialConvertToShares(assets, rounding) - : assets.mulDiv(supply, totalAssets(), rounding); - } - - /** - * @dev Internal conversion function (from assets to shares) to apply when the vault is empty. - * - * NOTE: Make sure to keep this function consistent with {_initialConvertToAssets} when overriding it. - */ - function _initialConvertToShares( - uint256 assets, - MathUpgradeable.Rounding /*rounding*/ - ) internal view virtual returns (uint256 shares) { - return assets; - } - - /** - * @dev Internal conversion function (from shares to assets) with support for rounding direction. - */ - function _convertToAssets(uint256 shares, MathUpgradeable.Rounding rounding) internal view virtual returns (uint256 assets) { - uint256 supply = totalSupply(); - return - (supply == 0) ? _initialConvertToAssets(shares, rounding) : shares.mulDiv(totalAssets(), supply, rounding); - } - - /** - * @dev Internal conversion function (from shares to assets) to apply when the vault is empty. - * - * NOTE: Make sure to keep this function consistent with {_initialConvertToShares} when overriding it. - */ - function _initialConvertToAssets( - uint256 shares, - MathUpgradeable.Rounding /*rounding*/ - ) internal view virtual returns (uint256 assets) { - return shares; - } - - /** - * @dev Deposit/mint common workflow. - */ - function _deposit( - address caller, - address receiver, - uint256 assets, - uint256 shares - ) internal virtual { - // If _asset is ERC777, `transferFrom` can trigger a reenterancy BEFORE the transfer happens through the - // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer, - // calls the vault, which is assumed not malicious. - // - // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the - // assets are transferred and before the shares are minted, which is a valid state. - // slither-disable-next-line reentrancy-no-eth - SafeERC20Upgradeable.safeTransferFrom(_asset, caller, address(this), assets); - _mint(receiver, shares); - - emit Deposit(caller, receiver, assets, shares); - } - - /** - * @dev Withdraw/redeem common workflow. - */ - function _withdraw( - address caller, - address receiver, - address owner, - uint256 assets, - uint256 shares - ) internal virtual { - if (caller != owner) { - _spendAllowance(owner, caller, shares); - } - - // If _asset is ERC777, `transfer` can trigger a reentrancy AFTER the transfer happens through the - // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer, - // calls the vault, which is assumed not malicious. - // - // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the - // shares are burned and after the assets are transferred, which is a valid state. - _burn(owner, shares); - SafeERC20Upgradeable.safeTransfer(_asset, receiver, assets); - - emit Withdraw(caller, receiver, owner, assets, shares); - } - - /** - * @dev Checks if vault is "healthy" in the sense of having assets backing the circulating shares. - */ - function _isVaultCollateralized() private view returns (bool) { - return totalAssets() > 0 || totalSupply() == 0; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol deleted file mode 100644 index 381d8ea..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) - -pragma solidity ^0.8.0; - -import "../IERC20Upgradeable.sol"; - -/** - * @dev Interface for the optional metadata functions from the ERC20 standard. - * - * _Available since v4.1._ - */ -interface IERC20MetadataUpgradeable is IERC20Upgradeable { - /** - * @dev Returns the name of the token. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the symbol of the token. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the decimals places of the token. - */ - function decimals() external view returns (uint8); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol deleted file mode 100644 index cdd2f42..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol) - -pragma solidity ^0.8.0; - -import "./draft-IERC20PermitUpgradeable.sol"; -import "../ERC20Upgradeable.sol"; -import "../../../utils/cryptography/ECDSAUpgradeable.sol"; -import "../../../utils/cryptography/EIP712Upgradeable.sol"; -import "../../../utils/CountersUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in - * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. - * - * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by - * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't - * need to send a transaction, and thus is not required to hold Ether at all. - * - * _Available since v3.4._ - * - * @custom:storage-size 51 - */ -abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable { - using CountersUpgradeable for CountersUpgradeable.Counter; - - mapping(address => CountersUpgradeable.Counter) private _nonces; - - // solhint-disable-next-line var-name-mixedcase - bytes32 private constant _PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - /** - * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. - * However, to ensure consistency with the upgradeable transpiler, we will continue - * to reserve a slot. - * @custom:oz-renamed-from _PERMIT_TYPEHASH - */ - // solhint-disable-next-line var-name-mixedcase - bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; - - /** - * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. - * - * It's a good idea to use the same `name` that is defined as the ERC20 token name. - */ - function __ERC20Permit_init(string memory name) internal onlyInitializing { - __EIP712_init_unchained(name, "1"); - } - - function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {} - - /** - * @dev See {IERC20Permit-permit}. - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override { - require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); - - bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); - - bytes32 hash = _hashTypedDataV4(structHash); - - address signer = ECDSAUpgradeable.recover(hash, v, r, s); - require(signer == owner, "ERC20Permit: invalid signature"); - - _approve(owner, spender, value); - } - - /** - * @dev See {IERC20Permit-nonces}. - */ - function nonces(address owner) public view virtual override returns (uint256) { - return _nonces[owner].current(); - } - - /** - * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view override returns (bytes32) { - return _domainSeparatorV4(); - } - - /** - * @dev "Consume a nonce": return the current value and increment. - * - * _Available since v4.1._ - */ - function _useNonce(address owner) internal virtual returns (uint256 current) { - CountersUpgradeable.Counter storage nonce = _nonces[owner]; - current = nonce.current(); - nonce.increment(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol deleted file mode 100644 index bd57513..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in - * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. - * - * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by - * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't - * need to send a transaction, and thus is not required to hold Ether at all. - */ -interface IERC20PermitUpgradeable { - /** - * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, - * given ``owner``'s signed approval. - * - * IMPORTANT: The same issues {IERC20-approve} has related to transaction - * ordering also apply here. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `deadline` must be a timestamp in the future. - * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` - * over the EIP712-formatted function arguments. - * - the signature must use ``owner``'s current nonce (see {nonces}). - * - * For more information on the signature format, see the - * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP - * section]. - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external; - - /** - * @dev Returns the current nonce for `owner`. This value must be - * included whenever a signature is generated for {permit}. - * - * Every successful call to {permit} increases ``owner``'s nonce by one. This - * prevents a signature from being used multiple times. - */ - function nonces(address owner) external view returns (uint256); - - /** - * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetFixedSupplyUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetFixedSupplyUpgradeable.sol deleted file mode 100644 index 6ac231a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetFixedSupplyUpgradeable.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/presets/ERC20PresetFixedSupply.sol) -pragma solidity ^0.8.0; - -import "../extensions/ERC20BurnableUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev {ERC20} token, including: - * - * - Preminted initial supply - * - Ability for holders to burn (destroy) their tokens - * - No access control mechanism (for minting/pausing) and hence no governance - * - * This contract uses {ERC20Burnable} to include burn capabilities - head to - * its documentation for details. - * - * _Available since v3.4._ - * - * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._ - */ -contract ERC20PresetFixedSupplyUpgradeable is Initializable, ERC20BurnableUpgradeable { - function initialize( - string memory name, - string memory symbol, - uint256 initialSupply, - address owner - ) public virtual initializer { - __ERC20PresetFixedSupply_init(name, symbol, initialSupply, owner); - } - /** - * @dev Mints `initialSupply` amount of token and transfers them to `owner`. - * - * See {ERC20-constructor}. - */ - function __ERC20PresetFixedSupply_init( - string memory name, - string memory symbol, - uint256 initialSupply, - address owner - ) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __ERC20PresetFixedSupply_init_unchained(name, symbol, initialSupply, owner); - } - - function __ERC20PresetFixedSupply_init_unchained( - string memory, - string memory, - uint256 initialSupply, - address owner - ) internal onlyInitializing { - _mint(owner, initialSupply); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol deleted file mode 100644 index dc481b8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/ERC20PresetMinterPauserUpgradeable.sol +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/presets/ERC20PresetMinterPauser.sol) - -pragma solidity ^0.8.0; - -import "../ERC20Upgradeable.sol"; -import "../extensions/ERC20BurnableUpgradeable.sol"; -import "../extensions/ERC20PausableUpgradeable.sol"; -import "../../../access/AccessControlEnumerableUpgradeable.sol"; -import "../../../utils/ContextUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev {ERC20} token, including: - * - * - ability for holders to burn (destroy) their tokens - * - a minter role that allows for token minting (creation) - * - a pauser role that allows to stop all token transfers - * - * This contract uses {AccessControl} to lock permissioned functions using the - * different roles - head to its documentation for details. - * - * The account that deploys the contract will be granted the minter and pauser - * roles, as well as the default admin role, which will let it grant both minter - * and pauser roles to other accounts. - * - * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._ - */ -contract ERC20PresetMinterPauserUpgradeable is Initializable, ContextUpgradeable, AccessControlEnumerableUpgradeable, ERC20BurnableUpgradeable, ERC20PausableUpgradeable { - function initialize(string memory name, string memory symbol) public virtual initializer { - __ERC20PresetMinterPauser_init(name, symbol); - } - bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); - bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); - - /** - * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the - * account that deploys the contract. - * - * See {ERC20-constructor}. - */ - function __ERC20PresetMinterPauser_init(string memory name, string memory symbol) internal onlyInitializing { - __ERC20_init_unchained(name, symbol); - __Pausable_init_unchained(); - __ERC20PresetMinterPauser_init_unchained(name, symbol); - } - - function __ERC20PresetMinterPauser_init_unchained(string memory, string memory) internal onlyInitializing { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - - _setupRole(MINTER_ROLE, _msgSender()); - _setupRole(PAUSER_ROLE, _msgSender()); - } - - /** - * @dev Creates `amount` new tokens for `to`. - * - * See {ERC20-_mint}. - * - * Requirements: - * - * - the caller must have the `MINTER_ROLE`. - */ - function mint(address to, uint256 amount) public virtual { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint"); - _mint(to, amount); - } - - /** - * @dev Pauses all token transfers. - * - * See {ERC20Pausable} and {Pausable-_pause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function pause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause"); - _pause(); - } - - /** - * @dev Unpauses all token transfers. - * - * See {ERC20Pausable} and {Pausable-_unpause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function unpause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause"); - _unpause(); - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override(ERC20Upgradeable, ERC20PausableUpgradeable) { - super._beforeTokenTransfer(from, to, amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/README.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/README.md deleted file mode 100644 index 468200b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/presets/README.md +++ /dev/null @@ -1 +0,0 @@ -Contract presets are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com/) as a more powerful alternative. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol deleted file mode 100644 index 5cd885c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) - -pragma solidity ^0.8.0; - -import "../IERC20Upgradeable.sol"; -import "../extensions/draft-IERC20PermitUpgradeable.sol"; -import "../../../utils/AddressUpgradeable.sol"; - -/** - * @title SafeERC20 - * @dev Wrappers around ERC20 operations that throw on failure (when the token - * contract returns false). Tokens that return no value (and instead revert or - * throw on failure) are also supported, non-reverting calls are assumed to be - * successful. - * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, - * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. - */ -library SafeERC20Upgradeable { - using AddressUpgradeable for address; - - function safeTransfer( - IERC20Upgradeable token, - address to, - uint256 value - ) internal { - _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); - } - - function safeTransferFrom( - IERC20Upgradeable token, - address from, - address to, - uint256 value - ) internal { - _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); - } - - /** - * @dev Deprecated. This function has issues similar to the ones found in - * {IERC20-approve}, and its usage is discouraged. - * - * Whenever possible, use {safeIncreaseAllowance} and - * {safeDecreaseAllowance} instead. - */ - function safeApprove( - IERC20Upgradeable token, - address spender, - uint256 value - ) internal { - // safeApprove should only be called when setting an initial allowance, - // or when resetting it to zero. To increase and decrease it, use - // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' - require( - (value == 0) || (token.allowance(address(this), spender) == 0), - "SafeERC20: approve from non-zero to non-zero allowance" - ); - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); - } - - function safeIncreaseAllowance( - IERC20Upgradeable token, - address spender, - uint256 value - ) internal { - uint256 newAllowance = token.allowance(address(this), spender) + value; - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); - } - - function safeDecreaseAllowance( - IERC20Upgradeable token, - address spender, - uint256 value - ) internal { - unchecked { - uint256 oldAllowance = token.allowance(address(this), spender); - require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); - uint256 newAllowance = oldAllowance - value; - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); - } - } - - function safePermit( - IERC20PermitUpgradeable token, - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) internal { - uint256 nonceBefore = token.nonces(owner); - token.permit(owner, spender, value, deadline, v, r, s); - uint256 nonceAfter = token.nonces(owner); - require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); - } - - /** - * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement - * on the return value: the return value is optional (but if data is returned, it must not be false). - * @param token The token targeted by the call. - * @param data The call data (encoded using abi.encode or one of its variants). - */ - function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { - // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since - // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that - // the target address contains contract code and also asserts for success in the low-level call. - - bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); - if (returndata.length > 0) { - // Return data is optional - require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/TokenTimelockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/TokenTimelockUpgradeable.sol deleted file mode 100644 index ed55f68..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/utils/TokenTimelockUpgradeable.sol +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/utils/TokenTimelock.sol) - -pragma solidity ^0.8.0; - -import "./SafeERC20Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev A token holder contract that will allow a beneficiary to extract the - * tokens after a given release time. - * - * Useful for simple vesting schedules like "advisors get all of their tokens - * after 1 year". - * - * @custom:storage-size 53 - */ -contract TokenTimelockUpgradeable is Initializable { - using SafeERC20Upgradeable for IERC20Upgradeable; - - // ERC20 basic token contract being held - IERC20Upgradeable private _token; - - // beneficiary of tokens after they are released - address private _beneficiary; - - // timestamp when token release is enabled - uint256 private _releaseTime; - - /** - * @dev Deploys a timelock instance that is able to hold the token specified, and will only release it to - * `beneficiary_` when {release} is invoked after `releaseTime_`. The release time is specified as a Unix timestamp - * (in seconds). - */ - function __TokenTimelock_init( - IERC20Upgradeable token_, - address beneficiary_, - uint256 releaseTime_ - ) internal onlyInitializing { - __TokenTimelock_init_unchained(token_, beneficiary_, releaseTime_); - } - - function __TokenTimelock_init_unchained( - IERC20Upgradeable token_, - address beneficiary_, - uint256 releaseTime_ - ) internal onlyInitializing { - require(releaseTime_ > block.timestamp, "TokenTimelock: release time is before current time"); - _token = token_; - _beneficiary = beneficiary_; - _releaseTime = releaseTime_; - } - - /** - * @dev Returns the token being held. - */ - function token() public view virtual returns (IERC20Upgradeable) { - return _token; - } - - /** - * @dev Returns the beneficiary that will receive the tokens. - */ - function beneficiary() public view virtual returns (address) { - return _beneficiary; - } - - /** - * @dev Returns the time when the tokens are released in seconds since Unix epoch (i.e. Unix timestamp). - */ - function releaseTime() public view virtual returns (uint256) { - return _releaseTime; - } - - /** - * @dev Transfers tokens held by the timelock to the beneficiary. Will only succeed if invoked after the release - * time. - */ - function release() public virtual { - require(block.timestamp >= releaseTime(), "TokenTimelock: current time is before release time"); - - uint256 amount = token().balanceOf(address(this)); - require(amount > 0, "TokenTimelock: no tokens to release"); - - token().safeTransfer(beneficiary(), amount); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol deleted file mode 100644 index 4ecb50c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol +++ /dev/null @@ -1,518 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol) - -pragma solidity ^0.8.0; - -import "./IERC721Upgradeable.sol"; -import "./IERC721ReceiverUpgradeable.sol"; -import "./extensions/IERC721MetadataUpgradeable.sol"; -import "../../utils/AddressUpgradeable.sol"; -import "../../utils/ContextUpgradeable.sol"; -import "../../utils/StringsUpgradeable.sol"; -import "../../utils/introspection/ERC165Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including - * the Metadata extension, but not including the Enumerable extension, which is available separately as - * {ERC721Enumerable}. - */ -contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable { - using AddressUpgradeable for address; - using StringsUpgradeable for uint256; - - // Token name - string private _name; - - // Token symbol - string private _symbol; - - // Mapping from token ID to owner address - mapping(uint256 => address) private _owners; - - // Mapping owner address to token count - mapping(address => uint256) private _balances; - - // Mapping from token ID to approved address - mapping(uint256 => address) private _tokenApprovals; - - // Mapping from owner to operator approvals - mapping(address => mapping(address => bool)) private _operatorApprovals; - - /** - * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. - */ - function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { - __ERC721_init_unchained(name_, symbol_); - } - - function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { - _name = name_; - _symbol = symbol_; - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { - return - interfaceId == type(IERC721Upgradeable).interfaceId || - interfaceId == type(IERC721MetadataUpgradeable).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @dev See {IERC721-balanceOf}. - */ - function balanceOf(address owner) public view virtual override returns (uint256) { - require(owner != address(0), "ERC721: address zero is not a valid owner"); - return _balances[owner]; - } - - /** - * @dev See {IERC721-ownerOf}. - */ - function ownerOf(uint256 tokenId) public view virtual override returns (address) { - address owner = _ownerOf(tokenId); - require(owner != address(0), "ERC721: invalid token ID"); - return owner; - } - - /** - * @dev See {IERC721Metadata-name}. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev See {IERC721Metadata-symbol}. - */ - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - /** - * @dev See {IERC721Metadata-tokenURI}. - */ - function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { - _requireMinted(tokenId); - - string memory baseURI = _baseURI(); - return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; - } - - /** - * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each - * token will be the concatenation of the `baseURI` and the `tokenId`. Empty - * by default, can be overridden in child contracts. - */ - function _baseURI() internal view virtual returns (string memory) { - return ""; - } - - /** - * @dev See {IERC721-approve}. - */ - function approve(address to, uint256 tokenId) public virtual override { - address owner = ERC721Upgradeable.ownerOf(tokenId); - require(to != owner, "ERC721: approval to current owner"); - - require( - _msgSender() == owner || isApprovedForAll(owner, _msgSender()), - "ERC721: approve caller is not token owner or approved for all" - ); - - _approve(to, tokenId); - } - - /** - * @dev See {IERC721-getApproved}. - */ - function getApproved(uint256 tokenId) public view virtual override returns (address) { - _requireMinted(tokenId); - - return _tokenApprovals[tokenId]; - } - - /** - * @dev See {IERC721-setApprovalForAll}. - */ - function setApprovalForAll(address operator, bool approved) public virtual override { - _setApprovalForAll(_msgSender(), operator, approved); - } - - /** - * @dev See {IERC721-isApprovedForAll}. - */ - function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { - return _operatorApprovals[owner][operator]; - } - - /** - * @dev See {IERC721-transferFrom}. - */ - function transferFrom( - address from, - address to, - uint256 tokenId - ) public virtual override { - //solhint-disable-next-line max-line-length - require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); - - _transfer(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId - ) public virtual override { - safeTransferFrom(from, to, tokenId, ""); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes memory data - ) public virtual override { - require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); - _safeTransfer(from, to, tokenId, data); - } - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients - * are aware of the ERC721 protocol to prevent tokens from being forever locked. - * - * `data` is additional data, it has no specified format and it is sent in call to `to`. - * - * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. - * implement alternative mechanisms to perform token transfer, such as signature-based. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function _safeTransfer( - address from, - address to, - uint256 tokenId, - bytes memory data - ) internal virtual { - _transfer(from, to, tokenId); - require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); - } - - /** - * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist - */ - function _ownerOf(uint256 tokenId) internal view virtual returns (address) { - return _owners[tokenId]; - } - - /** - * @dev Returns whether `tokenId` exists. - * - * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. - * - * Tokens start existing when they are minted (`_mint`), - * and stop existing when they are burned (`_burn`). - */ - function _exists(uint256 tokenId) internal view virtual returns (bool) { - return _ownerOf(tokenId) != address(0); - } - - /** - * @dev Returns whether `spender` is allowed to manage `tokenId`. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { - address owner = ERC721Upgradeable.ownerOf(tokenId); - return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); - } - - /** - * @dev Safely mints `tokenId` and transfers it to `to`. - * - * Requirements: - * - * - `tokenId` must not exist. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function _safeMint(address to, uint256 tokenId) internal virtual { - _safeMint(to, tokenId, ""); - } - - /** - * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is - * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. - */ - function _safeMint( - address to, - uint256 tokenId, - bytes memory data - ) internal virtual { - _mint(to, tokenId); - require( - _checkOnERC721Received(address(0), to, tokenId, data), - "ERC721: transfer to non ERC721Receiver implementer" - ); - } - - /** - * @dev Mints `tokenId` and transfers it to `to`. - * - * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible - * - * Requirements: - * - * - `tokenId` must not exist. - * - `to` cannot be the zero address. - * - * Emits a {Transfer} event. - */ - function _mint(address to, uint256 tokenId) internal virtual { - require(to != address(0), "ERC721: mint to the zero address"); - require(!_exists(tokenId), "ERC721: token already minted"); - - _beforeTokenTransfer(address(0), to, tokenId, 1); - - // Check that tokenId was not minted by `_beforeTokenTransfer` hook - require(!_exists(tokenId), "ERC721: token already minted"); - - unchecked { - // Will not overflow unless all 2**256 token ids are minted to the same owner. - // Given that tokens are minted one by one, it is impossible in practice that - // this ever happens. Might change if we allow batch minting. - // The ERC fails to describe this case. - _balances[to] += 1; - } - - _owners[tokenId] = to; - - emit Transfer(address(0), to, tokenId); - - _afterTokenTransfer(address(0), to, tokenId, 1); - } - - /** - * @dev Destroys `tokenId`. - * The approval is cleared when the token is burned. - * This is an internal function that does not check if the sender is authorized to operate on the token. - * - * Requirements: - * - * - `tokenId` must exist. - * - * Emits a {Transfer} event. - */ - function _burn(uint256 tokenId) internal virtual { - address owner = ERC721Upgradeable.ownerOf(tokenId); - - _beforeTokenTransfer(owner, address(0), tokenId, 1); - - // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook - owner = ERC721Upgradeable.ownerOf(tokenId); - - // Clear approvals - delete _tokenApprovals[tokenId]; - - unchecked { - // Cannot overflow, as that would require more tokens to be burned/transferred - // out than the owner initially received through minting and transferring in. - _balances[owner] -= 1; - } - delete _owners[tokenId]; - - emit Transfer(owner, address(0), tokenId); - - _afterTokenTransfer(owner, address(0), tokenId, 1); - } - - /** - * @dev Transfers `tokenId` from `from` to `to`. - * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - `tokenId` token must be owned by `from`. - * - * Emits a {Transfer} event. - */ - function _transfer( - address from, - address to, - uint256 tokenId - ) internal virtual { - require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); - require(to != address(0), "ERC721: transfer to the zero address"); - - _beforeTokenTransfer(from, to, tokenId, 1); - - // Check that tokenId was not transferred by `_beforeTokenTransfer` hook - require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); - - // Clear approvals from the previous owner - delete _tokenApprovals[tokenId]; - - unchecked { - // `_balances[from]` cannot overflow for the same reason as described in `_burn`: - // `from`'s balance is the number of token held, which is at least one before the current - // transfer. - // `_balances[to]` could overflow in the conditions described in `_mint`. That would require - // all 2**256 token ids to be minted, which in practice is impossible. - _balances[from] -= 1; - _balances[to] += 1; - } - _owners[tokenId] = to; - - emit Transfer(from, to, tokenId); - - _afterTokenTransfer(from, to, tokenId, 1); - } - - /** - * @dev Approve `to` to operate on `tokenId` - * - * Emits an {Approval} event. - */ - function _approve(address to, uint256 tokenId) internal virtual { - _tokenApprovals[tokenId] = to; - emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); - } - - /** - * @dev Approve `operator` to operate on all of `owner` tokens - * - * Emits an {ApprovalForAll} event. - */ - function _setApprovalForAll( - address owner, - address operator, - bool approved - ) internal virtual { - require(owner != operator, "ERC721: approve to caller"); - _operatorApprovals[owner][operator] = approved; - emit ApprovalForAll(owner, operator, approved); - } - - /** - * @dev Reverts if the `tokenId` has not been minted yet. - */ - function _requireMinted(uint256 tokenId) internal view virtual { - require(_exists(tokenId), "ERC721: invalid token ID"); - } - - /** - * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. - * The call is not executed if the target address is not a contract. - * - * @param from address representing the previous owner of the given token ID - * @param to target address that will receive the tokens - * @param tokenId uint256 ID of the token to be transferred - * @param data bytes optional data to send along with the call - * @return bool whether the call correctly returned the expected magic value - */ - function _checkOnERC721Received( - address from, - address to, - uint256 tokenId, - bytes memory data - ) private returns (bool) { - if (to.isContract()) { - try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { - return retval == IERC721ReceiverUpgradeable.onERC721Received.selector; - } catch (bytes memory reason) { - if (reason.length == 0) { - revert("ERC721: transfer to non ERC721Receiver implementer"); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } else { - return true; - } - } - - /** - * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is - * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. - * - * Calling conditions: - * - * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. - * - When `from` is zero, the tokens will be minted for `to`. - * - When `to` is zero, ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - `batchSize` is non-zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual {} - - /** - * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is - * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. - * - * Calling conditions: - * - * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. - * - When `from` is zero, the tokens were minted for `to`. - * - When `to` is zero, ``from``'s tokens were burned. - * - `from` and `to` are never both zero. - * - `batchSize` is non-zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual {} - - /** - * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. - * - * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant - * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such - * that `ownerOf(tokenId)` is `a`. - */ - // solhint-disable-next-line func-name-mixedcase - function __unsafe_increaseBalance(address account, uint256 amount) internal { - _balances[account] += amount; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[44] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721ReceiverUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721ReceiverUpgradeable.sol deleted file mode 100644 index c832817..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721ReceiverUpgradeable.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) - -pragma solidity ^0.8.0; - -/** - * @title ERC721 token receiver interface - * @dev Interface for any contract that wants to support safeTransfers - * from ERC721 asset contracts. - */ -interface IERC721ReceiverUpgradeable { - /** - * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} - * by `operator` from `from`, this function is called. - * - * It must return its Solidity selector to confirm the token transfer. - * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. - * - * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. - */ - function onERC721Received( - address operator, - address from, - uint256 tokenId, - bytes calldata data - ) external returns (bytes4); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721Upgradeable.sol deleted file mode 100644 index f2c4171..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/IERC721Upgradeable.sol +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165Upgradeable.sol"; - -/** - * @dev Required interface of an ERC721 compliant contract. - */ -interface IERC721Upgradeable is IERC165Upgradeable { - /** - * @dev Emitted when `tokenId` token is transferred from `from` to `to`. - */ - event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); - - /** - * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. - */ - event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); - - /** - * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. - */ - event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - - /** - * @dev Returns the number of tokens in ``owner``'s account. - */ - function balanceOf(address owner) external view returns (uint256 balance); - - /** - * @dev Returns the owner of the `tokenId` token. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function ownerOf(uint256 tokenId) external view returns (address owner); - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes calldata data - ) external; - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients - * are aware of the ERC721 protocol to prevent tokens from being forever locked. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId - ) external; - - /** - * @dev Transfers `tokenId` token from `from` to `to`. - * - * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 - * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must - * understand this adds an external call which potentially creates a reentrancy vulnerability. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must be owned by `from`. - * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - * - * Emits a {Transfer} event. - */ - function transferFrom( - address from, - address to, - uint256 tokenId - ) external; - - /** - * @dev Gives permission to `to` to transfer `tokenId` token to another account. - * The approval is cleared when the token is transferred. - * - * Only a single account can be approved at a time, so approving the zero address clears previous approvals. - * - * Requirements: - * - * - The caller must own the token or be an approved operator. - * - `tokenId` must exist. - * - * Emits an {Approval} event. - */ - function approve(address to, uint256 tokenId) external; - - /** - * @dev Approve or remove `operator` as an operator for the caller. - * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. - * - * Requirements: - * - * - The `operator` cannot be the caller. - * - * Emits an {ApprovalForAll} event. - */ - function setApprovalForAll(address operator, bool _approved) external; - - /** - * @dev Returns the account approved for `tokenId` token. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function getApproved(uint256 tokenId) external view returns (address operator); - - /** - * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. - * - * See {setApprovalForAll} - */ - function isApprovedForAll(address owner, address operator) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/README.adoc deleted file mode 100644 index b3377af..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/README.adoc +++ /dev/null @@ -1,70 +0,0 @@ -= ERC 721 - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc721 - -This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-721[ERC721 Non-Fungible Token Standard]. - -TIP: For a walk through on how to create an ERC721 token read our xref:ROOT:erc721.adoc[ERC721 guide]. - -The EIP specifies four interfaces: - -* {IERC721}: Core functionality required in all compliant implementation. -* {IERC721Metadata}: Optional extension that adds name, symbol, and token URI, almost always included. -* {IERC721Enumerable}: Optional extension that allows enumerating the tokens on chain, often not included since it requires large gas overhead. -* {IERC721Receiver}: An interface that must be implemented by contracts if they want to accept tokens through `safeTransferFrom`. - -OpenZeppelin Contracts provides implementations of all four interfaces: - -* {ERC721}: The core and metadata extensions, with a base URI mechanism. -* {ERC721Enumerable}: The enumerable extension. -* {ERC721Holder}: A bare bones implementation of the receiver interface. - -Additionally there are a few of other extensions: - -* {ERC721Consecutive}: An implementation of https://eips.ethereum.org/EIPS/eip-2309[ERC2309] for minting batchs of tokens during construction, in accordance with ERC721. -* {ERC721URIStorage}: A more flexible but more expensive way of storing metadata. -* {ERC721Votes}: Support for voting and vote delegation. -* {ERC721Royalty}: A way to signal royalty information following ERC2981. -* {ERC721Pausable}: A primitive to pause contract operation. -* {ERC721Burnable}: A way for token holders to burn their own tokens. - -NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC721 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc721.adoc#Presets[ERC721 Presets] (such as {ERC721PresetMinterPauserAutoId}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts. - -== Core - -{{IERC721}} - -{{IERC721Metadata}} - -{{IERC721Enumerable}} - -{{ERC721}} - -{{ERC721Enumerable}} - -{{IERC721Receiver}} - -== Extensions - -{{ERC721Pausable}} - -{{ERC721Burnable}} - -{{ERC721Consecutive}} - -{{ERC721URIStorage}} - -{{ERC721Votes}} - -{{ERC721Royalty}} - -== Presets - -These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code. - -{{ERC721PresetMinterPauserAutoId}} - -== Utilities - -{{ERC721Holder}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721BurnableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721BurnableUpgradeable.sol deleted file mode 100644 index 32effce..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721BurnableUpgradeable.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Burnable.sol) - -pragma solidity ^0.8.0; - -import "../ERC721Upgradeable.sol"; -import "../../../utils/ContextUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @title ERC721 Burnable Token - * @dev ERC721 Token that can be burned (destroyed). - */ -abstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable { - function __ERC721Burnable_init() internal onlyInitializing { - } - - function __ERC721Burnable_init_unchained() internal onlyInitializing { - } - /** - * @dev Burns `tokenId`. See {ERC721-_burn}. - * - * Requirements: - * - * - The caller must own `tokenId` or be an approved operator. - */ - function burn(uint256 tokenId) public virtual { - //solhint-disable-next-line max-line-length - require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); - _burn(tokenId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721ConsecutiveUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721ConsecutiveUpgradeable.sol deleted file mode 100644 index a23c8b3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721ConsecutiveUpgradeable.sol +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/extensions/ERC721Consecutive.sol) - -pragma solidity ^0.8.0; - -import "../ERC721Upgradeable.sol"; -import "../../../interfaces/IERC2309Upgradeable.sol"; -import "../../../utils/CheckpointsUpgradeable.sol"; -import "../../../utils/structs/BitMapsUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the ERC2309 "Consecutive Transfer Extension" as defined in - * https://eips.ethereum.org/EIPS/eip-2309[EIP-2309]. - * - * This extension allows the minting of large batches of tokens, during contract construction only. For upgradeable - * contracts this implies that batch minting is only available during proxy deployment, and not in subsequent upgrades. - * These batches are limited to 5000 tokens at a time by default to accommodate off-chain indexers. - * - * Using this extension removes the ability to mint single tokens during contract construction. This ability is - * regained after construction. During construction, only batch minting is allowed. - * - * IMPORTANT: This extension bypasses the hooks {_beforeTokenTransfer} and {_afterTokenTransfer} for tokens minted in - * batch. When using this extension, you should consider the {_beforeConsecutiveTokenTransfer} and - * {_afterConsecutiveTokenTransfer} hooks in addition to {_beforeTokenTransfer} and {_afterTokenTransfer}. - * - * IMPORTANT: When overriding {_afterTokenTransfer}, be careful about call ordering. {ownerOf} may return invalid - * values during the {_afterTokenTransfer} execution if the super call is not called first. To be safe, execute the - * super call before your custom logic. - * - * _Available since v4.8._ - */ -abstract contract ERC721ConsecutiveUpgradeable is Initializable, IERC2309Upgradeable, ERC721Upgradeable { - function __ERC721Consecutive_init() internal onlyInitializing { - } - - function __ERC721Consecutive_init_unchained() internal onlyInitializing { - } - using BitMapsUpgradeable for BitMapsUpgradeable.BitMap; - using CheckpointsUpgradeable for CheckpointsUpgradeable.Trace160; - - CheckpointsUpgradeable.Trace160 private _sequentialOwnership; - BitMapsUpgradeable.BitMap private _sequentialBurn; - - /** - * @dev Maximum size of a batch of consecutive tokens. This is designed to limit stress on off-chain indexing - * services that have to record one entry per token, and have protections against "unreasonably large" batches of - * tokens. - * - * NOTE: Overriding the default value of 5000 will not cause on-chain issues, but may result in the asset not being - * correctly supported by off-chain indexing services (including marketplaces). - */ - function _maxBatchSize() internal view virtual returns (uint96) { - return 5000; - } - - /** - * @dev See {ERC721-_ownerOf}. Override that checks the sequential ownership structure for tokens that have - * been minted as part of a batch, and not yet transferred. - */ - function _ownerOf(uint256 tokenId) internal view virtual override returns (address) { - address owner = super._ownerOf(tokenId); - - // If token is owned by the core, or beyond consecutive range, return base value - if (owner != address(0) || tokenId > type(uint96).max) { - return owner; - } - - // Otherwise, check the token was not burned, and fetch ownership from the anchors - // Note: no need for safe cast, we know that tokenId <= type(uint96).max - return _sequentialBurn.get(tokenId) ? address(0) : address(_sequentialOwnership.lowerLookup(uint96(tokenId))); - } - - /** - * @dev Mint a batch of tokens of length `batchSize` for `to`. Returns the token id of the first token minted in the - * batch; if `batchSize` is 0, returns the number of consecutive ids minted so far. - * - * Requirements: - * - * - `batchSize` must not be greater than {_maxBatchSize}. - * - The function is called in the constructor of the contract (directly or indirectly). - * - * CAUTION: Does not emit a `Transfer` event. This is ERC721 compliant as long as it is done outside of the - * constructor, which is enforced by this function. - * - * CAUTION: Does not invoke `onERC721Received` on the receiver. - * - * Emits a {IERC2309-ConsecutiveTransfer} event. - */ - function _mintConsecutive(address to, uint96 batchSize) internal virtual returns (uint96) { - uint96 first = _totalConsecutiveSupply(); - - // minting a batch of size 0 is a no-op - if (batchSize > 0) { - require(!AddressUpgradeable.isContract(address(this)), "ERC721Consecutive: batch minting restricted to constructor"); - require(to != address(0), "ERC721Consecutive: mint to the zero address"); - require(batchSize <= _maxBatchSize(), "ERC721Consecutive: batch too large"); - - // hook before - _beforeTokenTransfer(address(0), to, first, batchSize); - - // push an ownership checkpoint & emit event - uint96 last = first + batchSize - 1; - _sequentialOwnership.push(last, uint160(to)); - - // The invariant required by this function is preserved because the new sequentialOwnership checkpoint - // is attributing ownership of `batchSize` new tokens to account `to`. - __unsafe_increaseBalance(to, batchSize); - - emit ConsecutiveTransfer(first, last, address(0), to); - - // hook after - _afterTokenTransfer(address(0), to, first, batchSize); - } - - return first; - } - - /** - * @dev See {ERC721-_mint}. Override version that restricts normal minting to after construction. - * - * Warning: Using {ERC721Consecutive} prevents using {_mint} during construction in favor of {_mintConsecutive}. - * After construction, {_mintConsecutive} is no longer available and {_mint} becomes available. - */ - function _mint(address to, uint256 tokenId) internal virtual override { - require(AddressUpgradeable.isContract(address(this)), "ERC721Consecutive: can't mint during construction"); - super._mint(to, tokenId); - } - - /** - * @dev See {ERC721-_afterTokenTransfer}. Burning of tokens that have been sequentially minted must be explicit. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override { - if ( - to == address(0) && // if we burn - firstTokenId < _totalConsecutiveSupply() && // and the tokenId was minted in a batch - !_sequentialBurn.get(firstTokenId) // and the token was never marked as burnt - ) { - require(batchSize == 1, "ERC721Consecutive: batch burn not supported"); - _sequentialBurn.set(firstTokenId); - } - super._afterTokenTransfer(from, to, firstTokenId, batchSize); - } - - function _totalConsecutiveSupply() private view returns (uint96) { - (bool exists, uint96 latestId, ) = _sequentialOwnership.latestCheckpoint(); - return exists ? latestId + 1 : 0; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol deleted file mode 100644 index 2c61626..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) - -pragma solidity ^0.8.0; - -import "../ERC721Upgradeable.sol"; -import "./IERC721EnumerableUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev This implements an optional extension of {ERC721} defined in the EIP that adds - * enumerability of all the token ids in the contract as well as all token ids owned by each - * account. - */ -abstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721EnumerableUpgradeable { - function __ERC721Enumerable_init() internal onlyInitializing { - } - - function __ERC721Enumerable_init_unchained() internal onlyInitializing { - } - // Mapping from owner to list of owned token IDs - mapping(address => mapping(uint256 => uint256)) private _ownedTokens; - - // Mapping from token ID to index of the owner tokens list - mapping(uint256 => uint256) private _ownedTokensIndex; - - // Array with all token ids, used for enumeration - uint256[] private _allTokens; - - // Mapping from token id to position in the allTokens array - mapping(uint256 => uint256) private _allTokensIndex; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC721Upgradeable) returns (bool) { - return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. - */ - function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { - require(index < ERC721Upgradeable.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); - return _ownedTokens[owner][index]; - } - - /** - * @dev See {IERC721Enumerable-totalSupply}. - */ - function totalSupply() public view virtual override returns (uint256) { - return _allTokens.length; - } - - /** - * @dev See {IERC721Enumerable-tokenByIndex}. - */ - function tokenByIndex(uint256 index) public view virtual override returns (uint256) { - require(index < ERC721EnumerableUpgradeable.totalSupply(), "ERC721Enumerable: global index out of bounds"); - return _allTokens[index]; - } - - /** - * @dev See {ERC721-_beforeTokenTransfer}. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override { - super._beforeTokenTransfer(from, to, firstTokenId, batchSize); - - if (batchSize > 1) { - // Will only trigger during construction. Batch transferring (minting) is not available afterwards. - revert("ERC721Enumerable: consecutive transfers not supported"); - } - - uint256 tokenId = firstTokenId; - - if (from == address(0)) { - _addTokenToAllTokensEnumeration(tokenId); - } else if (from != to) { - _removeTokenFromOwnerEnumeration(from, tokenId); - } - if (to == address(0)) { - _removeTokenFromAllTokensEnumeration(tokenId); - } else if (to != from) { - _addTokenToOwnerEnumeration(to, tokenId); - } - } - - /** - * @dev Private function to add a token to this extension's ownership-tracking data structures. - * @param to address representing the new owner of the given token ID - * @param tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { - uint256 length = ERC721Upgradeable.balanceOf(to); - _ownedTokens[to][length] = tokenId; - _ownedTokensIndex[tokenId] = length; - } - - /** - * @dev Private function to add a token to this extension's token tracking data structures. - * @param tokenId uint256 ID of the token to be added to the tokens list - */ - function _addTokenToAllTokensEnumeration(uint256 tokenId) private { - _allTokensIndex[tokenId] = _allTokens.length; - _allTokens.push(tokenId); - } - - /** - * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that - * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for - * gas optimizations e.g. when performing a transfer operation (avoiding double writes). - * This has O(1) time complexity, but alters the order of the _ownedTokens array. - * @param from address representing the previous owner of the given token ID - * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { - // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and - // then delete the last slot (swap and pop). - - uint256 lastTokenIndex = ERC721Upgradeable.balanceOf(from) - 1; - uint256 tokenIndex = _ownedTokensIndex[tokenId]; - - // When the token to delete is the last token, the swap operation is unnecessary - if (tokenIndex != lastTokenIndex) { - uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; - - _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token - _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index - } - - // This also deletes the contents at the last position of the array - delete _ownedTokensIndex[tokenId]; - delete _ownedTokens[from][lastTokenIndex]; - } - - /** - * @dev Private function to remove a token from this extension's token tracking data structures. - * This has O(1) time complexity, but alters the order of the _allTokens array. - * @param tokenId uint256 ID of the token to be removed from the tokens list - */ - function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { - // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and - // then delete the last slot (swap and pop). - - uint256 lastTokenIndex = _allTokens.length - 1; - uint256 tokenIndex = _allTokensIndex[tokenId]; - - // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so - // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding - // an 'if' statement (like in _removeTokenFromOwnerEnumeration) - uint256 lastTokenId = _allTokens[lastTokenIndex]; - - _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token - _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index - - // This also deletes the contents at the last position of the array - delete _allTokensIndex[tokenId]; - _allTokens.pop(); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[46] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721PausableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721PausableUpgradeable.sol deleted file mode 100644 index 876fb37..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721PausableUpgradeable.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/extensions/ERC721Pausable.sol) - -pragma solidity ^0.8.0; - -import "../ERC721Upgradeable.sol"; -import "../../../security/PausableUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev ERC721 token with pausable token transfers, minting and burning. - * - * Useful for scenarios such as preventing trades until the end of an evaluation - * period, or having an emergency switch for freezing all token transfers in the - * event of a large bug. - * - * IMPORTANT: This contract does not include public pause and unpause functions. In - * addition to inheriting this contract, you must define both functions, invoking the - * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate - * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will - * make the contract unpausable. - */ -abstract contract ERC721PausableUpgradeable is Initializable, ERC721Upgradeable, PausableUpgradeable { - function __ERC721Pausable_init() internal onlyInitializing { - __Pausable_init_unchained(); - } - - function __ERC721Pausable_init_unchained() internal onlyInitializing { - } - /** - * @dev See {ERC721-_beforeTokenTransfer}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override { - super._beforeTokenTransfer(from, to, firstTokenId, batchSize); - - require(!paused(), "ERC721Pausable: token transfer while paused"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol deleted file mode 100644 index 7e18da5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Royalty.sol) - -pragma solidity ^0.8.0; - -import "../ERC721Upgradeable.sol"; -import "../../common/ERC2981Upgradeable.sol"; -import "../../../utils/introspection/ERC165Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of ERC721 with the ERC2981 NFT Royalty Standard, a standardized way to retrieve royalty payment - * information. - * - * Royalty information can be specified globally for all token ids via {ERC2981-_setDefaultRoyalty}, and/or individually for - * specific token ids via {ERC2981-_setTokenRoyalty}. The latter takes precedence over the first. - * - * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See - * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to - * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. - * - * _Available since v4.5._ - */ -abstract contract ERC721RoyaltyUpgradeable is Initializable, ERC2981Upgradeable, ERC721Upgradeable { - function __ERC721Royalty_init() internal onlyInitializing { - } - - function __ERC721Royalty_init_unchained() internal onlyInitializing { - } - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable, ERC2981Upgradeable) returns (bool) { - return super.supportsInterface(interfaceId); - } - - /** - * @dev See {ERC721-_burn}. This override additionally clears the royalty information for the token. - */ - function _burn(uint256 tokenId) internal virtual override { - super._burn(tokenId); - _resetTokenRoyalty(tokenId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol deleted file mode 100644 index 5f349d2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol) - -pragma solidity ^0.8.0; - -import "../ERC721Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev ERC721 token with storage based token URI management. - */ -abstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable { - function __ERC721URIStorage_init() internal onlyInitializing { - } - - function __ERC721URIStorage_init_unchained() internal onlyInitializing { - } - using StringsUpgradeable for uint256; - - // Optional mapping for token URIs - mapping(uint256 => string) private _tokenURIs; - - /** - * @dev See {IERC721Metadata-tokenURI}. - */ - function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { - _requireMinted(tokenId); - - string memory _tokenURI = _tokenURIs[tokenId]; - string memory base = _baseURI(); - - // If there is no base URI, return the token URI. - if (bytes(base).length == 0) { - return _tokenURI; - } - // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). - if (bytes(_tokenURI).length > 0) { - return string(abi.encodePacked(base, _tokenURI)); - } - - return super.tokenURI(tokenId); - } - - /** - * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { - require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); - _tokenURIs[tokenId] = _tokenURI; - } - - /** - * @dev See {ERC721-_burn}. This override additionally checks to see if a - * token-specific URI was set for the token, and if so, it deletes the token URI from - * the storage mapping. - */ - function _burn(uint256 tokenId) internal virtual override { - super._burn(tokenId); - - if (bytes(_tokenURIs[tokenId]).length != 0) { - delete _tokenURIs[tokenId]; - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721VotesUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721VotesUpgradeable.sol deleted file mode 100644 index 8c459f5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/ERC721VotesUpgradeable.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Votes.sol) - -pragma solidity ^0.8.0; - -import "../ERC721Upgradeable.sol"; -import "../../../governance/utils/VotesUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Extension of ERC721 to support voting and delegation as implemented by {Votes}, where each individual NFT counts - * as 1 vote unit. - * - * Tokens do not count as votes until they are delegated, because votes must be tracked which incurs an additional cost - * on every transfer. Token holders can either delegate to a trusted representative who will decide how to make use of - * the votes in governance decisions, or they can delegate to themselves to be their own representative. - * - * _Available since v4.5._ - */ -abstract contract ERC721VotesUpgradeable is Initializable, ERC721Upgradeable, VotesUpgradeable { - function __ERC721Votes_init() internal onlyInitializing { - } - - function __ERC721Votes_init_unchained() internal onlyInitializing { - } - /** - * @dev See {ERC721-_afterTokenTransfer}. Adjusts votes when tokens are transferred. - * - * Emits a {IVotes-DelegateVotesChanged} event. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override { - _transferVotingUnits(from, to, batchSize); - super._afterTokenTransfer(from, to, firstTokenId, batchSize); - } - - /** - * @dev Returns the balance of `account`. - */ - function _getVotingUnits(address account) internal view virtual override returns (uint256) { - return balanceOf(account); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol deleted file mode 100644 index 77a7631..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) - -pragma solidity ^0.8.0; - -import "../IERC721Upgradeable.sol"; - -/** - * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721EnumerableUpgradeable is IERC721Upgradeable { - /** - * @dev Returns the total amount of tokens stored by the contract. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns a token ID owned by `owner` at a given `index` of its token list. - * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. - */ - function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); - - /** - * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. - * Use along with {totalSupply} to enumerate all tokens. - */ - function tokenByIndex(uint256 index) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721MetadataUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721MetadataUpgradeable.sol deleted file mode 100644 index 2a3ce91..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/IERC721MetadataUpgradeable.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) - -pragma solidity ^0.8.0; - -import "../IERC721Upgradeable.sol"; - -/** - * @title ERC-721 Non-Fungible Token Standard, optional metadata extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721MetadataUpgradeable is IERC721Upgradeable { - /** - * @dev Returns the token collection name. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the token collection symbol. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. - */ - function tokenURI(uint256 tokenId) external view returns (string memory); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/draft-ERC721VotesUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/draft-ERC721VotesUpgradeable.sol deleted file mode 100644 index 80e8f44..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/extensions/draft-ERC721VotesUpgradeable.sol +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/draft-ERC721Votes.sol) - -pragma solidity ^0.8.0; - -// ERC721Votes was marked as draft due to the EIP-712 dependency. -// EIP-712 is Final as of 2022-08-11. This file is deprecated. - -import "./ERC721VotesUpgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoIdUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoIdUpgradeable.sol deleted file mode 100644 index df8d29d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoIdUpgradeable.sol +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol) - -pragma solidity ^0.8.0; - -import "../ERC721Upgradeable.sol"; -import "../extensions/ERC721EnumerableUpgradeable.sol"; -import "../extensions/ERC721BurnableUpgradeable.sol"; -import "../extensions/ERC721PausableUpgradeable.sol"; -import "../../../access/AccessControlEnumerableUpgradeable.sol"; -import "../../../utils/ContextUpgradeable.sol"; -import "../../../utils/CountersUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev {ERC721} token, including: - * - * - ability for holders to burn (destroy) their tokens - * - a minter role that allows for token minting (creation) - * - a pauser role that allows to stop all token transfers - * - token ID and URI autogeneration - * - * This contract uses {AccessControl} to lock permissioned functions using the - * different roles - head to its documentation for details. - * - * The account that deploys the contract will be granted the minter and pauser - * roles, as well as the default admin role, which will let it grant both minter - * and pauser roles to other accounts. - * - * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._ - */ -contract ERC721PresetMinterPauserAutoIdUpgradeable is - Initializable, ContextUpgradeable, - AccessControlEnumerableUpgradeable, - ERC721EnumerableUpgradeable, - ERC721BurnableUpgradeable, - ERC721PausableUpgradeable -{ - function initialize( - string memory name, - string memory symbol, - string memory baseTokenURI - ) public virtual initializer { - __ERC721PresetMinterPauserAutoId_init(name, symbol, baseTokenURI); - } - using CountersUpgradeable for CountersUpgradeable.Counter; - - bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); - bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); - - CountersUpgradeable.Counter private _tokenIdTracker; - - string private _baseTokenURI; - - /** - * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the - * account that deploys the contract. - * - * Token URIs will be autogenerated based on `baseURI` and their token IDs. - * See {ERC721-tokenURI}. - */ - function __ERC721PresetMinterPauserAutoId_init( - string memory name, - string memory symbol, - string memory baseTokenURI - ) internal onlyInitializing { - __ERC721_init_unchained(name, symbol); - __Pausable_init_unchained(); - __ERC721PresetMinterPauserAutoId_init_unchained(name, symbol, baseTokenURI); - } - - function __ERC721PresetMinterPauserAutoId_init_unchained( - string memory, - string memory, - string memory baseTokenURI - ) internal onlyInitializing { - _baseTokenURI = baseTokenURI; - - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - - _setupRole(MINTER_ROLE, _msgSender()); - _setupRole(PAUSER_ROLE, _msgSender()); - } - - function _baseURI() internal view virtual override returns (string memory) { - return _baseTokenURI; - } - - /** - * @dev Creates a new token for `to`. Its token ID will be automatically - * assigned (and available on the emitted {IERC721-Transfer} event), and the token - * URI autogenerated based on the base URI passed at construction. - * - * See {ERC721-_mint}. - * - * Requirements: - * - * - the caller must have the `MINTER_ROLE`. - */ - function mint(address to) public virtual { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint"); - - // We cannot just use balanceOf to create the new tokenId because tokens - // can be burned (destroyed), so we need a separate counter. - _mint(to, _tokenIdTracker.current()); - _tokenIdTracker.increment(); - } - - /** - * @dev Pauses all token transfers. - * - * See {ERC721Pausable} and {Pausable-_pause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function pause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause"); - _pause(); - } - - /** - * @dev Unpauses all token transfers. - * - * See {ERC721Pausable} and {Pausable-_unpause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function unpause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause"); - _unpause(); - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 firstTokenId, - uint256 batchSize - ) internal virtual override(ERC721Upgradeable, ERC721EnumerableUpgradeable, ERC721PausableUpgradeable) { - super._beforeTokenTransfer(from, to, firstTokenId, batchSize); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(AccessControlEnumerableUpgradeable, ERC721Upgradeable, ERC721EnumerableUpgradeable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/README.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/README.md deleted file mode 100644 index 468200b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/presets/README.md +++ /dev/null @@ -1 +0,0 @@ -Contract presets are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com/) as a more powerful alternative. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/utils/ERC721HolderUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/utils/ERC721HolderUpgradeable.sol deleted file mode 100644 index df0166e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/utils/ERC721HolderUpgradeable.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol) - -pragma solidity ^0.8.0; - -import "../IERC721ReceiverUpgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the {IERC721Receiver} interface. - * - * Accepts all token transfers. - * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. - */ -contract ERC721HolderUpgradeable is Initializable, IERC721ReceiverUpgradeable { - function __ERC721Holder_init() internal onlyInitializing { - } - - function __ERC721Holder_init_unchained() internal onlyInitializing { - } - /** - * @dev See {IERC721Receiver-onERC721Received}. - * - * Always returns `IERC721Receiver.onERC721Received.selector`. - */ - function onERC721Received( - address, - address, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC721Received.selector; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/ERC777Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/ERC777Upgradeable.sol deleted file mode 100644 index 1a260aa..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/ERC777Upgradeable.sol +++ /dev/null @@ -1,563 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC777/ERC777.sol) - -pragma solidity ^0.8.0; - -import "./IERC777Upgradeable.sol"; -import "./IERC777RecipientUpgradeable.sol"; -import "./IERC777SenderUpgradeable.sol"; -import "../ERC20/IERC20Upgradeable.sol"; -import "../../utils/AddressUpgradeable.sol"; -import "../../utils/ContextUpgradeable.sol"; -import "../../utils/introspection/IERC1820RegistryUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the {IERC777} interface. - * - * This implementation is agnostic to the way tokens are created. This means - * that a supply mechanism has to be added in a derived contract using {_mint}. - * - * Support for ERC20 is included in this contract, as specified by the EIP: both - * the ERC777 and ERC20 interfaces can be safely used when interacting with it. - * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token - * movements. - * - * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there - * are no special restrictions in the amount of tokens that created, moved, or - * destroyed. This makes integration with ERC20 applications seamless. - */ -contract ERC777Upgradeable is Initializable, ContextUpgradeable, IERC777Upgradeable, IERC20Upgradeable { - using AddressUpgradeable for address; - - IERC1820RegistryUpgradeable internal constant _ERC1820_REGISTRY = IERC1820RegistryUpgradeable(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); - - mapping(address => uint256) private _balances; - - uint256 private _totalSupply; - - string private _name; - string private _symbol; - - bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender"); - bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); - - // This isn't ever read from - it's only used to respond to the defaultOperators query. - address[] private _defaultOperatorsArray; - - // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators). - mapping(address => bool) private _defaultOperators; - - // For each account, a mapping of its operators and revoked default operators. - mapping(address => mapping(address => bool)) private _operators; - mapping(address => mapping(address => bool)) private _revokedDefaultOperators; - - // ERC20-allowances - mapping(address => mapping(address => uint256)) private _allowances; - - /** - * @dev `defaultOperators` may be an empty array. - */ - function __ERC777_init( - string memory name_, - string memory symbol_, - address[] memory defaultOperators_ - ) internal onlyInitializing { - __ERC777_init_unchained(name_, symbol_, defaultOperators_); - } - - function __ERC777_init_unchained( - string memory name_, - string memory symbol_, - address[] memory defaultOperators_ - ) internal onlyInitializing { - _name = name_; - _symbol = symbol_; - - _defaultOperatorsArray = defaultOperators_; - for (uint256 i = 0; i < defaultOperators_.length; i++) { - _defaultOperators[defaultOperators_[i]] = true; - } - - // register interfaces - _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this)); - _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this)); - } - - /** - * @dev See {IERC777-name}. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev See {IERC777-symbol}. - */ - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - /** - * @dev See {ERC20-decimals}. - * - * Always returns 18, as per the - * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility). - */ - function decimals() public pure virtual returns (uint8) { - return 18; - } - - /** - * @dev See {IERC777-granularity}. - * - * This implementation always returns `1`. - */ - function granularity() public view virtual override returns (uint256) { - return 1; - } - - /** - * @dev See {IERC777-totalSupply}. - */ - function totalSupply() public view virtual override(IERC20Upgradeable, IERC777Upgradeable) returns (uint256) { - return _totalSupply; - } - - /** - * @dev Returns the amount of tokens owned by an account (`tokenHolder`). - */ - function balanceOf(address tokenHolder) public view virtual override(IERC20Upgradeable, IERC777Upgradeable) returns (uint256) { - return _balances[tokenHolder]; - } - - /** - * @dev See {IERC777-send}. - * - * Also emits a {IERC20-Transfer} event for ERC20 compatibility. - */ - function send( - address recipient, - uint256 amount, - bytes memory data - ) public virtual override { - _send(_msgSender(), recipient, amount, data, "", true); - } - - /** - * @dev See {IERC20-transfer}. - * - * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient} - * interface if it is a contract. - * - * Also emits a {Sent} event. - */ - function transfer(address recipient, uint256 amount) public virtual override returns (bool) { - _send(_msgSender(), recipient, amount, "", "", false); - return true; - } - - /** - * @dev See {IERC777-burn}. - * - * Also emits a {IERC20-Transfer} event for ERC20 compatibility. - */ - function burn(uint256 amount, bytes memory data) public virtual override { - _burn(_msgSender(), amount, data, ""); - } - - /** - * @dev See {IERC777-isOperatorFor}. - */ - function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) { - return - operator == tokenHolder || - (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) || - _operators[tokenHolder][operator]; - } - - /** - * @dev See {IERC777-authorizeOperator}. - */ - function authorizeOperator(address operator) public virtual override { - require(_msgSender() != operator, "ERC777: authorizing self as operator"); - - if (_defaultOperators[operator]) { - delete _revokedDefaultOperators[_msgSender()][operator]; - } else { - _operators[_msgSender()][operator] = true; - } - - emit AuthorizedOperator(operator, _msgSender()); - } - - /** - * @dev See {IERC777-revokeOperator}. - */ - function revokeOperator(address operator) public virtual override { - require(operator != _msgSender(), "ERC777: revoking self as operator"); - - if (_defaultOperators[operator]) { - _revokedDefaultOperators[_msgSender()][operator] = true; - } else { - delete _operators[_msgSender()][operator]; - } - - emit RevokedOperator(operator, _msgSender()); - } - - /** - * @dev See {IERC777-defaultOperators}. - */ - function defaultOperators() public view virtual override returns (address[] memory) { - return _defaultOperatorsArray; - } - - /** - * @dev See {IERC777-operatorSend}. - * - * Emits {Sent} and {IERC20-Transfer} events. - */ - function operatorSend( - address sender, - address recipient, - uint256 amount, - bytes memory data, - bytes memory operatorData - ) public virtual override { - require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder"); - _send(sender, recipient, amount, data, operatorData, true); - } - - /** - * @dev See {IERC777-operatorBurn}. - * - * Emits {Burned} and {IERC20-Transfer} events. - */ - function operatorBurn( - address account, - uint256 amount, - bytes memory data, - bytes memory operatorData - ) public virtual override { - require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder"); - _burn(account, amount, data, operatorData); - } - - /** - * @dev See {IERC20-allowance}. - * - * Note that operator and allowance concepts are orthogonal: operators may - * not have allowance, and accounts with allowance may not be operators - * themselves. - */ - function allowance(address holder, address spender) public view virtual override returns (uint256) { - return _allowances[holder][spender]; - } - - /** - * @dev See {IERC20-approve}. - * - * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on - * `transferFrom`. This is semantically equivalent to an infinite approval. - * - * Note that accounts cannot have allowance issued by their operators. - */ - function approve(address spender, uint256 value) public virtual override returns (bool) { - address holder = _msgSender(); - _approve(holder, spender, value); - return true; - } - - /** - * @dev See {IERC20-transferFrom}. - * - * NOTE: Does not update the allowance if the current allowance - * is the maximum `uint256`. - * - * Note that operator and allowance concepts are orthogonal: operators cannot - * call `transferFrom` (unless they have allowance), and accounts with - * allowance cannot call `operatorSend` (unless they are operators). - * - * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events. - */ - function transferFrom( - address holder, - address recipient, - uint256 amount - ) public virtual override returns (bool) { - address spender = _msgSender(); - _spendAllowance(holder, spender, amount); - _send(holder, recipient, amount, "", "", false); - return true; - } - - /** - * @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. - * - * If a send hook is registered for `account`, the corresponding function - * will be called with the caller address as the `operator` and with - * `userData` and `operatorData`. - * - * See {IERC777Sender} and {IERC777Recipient}. - * - * Emits {Minted} and {IERC20-Transfer} events. - * - * Requirements - * - * - `account` cannot be the zero address. - * - if `account` is a contract, it must implement the {IERC777Recipient} - * interface. - */ - function _mint( - address account, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) internal virtual { - _mint(account, amount, userData, operatorData, true); - } - - /** - * @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. - * - * If `requireReceptionAck` is set to true, and if a send hook is - * registered for `account`, the corresponding function will be called with - * `operator`, `data` and `operatorData`. - * - * See {IERC777Sender} and {IERC777Recipient}. - * - * Emits {Minted} and {IERC20-Transfer} events. - * - * Requirements - * - * - `account` cannot be the zero address. - * - if `account` is a contract, it must implement the {IERC777Recipient} - * interface. - */ - function _mint( - address account, - uint256 amount, - bytes memory userData, - bytes memory operatorData, - bool requireReceptionAck - ) internal virtual { - require(account != address(0), "ERC777: mint to the zero address"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, address(0), account, amount); - - // Update state variables - _totalSupply += amount; - _balances[account] += amount; - - _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck); - - emit Minted(operator, account, amount, userData, operatorData); - emit Transfer(address(0), account, amount); - } - - /** - * @dev Send tokens - * @param from address token holder address - * @param to address recipient address - * @param amount uint256 amount of tokens to transfer - * @param userData bytes extra information provided by the token holder (if any) - * @param operatorData bytes extra information provided by the operator (if any) - * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient - */ - function _send( - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData, - bool requireReceptionAck - ) internal virtual { - require(from != address(0), "ERC777: transfer from the zero address"); - require(to != address(0), "ERC777: transfer to the zero address"); - - address operator = _msgSender(); - - _callTokensToSend(operator, from, to, amount, userData, operatorData); - - _move(operator, from, to, amount, userData, operatorData); - - _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck); - } - - /** - * @dev Burn tokens - * @param from address token holder address - * @param amount uint256 amount of tokens to burn - * @param data bytes extra information provided by the token holder - * @param operatorData bytes extra information provided by the operator (if any) - */ - function _burn( - address from, - uint256 amount, - bytes memory data, - bytes memory operatorData - ) internal virtual { - require(from != address(0), "ERC777: burn from the zero address"); - - address operator = _msgSender(); - - _callTokensToSend(operator, from, address(0), amount, data, operatorData); - - _beforeTokenTransfer(operator, from, address(0), amount); - - // Update state variables - uint256 fromBalance = _balances[from]; - require(fromBalance >= amount, "ERC777: burn amount exceeds balance"); - unchecked { - _balances[from] = fromBalance - amount; - } - _totalSupply -= amount; - - emit Burned(operator, from, amount, data, operatorData); - emit Transfer(from, address(0), amount); - } - - function _move( - address operator, - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) private { - _beforeTokenTransfer(operator, from, to, amount); - - uint256 fromBalance = _balances[from]; - require(fromBalance >= amount, "ERC777: transfer amount exceeds balance"); - unchecked { - _balances[from] = fromBalance - amount; - } - _balances[to] += amount; - - emit Sent(operator, from, to, amount, userData, operatorData); - emit Transfer(from, to, amount); - } - - /** - * @dev See {ERC20-_approve}. - * - * Note that accounts cannot have allowance issued by their operators. - */ - function _approve( - address holder, - address spender, - uint256 value - ) internal virtual { - require(holder != address(0), "ERC777: approve from the zero address"); - require(spender != address(0), "ERC777: approve to the zero address"); - - _allowances[holder][spender] = value; - emit Approval(holder, spender, value); - } - - /** - * @dev Call from.tokensToSend() if the interface is registered - * @param operator address operator requesting the transfer - * @param from address token holder address - * @param to address recipient address - * @param amount uint256 amount of tokens to transfer - * @param userData bytes extra information provided by the token holder (if any) - * @param operatorData bytes extra information provided by the operator (if any) - */ - function _callTokensToSend( - address operator, - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) private { - address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH); - if (implementer != address(0)) { - IERC777SenderUpgradeable(implementer).tokensToSend(operator, from, to, amount, userData, operatorData); - } - } - - /** - * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but - * tokensReceived() was not registered for the recipient - * @param operator address operator requesting the transfer - * @param from address token holder address - * @param to address recipient address - * @param amount uint256 amount of tokens to transfer - * @param userData bytes extra information provided by the token holder (if any) - * @param operatorData bytes extra information provided by the operator (if any) - * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient - */ - function _callTokensReceived( - address operator, - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData, - bool requireReceptionAck - ) private { - address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH); - if (implementer != address(0)) { - IERC777RecipientUpgradeable(implementer).tokensReceived(operator, from, to, amount, userData, operatorData); - } else if (requireReceptionAck) { - require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient"); - } - } - - /** - * @dev Updates `owner` s allowance for `spender` based on spent `amount`. - * - * Does not update the allowance amount in case of infinite allowance. - * Revert if not enough allowance is available. - * - * Might emit an {IERC20-Approval} event. - */ - function _spendAllowance( - address owner, - address spender, - uint256 amount - ) internal virtual { - uint256 currentAllowance = allowance(owner, spender); - if (currentAllowance != type(uint256).max) { - require(currentAllowance >= amount, "ERC777: insufficient allowance"); - unchecked { - _approve(owner, spender, currentAllowance - amount); - } - } - } - - /** - * @dev Hook that is called before any token transfer. This includes - * calls to {send}, {transfer}, {operatorSend}, minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be to transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256 amount - ) internal virtual {} - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[41] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777RecipientUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777RecipientUpgradeable.sol deleted file mode 100644 index 9ffe79c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777RecipientUpgradeable.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP. - * - * Accounts can be notified of {IERC777} tokens being sent to them by having a - * contract implement this interface (contract holders can be their own - * implementer) and registering it on the - * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. - * - * See {IERC1820Registry} and {ERC1820Implementer}. - */ -interface IERC777RecipientUpgradeable { - /** - * @dev Called by an {IERC777} token contract whenever tokens are being - * moved or created into a registered account (`to`). The type of operation - * is conveyed by `from` being the zero address or not. - * - * This call occurs _after_ the token contract's state is updated, so - * {IERC777-balanceOf}, etc., can be used to query the post-operation state. - * - * This function may revert to prevent the operation from being executed. - */ - function tokensReceived( - address operator, - address from, - address to, - uint256 amount, - bytes calldata userData, - bytes calldata operatorData - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777SenderUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777SenderUpgradeable.sol deleted file mode 100644 index 3455d0a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777SenderUpgradeable.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC777TokensSender standard as defined in the EIP. - * - * {IERC777} Token holders can be notified of operations performed on their - * tokens by having a contract implement this interface (contract holders can be - * their own implementer) and registering it on the - * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. - * - * See {IERC1820Registry} and {ERC1820Implementer}. - */ -interface IERC777SenderUpgradeable { - /** - * @dev Called by an {IERC777} token contract whenever a registered holder's - * (`from`) tokens are about to be moved or destroyed. The type of operation - * is conveyed by `to` being the zero address or not. - * - * This call occurs _before_ the token contract's state is updated, so - * {IERC777-balanceOf}, etc., can be used to query the pre-operation state. - * - * This function may revert to prevent the operation from being executed. - */ - function tokensToSend( - address operator, - address from, - address to, - uint256 amount, - bytes calldata userData, - bytes calldata operatorData - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777Upgradeable.sol deleted file mode 100644 index bc9e2e8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/IERC777Upgradeable.sol +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC777/IERC777.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC777Token standard as defined in the EIP. - * - * This contract uses the - * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let - * token holders and recipients react to token movements by using setting implementers - * for the associated interfaces in said registry. See {IERC1820Registry} and - * {ERC1820Implementer}. - */ -interface IERC777Upgradeable { - /** - * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`. - * - * Note that some additional user `data` and `operatorData` can be logged in the event. - */ - event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); - - /** - * @dev Emitted when `operator` destroys `amount` tokens from `account`. - * - * Note that some additional user `data` and `operatorData` can be logged in the event. - */ - event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); - - /** - * @dev Emitted when `operator` is made operator for `tokenHolder`. - */ - event AuthorizedOperator(address indexed operator, address indexed tokenHolder); - - /** - * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`. - */ - event RevokedOperator(address indexed operator, address indexed tokenHolder); - - /** - * @dev Returns the name of the token. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the smallest part of the token that is not divisible. This - * means all token operations (creation, movement and destruction) must have - * amounts that are a multiple of this number. - * - * For most token contracts, this value will equal 1. - */ - function granularity() external view returns (uint256); - - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by an account (`owner`). - */ - function balanceOf(address owner) external view returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `recipient`. - * - * If send or receive hooks are registered for the caller and `recipient`, - * the corresponding functions will be called with `data` and empty - * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. - * - * Emits a {Sent} event. - * - * Requirements - * - * - the caller must have at least `amount` tokens. - * - `recipient` cannot be the zero address. - * - if `recipient` is a contract, it must implement the {IERC777Recipient} - * interface. - */ - function send( - address recipient, - uint256 amount, - bytes calldata data - ) external; - - /** - * @dev Destroys `amount` tokens from the caller's account, reducing the - * total supply. - * - * If a send hook is registered for the caller, the corresponding function - * will be called with `data` and empty `operatorData`. See {IERC777Sender}. - * - * Emits a {Burned} event. - * - * Requirements - * - * - the caller must have at least `amount` tokens. - */ - function burn(uint256 amount, bytes calldata data) external; - - /** - * @dev Returns true if an account is an operator of `tokenHolder`. - * Operators can send and burn tokens on behalf of their owners. All - * accounts are their own operator. - * - * See {operatorSend} and {operatorBurn}. - */ - function isOperatorFor(address operator, address tokenHolder) external view returns (bool); - - /** - * @dev Make an account an operator of the caller. - * - * See {isOperatorFor}. - * - * Emits an {AuthorizedOperator} event. - * - * Requirements - * - * - `operator` cannot be calling address. - */ - function authorizeOperator(address operator) external; - - /** - * @dev Revoke an account's operator status for the caller. - * - * See {isOperatorFor} and {defaultOperators}. - * - * Emits a {RevokedOperator} event. - * - * Requirements - * - * - `operator` cannot be calling address. - */ - function revokeOperator(address operator) external; - - /** - * @dev Returns the list of default operators. These accounts are operators - * for all token holders, even if {authorizeOperator} was never called on - * them. - * - * This list is immutable, but individual holders may revoke these via - * {revokeOperator}, in which case {isOperatorFor} will return false. - */ - function defaultOperators() external view returns (address[] memory); - - /** - * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must - * be an operator of `sender`. - * - * If send or receive hooks are registered for `sender` and `recipient`, - * the corresponding functions will be called with `data` and - * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. - * - * Emits a {Sent} event. - * - * Requirements - * - * - `sender` cannot be the zero address. - * - `sender` must have at least `amount` tokens. - * - the caller must be an operator for `sender`. - * - `recipient` cannot be the zero address. - * - if `recipient` is a contract, it must implement the {IERC777Recipient} - * interface. - */ - function operatorSend( - address sender, - address recipient, - uint256 amount, - bytes calldata data, - bytes calldata operatorData - ) external; - - /** - * @dev Destroys `amount` tokens from `account`, reducing the total supply. - * The caller must be an operator of `account`. - * - * If a send hook is registered for `account`, the corresponding function - * will be called with `data` and `operatorData`. See {IERC777Sender}. - * - * Emits a {Burned} event. - * - * Requirements - * - * - `account` cannot be the zero address. - * - `account` must have at least `amount` tokens. - * - the caller must be an operator for `account`. - */ - function operatorBurn( - address account, - uint256 amount, - bytes calldata data, - bytes calldata operatorData - ) external; - - event Sent( - address indexed operator, - address indexed from, - address indexed to, - uint256 amount, - bytes data, - bytes operatorData - ); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/README.adoc deleted file mode 100644 index 5012a31..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/README.adoc +++ /dev/null @@ -1,30 +0,0 @@ -= ERC 777 - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc777 - -This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-777[ERC777 token standard]. - -TIP: For an overview of ERC777 tokens and a walk through on how to create a token contract read our xref:ROOT:erc777.adoc[ERC777 guide]. - -The token behavior itself is implemented in the core contracts: {IERC777}, {ERC777}. - -Additionally there are interfaces used to develop contracts that react to token movements: {IERC777Sender}, {IERC777Recipient}. - -== Core - -{{IERC777}} - -{{ERC777}} - -== Hooks - -{{IERC777Sender}} - -{{IERC777Recipient}} - -== Presets - -These contracts are preconfigured combinations of features. They can be used through inheritance or as models to copy and paste their source code. - -{{ERC777PresetFixedSupply}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/presets/ERC777PresetFixedSupplyUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/presets/ERC777PresetFixedSupplyUpgradeable.sol deleted file mode 100644 index 1f10f10..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/ERC777/presets/ERC777PresetFixedSupplyUpgradeable.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC777/presets/ERC777PresetFixedSupply.sol) -pragma solidity ^0.8.0; - -import "../ERC777Upgradeable.sol"; -import "../../../proxy/utils/Initializable.sol"; - -/** - * @dev {ERC777} token, including: - * - * - Preminted initial supply - * - No access control mechanism (for minting/pausing) and hence no governance - * - * _Available since v3.4._ - */ -contract ERC777PresetFixedSupplyUpgradeable is Initializable, ERC777Upgradeable { - function initialize( - string memory name, - string memory symbol, - address[] memory defaultOperators, - uint256 initialSupply, - address owner - ) public virtual initializer { - __ERC777PresetFixedSupply_init(name, symbol, defaultOperators, initialSupply, owner); - } - /** - * @dev Mints `initialSupply` amount of token and transfers them to `owner`. - * - * See {ERC777-constructor}. - */ - function __ERC777PresetFixedSupply_init( - string memory name, - string memory symbol, - address[] memory defaultOperators, - uint256 initialSupply, - address owner - ) internal onlyInitializing { - __ERC777_init_unchained(name, symbol, defaultOperators); - __ERC777PresetFixedSupply_init_unchained(name, symbol, defaultOperators, initialSupply, owner); - } - - function __ERC777PresetFixedSupply_init_unchained( - string memory, - string memory, - address[] memory, - uint256 initialSupply, - address owner - ) internal onlyInitializing { - _mint(owner, initialSupply, "", ""); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/common/ERC2981Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/common/ERC2981Upgradeable.sol deleted file mode 100644 index 12ef990..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/common/ERC2981Upgradeable.sol +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) - -pragma solidity ^0.8.0; - -import "../../interfaces/IERC2981Upgradeable.sol"; -import "../../utils/introspection/ERC165Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. - * - * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for - * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. - * - * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the - * fee is specified in basis points by default. - * - * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See - * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to - * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. - * - * _Available since v4.5._ - */ -abstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable { - function __ERC2981_init() internal onlyInitializing { - } - - function __ERC2981_init_unchained() internal onlyInitializing { - } - struct RoyaltyInfo { - address receiver; - uint96 royaltyFraction; - } - - RoyaltyInfo private _defaultRoyaltyInfo; - mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) { - return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @inheritdoc IERC2981Upgradeable - */ - function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { - RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; - - if (royalty.receiver == address(0)) { - royalty = _defaultRoyaltyInfo; - } - - uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); - - return (royalty.receiver, royaltyAmount); - } - - /** - * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a - * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an - * override. - */ - function _feeDenominator() internal pure virtual returns (uint96) { - return 10000; - } - - /** - * @dev Sets the royalty information that all ids in this contract will default to. - * - * Requirements: - * - * - `receiver` cannot be the zero address. - * - `feeNumerator` cannot be greater than the fee denominator. - */ - function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { - require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); - require(receiver != address(0), "ERC2981: invalid receiver"); - - _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); - } - - /** - * @dev Removes default royalty information. - */ - function _deleteDefaultRoyalty() internal virtual { - delete _defaultRoyaltyInfo; - } - - /** - * @dev Sets the royalty information for a specific token id, overriding the global default. - * - * Requirements: - * - * - `receiver` cannot be the zero address. - * - `feeNumerator` cannot be greater than the fee denominator. - */ - function _setTokenRoyalty( - uint256 tokenId, - address receiver, - uint96 feeNumerator - ) internal virtual { - require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); - require(receiver != address(0), "ERC2981: Invalid parameters"); - - _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); - } - - /** - * @dev Resets royalty information for the token id back to the global default. - */ - function _resetTokenRoyalty(uint256 tokenId) internal virtual { - delete _tokenRoyaltyInfo[tokenId]; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[48] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/common/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/common/README.adoc deleted file mode 100644 index af61674..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/token/common/README.adoc +++ /dev/null @@ -1,10 +0,0 @@ -= Common (Tokens) - -Functionality that is common to multiple token standards. - -* {ERC2981}: NFT Royalties compatible with both ERC721 and ERC1155. -** For ERC721 consider {ERC721Royalty} which clears the royalty information from storage on burn. - -== Contracts - -{{ERC2981}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol deleted file mode 100644 index 203c05f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol +++ /dev/null @@ -1,219 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) - -pragma solidity ^0.8.1; - -/** - * @dev Collection of functions related to the address type - */ -library AddressUpgradeable { - /** - * @dev Returns true if `account` is a contract. - * - * [IMPORTANT] - * ==== - * It is unsafe to assume that an address for which this function returns - * false is an externally-owned account (EOA) and not a contract. - * - * Among others, `isContract` will return false for the following - * types of addresses: - * - * - an externally-owned account - * - a contract in construction - * - an address where a contract will be created - * - an address where a contract lived, but was destroyed - * ==== - * - * [IMPORTANT] - * ==== - * You shouldn't rely on `isContract` to protect against flash loan attacks! - * - * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets - * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract - * constructor. - * ==== - */ - function isContract(address account) internal view returns (bool) { - // This method relies on extcodesize/address.code.length, which returns 0 - // for contracts in construction, since the code is only stored at the end - // of the constructor execution. - - return account.code.length > 0; - } - - /** - * @dev Replacement for Solidity's `transfer`: sends `amount` wei to - * `recipient`, forwarding all available gas and reverting on errors. - * - * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost - * of certain opcodes, possibly making contracts go over the 2300 gas limit - * imposed by `transfer`, making them unable to receive funds via - * `transfer`. {sendValue} removes this limitation. - * - * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. - * - * IMPORTANT: because control is transferred to `recipient`, care must be - * taken to not create reentrancy vulnerabilities. Consider using - * {ReentrancyGuard} or the - * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. - */ - function sendValue(address payable recipient, uint256 amount) internal { - require(address(this).balance >= amount, "Address: insufficient balance"); - - (bool success, ) = recipient.call{value: amount}(""); - require(success, "Address: unable to send value, recipient may have reverted"); - } - - /** - * @dev Performs a Solidity function call using a low level `call`. A - * plain `call` is an unsafe replacement for a function call: use this - * function instead. - * - * If `target` reverts with a revert reason, it is bubbled up by this - * function (like regular Solidity function calls). - * - * Returns the raw returned data. To convert to the expected return value, - * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. - * - * Requirements: - * - * - `target` must be a contract. - * - calling `target` with `data` must not revert. - * - * _Available since v3.1._ - */ - function functionCall(address target, bytes memory data) internal returns (bytes memory) { - return functionCallWithValue(target, data, 0, "Address: low-level call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with - * `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCall( - address target, - bytes memory data, - string memory errorMessage - ) internal returns (bytes memory) { - return functionCallWithValue(target, data, 0, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but also transferring `value` wei to `target`. - * - * Requirements: - * - * - the calling contract must have an ETH balance of at least `value`. - * - the called Solidity function must be `payable`. - * - * _Available since v3.1._ - */ - function functionCallWithValue( - address target, - bytes memory data, - uint256 value - ) internal returns (bytes memory) { - return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); - } - - /** - * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but - * with `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCallWithValue( - address target, - bytes memory data, - uint256 value, - string memory errorMessage - ) internal returns (bytes memory) { - require(address(this).balance >= value, "Address: insufficient balance for call"); - (bool success, bytes memory returndata) = target.call{value: value}(data); - return verifyCallResultFromTarget(target, success, returndata, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but performing a static call. - * - * _Available since v3.3._ - */ - function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { - return functionStaticCall(target, data, "Address: low-level static call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], - * but performing a static call. - * - * _Available since v3.3._ - */ - function functionStaticCall( - address target, - bytes memory data, - string memory errorMessage - ) internal view returns (bytes memory) { - (bool success, bytes memory returndata) = target.staticcall(data); - return verifyCallResultFromTarget(target, success, returndata, errorMessage); - } - - /** - * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling - * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. - * - * _Available since v4.8._ - */ - function verifyCallResultFromTarget( - address target, - bool success, - bytes memory returndata, - string memory errorMessage - ) internal view returns (bytes memory) { - if (success) { - if (returndata.length == 0) { - // only check isContract if the call was successful and the return data is empty - // otherwise we already know that it was a contract - require(isContract(target), "Address: call to non-contract"); - } - return returndata; - } else { - _revert(returndata, errorMessage); - } - } - - /** - * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the - * revert reason or using the provided one. - * - * _Available since v4.3._ - */ - function verifyCallResult( - bool success, - bytes memory returndata, - string memory errorMessage - ) internal pure returns (bytes memory) { - if (success) { - return returndata; - } else { - _revert(returndata, errorMessage); - } - } - - function _revert(bytes memory returndata, string memory errorMessage) private pure { - // Look for revert reason and bubble it up if present - if (returndata.length > 0) { - // The easiest way to bubble the revert reason is using memory via assembly - /// @solidity memory-safe-assembly - assembly { - let returndata_size := mload(returndata) - revert(add(32, returndata), returndata_size) - } - } else { - revert(errorMessage); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ArraysUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ArraysUpgradeable.sol deleted file mode 100644 index 96a3bb2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ArraysUpgradeable.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/Arrays.sol) - -pragma solidity ^0.8.0; - -import "./StorageSlotUpgradeable.sol"; -import "./math/MathUpgradeable.sol"; - -/** - * @dev Collection of functions related to array types. - */ -library ArraysUpgradeable { - using StorageSlotUpgradeable for bytes32; - - /** - * @dev Searches a sorted `array` and returns the first index that contains - * a value greater or equal to `element`. If no such index exists (i.e. all - * values in the array are strictly less than `element`), the array length is - * returned. Time complexity O(log n). - * - * `array` is expected to be sorted in ascending order, and to contain no - * repeated elements. - */ - function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { - if (array.length == 0) { - return 0; - } - - uint256 low = 0; - uint256 high = array.length; - - while (low < high) { - uint256 mid = MathUpgradeable.average(low, high); - - // Note that mid will always be strictly less than high (i.e. it will be a valid array index) - // because Math.average rounds down (it does integer division with truncation). - if (unsafeAccess(array, mid).value > element) { - high = mid; - } else { - low = mid + 1; - } - } - - // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. - if (low > 0 && unsafeAccess(array, low - 1).value == element) { - return low - 1; - } else { - return low; - } - } - - /** - * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check. - * - * WARNING: Only use if you are certain `pos` is lower than the array length. - */ - function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlotUpgradeable.AddressSlot storage) { - bytes32 slot; - /// @solidity memory-safe-assembly - assembly { - mstore(0, arr.slot) - slot := add(keccak256(0, 0x20), pos) - } - return slot.getAddressSlot(); - } - - /** - * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check. - * - * WARNING: Only use if you are certain `pos` is lower than the array length. - */ - function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlotUpgradeable.Bytes32Slot storage) { - bytes32 slot; - /// @solidity memory-safe-assembly - assembly { - mstore(0, arr.slot) - slot := add(keccak256(0, 0x20), pos) - } - return slot.getBytes32Slot(); - } - - /** - * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check. - * - * WARNING: Only use if you are certain `pos` is lower than the array length. - */ - function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlotUpgradeable.Uint256Slot storage) { - bytes32 slot; - /// @solidity memory-safe-assembly - assembly { - mstore(0, arr.slot) - slot := add(keccak256(0, 0x20), pos) - } - return slot.getUint256Slot(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/Base64Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/Base64Upgradeable.sol deleted file mode 100644 index 1ca0a0b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/Base64Upgradeable.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Provides a set of functions to operate with Base64 strings. - * - * _Available since v4.5._ - */ -library Base64Upgradeable { - /** - * @dev Base64 Encoding/Decoding Table - */ - string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - /** - * @dev Converts a `bytes` to its Bytes64 `string` representation. - */ - function encode(bytes memory data) internal pure returns (string memory) { - /** - * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence - * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol - */ - if (data.length == 0) return ""; - - // Loads the table into memory - string memory table = _TABLE; - - // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter - // and split into 4 numbers of 6 bits. - // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up - // - `data.length + 2` -> Round up - // - `/ 3` -> Number of 3-bytes chunks - // - `4 *` -> 4 characters for each chunk - string memory result = new string(4 * ((data.length + 2) / 3)); - - /// @solidity memory-safe-assembly - assembly { - // Prepare the lookup table (skip the first "length" byte) - let tablePtr := add(table, 1) - - // Prepare result pointer, jump over length - let resultPtr := add(result, 32) - - // Run over the input, 3 bytes at a time - for { - let dataPtr := data - let endPtr := add(data, mload(data)) - } lt(dataPtr, endPtr) { - - } { - // Advance 3 bytes - dataPtr := add(dataPtr, 3) - let input := mload(dataPtr) - - // To write each character, shift the 3 bytes (18 bits) chunk - // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) - // and apply logical AND with 0x3F which is the number of - // the previous character in the ASCII table prior to the Base64 Table - // The result is then added to the table to get the character to write, - // and finally write it in the result pointer but with a left shift - // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits - - mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) - resultPtr := add(resultPtr, 1) // Advance - - mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) - resultPtr := add(resultPtr, 1) // Advance - - mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) - resultPtr := add(resultPtr, 1) // Advance - - mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) - resultPtr := add(resultPtr, 1) // Advance - } - - // When data `bytes` is not exactly 3 bytes long - // it is padded with `=` characters at the end - switch mod(mload(data), 3) - case 1 { - mstore8(sub(resultPtr, 1), 0x3d) - mstore8(sub(resultPtr, 2), 0x3d) - } - case 2 { - mstore8(sub(resultPtr, 1), 0x3d) - } - } - - return result; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/CheckpointsUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/CheckpointsUpgradeable.sol deleted file mode 100644 index 7b1f3cb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/CheckpointsUpgradeable.sol +++ /dev/null @@ -1,554 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.1) (utils/Checkpoints.sol) -// This file was procedurally generated from scripts/generate/templates/Checkpoints.js. - -pragma solidity ^0.8.0; - -import "./math/MathUpgradeable.sol"; -import "./math/SafeCastUpgradeable.sol"; - -/** - * @dev This library defines the `History` struct, for checkpointing values as they change at different points in - * time, and later looking up past values by block number. See {Votes} as an example. - * - * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new - * checkpoint for the current transaction block using the {push} function. - * - * _Available since v4.5._ - */ -library CheckpointsUpgradeable { - struct History { - Checkpoint[] _checkpoints; - } - - struct Checkpoint { - uint32 _blockNumber; - uint224 _value; - } - - /** - * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one - * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the - * block, the requested block number must be in the past, excluding the current block. - */ - function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { - require(blockNumber < block.number, "Checkpoints: block not yet mined"); - uint32 key = SafeCastUpgradeable.toUint32(blockNumber); - - uint256 len = self._checkpoints.length; - uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); - return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; - } - - /** - * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one - * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched - * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of - * checkpoints. - */ - function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { - require(blockNumber < block.number, "Checkpoints: block not yet mined"); - uint32 key = SafeCastUpgradeable.toUint32(blockNumber); - - uint256 len = self._checkpoints.length; - - uint256 low = 0; - uint256 high = len; - - if (len > 5) { - uint256 mid = len - MathUpgradeable.sqrt(len); - if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) { - high = mid; - } else { - low = mid + 1; - } - } - - uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); - - return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; - } - - /** - * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block. - * - * Returns previous value and new value. - */ - function push(History storage self, uint256 value) internal returns (uint256, uint256) { - return _insert(self._checkpoints, SafeCastUpgradeable.toUint32(block.number), SafeCastUpgradeable.toUint224(value)); - } - - /** - * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will - * be set to `op(latest, delta)`. - * - * Returns previous value and new value. - */ - function push( - History storage self, - function(uint256, uint256) view returns (uint256) op, - uint256 delta - ) internal returns (uint256, uint256) { - return push(self, op(latest(self), delta)); - } - - /** - * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. - */ - function latest(History storage self) internal view returns (uint224) { - uint256 pos = self._checkpoints.length; - return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; - } - - /** - * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value - * in the most recent checkpoint. - */ - function latestCheckpoint(History storage self) - internal - view - returns ( - bool exists, - uint32 _blockNumber, - uint224 _value - ) - { - uint256 pos = self._checkpoints.length; - if (pos == 0) { - return (false, 0, 0); - } else { - Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); - return (true, ckpt._blockNumber, ckpt._value); - } - } - - /** - * @dev Returns the number of checkpoint. - */ - function length(History storage self) internal view returns (uint256) { - return self._checkpoints.length; - } - - /** - * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, - * or by updating the last one. - */ - function _insert( - Checkpoint[] storage self, - uint32 key, - uint224 value - ) private returns (uint224, uint224) { - uint256 pos = self.length; - - if (pos > 0) { - // Copying to memory is important here. - Checkpoint memory last = _unsafeAccess(self, pos - 1); - - // Checkpoints keys must be increasing. - require(last._blockNumber <= key, "Checkpoint: invalid key"); - - // Update or push new checkpoint - if (last._blockNumber == key) { - _unsafeAccess(self, pos - 1)._value = value; - } else { - self.push(Checkpoint({_blockNumber: key, _value: value})); - } - return (last._value, value); - } else { - self.push(Checkpoint({_blockNumber: key, _value: value})); - return (0, value); - } - } - - /** - * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none. - * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. - * - * WARNING: `high` should not be greater than the array's length. - */ - function _upperBinaryLookup( - Checkpoint[] storage self, - uint32 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = MathUpgradeable.average(low, high); - if (_unsafeAccess(self, mid)._blockNumber > key) { - high = mid; - } else { - low = mid + 1; - } - } - return high; - } - - /** - * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none. - * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. - * - * WARNING: `high` should not be greater than the array's length. - */ - function _lowerBinaryLookup( - Checkpoint[] storage self, - uint32 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = MathUpgradeable.average(low, high); - if (_unsafeAccess(self, mid)._blockNumber < key) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - - /** - * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. - */ - function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) { - assembly { - mstore(0, self.slot) - result.slot := add(keccak256(0, 0x20), pos) - } - } - - struct Trace224 { - Checkpoint224[] _checkpoints; - } - - struct Checkpoint224 { - uint32 _key; - uint224 _value; - } - - /** - * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint. - * - * Returns previous value and new value. - */ - function push( - Trace224 storage self, - uint32 key, - uint224 value - ) internal returns (uint224, uint224) { - return _insert(self._checkpoints, key, value); - } - - /** - * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none. - */ - function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { - uint256 len = self._checkpoints.length; - uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); - return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; - } - - /** - * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key. - */ - function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { - uint256 len = self._checkpoints.length; - uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); - return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; - } - - /** - * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. - */ - function latest(Trace224 storage self) internal view returns (uint224) { - uint256 pos = self._checkpoints.length; - return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; - } - - /** - * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value - * in the most recent checkpoint. - */ - function latestCheckpoint(Trace224 storage self) - internal - view - returns ( - bool exists, - uint32 _key, - uint224 _value - ) - { - uint256 pos = self._checkpoints.length; - if (pos == 0) { - return (false, 0, 0); - } else { - Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); - return (true, ckpt._key, ckpt._value); - } - } - - /** - * @dev Returns the number of checkpoint. - */ - function length(Trace224 storage self) internal view returns (uint256) { - return self._checkpoints.length; - } - - /** - * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, - * or by updating the last one. - */ - function _insert( - Checkpoint224[] storage self, - uint32 key, - uint224 value - ) private returns (uint224, uint224) { - uint256 pos = self.length; - - if (pos > 0) { - // Copying to memory is important here. - Checkpoint224 memory last = _unsafeAccess(self, pos - 1); - - // Checkpoints keys must be increasing. - require(last._key <= key, "Checkpoint: invalid key"); - - // Update or push new checkpoint - if (last._key == key) { - _unsafeAccess(self, pos - 1)._value = value; - } else { - self.push(Checkpoint224({_key: key, _value: value})); - } - return (last._value, value); - } else { - self.push(Checkpoint224({_key: key, _value: value})); - return (0, value); - } - } - - /** - * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none. - * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. - * - * WARNING: `high` should not be greater than the array's length. - */ - function _upperBinaryLookup( - Checkpoint224[] storage self, - uint32 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = MathUpgradeable.average(low, high); - if (_unsafeAccess(self, mid)._key > key) { - high = mid; - } else { - low = mid + 1; - } - } - return high; - } - - /** - * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none. - * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. - * - * WARNING: `high` should not be greater than the array's length. - */ - function _lowerBinaryLookup( - Checkpoint224[] storage self, - uint32 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = MathUpgradeable.average(low, high); - if (_unsafeAccess(self, mid)._key < key) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - - /** - * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. - */ - function _unsafeAccess(Checkpoint224[] storage self, uint256 pos) - private - pure - returns (Checkpoint224 storage result) - { - assembly { - mstore(0, self.slot) - result.slot := add(keccak256(0, 0x20), pos) - } - } - - struct Trace160 { - Checkpoint160[] _checkpoints; - } - - struct Checkpoint160 { - uint96 _key; - uint160 _value; - } - - /** - * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint. - * - * Returns previous value and new value. - */ - function push( - Trace160 storage self, - uint96 key, - uint160 value - ) internal returns (uint160, uint160) { - return _insert(self._checkpoints, key, value); - } - - /** - * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none. - */ - function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { - uint256 len = self._checkpoints.length; - uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); - return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; - } - - /** - * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key. - */ - function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { - uint256 len = self._checkpoints.length; - uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); - return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; - } - - /** - * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. - */ - function latest(Trace160 storage self) internal view returns (uint160) { - uint256 pos = self._checkpoints.length; - return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; - } - - /** - * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value - * in the most recent checkpoint. - */ - function latestCheckpoint(Trace160 storage self) - internal - view - returns ( - bool exists, - uint96 _key, - uint160 _value - ) - { - uint256 pos = self._checkpoints.length; - if (pos == 0) { - return (false, 0, 0); - } else { - Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); - return (true, ckpt._key, ckpt._value); - } - } - - /** - * @dev Returns the number of checkpoint. - */ - function length(Trace160 storage self) internal view returns (uint256) { - return self._checkpoints.length; - } - - /** - * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, - * or by updating the last one. - */ - function _insert( - Checkpoint160[] storage self, - uint96 key, - uint160 value - ) private returns (uint160, uint160) { - uint256 pos = self.length; - - if (pos > 0) { - // Copying to memory is important here. - Checkpoint160 memory last = _unsafeAccess(self, pos - 1); - - // Checkpoints keys must be increasing. - require(last._key <= key, "Checkpoint: invalid key"); - - // Update or push new checkpoint - if (last._key == key) { - _unsafeAccess(self, pos - 1)._value = value; - } else { - self.push(Checkpoint160({_key: key, _value: value})); - } - return (last._value, value); - } else { - self.push(Checkpoint160({_key: key, _value: value})); - return (0, value); - } - } - - /** - * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none. - * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. - * - * WARNING: `high` should not be greater than the array's length. - */ - function _upperBinaryLookup( - Checkpoint160[] storage self, - uint96 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = MathUpgradeable.average(low, high); - if (_unsafeAccess(self, mid)._key > key) { - high = mid; - } else { - low = mid + 1; - } - } - return high; - } - - /** - * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none. - * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. - * - * WARNING: `high` should not be greater than the array's length. - */ - function _lowerBinaryLookup( - Checkpoint160[] storage self, - uint96 key, - uint256 low, - uint256 high - ) private view returns (uint256) { - while (low < high) { - uint256 mid = MathUpgradeable.average(low, high); - if (_unsafeAccess(self, mid)._key < key) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - - /** - * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. - */ - function _unsafeAccess(Checkpoint160[] storage self, uint256 pos) - private - pure - returns (Checkpoint160 storage result) - { - assembly { - mstore(0, self.slot) - result.slot := add(keccak256(0, 0x20), pos) - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol deleted file mode 100644 index 481064e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Context.sol) - -pragma solidity ^0.8.0; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Provides information about the current execution context, including the - * sender of the transaction and its data. While these are generally available - * via msg.sender and msg.data, they should not be accessed in such a direct - * manner, since when dealing with meta-transactions the account sending and - * paying for execution may not be the actual sender (as far as an application - * is concerned). - * - * This contract is only required for intermediate, library-like contracts. - */ -abstract contract ContextUpgradeable is Initializable { - function __Context_init() internal onlyInitializing { - } - - function __Context_init_unchained() internal onlyInitializing { - } - function _msgSender() internal view virtual returns (address) { - return msg.sender; - } - - function _msgData() internal view virtual returns (bytes calldata) { - return msg.data; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/CountersUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/CountersUpgradeable.sol deleted file mode 100644 index cfe7e90..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/CountersUpgradeable.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) - -pragma solidity ^0.8.0; - -/** - * @title Counters - * @author Matt Condon (@shrugs) - * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number - * of elements in a mapping, issuing ERC721 ids, or counting request ids. - * - * Include with `using Counters for Counters.Counter;` - */ -library CountersUpgradeable { - struct Counter { - // This variable should never be directly accessed by users of the library: interactions must be restricted to - // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add - // this feature: see https://github.com/ethereum/solidity/issues/4637 - uint256 _value; // default: 0 - } - - function current(Counter storage counter) internal view returns (uint256) { - return counter._value; - } - - function increment(Counter storage counter) internal { - unchecked { - counter._value += 1; - } - } - - function decrement(Counter storage counter) internal { - uint256 value = counter._value; - require(value > 0, "Counter: decrement overflow"); - unchecked { - counter._value = value - 1; - } - } - - function reset(Counter storage counter) internal { - counter._value = 0; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/Create2Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/Create2Upgradeable.sol deleted file mode 100644 index c9ee385..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/Create2Upgradeable.sol +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/Create2.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. - * `CREATE2` can be used to compute in advance the address where a smart - * contract will be deployed, which allows for interesting new mechanisms known - * as 'counterfactual interactions'. - * - * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more - * information. - */ -library Create2Upgradeable { - /** - * @dev Deploys a contract using `CREATE2`. The address where the contract - * will be deployed can be known in advance via {computeAddress}. - * - * The bytecode for a contract can be obtained from Solidity with - * `type(contractName).creationCode`. - * - * Requirements: - * - * - `bytecode` must not be empty. - * - `salt` must have not been used for `bytecode` already. - * - the factory must have a balance of at least `amount`. - * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. - */ - function deploy( - uint256 amount, - bytes32 salt, - bytes memory bytecode - ) internal returns (address addr) { - require(address(this).balance >= amount, "Create2: insufficient balance"); - require(bytecode.length != 0, "Create2: bytecode length is zero"); - /// @solidity memory-safe-assembly - assembly { - addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) - } - require(addr != address(0), "Create2: Failed on deploy"); - } - - /** - * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the - * `bytecodeHash` or `salt` will result in a new destination address. - */ - function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { - return computeAddress(salt, bytecodeHash, address(this)); - } - - /** - * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at - * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. - */ - function computeAddress( - bytes32 salt, - bytes32 bytecodeHash, - address deployer - ) internal pure returns (address addr) { - /// @solidity memory-safe-assembly - assembly { - let ptr := mload(0x40) // Get free memory pointer - - // | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... | - // |-------------------|---------------------------------------------------------------------------| - // | bytecodeHash | CCCCCCCCCCCCC...CC | - // | salt | BBBBBBBBBBBBB...BB | - // | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA | - // | 0xFF | FF | - // |-------------------|---------------------------------------------------------------------------| - // | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC | - // | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ | - - mstore(add(ptr, 0x40), bytecodeHash) - mstore(add(ptr, 0x20), salt) - mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes - let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff - mstore8(start, 0xff) - addr := keccak256(start, 85) - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol deleted file mode 100644 index bbdde89..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/MulticallUpgradeable.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (utils/Multicall.sol) - -pragma solidity ^0.8.0; - -import "./AddressUpgradeable.sol"; -import "../proxy/utils/Initializable.sol"; - -/** - * @dev Provides a function to batch together multiple calls in a single external call. - * - * _Available since v4.1._ - */ -abstract contract MulticallUpgradeable is Initializable { - function __Multicall_init() internal onlyInitializing { - } - - function __Multicall_init_unchained() internal onlyInitializing { - } - /** - * @dev Receives and executes a batch of function calls on this contract. - */ - function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) { - results = new bytes[](data.length); - for (uint256 i = 0; i < data.length; i++) { - results[i] = _functionDelegateCall(address(this), data[i]); - } - return results; - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], - * but performing a delegate call. - * - * _Available since v3.4._ - */ - function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { - require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); - - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory returndata) = target.delegatecall(data); - return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/README.adoc deleted file mode 100644 index 7fef825..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/README.adoc +++ /dev/null @@ -1,111 +0,0 @@ -= Utilities - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/utils - -Miscellaneous contracts and libraries containing utility functions you can use to improve security, work with new data types, or safely use low-level primitives. - -The {Address}, {Arrays}, {Base64} and {Strings} libraries provide more operations related to these native data types, while {SafeCast} adds ways to safely convert between the different signed and unsigned numeric types. -{Multicall} provides a function to batch together multiple calls in a single external call. - -For new data types: - - * {Counters}: a simple way to get a counter that can only be incremented, decremented or reset. Very useful for ID generation, counting contract activity, among others. - * {EnumerableMap}: like Solidity's https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] type, but with key-value _enumeration_: this will let you know how many entries a mapping has, and iterate over them (which is not possible with `mapping`). - * {EnumerableSet}: like {EnumerableMap}, but for https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets]. Can be used to store privileged accounts, issued IDs, etc. - -[NOTE] -==== -Because Solidity does not support generic types, {EnumerableMap} and {EnumerableSet} are specialized to a limited number of key-value types. - -As of v3.0, {EnumerableMap} supports `uint256 -> address` (`UintToAddressMap`), and {EnumerableSet} supports `address` and `uint256` (`AddressSet` and `UintSet`). -==== - -Finally, {Create2} contains all necessary utilities to safely use the https://blog.openzeppelin.com/getting-the-most-out-of-create2/[`CREATE2` EVM opcode], without having to deal with low-level assembly. - -== Math - -{{Math}} - -{{SignedMath}} - -{{SafeCast}} - -{{SafeMath}} - -{{SignedSafeMath}} - -== Cryptography - -{{ECDSA}} - -{{SignatureChecker}} - -{{MerkleProof}} - -{{EIP712}} - -== Escrow - -{{ConditionalEscrow}} - -{{Escrow}} - -{{RefundEscrow}} - -== Introspection - -This set of interfaces and contracts deal with https://en.wikipedia.org/wiki/Type_introspection[type introspection] of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_. - -Ethereum contracts have no native concept of an interface, so applications must usually simply trust they are not making an incorrect call. For trusted setups this is a non-issue, but often unknown and untrusted third-party addresses need to be interacted with. There may even not be any direct calls to them! (e.g. `ERC20` tokens may be sent to a contract that lacks a way to transfer them out of it, locking them forever). In these cases, a contract _declaring_ its interface can be very helpful in preventing errors. - -There are two main ways to approach this. - -* Locally, where a contract implements `IERC165` and declares an interface, and a second one queries it directly via `ERC165Checker`. -* Globally, where a global and unique registry (`IERC1820Registry`) is used to register implementers of a certain interface (`IERC1820Implementer`). It is then the registry that is queried, which allows for more complex setups, like contracts implementing interfaces for externally-owned accounts. - -Note that, in all cases, accounts simply _declare_ their interfaces, but they are not required to actually implement them. This mechanism can therefore be used to both prevent errors and allow for complex interactions (see `ERC777`), but it must not be relied on for security. - -{{IERC165}} - -{{ERC165}} - -{{ERC165Storage}} - -{{ERC165Checker}} - -{{IERC1820Registry}} - -{{IERC1820Implementer}} - -{{ERC1820Implementer}} - -== Data Structures - -{{BitMaps}} - -{{EnumerableMap}} - -{{EnumerableSet}} - -{{DoubleEndedQueue}} - -{{Checkpoints}} - -== Libraries - -{{Create2}} - -{{Address}} - -{{Arrays}} - -{{Base64}} - -{{Counters}} - -{{Strings}} - -{{StorageSlot}} - -{{Multicall}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/StorageSlotUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/StorageSlotUpgradeable.sol deleted file mode 100644 index d95ae3c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/StorageSlotUpgradeable.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Library for reading and writing primitive types to specific storage slots. - * - * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. - * This library helps with reading and writing to such slots without the need for inline assembly. - * - * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. - * - * Example usage to set ERC1967 implementation slot: - * ``` - * contract ERC1967 { - * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - * - * function _getImplementation() internal view returns (address) { - * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; - * } - * - * function _setImplementation(address newImplementation) internal { - * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); - * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; - * } - * } - * ``` - * - * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ - */ -library StorageSlotUpgradeable { - struct AddressSlot { - address value; - } - - struct BooleanSlot { - bool value; - } - - struct Bytes32Slot { - bytes32 value; - } - - struct Uint256Slot { - uint256 value; - } - - /** - * @dev Returns an `AddressSlot` with member `value` located at `slot`. - */ - function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `BooleanSlot` with member `value` located at `slot`. - */ - function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. - */ - function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `Uint256Slot` with member `value` located at `slot`. - */ - function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol deleted file mode 100644 index f1598fc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/StringsUpgradeable.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) - -pragma solidity ^0.8.0; - -import "./math/MathUpgradeable.sol"; - -/** - * @dev String operations. - */ -library StringsUpgradeable { - bytes16 private constant _SYMBOLS = "0123456789abcdef"; - uint8 private constant _ADDRESS_LENGTH = 20; - - /** - * @dev Converts a `uint256` to its ASCII `string` decimal representation. - */ - function toString(uint256 value) internal pure returns (string memory) { - unchecked { - uint256 length = MathUpgradeable.log10(value) + 1; - string memory buffer = new string(length); - uint256 ptr; - /// @solidity memory-safe-assembly - assembly { - ptr := add(buffer, add(32, length)) - } - while (true) { - ptr--; - /// @solidity memory-safe-assembly - assembly { - mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) - } - value /= 10; - if (value == 0) break; - } - return buffer; - } - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. - */ - function toHexString(uint256 value) internal pure returns (string memory) { - unchecked { - return toHexString(value, MathUpgradeable.log256(value) + 1); - } - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. - */ - function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { - bytes memory buffer = new bytes(2 * length + 2); - buffer[0] = "0"; - buffer[1] = "x"; - for (uint256 i = 2 * length + 1; i > 1; --i) { - buffer[i] = _SYMBOLS[value & 0xf]; - value >>= 4; - } - require(value == 0, "Strings: hex length insufficient"); - return string(buffer); - } - - /** - * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. - */ - function toHexString(address addr) internal pure returns (string memory) { - return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/TimersUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/TimersUpgradeable.sol deleted file mode 100644 index e58325a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/TimersUpgradeable.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Timers.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Tooling for timepoints, timers and delays - */ -library TimersUpgradeable { - struct Timestamp { - uint64 _deadline; - } - - function getDeadline(Timestamp memory timer) internal pure returns (uint64) { - return timer._deadline; - } - - function setDeadline(Timestamp storage timer, uint64 timestamp) internal { - timer._deadline = timestamp; - } - - function reset(Timestamp storage timer) internal { - timer._deadline = 0; - } - - function isUnset(Timestamp memory timer) internal pure returns (bool) { - return timer._deadline == 0; - } - - function isStarted(Timestamp memory timer) internal pure returns (bool) { - return timer._deadline > 0; - } - - function isPending(Timestamp memory timer) internal view returns (bool) { - return timer._deadline > block.timestamp; - } - - function isExpired(Timestamp memory timer) internal view returns (bool) { - return isStarted(timer) && timer._deadline <= block.timestamp; - } - - struct BlockNumber { - uint64 _deadline; - } - - function getDeadline(BlockNumber memory timer) internal pure returns (uint64) { - return timer._deadline; - } - - function setDeadline(BlockNumber storage timer, uint64 timestamp) internal { - timer._deadline = timestamp; - } - - function reset(BlockNumber storage timer) internal { - timer._deadline = 0; - } - - function isUnset(BlockNumber memory timer) internal pure returns (bool) { - return timer._deadline == 0; - } - - function isStarted(BlockNumber memory timer) internal pure returns (bool) { - return timer._deadline > 0; - } - - function isPending(BlockNumber memory timer) internal view returns (bool) { - return timer._deadline > block.number; - } - - function isExpired(BlockNumber memory timer) internal view returns (bool) { - return isStarted(timer) && timer._deadline <= block.number; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/ECDSAUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/ECDSAUpgradeable.sol deleted file mode 100644 index c9be10d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/ECDSAUpgradeable.sol +++ /dev/null @@ -1,213 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) - -pragma solidity ^0.8.0; - -import "../StringsUpgradeable.sol"; - -/** - * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. - * - * These functions can be used to verify that a message was signed by the holder - * of the private keys of a given address. - */ -library ECDSAUpgradeable { - enum RecoverError { - NoError, - InvalidSignature, - InvalidSignatureLength, - InvalidSignatureS, - InvalidSignatureV // Deprecated in v4.8 - } - - function _throwError(RecoverError error) private pure { - if (error == RecoverError.NoError) { - return; // no error: do nothing - } else if (error == RecoverError.InvalidSignature) { - revert("ECDSA: invalid signature"); - } else if (error == RecoverError.InvalidSignatureLength) { - revert("ECDSA: invalid signature length"); - } else if (error == RecoverError.InvalidSignatureS) { - revert("ECDSA: invalid signature 's' value"); - } - } - - /** - * @dev Returns the address that signed a hashed message (`hash`) with - * `signature` or error string. This address can then be used for verification purposes. - * - * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: - * this function rejects them by requiring the `s` value to be in the lower - * half order, and the `v` value to be either 27 or 28. - * - * IMPORTANT: `hash` _must_ be the result of a hash operation for the - * verification to be secure: it is possible to craft signatures that - * recover to arbitrary addresses for non-hashed data. A safe way to ensure - * this is by receiving a hash of the original message (which may otherwise - * be too long), and then calling {toEthSignedMessageHash} on it. - * - * Documentation for signature generation: - * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] - * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] - * - * _Available since v4.3._ - */ - function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { - if (signature.length == 65) { - bytes32 r; - bytes32 s; - uint8 v; - // ecrecover takes the signature parameters, and the only way to get them - // currently is to use assembly. - /// @solidity memory-safe-assembly - assembly { - r := mload(add(signature, 0x20)) - s := mload(add(signature, 0x40)) - v := byte(0, mload(add(signature, 0x60))) - } - return tryRecover(hash, v, r, s); - } else { - return (address(0), RecoverError.InvalidSignatureLength); - } - } - - /** - * @dev Returns the address that signed a hashed message (`hash`) with - * `signature`. This address can then be used for verification purposes. - * - * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: - * this function rejects them by requiring the `s` value to be in the lower - * half order, and the `v` value to be either 27 or 28. - * - * IMPORTANT: `hash` _must_ be the result of a hash operation for the - * verification to be secure: it is possible to craft signatures that - * recover to arbitrary addresses for non-hashed data. A safe way to ensure - * this is by receiving a hash of the original message (which may otherwise - * be too long), and then calling {toEthSignedMessageHash} on it. - */ - function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { - (address recovered, RecoverError error) = tryRecover(hash, signature); - _throwError(error); - return recovered; - } - - /** - * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. - * - * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] - * - * _Available since v4.3._ - */ - function tryRecover( - bytes32 hash, - bytes32 r, - bytes32 vs - ) internal pure returns (address, RecoverError) { - bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); - uint8 v = uint8((uint256(vs) >> 255) + 27); - return tryRecover(hash, v, r, s); - } - - /** - * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. - * - * _Available since v4.2._ - */ - function recover( - bytes32 hash, - bytes32 r, - bytes32 vs - ) internal pure returns (address) { - (address recovered, RecoverError error) = tryRecover(hash, r, vs); - _throwError(error); - return recovered; - } - - /** - * @dev Overload of {ECDSA-tryRecover} that receives the `v`, - * `r` and `s` signature fields separately. - * - * _Available since v4.3._ - */ - function tryRecover( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) internal pure returns (address, RecoverError) { - // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature - // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines - // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most - // signatures from current libraries generate a unique signature with an s-value in the lower half order. - // - // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value - // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or - // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept - // these malleable signatures as well. - if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { - return (address(0), RecoverError.InvalidSignatureS); - } - - // If the signature is valid (and not malleable), return the signer address - address signer = ecrecover(hash, v, r, s); - if (signer == address(0)) { - return (address(0), RecoverError.InvalidSignature); - } - - return (signer, RecoverError.NoError); - } - - /** - * @dev Overload of {ECDSA-recover} that receives the `v`, - * `r` and `s` signature fields separately. - */ - function recover( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) internal pure returns (address) { - (address recovered, RecoverError error) = tryRecover(hash, v, r, s); - _throwError(error); - return recovered; - } - - /** - * @dev Returns an Ethereum Signed Message, created from a `hash`. This - * produces hash corresponding to the one signed with the - * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] - * JSON-RPC method as part of EIP-191. - * - * See {recover}. - */ - function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { - // 32 is the length in bytes of hash, - // enforced by the type signature above - return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); - } - - /** - * @dev Returns an Ethereum Signed Message, created from `s`. This - * produces hash corresponding to the one signed with the - * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] - * JSON-RPC method as part of EIP-191. - * - * See {recover}. - */ - function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { - return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s)); - } - - /** - * @dev Returns an Ethereum Signed Typed Data, created from a - * `domainSeparator` and a `structHash`. This produces hash corresponding - * to the one signed with the - * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] - * JSON-RPC method as part of EIP-712. - * - * See {recover}. - */ - function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { - return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol deleted file mode 100644 index df06656..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol) - -pragma solidity ^0.8.0; - -import "./ECDSAUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. - * - * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, - * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding - * they need in their contracts using a combination of `abi.encode` and `keccak256`. - * - * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding - * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA - * ({_hashTypedDataV4}). - * - * The implementation of the domain separator was designed to be as efficient as possible while still properly updating - * the chain id to protect against replay attacks on an eventual fork of the chain. - * - * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method - * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. - * - * _Available since v3.4._ - * - * @custom:storage-size 52 - */ -abstract contract EIP712Upgradeable is Initializable { - /* solhint-disable var-name-mixedcase */ - bytes32 private _HASHED_NAME; - bytes32 private _HASHED_VERSION; - bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - - /* solhint-enable var-name-mixedcase */ - - /** - * @dev Initializes the domain separator and parameter caches. - * - * The meaning of `name` and `version` is specified in - * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: - * - * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. - * - `version`: the current major version of the signing domain. - * - * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart - * contract upgrade]. - */ - function __EIP712_init(string memory name, string memory version) internal onlyInitializing { - __EIP712_init_unchained(name, version); - } - - function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing { - bytes32 hashedName = keccak256(bytes(name)); - bytes32 hashedVersion = keccak256(bytes(version)); - _HASHED_NAME = hashedName; - _HASHED_VERSION = hashedVersion; - } - - /** - * @dev Returns the domain separator for the current chain. - */ - function _domainSeparatorV4() internal view returns (bytes32) { - return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash()); - } - - function _buildDomainSeparator( - bytes32 typeHash, - bytes32 nameHash, - bytes32 versionHash - ) private view returns (bytes32) { - return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); - } - - /** - * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this - * function returns the hash of the fully encoded EIP712 message for this domain. - * - * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: - * - * ```solidity - * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( - * keccak256("Mail(address to,string contents)"), - * mailTo, - * keccak256(bytes(mailContents)) - * ))); - * address signer = ECDSA.recover(digest, signature); - * ``` - */ - function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { - return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash); - } - - /** - * @dev The hash of the name parameter for the EIP712 domain. - * - * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs - * are a concern. - */ - function _EIP712NameHash() internal virtual view returns (bytes32) { - return _HASHED_NAME; - } - - /** - * @dev The hash of the version parameter for the EIP712 domain. - * - * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs - * are a concern. - */ - function _EIP712VersionHash() internal virtual view returns (bytes32) { - return _HASHED_VERSION; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/MerkleProofUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/MerkleProofUpgradeable.sol deleted file mode 100644 index beb43e4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/MerkleProofUpgradeable.sol +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol) - -pragma solidity ^0.8.0; - -/** - * @dev These functions deal with verification of Merkle Tree proofs. - * - * The tree and the proofs can be generated using our - * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. - * You will find a quickstart guide in the readme. - * - * WARNING: You should avoid using leaf values that are 64 bytes long prior to - * hashing, or use a hash function other than keccak256 for hashing leaves. - * This is because the concatenation of a sorted pair of internal nodes in - * the merkle tree could be reinterpreted as a leaf value. - * OpenZeppelin's JavaScript library generates merkle trees that are safe - * against this attack out of the box. - */ -library MerkleProofUpgradeable { - /** - * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree - * defined by `root`. For this, a `proof` must be provided, containing - * sibling hashes on the branch from the leaf to the root of the tree. Each - * pair of leaves and each pair of pre-images are assumed to be sorted. - */ - function verify( - bytes32[] memory proof, - bytes32 root, - bytes32 leaf - ) internal pure returns (bool) { - return processProof(proof, leaf) == root; - } - - /** - * @dev Calldata version of {verify} - * - * _Available since v4.7._ - */ - function verifyCalldata( - bytes32[] calldata proof, - bytes32 root, - bytes32 leaf - ) internal pure returns (bool) { - return processProofCalldata(proof, leaf) == root; - } - - /** - * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up - * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt - * hash matches the root of the tree. When processing the proof, the pairs - * of leafs & pre-images are assumed to be sorted. - * - * _Available since v4.4._ - */ - function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = _hashPair(computedHash, proof[i]); - } - return computedHash; - } - - /** - * @dev Calldata version of {processProof} - * - * _Available since v4.7._ - */ - function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = _hashPair(computedHash, proof[i]); - } - return computedHash; - } - - /** - * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by - * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. - * - * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. - * - * _Available since v4.7._ - */ - function multiProofVerify( - bytes32[] memory proof, - bool[] memory proofFlags, - bytes32 root, - bytes32[] memory leaves - ) internal pure returns (bool) { - return processMultiProof(proof, proofFlags, leaves) == root; - } - - /** - * @dev Calldata version of {multiProofVerify} - * - * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. - * - * _Available since v4.7._ - */ - function multiProofVerifyCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32 root, - bytes32[] memory leaves - ) internal pure returns (bool) { - return processMultiProofCalldata(proof, proofFlags, leaves) == root; - } - - /** - * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction - * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another - * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false - * respectively. - * - * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree - * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the - * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). - * - * _Available since v4.7._ - */ - function processMultiProof( - bytes32[] memory proof, - bool[] memory proofFlags, - bytes32[] memory leaves - ) internal pure returns (bytes32 merkleRoot) { - // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by - // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the - // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of - // the merkle tree. - uint256 leavesLen = leaves.length; - uint256 totalHashes = proofFlags.length; - - // Check proof validity. - require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); - - // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using - // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". - bytes32[] memory hashes = new bytes32[](totalHashes); - uint256 leafPos = 0; - uint256 hashPos = 0; - uint256 proofPos = 0; - // At each step, we compute the next hash using two values: - // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we - // get the next hash. - // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the - // `proof` array. - for (uint256 i = 0; i < totalHashes; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; - hashes[i] = _hashPair(a, b); - } - - if (totalHashes > 0) { - return hashes[totalHashes - 1]; - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } - } - - /** - * @dev Calldata version of {processMultiProof}. - * - * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. - * - * _Available since v4.7._ - */ - function processMultiProofCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32[] memory leaves - ) internal pure returns (bytes32 merkleRoot) { - // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by - // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the - // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of - // the merkle tree. - uint256 leavesLen = leaves.length; - uint256 totalHashes = proofFlags.length; - - // Check proof validity. - require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); - - // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using - // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". - bytes32[] memory hashes = new bytes32[](totalHashes); - uint256 leafPos = 0; - uint256 hashPos = 0; - uint256 proofPos = 0; - // At each step, we compute the next hash using two values: - // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we - // get the next hash. - // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the - // `proof` array. - for (uint256 i = 0; i < totalHashes; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; - hashes[i] = _hashPair(a, b); - } - - if (totalHashes > 0) { - return hashes[totalHashes - 1]; - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } - } - - function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { - return a < b ? _efficientHash(a, b) : _efficientHash(b, a); - } - - function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, a) - mstore(0x20, b) - value := keccak256(0x00, 0x40) - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/SignatureCheckerUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/SignatureCheckerUpgradeable.sol deleted file mode 100644 index 6bcd547..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/SignatureCheckerUpgradeable.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/SignatureChecker.sol) - -pragma solidity ^0.8.0; - -import "./ECDSAUpgradeable.sol"; -import "../AddressUpgradeable.sol"; -import "../../interfaces/IERC1271Upgradeable.sol"; - -/** - * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA - * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like - * Argent and Gnosis Safe. - * - * _Available since v4.1._ - */ -library SignatureCheckerUpgradeable { - /** - * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the - * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`. - * - * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus - * change through time. It could return true at block N and false at block N+1 (or the opposite). - */ - function isValidSignatureNow( - address signer, - bytes32 hash, - bytes memory signature - ) internal view returns (bool) { - (address recovered, ECDSAUpgradeable.RecoverError error) = ECDSAUpgradeable.tryRecover(hash, signature); - if (error == ECDSAUpgradeable.RecoverError.NoError && recovered == signer) { - return true; - } - - (bool success, bytes memory result) = signer.staticcall( - abi.encodeWithSelector(IERC1271Upgradeable.isValidSignature.selector, hash, signature) - ); - return (success && - result.length == 32 && - abi.decode(result, (bytes32)) == bytes32(IERC1271Upgradeable.isValidSignature.selector)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/draft-EIP712Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/draft-EIP712Upgradeable.sol deleted file mode 100644 index 001c34e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/draft-EIP712Upgradeable.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/draft-EIP712.sol) - -pragma solidity ^0.8.0; - -// EIP-712 is Final as of 2022-08-11. This file is deprecated. - -import "./EIP712Upgradeable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/ConditionalEscrowUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/ConditionalEscrowUpgradeable.sol deleted file mode 100644 index 9c7e02b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/ConditionalEscrowUpgradeable.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/escrow/ConditionalEscrow.sol) - -pragma solidity ^0.8.0; - -import "./EscrowUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @title ConditionalEscrow - * @dev Base abstract escrow to only allow withdrawal if a condition is met. - * @dev Intended usage: See {Escrow}. Same usage guidelines apply here. - */ -abstract contract ConditionalEscrowUpgradeable is Initializable, EscrowUpgradeable { - function __ConditionalEscrow_init() internal onlyInitializing { - __Ownable_init_unchained(); - } - - function __ConditionalEscrow_init_unchained() internal onlyInitializing { - } - /** - * @dev Returns whether an address is allowed to withdraw their funds. To be - * implemented by derived contracts. - * @param payee The destination address of the funds. - */ - function withdrawalAllowed(address payee) public view virtual returns (bool); - - function withdraw(address payable payee) public virtual override { - require(withdrawalAllowed(payee), "ConditionalEscrow: payee is not allowed to withdraw"); - super.withdraw(payee); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/EscrowUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/EscrowUpgradeable.sol deleted file mode 100644 index 4174037..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/EscrowUpgradeable.sol +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/escrow/Escrow.sol) - -pragma solidity ^0.8.0; - -import "../../access/OwnableUpgradeable.sol"; -import "../AddressUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @title Escrow - * @dev Base escrow contract, holds funds designated for a payee until they - * withdraw them. - * - * Intended usage: This contract (and derived escrow contracts) should be a - * standalone contract, that only interacts with the contract that instantiated - * it. That way, it is guaranteed that all Ether will be handled according to - * the `Escrow` rules, and there is no need to check for payable functions or - * transfers in the inheritance tree. The contract that uses the escrow as its - * payment method should be its owner, and provide public methods redirecting - * to the escrow's deposit and withdraw. - */ -contract EscrowUpgradeable is Initializable, OwnableUpgradeable { - function __Escrow_init() internal onlyInitializing { - __Ownable_init_unchained(); - } - - function __Escrow_init_unchained() internal onlyInitializing { - } - function initialize() public virtual initializer { - __Escrow_init(); - } - using AddressUpgradeable for address payable; - - event Deposited(address indexed payee, uint256 weiAmount); - event Withdrawn(address indexed payee, uint256 weiAmount); - - mapping(address => uint256) private _deposits; - - function depositsOf(address payee) public view returns (uint256) { - return _deposits[payee]; - } - - /** - * @dev Stores the sent amount as credit to be withdrawn. - * @param payee The destination address of the funds. - * - * Emits a {Deposited} event. - */ - function deposit(address payee) public payable virtual onlyOwner { - uint256 amount = msg.value; - _deposits[payee] += amount; - emit Deposited(payee, amount); - } - - /** - * @dev Withdraw accumulated balance for a payee, forwarding all gas to the - * recipient. - * - * WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities. - * Make sure you trust the recipient, or are either following the - * checks-effects-interactions pattern or using {ReentrancyGuard}. - * - * @param payee The address whose funds will be withdrawn and transferred to. - * - * Emits a {Withdrawn} event. - */ - function withdraw(address payable payee) public virtual onlyOwner { - uint256 payment = _deposits[payee]; - - _deposits[payee] = 0; - - payee.sendValue(payment); - - emit Withdrawn(payee, payment); - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/RefundEscrowUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/RefundEscrowUpgradeable.sol deleted file mode 100644 index f2bb794..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/escrow/RefundEscrowUpgradeable.sol +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/escrow/RefundEscrow.sol) - -pragma solidity ^0.8.0; - -import "./ConditionalEscrowUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @title RefundEscrow - * @dev Escrow that holds funds for a beneficiary, deposited from multiple - * parties. - * @dev Intended usage: See {Escrow}. Same usage guidelines apply here. - * @dev The owner account (that is, the contract that instantiates this - * contract) may deposit, close the deposit period, and allow for either - * withdrawal by the beneficiary, or refunds to the depositors. All interactions - * with `RefundEscrow` will be made through the owner contract. - */ -contract RefundEscrowUpgradeable is Initializable, ConditionalEscrowUpgradeable { - using AddressUpgradeable for address payable; - - enum State { - Active, - Refunding, - Closed - } - - event RefundsClosed(); - event RefundsEnabled(); - - State private _state; - address payable private _beneficiary; - - /** - * @dev Constructor. - * @param beneficiary_ The beneficiary of the deposits. - */ - function __RefundEscrow_init(address payable beneficiary_) internal onlyInitializing { - __Ownable_init_unchained(); - __RefundEscrow_init_unchained(beneficiary_); - } - - function __RefundEscrow_init_unchained(address payable beneficiary_) internal onlyInitializing { - require(beneficiary_ != address(0), "RefundEscrow: beneficiary is the zero address"); - _beneficiary = beneficiary_; - _state = State.Active; - } - - /** - * @return The current state of the escrow. - */ - function state() public view virtual returns (State) { - return _state; - } - - /** - * @return The beneficiary of the escrow. - */ - function beneficiary() public view virtual returns (address payable) { - return _beneficiary; - } - - /** - * @dev Stores funds that may later be refunded. - * @param refundee The address funds will be sent to if a refund occurs. - */ - function deposit(address refundee) public payable virtual override { - require(state() == State.Active, "RefundEscrow: can only deposit while active"); - super.deposit(refundee); - } - - /** - * @dev Allows for the beneficiary to withdraw their funds, rejecting - * further deposits. - */ - function close() public virtual onlyOwner { - require(state() == State.Active, "RefundEscrow: can only close while active"); - _state = State.Closed; - emit RefundsClosed(); - } - - /** - * @dev Allows for refunds to take place, rejecting further deposits. - */ - function enableRefunds() public virtual onlyOwner { - require(state() == State.Active, "RefundEscrow: can only enable refunds while active"); - _state = State.Refunding; - emit RefundsEnabled(); - } - - /** - * @dev Withdraws the beneficiary's funds. - */ - function beneficiaryWithdraw() public virtual { - require(state() == State.Closed, "RefundEscrow: beneficiary can only withdraw while closed"); - beneficiary().sendValue(address(this).balance); - } - - /** - * @dev Returns whether refundees can withdraw their deposits (be refunded). The overridden function receives a - * 'payee' argument, but we ignore it here since the condition is global, not per-payee. - */ - function withdrawalAllowed(address) public view override returns (bool) { - return state() == State.Refunding; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165CheckerUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165CheckerUpgradeable.sol deleted file mode 100644 index 93870ae..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165CheckerUpgradeable.sol +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.2) (utils/introspection/ERC165Checker.sol) - -pragma solidity ^0.8.0; - -import "./IERC165Upgradeable.sol"; - -/** - * @dev Library used to query support of an interface declared via {IERC165}. - * - * Note that these functions return the actual result of the query: they do not - * `revert` if an interface is not supported. It is up to the caller to decide - * what to do in these cases. - */ -library ERC165CheckerUpgradeable { - // As per the EIP-165 spec, no interface should ever match 0xffffffff - bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; - - /** - * @dev Returns true if `account` supports the {IERC165} interface. - */ - function supportsERC165(address account) internal view returns (bool) { - // Any contract that implements ERC165 must explicitly indicate support of - // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid - return - supportsERC165InterfaceUnchecked(account, type(IERC165Upgradeable).interfaceId) && - !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID); - } - - /** - * @dev Returns true if `account` supports the interface defined by - * `interfaceId`. Support for {IERC165} itself is queried automatically. - * - * See {IERC165-supportsInterface}. - */ - function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { - // query support of both ERC165 as per the spec and support of _interfaceId - return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); - } - - /** - * @dev Returns a boolean array where each value corresponds to the - * interfaces passed in and whether they're supported or not. This allows - * you to batch check interfaces for a contract where your expectation - * is that some interfaces may not be supported. - * - * See {IERC165-supportsInterface}. - * - * _Available since v3.4._ - */ - function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) - internal - view - returns (bool[] memory) - { - // an array of booleans corresponding to interfaceIds and whether they're supported or not - bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); - - // query support of ERC165 itself - if (supportsERC165(account)) { - // query support of each interface in interfaceIds - for (uint256 i = 0; i < interfaceIds.length; i++) { - interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); - } - } - - return interfaceIdsSupported; - } - - /** - * @dev Returns true if `account` supports all the interfaces defined in - * `interfaceIds`. Support for {IERC165} itself is queried automatically. - * - * Batch-querying can lead to gas savings by skipping repeated checks for - * {IERC165} support. - * - * See {IERC165-supportsInterface}. - */ - function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { - // query support of ERC165 itself - if (!supportsERC165(account)) { - return false; - } - - // query support of each interface in interfaceIds - for (uint256 i = 0; i < interfaceIds.length; i++) { - if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { - return false; - } - } - - // all interfaces supported - return true; - } - - /** - * @notice Query if a contract implements an interface, does not check ERC165 support - * @param account The address of the contract to query for support of an interface - * @param interfaceId The interface identifier, as specified in ERC-165 - * @return true if the contract at account indicates support of the interface with - * identifier interfaceId, false otherwise - * @dev Assumes that account contains a contract that supports ERC165, otherwise - * the behavior of this method is undefined. This precondition can be checked - * with {supportsERC165}. - * - * Some precompiled contracts will falsely indicate support for a given interface, so caution - * should be exercised when using this function. - * - * Interface identification is specified in ERC-165. - */ - function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { - // prepare call - bytes memory encodedParams = abi.encodeWithSelector(IERC165Upgradeable.supportsInterface.selector, interfaceId); - - // perform static call - bool success; - uint256 returnSize; - uint256 returnValue; - assembly { - success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) - returnSize := returndatasize() - returnValue := mload(0x00) - } - - return success && returnSize >= 0x20 && returnValue > 0; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165StorageUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165StorageUpgradeable.sol deleted file mode 100644 index 549e646..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165StorageUpgradeable.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol) - -pragma solidity ^0.8.0; - -import "./ERC165Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Storage based implementation of the {IERC165} interface. - * - * Contracts may inherit from this and call {_registerInterface} to declare - * their support of an interface. - */ -abstract contract ERC165StorageUpgradeable is Initializable, ERC165Upgradeable { - function __ERC165Storage_init() internal onlyInitializing { - } - - function __ERC165Storage_init_unchained() internal onlyInitializing { - } - /** - * @dev Mapping of interface ids to whether or not it's supported. - */ - mapping(bytes4 => bool) private _supportedInterfaces; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId]; - } - - /** - * @dev Registers the contract as an implementer of the interface defined by - * `interfaceId`. Support of the actual ERC165 interface is automatic and - * registering its interface id is not required. - * - * See {IERC165-supportsInterface}. - * - * Requirements: - * - * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). - */ - function _registerInterface(bytes4 interfaceId) internal virtual { - require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); - _supportedInterfaces[interfaceId] = true; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol deleted file mode 100644 index 90158f0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) - -pragma solidity ^0.8.0; - -import "./IERC165Upgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the {IERC165} interface. - * - * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check - * for the additional interface id that will be supported. For example: - * - * ```solidity - * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); - * } - * ``` - * - * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. - */ -abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { - function __ERC165_init() internal onlyInitializing { - } - - function __ERC165_init_unchained() internal onlyInitializing { - } - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IERC165Upgradeable).interfaceId; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC1820ImplementerUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC1820ImplementerUpgradeable.sol deleted file mode 100644 index a047452..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC1820ImplementerUpgradeable.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC1820Implementer.sol) - -pragma solidity ^0.8.0; - -import "./IERC1820ImplementerUpgradeable.sol"; -import "../../proxy/utils/Initializable.sol"; - -/** - * @dev Implementation of the {IERC1820Implementer} interface. - * - * Contracts may inherit from this and call {_registerInterfaceForAddress} to - * declare their willingness to be implementers. - * {IERC1820Registry-setInterfaceImplementer} should then be called for the - * registration to be complete. - */ -contract ERC1820ImplementerUpgradeable is Initializable, IERC1820ImplementerUpgradeable { - function __ERC1820Implementer_init() internal onlyInitializing { - } - - function __ERC1820Implementer_init_unchained() internal onlyInitializing { - } - bytes32 private constant _ERC1820_ACCEPT_MAGIC = keccak256("ERC1820_ACCEPT_MAGIC"); - - mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces; - - /** - * @dev See {IERC1820Implementer-canImplementInterfaceForAddress}. - */ - function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) - public - view - virtual - override - returns (bytes32) - { - return _supportedInterfaces[interfaceHash][account] ? _ERC1820_ACCEPT_MAGIC : bytes32(0x00); - } - - /** - * @dev Declares the contract as willing to be an implementer of - * `interfaceHash` for `account`. - * - * See {IERC1820Registry-setInterfaceImplementer} and - * {IERC1820Registry-interfaceHash}. - */ - function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal virtual { - _supportedInterfaces[interfaceHash][account] = true; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol deleted file mode 100644 index 26fc1d7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC165 standard, as defined in the - * https://eips.ethereum.org/EIPS/eip-165[EIP]. - * - * Implementers can declare support of contract interfaces, which can then be - * queried by others ({ERC165Checker}). - * - * For an implementation, see {ERC165}. - */ -interface IERC165Upgradeable { - /** - * @dev Returns true if this contract implements the interface defined by - * `interfaceId`. See the corresponding - * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] - * to learn more about how these ids are created. - * - * This function call must use less than 30 000 gas. - */ - function supportsInterface(bytes4 interfaceId) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820ImplementerUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820ImplementerUpgradeable.sol deleted file mode 100644 index 7a19d89..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820ImplementerUpgradeable.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC1820Implementer.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface for an ERC1820 implementer, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP]. - * Used by contracts that will be registered as implementers in the - * {IERC1820Registry}. - */ -interface IERC1820ImplementerUpgradeable { - /** - * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract - * implements `interfaceHash` for `account`. - * - * See {IERC1820Registry-setInterfaceImplementer}. - */ - function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820RegistryUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820RegistryUpgradeable.sol deleted file mode 100644 index e7f7541..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC1820RegistryUpgradeable.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/introspection/IERC1820Registry.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the global ERC1820 Registry, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register - * implementers for interfaces in this registry, as well as query support. - * - * Implementers may be shared by multiple accounts, and can also implement more - * than a single interface for each account. Contracts can implement interfaces - * for themselves, but externally-owned accounts (EOA) must delegate this to a - * contract. - * - * {IERC165} interfaces can also be queried via the registry. - * - * For an in-depth explanation and source code analysis, see the EIP text. - */ -interface IERC1820RegistryUpgradeable { - event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); - - event ManagerChanged(address indexed account, address indexed newManager); - - /** - * @dev Sets `newManager` as the manager for `account`. A manager of an - * account is able to set interface implementers for it. - * - * By default, each account is its own manager. Passing a value of `0x0` in - * `newManager` will reset the manager to this initial state. - * - * Emits a {ManagerChanged} event. - * - * Requirements: - * - * - the caller must be the current manager for `account`. - */ - function setManager(address account, address newManager) external; - - /** - * @dev Returns the manager for `account`. - * - * See {setManager}. - */ - function getManager(address account) external view returns (address); - - /** - * @dev Sets the `implementer` contract as ``account``'s implementer for - * `interfaceHash`. - * - * `account` being the zero address is an alias for the caller's address. - * The zero address can also be used in `implementer` to remove an old one. - * - * See {interfaceHash} to learn how these are created. - * - * Emits an {InterfaceImplementerSet} event. - * - * Requirements: - * - * - the caller must be the current manager for `account`. - * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not - * end in 28 zeroes). - * - `implementer` must implement {IERC1820Implementer} and return true when - * queried for support, unless `implementer` is the caller. See - * {IERC1820Implementer-canImplementInterfaceForAddress}. - */ - function setInterfaceImplementer( - address account, - bytes32 _interfaceHash, - address implementer - ) external; - - /** - * @dev Returns the implementer of `interfaceHash` for `account`. If no such - * implementer is registered, returns the zero address. - * - * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 - * zeroes), `account` will be queried for support of it. - * - * `account` being the zero address is an alias for the caller's address. - */ - function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); - - /** - * @dev Returns the interface hash for an `interfaceName`, as defined in the - * corresponding - * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. - */ - function interfaceHash(string calldata interfaceName) external pure returns (bytes32); - - /** - * @notice Updates the cache with whether the contract implements an ERC165 interface or not. - * @param account Address of the contract for which to update the cache. - * @param interfaceId ERC165 interface for which to update the cache. - */ - function updateERC165Cache(address account, bytes4 interfaceId) external; - - /** - * @notice Checks whether a contract implements an ERC165 interface or not. - * If the result is not cached a direct lookup on the contract address is performed. - * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling - * {updateERC165Cache} with the contract address. - * @param account Address of the contract to check. - * @param interfaceId ERC165 interface to check. - * @return True if `account` implements `interfaceId`, false otherwise. - */ - function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); - - /** - * @notice Checks whether a contract implements an ERC165 interface or not without using or updating the cache. - * @param account Address of the contract to check. - * @param interfaceId ERC165 interface to check. - * @return True if `account` implements `interfaceId`, false otherwise. - */ - function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/MathUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/MathUpgradeable.sol deleted file mode 100644 index cbef41e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/MathUpgradeable.sol +++ /dev/null @@ -1,345 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Standard math utilities missing in the Solidity language. - */ -library MathUpgradeable { - enum Rounding { - Down, // Toward negative infinity - Up, // Toward infinity - Zero // Toward zero - } - - /** - * @dev Returns the largest of two numbers. - */ - function max(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? a : b; - } - - /** - * @dev Returns the smallest of two numbers. - */ - function min(uint256 a, uint256 b) internal pure returns (uint256) { - return a < b ? a : b; - } - - /** - * @dev Returns the average of two numbers. The result is rounded towards - * zero. - */ - function average(uint256 a, uint256 b) internal pure returns (uint256) { - // (a + b) / 2 can overflow. - return (a & b) + (a ^ b) / 2; - } - - /** - * @dev Returns the ceiling of the division of two numbers. - * - * This differs from standard division with `/` in that it rounds up instead - * of rounding down. - */ - function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { - // (a + b - 1) / b can overflow on addition, so we distribute. - return a == 0 ? 0 : (a - 1) / b + 1; - } - - /** - * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 - * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) - * with further edits by Uniswap Labs also under MIT license. - */ - function mulDiv( - uint256 x, - uint256 y, - uint256 denominator - ) internal pure returns (uint256 result) { - unchecked { - // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use - // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 - // variables such that product = prod1 * 2^256 + prod0. - uint256 prod0; // Least significant 256 bits of the product - uint256 prod1; // Most significant 256 bits of the product - assembly { - let mm := mulmod(x, y, not(0)) - prod0 := mul(x, y) - prod1 := sub(sub(mm, prod0), lt(mm, prod0)) - } - - // Handle non-overflow cases, 256 by 256 division. - if (prod1 == 0) { - return prod0 / denominator; - } - - // Make sure the result is less than 2^256. Also prevents denominator == 0. - require(denominator > prod1); - - /////////////////////////////////////////////// - // 512 by 256 division. - /////////////////////////////////////////////// - - // Make division exact by subtracting the remainder from [prod1 prod0]. - uint256 remainder; - assembly { - // Compute remainder using mulmod. - remainder := mulmod(x, y, denominator) - - // Subtract 256 bit number from 512 bit number. - prod1 := sub(prod1, gt(remainder, prod0)) - prod0 := sub(prod0, remainder) - } - - // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. - // See https://cs.stackexchange.com/q/138556/92363. - - // Does not overflow because the denominator cannot be zero at this stage in the function. - uint256 twos = denominator & (~denominator + 1); - assembly { - // Divide denominator by twos. - denominator := div(denominator, twos) - - // Divide [prod1 prod0] by twos. - prod0 := div(prod0, twos) - - // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. - twos := add(div(sub(0, twos), twos), 1) - } - - // Shift in bits from prod1 into prod0. - prod0 |= prod1 * twos; - - // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such - // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for - // four bits. That is, denominator * inv = 1 mod 2^4. - uint256 inverse = (3 * denominator) ^ 2; - - // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works - // in modular arithmetic, doubling the correct bits in each step. - inverse *= 2 - denominator * inverse; // inverse mod 2^8 - inverse *= 2 - denominator * inverse; // inverse mod 2^16 - inverse *= 2 - denominator * inverse; // inverse mod 2^32 - inverse *= 2 - denominator * inverse; // inverse mod 2^64 - inverse *= 2 - denominator * inverse; // inverse mod 2^128 - inverse *= 2 - denominator * inverse; // inverse mod 2^256 - - // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. - // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is - // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 - // is no longer required. - result = prod0 * inverse; - return result; - } - } - - /** - * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. - */ - function mulDiv( - uint256 x, - uint256 y, - uint256 denominator, - Rounding rounding - ) internal pure returns (uint256) { - uint256 result = mulDiv(x, y, denominator); - if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { - result += 1; - } - return result; - } - - /** - * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. - * - * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). - */ - function sqrt(uint256 a) internal pure returns (uint256) { - if (a == 0) { - return 0; - } - - // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. - // - // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have - // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. - // - // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` - // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` - // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` - // - // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. - uint256 result = 1 << (log2(a) >> 1); - - // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, - // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at - // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision - // into the expected uint128 result. - unchecked { - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - return min(result, a / result); - } - } - - /** - * @notice Calculates sqrt(a), following the selected rounding direction. - */ - function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { - unchecked { - uint256 result = sqrt(a); - return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); - } - } - - /** - * @dev Return the log in base 2, rounded down, of a positive value. - * Returns 0 if given 0. - */ - function log2(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - unchecked { - if (value >> 128 > 0) { - value >>= 128; - result += 128; - } - if (value >> 64 > 0) { - value >>= 64; - result += 64; - } - if (value >> 32 > 0) { - value >>= 32; - result += 32; - } - if (value >> 16 > 0) { - value >>= 16; - result += 16; - } - if (value >> 8 > 0) { - value >>= 8; - result += 8; - } - if (value >> 4 > 0) { - value >>= 4; - result += 4; - } - if (value >> 2 > 0) { - value >>= 2; - result += 2; - } - if (value >> 1 > 0) { - result += 1; - } - } - return result; - } - - /** - * @dev Return the log in base 2, following the selected rounding direction, of a positive value. - * Returns 0 if given 0. - */ - function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { - unchecked { - uint256 result = log2(value); - return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); - } - } - - /** - * @dev Return the log in base 10, rounded down, of a positive value. - * Returns 0 if given 0. - */ - function log10(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - unchecked { - if (value >= 10**64) { - value /= 10**64; - result += 64; - } - if (value >= 10**32) { - value /= 10**32; - result += 32; - } - if (value >= 10**16) { - value /= 10**16; - result += 16; - } - if (value >= 10**8) { - value /= 10**8; - result += 8; - } - if (value >= 10**4) { - value /= 10**4; - result += 4; - } - if (value >= 10**2) { - value /= 10**2; - result += 2; - } - if (value >= 10**1) { - result += 1; - } - } - return result; - } - - /** - * @dev Return the log in base 10, following the selected rounding direction, of a positive value. - * Returns 0 if given 0. - */ - function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { - unchecked { - uint256 result = log10(value); - return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); - } - } - - /** - * @dev Return the log in base 256, rounded down, of a positive value. - * Returns 0 if given 0. - * - * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. - */ - function log256(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - unchecked { - if (value >> 128 > 0) { - value >>= 128; - result += 16; - } - if (value >> 64 > 0) { - value >>= 64; - result += 8; - } - if (value >> 32 > 0) { - value >>= 32; - result += 4; - } - if (value >> 16 > 0) { - value >>= 16; - result += 2; - } - if (value >> 8 > 0) { - result += 1; - } - } - return result; - } - - /** - * @dev Return the log in base 10, following the selected rounding direction, of a positive value. - * Returns 0 if given 0. - */ - function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { - unchecked { - uint256 result = log256(value); - return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeCastUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeCastUpgradeable.sol deleted file mode 100644 index 9b2db2a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeCastUpgradeable.sol +++ /dev/null @@ -1,1136 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) -// This file was procedurally generated from scripts/generate/templates/SafeCast.js. - -pragma solidity ^0.8.0; - -/** - * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow - * checks. - * - * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can - * easily result in undesired exploitation or bugs, since developers usually - * assume that overflows raise errors. `SafeCast` restores this intuition by - * reverting the transaction when such an operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - * - * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing - * all math on `uint256` and `int256` and then downcasting. - */ -library SafeCastUpgradeable { - /** - * @dev Returns the downcasted uint248 from uint256, reverting on - * overflow (when the input is greater than largest uint248). - * - * Counterpart to Solidity's `uint248` operator. - * - * Requirements: - * - * - input must fit into 248 bits - * - * _Available since v4.7._ - */ - function toUint248(uint256 value) internal pure returns (uint248) { - require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); - return uint248(value); - } - - /** - * @dev Returns the downcasted uint240 from uint256, reverting on - * overflow (when the input is greater than largest uint240). - * - * Counterpart to Solidity's `uint240` operator. - * - * Requirements: - * - * - input must fit into 240 bits - * - * _Available since v4.7._ - */ - function toUint240(uint256 value) internal pure returns (uint240) { - require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); - return uint240(value); - } - - /** - * @dev Returns the downcasted uint232 from uint256, reverting on - * overflow (when the input is greater than largest uint232). - * - * Counterpart to Solidity's `uint232` operator. - * - * Requirements: - * - * - input must fit into 232 bits - * - * _Available since v4.7._ - */ - function toUint232(uint256 value) internal pure returns (uint232) { - require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); - return uint232(value); - } - - /** - * @dev Returns the downcasted uint224 from uint256, reverting on - * overflow (when the input is greater than largest uint224). - * - * Counterpart to Solidity's `uint224` operator. - * - * Requirements: - * - * - input must fit into 224 bits - * - * _Available since v4.2._ - */ - function toUint224(uint256 value) internal pure returns (uint224) { - require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); - return uint224(value); - } - - /** - * @dev Returns the downcasted uint216 from uint256, reverting on - * overflow (when the input is greater than largest uint216). - * - * Counterpart to Solidity's `uint216` operator. - * - * Requirements: - * - * - input must fit into 216 bits - * - * _Available since v4.7._ - */ - function toUint216(uint256 value) internal pure returns (uint216) { - require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); - return uint216(value); - } - - /** - * @dev Returns the downcasted uint208 from uint256, reverting on - * overflow (when the input is greater than largest uint208). - * - * Counterpart to Solidity's `uint208` operator. - * - * Requirements: - * - * - input must fit into 208 bits - * - * _Available since v4.7._ - */ - function toUint208(uint256 value) internal pure returns (uint208) { - require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); - return uint208(value); - } - - /** - * @dev Returns the downcasted uint200 from uint256, reverting on - * overflow (when the input is greater than largest uint200). - * - * Counterpart to Solidity's `uint200` operator. - * - * Requirements: - * - * - input must fit into 200 bits - * - * _Available since v4.7._ - */ - function toUint200(uint256 value) internal pure returns (uint200) { - require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); - return uint200(value); - } - - /** - * @dev Returns the downcasted uint192 from uint256, reverting on - * overflow (when the input is greater than largest uint192). - * - * Counterpart to Solidity's `uint192` operator. - * - * Requirements: - * - * - input must fit into 192 bits - * - * _Available since v4.7._ - */ - function toUint192(uint256 value) internal pure returns (uint192) { - require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); - return uint192(value); - } - - /** - * @dev Returns the downcasted uint184 from uint256, reverting on - * overflow (when the input is greater than largest uint184). - * - * Counterpart to Solidity's `uint184` operator. - * - * Requirements: - * - * - input must fit into 184 bits - * - * _Available since v4.7._ - */ - function toUint184(uint256 value) internal pure returns (uint184) { - require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); - return uint184(value); - } - - /** - * @dev Returns the downcasted uint176 from uint256, reverting on - * overflow (when the input is greater than largest uint176). - * - * Counterpart to Solidity's `uint176` operator. - * - * Requirements: - * - * - input must fit into 176 bits - * - * _Available since v4.7._ - */ - function toUint176(uint256 value) internal pure returns (uint176) { - require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); - return uint176(value); - } - - /** - * @dev Returns the downcasted uint168 from uint256, reverting on - * overflow (when the input is greater than largest uint168). - * - * Counterpart to Solidity's `uint168` operator. - * - * Requirements: - * - * - input must fit into 168 bits - * - * _Available since v4.7._ - */ - function toUint168(uint256 value) internal pure returns (uint168) { - require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); - return uint168(value); - } - - /** - * @dev Returns the downcasted uint160 from uint256, reverting on - * overflow (when the input is greater than largest uint160). - * - * Counterpart to Solidity's `uint160` operator. - * - * Requirements: - * - * - input must fit into 160 bits - * - * _Available since v4.7._ - */ - function toUint160(uint256 value) internal pure returns (uint160) { - require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); - return uint160(value); - } - - /** - * @dev Returns the downcasted uint152 from uint256, reverting on - * overflow (when the input is greater than largest uint152). - * - * Counterpart to Solidity's `uint152` operator. - * - * Requirements: - * - * - input must fit into 152 bits - * - * _Available since v4.7._ - */ - function toUint152(uint256 value) internal pure returns (uint152) { - require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); - return uint152(value); - } - - /** - * @dev Returns the downcasted uint144 from uint256, reverting on - * overflow (when the input is greater than largest uint144). - * - * Counterpart to Solidity's `uint144` operator. - * - * Requirements: - * - * - input must fit into 144 bits - * - * _Available since v4.7._ - */ - function toUint144(uint256 value) internal pure returns (uint144) { - require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); - return uint144(value); - } - - /** - * @dev Returns the downcasted uint136 from uint256, reverting on - * overflow (when the input is greater than largest uint136). - * - * Counterpart to Solidity's `uint136` operator. - * - * Requirements: - * - * - input must fit into 136 bits - * - * _Available since v4.7._ - */ - function toUint136(uint256 value) internal pure returns (uint136) { - require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); - return uint136(value); - } - - /** - * @dev Returns the downcasted uint128 from uint256, reverting on - * overflow (when the input is greater than largest uint128). - * - * Counterpart to Solidity's `uint128` operator. - * - * Requirements: - * - * - input must fit into 128 bits - * - * _Available since v2.5._ - */ - function toUint128(uint256 value) internal pure returns (uint128) { - require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); - return uint128(value); - } - - /** - * @dev Returns the downcasted uint120 from uint256, reverting on - * overflow (when the input is greater than largest uint120). - * - * Counterpart to Solidity's `uint120` operator. - * - * Requirements: - * - * - input must fit into 120 bits - * - * _Available since v4.7._ - */ - function toUint120(uint256 value) internal pure returns (uint120) { - require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); - return uint120(value); - } - - /** - * @dev Returns the downcasted uint112 from uint256, reverting on - * overflow (when the input is greater than largest uint112). - * - * Counterpart to Solidity's `uint112` operator. - * - * Requirements: - * - * - input must fit into 112 bits - * - * _Available since v4.7._ - */ - function toUint112(uint256 value) internal pure returns (uint112) { - require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); - return uint112(value); - } - - /** - * @dev Returns the downcasted uint104 from uint256, reverting on - * overflow (when the input is greater than largest uint104). - * - * Counterpart to Solidity's `uint104` operator. - * - * Requirements: - * - * - input must fit into 104 bits - * - * _Available since v4.7._ - */ - function toUint104(uint256 value) internal pure returns (uint104) { - require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); - return uint104(value); - } - - /** - * @dev Returns the downcasted uint96 from uint256, reverting on - * overflow (when the input is greater than largest uint96). - * - * Counterpart to Solidity's `uint96` operator. - * - * Requirements: - * - * - input must fit into 96 bits - * - * _Available since v4.2._ - */ - function toUint96(uint256 value) internal pure returns (uint96) { - require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); - return uint96(value); - } - - /** - * @dev Returns the downcasted uint88 from uint256, reverting on - * overflow (when the input is greater than largest uint88). - * - * Counterpart to Solidity's `uint88` operator. - * - * Requirements: - * - * - input must fit into 88 bits - * - * _Available since v4.7._ - */ - function toUint88(uint256 value) internal pure returns (uint88) { - require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); - return uint88(value); - } - - /** - * @dev Returns the downcasted uint80 from uint256, reverting on - * overflow (when the input is greater than largest uint80). - * - * Counterpart to Solidity's `uint80` operator. - * - * Requirements: - * - * - input must fit into 80 bits - * - * _Available since v4.7._ - */ - function toUint80(uint256 value) internal pure returns (uint80) { - require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); - return uint80(value); - } - - /** - * @dev Returns the downcasted uint72 from uint256, reverting on - * overflow (when the input is greater than largest uint72). - * - * Counterpart to Solidity's `uint72` operator. - * - * Requirements: - * - * - input must fit into 72 bits - * - * _Available since v4.7._ - */ - function toUint72(uint256 value) internal pure returns (uint72) { - require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); - return uint72(value); - } - - /** - * @dev Returns the downcasted uint64 from uint256, reverting on - * overflow (when the input is greater than largest uint64). - * - * Counterpart to Solidity's `uint64` operator. - * - * Requirements: - * - * - input must fit into 64 bits - * - * _Available since v2.5._ - */ - function toUint64(uint256 value) internal pure returns (uint64) { - require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); - return uint64(value); - } - - /** - * @dev Returns the downcasted uint56 from uint256, reverting on - * overflow (when the input is greater than largest uint56). - * - * Counterpart to Solidity's `uint56` operator. - * - * Requirements: - * - * - input must fit into 56 bits - * - * _Available since v4.7._ - */ - function toUint56(uint256 value) internal pure returns (uint56) { - require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); - return uint56(value); - } - - /** - * @dev Returns the downcasted uint48 from uint256, reverting on - * overflow (when the input is greater than largest uint48). - * - * Counterpart to Solidity's `uint48` operator. - * - * Requirements: - * - * - input must fit into 48 bits - * - * _Available since v4.7._ - */ - function toUint48(uint256 value) internal pure returns (uint48) { - require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); - return uint48(value); - } - - /** - * @dev Returns the downcasted uint40 from uint256, reverting on - * overflow (when the input is greater than largest uint40). - * - * Counterpart to Solidity's `uint40` operator. - * - * Requirements: - * - * - input must fit into 40 bits - * - * _Available since v4.7._ - */ - function toUint40(uint256 value) internal pure returns (uint40) { - require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); - return uint40(value); - } - - /** - * @dev Returns the downcasted uint32 from uint256, reverting on - * overflow (when the input is greater than largest uint32). - * - * Counterpart to Solidity's `uint32` operator. - * - * Requirements: - * - * - input must fit into 32 bits - * - * _Available since v2.5._ - */ - function toUint32(uint256 value) internal pure returns (uint32) { - require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); - return uint32(value); - } - - /** - * @dev Returns the downcasted uint24 from uint256, reverting on - * overflow (when the input is greater than largest uint24). - * - * Counterpart to Solidity's `uint24` operator. - * - * Requirements: - * - * - input must fit into 24 bits - * - * _Available since v4.7._ - */ - function toUint24(uint256 value) internal pure returns (uint24) { - require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); - return uint24(value); - } - - /** - * @dev Returns the downcasted uint16 from uint256, reverting on - * overflow (when the input is greater than largest uint16). - * - * Counterpart to Solidity's `uint16` operator. - * - * Requirements: - * - * - input must fit into 16 bits - * - * _Available since v2.5._ - */ - function toUint16(uint256 value) internal pure returns (uint16) { - require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); - return uint16(value); - } - - /** - * @dev Returns the downcasted uint8 from uint256, reverting on - * overflow (when the input is greater than largest uint8). - * - * Counterpart to Solidity's `uint8` operator. - * - * Requirements: - * - * - input must fit into 8 bits - * - * _Available since v2.5._ - */ - function toUint8(uint256 value) internal pure returns (uint8) { - require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); - return uint8(value); - } - - /** - * @dev Converts a signed int256 into an unsigned uint256. - * - * Requirements: - * - * - input must be greater than or equal to 0. - * - * _Available since v3.0._ - */ - function toUint256(int256 value) internal pure returns (uint256) { - require(value >= 0, "SafeCast: value must be positive"); - return uint256(value); - } - - /** - * @dev Returns the downcasted int248 from int256, reverting on - * overflow (when the input is less than smallest int248 or - * greater than largest int248). - * - * Counterpart to Solidity's `int248` operator. - * - * Requirements: - * - * - input must fit into 248 bits - * - * _Available since v4.7._ - */ - function toInt248(int256 value) internal pure returns (int248 downcasted) { - downcasted = int248(value); - require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); - } - - /** - * @dev Returns the downcasted int240 from int256, reverting on - * overflow (when the input is less than smallest int240 or - * greater than largest int240). - * - * Counterpart to Solidity's `int240` operator. - * - * Requirements: - * - * - input must fit into 240 bits - * - * _Available since v4.7._ - */ - function toInt240(int256 value) internal pure returns (int240 downcasted) { - downcasted = int240(value); - require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); - } - - /** - * @dev Returns the downcasted int232 from int256, reverting on - * overflow (when the input is less than smallest int232 or - * greater than largest int232). - * - * Counterpart to Solidity's `int232` operator. - * - * Requirements: - * - * - input must fit into 232 bits - * - * _Available since v4.7._ - */ - function toInt232(int256 value) internal pure returns (int232 downcasted) { - downcasted = int232(value); - require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); - } - - /** - * @dev Returns the downcasted int224 from int256, reverting on - * overflow (when the input is less than smallest int224 or - * greater than largest int224). - * - * Counterpart to Solidity's `int224` operator. - * - * Requirements: - * - * - input must fit into 224 bits - * - * _Available since v4.7._ - */ - function toInt224(int256 value) internal pure returns (int224 downcasted) { - downcasted = int224(value); - require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); - } - - /** - * @dev Returns the downcasted int216 from int256, reverting on - * overflow (when the input is less than smallest int216 or - * greater than largest int216). - * - * Counterpart to Solidity's `int216` operator. - * - * Requirements: - * - * - input must fit into 216 bits - * - * _Available since v4.7._ - */ - function toInt216(int256 value) internal pure returns (int216 downcasted) { - downcasted = int216(value); - require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); - } - - /** - * @dev Returns the downcasted int208 from int256, reverting on - * overflow (when the input is less than smallest int208 or - * greater than largest int208). - * - * Counterpart to Solidity's `int208` operator. - * - * Requirements: - * - * - input must fit into 208 bits - * - * _Available since v4.7._ - */ - function toInt208(int256 value) internal pure returns (int208 downcasted) { - downcasted = int208(value); - require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); - } - - /** - * @dev Returns the downcasted int200 from int256, reverting on - * overflow (when the input is less than smallest int200 or - * greater than largest int200). - * - * Counterpart to Solidity's `int200` operator. - * - * Requirements: - * - * - input must fit into 200 bits - * - * _Available since v4.7._ - */ - function toInt200(int256 value) internal pure returns (int200 downcasted) { - downcasted = int200(value); - require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); - } - - /** - * @dev Returns the downcasted int192 from int256, reverting on - * overflow (when the input is less than smallest int192 or - * greater than largest int192). - * - * Counterpart to Solidity's `int192` operator. - * - * Requirements: - * - * - input must fit into 192 bits - * - * _Available since v4.7._ - */ - function toInt192(int256 value) internal pure returns (int192 downcasted) { - downcasted = int192(value); - require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); - } - - /** - * @dev Returns the downcasted int184 from int256, reverting on - * overflow (when the input is less than smallest int184 or - * greater than largest int184). - * - * Counterpart to Solidity's `int184` operator. - * - * Requirements: - * - * - input must fit into 184 bits - * - * _Available since v4.7._ - */ - function toInt184(int256 value) internal pure returns (int184 downcasted) { - downcasted = int184(value); - require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); - } - - /** - * @dev Returns the downcasted int176 from int256, reverting on - * overflow (when the input is less than smallest int176 or - * greater than largest int176). - * - * Counterpart to Solidity's `int176` operator. - * - * Requirements: - * - * - input must fit into 176 bits - * - * _Available since v4.7._ - */ - function toInt176(int256 value) internal pure returns (int176 downcasted) { - downcasted = int176(value); - require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); - } - - /** - * @dev Returns the downcasted int168 from int256, reverting on - * overflow (when the input is less than smallest int168 or - * greater than largest int168). - * - * Counterpart to Solidity's `int168` operator. - * - * Requirements: - * - * - input must fit into 168 bits - * - * _Available since v4.7._ - */ - function toInt168(int256 value) internal pure returns (int168 downcasted) { - downcasted = int168(value); - require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); - } - - /** - * @dev Returns the downcasted int160 from int256, reverting on - * overflow (when the input is less than smallest int160 or - * greater than largest int160). - * - * Counterpart to Solidity's `int160` operator. - * - * Requirements: - * - * - input must fit into 160 bits - * - * _Available since v4.7._ - */ - function toInt160(int256 value) internal pure returns (int160 downcasted) { - downcasted = int160(value); - require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); - } - - /** - * @dev Returns the downcasted int152 from int256, reverting on - * overflow (when the input is less than smallest int152 or - * greater than largest int152). - * - * Counterpart to Solidity's `int152` operator. - * - * Requirements: - * - * - input must fit into 152 bits - * - * _Available since v4.7._ - */ - function toInt152(int256 value) internal pure returns (int152 downcasted) { - downcasted = int152(value); - require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); - } - - /** - * @dev Returns the downcasted int144 from int256, reverting on - * overflow (when the input is less than smallest int144 or - * greater than largest int144). - * - * Counterpart to Solidity's `int144` operator. - * - * Requirements: - * - * - input must fit into 144 bits - * - * _Available since v4.7._ - */ - function toInt144(int256 value) internal pure returns (int144 downcasted) { - downcasted = int144(value); - require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); - } - - /** - * @dev Returns the downcasted int136 from int256, reverting on - * overflow (when the input is less than smallest int136 or - * greater than largest int136). - * - * Counterpart to Solidity's `int136` operator. - * - * Requirements: - * - * - input must fit into 136 bits - * - * _Available since v4.7._ - */ - function toInt136(int256 value) internal pure returns (int136 downcasted) { - downcasted = int136(value); - require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); - } - - /** - * @dev Returns the downcasted int128 from int256, reverting on - * overflow (when the input is less than smallest int128 or - * greater than largest int128). - * - * Counterpart to Solidity's `int128` operator. - * - * Requirements: - * - * - input must fit into 128 bits - * - * _Available since v3.1._ - */ - function toInt128(int256 value) internal pure returns (int128 downcasted) { - downcasted = int128(value); - require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); - } - - /** - * @dev Returns the downcasted int120 from int256, reverting on - * overflow (when the input is less than smallest int120 or - * greater than largest int120). - * - * Counterpart to Solidity's `int120` operator. - * - * Requirements: - * - * - input must fit into 120 bits - * - * _Available since v4.7._ - */ - function toInt120(int256 value) internal pure returns (int120 downcasted) { - downcasted = int120(value); - require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); - } - - /** - * @dev Returns the downcasted int112 from int256, reverting on - * overflow (when the input is less than smallest int112 or - * greater than largest int112). - * - * Counterpart to Solidity's `int112` operator. - * - * Requirements: - * - * - input must fit into 112 bits - * - * _Available since v4.7._ - */ - function toInt112(int256 value) internal pure returns (int112 downcasted) { - downcasted = int112(value); - require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); - } - - /** - * @dev Returns the downcasted int104 from int256, reverting on - * overflow (when the input is less than smallest int104 or - * greater than largest int104). - * - * Counterpart to Solidity's `int104` operator. - * - * Requirements: - * - * - input must fit into 104 bits - * - * _Available since v4.7._ - */ - function toInt104(int256 value) internal pure returns (int104 downcasted) { - downcasted = int104(value); - require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); - } - - /** - * @dev Returns the downcasted int96 from int256, reverting on - * overflow (when the input is less than smallest int96 or - * greater than largest int96). - * - * Counterpart to Solidity's `int96` operator. - * - * Requirements: - * - * - input must fit into 96 bits - * - * _Available since v4.7._ - */ - function toInt96(int256 value) internal pure returns (int96 downcasted) { - downcasted = int96(value); - require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); - } - - /** - * @dev Returns the downcasted int88 from int256, reverting on - * overflow (when the input is less than smallest int88 or - * greater than largest int88). - * - * Counterpart to Solidity's `int88` operator. - * - * Requirements: - * - * - input must fit into 88 bits - * - * _Available since v4.7._ - */ - function toInt88(int256 value) internal pure returns (int88 downcasted) { - downcasted = int88(value); - require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); - } - - /** - * @dev Returns the downcasted int80 from int256, reverting on - * overflow (when the input is less than smallest int80 or - * greater than largest int80). - * - * Counterpart to Solidity's `int80` operator. - * - * Requirements: - * - * - input must fit into 80 bits - * - * _Available since v4.7._ - */ - function toInt80(int256 value) internal pure returns (int80 downcasted) { - downcasted = int80(value); - require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); - } - - /** - * @dev Returns the downcasted int72 from int256, reverting on - * overflow (when the input is less than smallest int72 or - * greater than largest int72). - * - * Counterpart to Solidity's `int72` operator. - * - * Requirements: - * - * - input must fit into 72 bits - * - * _Available since v4.7._ - */ - function toInt72(int256 value) internal pure returns (int72 downcasted) { - downcasted = int72(value); - require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); - } - - /** - * @dev Returns the downcasted int64 from int256, reverting on - * overflow (when the input is less than smallest int64 or - * greater than largest int64). - * - * Counterpart to Solidity's `int64` operator. - * - * Requirements: - * - * - input must fit into 64 bits - * - * _Available since v3.1._ - */ - function toInt64(int256 value) internal pure returns (int64 downcasted) { - downcasted = int64(value); - require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); - } - - /** - * @dev Returns the downcasted int56 from int256, reverting on - * overflow (when the input is less than smallest int56 or - * greater than largest int56). - * - * Counterpart to Solidity's `int56` operator. - * - * Requirements: - * - * - input must fit into 56 bits - * - * _Available since v4.7._ - */ - function toInt56(int256 value) internal pure returns (int56 downcasted) { - downcasted = int56(value); - require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); - } - - /** - * @dev Returns the downcasted int48 from int256, reverting on - * overflow (when the input is less than smallest int48 or - * greater than largest int48). - * - * Counterpart to Solidity's `int48` operator. - * - * Requirements: - * - * - input must fit into 48 bits - * - * _Available since v4.7._ - */ - function toInt48(int256 value) internal pure returns (int48 downcasted) { - downcasted = int48(value); - require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); - } - - /** - * @dev Returns the downcasted int40 from int256, reverting on - * overflow (when the input is less than smallest int40 or - * greater than largest int40). - * - * Counterpart to Solidity's `int40` operator. - * - * Requirements: - * - * - input must fit into 40 bits - * - * _Available since v4.7._ - */ - function toInt40(int256 value) internal pure returns (int40 downcasted) { - downcasted = int40(value); - require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); - } - - /** - * @dev Returns the downcasted int32 from int256, reverting on - * overflow (when the input is less than smallest int32 or - * greater than largest int32). - * - * Counterpart to Solidity's `int32` operator. - * - * Requirements: - * - * - input must fit into 32 bits - * - * _Available since v3.1._ - */ - function toInt32(int256 value) internal pure returns (int32 downcasted) { - downcasted = int32(value); - require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); - } - - /** - * @dev Returns the downcasted int24 from int256, reverting on - * overflow (when the input is less than smallest int24 or - * greater than largest int24). - * - * Counterpart to Solidity's `int24` operator. - * - * Requirements: - * - * - input must fit into 24 bits - * - * _Available since v4.7._ - */ - function toInt24(int256 value) internal pure returns (int24 downcasted) { - downcasted = int24(value); - require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); - } - - /** - * @dev Returns the downcasted int16 from int256, reverting on - * overflow (when the input is less than smallest int16 or - * greater than largest int16). - * - * Counterpart to Solidity's `int16` operator. - * - * Requirements: - * - * - input must fit into 16 bits - * - * _Available since v3.1._ - */ - function toInt16(int256 value) internal pure returns (int16 downcasted) { - downcasted = int16(value); - require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); - } - - /** - * @dev Returns the downcasted int8 from int256, reverting on - * overflow (when the input is less than smallest int8 or - * greater than largest int8). - * - * Counterpart to Solidity's `int8` operator. - * - * Requirements: - * - * - input must fit into 8 bits - * - * _Available since v3.1._ - */ - function toInt8(int256 value) internal pure returns (int8 downcasted) { - downcasted = int8(value); - require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); - } - - /** - * @dev Converts an unsigned uint256 into a signed int256. - * - * Requirements: - * - * - input must be less than or equal to maxInt256. - * - * _Available since v3.0._ - */ - function toInt256(uint256 value) internal pure returns (int256) { - // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive - require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); - return int256(value); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeMathUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeMathUpgradeable.sol deleted file mode 100644 index a31ea2b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SafeMathUpgradeable.sol +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) - -pragma solidity ^0.8.0; - -// CAUTION -// This version of SafeMath should only be used with Solidity 0.8 or later, -// because it relies on the compiler's built in overflow checks. - -/** - * @dev Wrappers over Solidity's arithmetic operations. - * - * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler - * now has built in overflow checking. - */ -library SafeMathUpgradeable { - /** - * @dev Returns the addition of two unsigned integers, with an overflow flag. - * - * _Available since v3.4._ - */ - function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - uint256 c = a + b; - if (c < a) return (false, 0); - return (true, c); - } - } - - /** - * @dev Returns the subtraction of two unsigned integers, with an overflow flag. - * - * _Available since v3.4._ - */ - function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - if (b > a) return (false, 0); - return (true, a - b); - } - } - - /** - * @dev Returns the multiplication of two unsigned integers, with an overflow flag. - * - * _Available since v3.4._ - */ - function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) return (true, 0); - uint256 c = a * b; - if (c / a != b) return (false, 0); - return (true, c); - } - } - - /** - * @dev Returns the division of two unsigned integers, with a division by zero flag. - * - * _Available since v3.4._ - */ - function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - if (b == 0) return (false, 0); - return (true, a / b); - } - } - - /** - * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. - * - * _Available since v3.4._ - */ - function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - if (b == 0) return (false, 0); - return (true, a % b); - } - } - - /** - * @dev Returns the addition of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - return a + b; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return a - b; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - return a * b; - } - - /** - * @dev Returns the integer division of two unsigned integers, reverting on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return a / b; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * reverting when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return a % b; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on - * overflow (when the result is negative). - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {trySub}. - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { - unchecked { - require(b <= a, errorMessage); - return a - b; - } - } - - /** - * @dev Returns the integer division of two unsigned integers, reverting with custom message on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { - unchecked { - require(b > 0, errorMessage); - return a / b; - } - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * reverting with custom message when dividing by zero. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryMod}. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function mod( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { - unchecked { - require(b > 0, errorMessage); - return a % b; - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedMathUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedMathUpgradeable.sol deleted file mode 100644 index 122fcbc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedMathUpgradeable.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Standard signed math utilities missing in the Solidity language. - */ -library SignedMathUpgradeable { - /** - * @dev Returns the largest of two signed numbers. - */ - function max(int256 a, int256 b) internal pure returns (int256) { - return a > b ? a : b; - } - - /** - * @dev Returns the smallest of two signed numbers. - */ - function min(int256 a, int256 b) internal pure returns (int256) { - return a < b ? a : b; - } - - /** - * @dev Returns the average of two signed numbers without overflow. - * The result is rounded towards zero. - */ - function average(int256 a, int256 b) internal pure returns (int256) { - // Formula from the book "Hacker's Delight" - int256 x = (a & b) + ((a ^ b) >> 1); - return x + (int256(uint256(x) >> 255) & (a ^ b)); - } - - /** - * @dev Returns the absolute unsigned value of a signed value. - */ - function abs(int256 n) internal pure returns (uint256) { - unchecked { - // must be unchecked in order to support `n = type(int256).min` - return uint256(n >= 0 ? n : -n); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedSafeMathUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedSafeMathUpgradeable.sol deleted file mode 100644 index 4d9ee8b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/math/SignedSafeMathUpgradeable.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/math/SignedSafeMath.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Wrappers over Solidity's arithmetic operations. - * - * NOTE: `SignedSafeMath` is no longer needed starting with Solidity 0.8. The compiler - * now has built in overflow checking. - */ -library SignedSafeMathUpgradeable { - /** - * @dev Returns the multiplication of two signed integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - * - Multiplication cannot overflow. - */ - function mul(int256 a, int256 b) internal pure returns (int256) { - return a * b; - } - - /** - * @dev Returns the integer division of two signed integers. Reverts on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div(int256 a, int256 b) internal pure returns (int256) { - return a / b; - } - - /** - * @dev Returns the subtraction of two signed integers, reverting on - * overflow. - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub(int256 a, int256 b) internal pure returns (int256) { - return a - b; - } - - /** - * @dev Returns the addition of two signed integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - * - Addition cannot overflow. - */ - function add(int256 a, int256 b) internal pure returns (int256) { - return a + b; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/BitMapsUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/BitMapsUpgradeable.sol deleted file mode 100644 index f3f0520..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/BitMapsUpgradeable.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/BitMaps.sol) -pragma solidity ^0.8.0; - -/** - * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential. - * Largely inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor]. - */ -library BitMapsUpgradeable { - struct BitMap { - mapping(uint256 => uint256) _data; - } - - /** - * @dev Returns whether the bit at `index` is set. - */ - function get(BitMap storage bitmap, uint256 index) internal view returns (bool) { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - return bitmap._data[bucket] & mask != 0; - } - - /** - * @dev Sets the bit at `index` to the boolean `value`. - */ - function setTo( - BitMap storage bitmap, - uint256 index, - bool value - ) internal { - if (value) { - set(bitmap, index); - } else { - unset(bitmap, index); - } - } - - /** - * @dev Sets the bit at `index`. - */ - function set(BitMap storage bitmap, uint256 index) internal { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - bitmap._data[bucket] |= mask; - } - - /** - * @dev Unsets the bit at `index`. - */ - function unset(BitMap storage bitmap, uint256 index) internal { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - bitmap._data[bucket] &= ~mask; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/DoubleEndedQueueUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/DoubleEndedQueueUpgradeable.sol deleted file mode 100644 index 32040ba..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/DoubleEndedQueueUpgradeable.sol +++ /dev/null @@ -1,170 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol) -pragma solidity ^0.8.4; - -import "../math/SafeCastUpgradeable.sol"; - -/** - * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of - * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and - * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that - * the existing queue contents are left in storage. - * - * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be - * used in storage, and not in memory. - * ``` - * DoubleEndedQueue.Bytes32Deque queue; - * ``` - * - * _Available since v4.6._ - */ -library DoubleEndedQueueUpgradeable { - /** - * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty. - */ - error Empty(); - - /** - * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds. - */ - error OutOfBounds(); - - /** - * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end - * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely - * assume that these 128-bit indices will not overflow, and use unchecked arithmetic. - * - * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to - * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and - * lead to unexpected behavior. - * - * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at - * data[end - 1]. - */ - struct Bytes32Deque { - int128 _begin; - int128 _end; - mapping(int128 => bytes32) _data; - } - - /** - * @dev Inserts an item at the end of the queue. - */ - function pushBack(Bytes32Deque storage deque, bytes32 value) internal { - int128 backIndex = deque._end; - deque._data[backIndex] = value; - unchecked { - deque._end = backIndex + 1; - } - } - - /** - * @dev Removes the item at the end of the queue and returns it. - * - * Reverts with `Empty` if the queue is empty. - */ - function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) { - if (empty(deque)) revert Empty(); - int128 backIndex; - unchecked { - backIndex = deque._end - 1; - } - value = deque._data[backIndex]; - delete deque._data[backIndex]; - deque._end = backIndex; - } - - /** - * @dev Inserts an item at the beginning of the queue. - */ - function pushFront(Bytes32Deque storage deque, bytes32 value) internal { - int128 frontIndex; - unchecked { - frontIndex = deque._begin - 1; - } - deque._data[frontIndex] = value; - deque._begin = frontIndex; - } - - /** - * @dev Removes the item at the beginning of the queue and returns it. - * - * Reverts with `Empty` if the queue is empty. - */ - function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) { - if (empty(deque)) revert Empty(); - int128 frontIndex = deque._begin; - value = deque._data[frontIndex]; - delete deque._data[frontIndex]; - unchecked { - deque._begin = frontIndex + 1; - } - } - - /** - * @dev Returns the item at the beginning of the queue. - * - * Reverts with `Empty` if the queue is empty. - */ - function front(Bytes32Deque storage deque) internal view returns (bytes32 value) { - if (empty(deque)) revert Empty(); - int128 frontIndex = deque._begin; - return deque._data[frontIndex]; - } - - /** - * @dev Returns the item at the end of the queue. - * - * Reverts with `Empty` if the queue is empty. - */ - function back(Bytes32Deque storage deque) internal view returns (bytes32 value) { - if (empty(deque)) revert Empty(); - int128 backIndex; - unchecked { - backIndex = deque._end - 1; - } - return deque._data[backIndex]; - } - - /** - * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at - * `length(deque) - 1`. - * - * Reverts with `OutOfBounds` if the index is out of bounds. - */ - function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) { - // int256(deque._begin) is a safe upcast - int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index)); - if (idx >= deque._end) revert OutOfBounds(); - return deque._data[idx]; - } - - /** - * @dev Resets the queue back to being empty. - * - * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses - * out on potential gas refunds. - */ - function clear(Bytes32Deque storage deque) internal { - deque._begin = 0; - deque._end = 0; - } - - /** - * @dev Returns the number of items in the queue. - */ - function length(Bytes32Deque storage deque) internal view returns (uint256) { - // The interface preserves the invariant that begin <= end so we assume this will not overflow. - // We also assume there are at most int256.max items in the queue. - unchecked { - return uint256(int256(deque._end) - int256(deque._begin)); - } - } - - /** - * @dev Returns true if the queue is empty. - */ - function empty(Bytes32Deque storage deque) internal view returns (bool) { - return deque._end <= deque._begin; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableMapUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableMapUpgradeable.sol deleted file mode 100644 index 642e21a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableMapUpgradeable.sol +++ /dev/null @@ -1,530 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableMap.sol) -// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. - -pragma solidity ^0.8.0; - -import "./EnumerableSetUpgradeable.sol"; - -/** - * @dev Library for managing an enumerable variant of Solidity's - * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] - * type. - * - * Maps have the following properties: - * - * - Entries are added, removed, and checked for existence in constant time - * (O(1)). - * - Entries are enumerated in O(n). No guarantees are made on the ordering. - * - * ``` - * contract Example { - * // Add the library methods - * using EnumerableMap for EnumerableMap.UintToAddressMap; - * - * // Declare a set state variable - * EnumerableMap.UintToAddressMap private myMap; - * } - * ``` - * - * The following map types are supported: - * - * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 - * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 - * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0 - * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 - * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 - * - * [WARNING] - * ==== - * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure - * unusable. - * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. - * - * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an - * array of EnumerableMap. - * ==== - */ -library EnumerableMapUpgradeable { - using EnumerableSetUpgradeable for EnumerableSetUpgradeable.Bytes32Set; - - // To implement this library for multiple types with as little code - // repetition as possible, we write it in terms of a generic Map type with - // bytes32 keys and values. - // The Map implementation uses private functions, and user-facing - // implementations (such as Uint256ToAddressMap) are just wrappers around - // the underlying Map. - // This means that we can only create new EnumerableMaps for types that fit - // in bytes32. - - struct Bytes32ToBytes32Map { - // Storage of keys - EnumerableSetUpgradeable.Bytes32Set _keys; - mapping(bytes32 => bytes32) _values; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - Bytes32ToBytes32Map storage map, - bytes32 key, - bytes32 value - ) internal returns (bool) { - map._values[key] = value; - return map._keys.add(key); - } - - /** - * @dev Removes a key-value pair from a map. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return map._keys.remove(key); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { - return map._keys.contains(key); - } - - /** - * @dev Returns the number of key-value pairs in the map. O(1). - */ - function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { - return map._keys.length(); - } - - /** - * @dev Returns the key-value pair stored at position `index` in the map. O(1). - * - * Note that there are no guarantees on the ordering of entries inside the - * array, and it may change when more entries are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { - bytes32 key = map._keys.at(index); - return (key, map._values[key]); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { - bytes32 value = map._values[key]; - if (value == bytes32(0)) { - return (contains(map, key), bytes32(0)); - } else { - return (true, value); - } - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { - bytes32 value = map._values[key]; - require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key"); - return value; - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - Bytes32ToBytes32Map storage map, - bytes32 key, - string memory errorMessage - ) internal view returns (bytes32) { - bytes32 value = map._values[key]; - require(value != 0 || contains(map, key), errorMessage); - return value; - } - - // UintToUintMap - - struct UintToUintMap { - Bytes32ToBytes32Map _inner; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - UintToUintMap storage map, - uint256 key, - uint256 value - ) internal returns (bool) { - return set(map._inner, bytes32(key), bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { - return remove(map._inner, bytes32(key)); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { - return contains(map._inner, bytes32(key)); - } - - /** - * @dev Returns the number of elements in the map. O(1). - */ - function length(UintToUintMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (uint256(key), uint256(value)); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); - return (success, uint256(value)); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { - return uint256(get(map._inner, bytes32(key))); - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - UintToUintMap storage map, - uint256 key, - string memory errorMessage - ) internal view returns (uint256) { - return uint256(get(map._inner, bytes32(key), errorMessage)); - } - - // UintToAddressMap - - struct UintToAddressMap { - Bytes32ToBytes32Map _inner; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - UintToAddressMap storage map, - uint256 key, - address value - ) internal returns (bool) { - return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { - return remove(map._inner, bytes32(key)); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { - return contains(map._inner, bytes32(key)); - } - - /** - * @dev Returns the number of elements in the map. O(1). - */ - function length(UintToAddressMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (uint256(key), address(uint160(uint256(value)))); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); - return (success, address(uint160(uint256(value)))); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { - return address(uint160(uint256(get(map._inner, bytes32(key))))); - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - UintToAddressMap storage map, - uint256 key, - string memory errorMessage - ) internal view returns (address) { - return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage)))); - } - - // AddressToUintMap - - struct AddressToUintMap { - Bytes32ToBytes32Map _inner; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - AddressToUintMap storage map, - address key, - uint256 value - ) internal returns (bool) { - return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(AddressToUintMap storage map, address key) internal returns (bool) { - return remove(map._inner, bytes32(uint256(uint160(key)))); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(AddressToUintMap storage map, address key) internal view returns (bool) { - return contains(map._inner, bytes32(uint256(uint160(key)))); - } - - /** - * @dev Returns the number of elements in the map. O(1). - */ - function length(AddressToUintMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (address(uint160(uint256(key))), uint256(value)); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); - return (success, uint256(value)); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(AddressToUintMap storage map, address key) internal view returns (uint256) { - return uint256(get(map._inner, bytes32(uint256(uint160(key))))); - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - AddressToUintMap storage map, - address key, - string memory errorMessage - ) internal view returns (uint256) { - return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage)); - } - - // Bytes32ToUintMap - - struct Bytes32ToUintMap { - Bytes32ToBytes32Map _inner; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - Bytes32ToUintMap storage map, - bytes32 key, - uint256 value - ) internal returns (bool) { - return set(map._inner, key, bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { - return remove(map._inner, key); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { - return contains(map._inner, key); - } - - /** - * @dev Returns the number of elements in the map. O(1). - */ - function length(Bytes32ToUintMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (key, uint256(value)); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { - (bool success, bytes32 value) = tryGet(map._inner, key); - return (success, uint256(value)); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { - return uint256(get(map._inner, key)); - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - Bytes32ToUintMap storage map, - bytes32 key, - string memory errorMessage - ) internal view returns (uint256) { - return uint256(get(map._inner, key, errorMessage)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableSetUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableSetUpgradeable.sol deleted file mode 100644 index 0b3c84d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/structs/EnumerableSetUpgradeable.sol +++ /dev/null @@ -1,378 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol) -// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. - -pragma solidity ^0.8.0; - -/** - * @dev Library for managing - * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive - * types. - * - * Sets have the following properties: - * - * - Elements are added, removed, and checked for existence in constant time - * (O(1)). - * - Elements are enumerated in O(n). No guarantees are made on the ordering. - * - * ``` - * contract Example { - * // Add the library methods - * using EnumerableSet for EnumerableSet.AddressSet; - * - * // Declare a set state variable - * EnumerableSet.AddressSet private mySet; - * } - * ``` - * - * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) - * and `uint256` (`UintSet`) are supported. - * - * [WARNING] - * ==== - * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure - * unusable. - * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. - * - * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an - * array of EnumerableSet. - * ==== - */ -library EnumerableSetUpgradeable { - // To implement this library for multiple types with as little code - // repetition as possible, we write it in terms of a generic Set type with - // bytes32 values. - // The Set implementation uses private functions, and user-facing - // implementations (such as AddressSet) are just wrappers around the - // underlying Set. - // This means that we can only create new EnumerableSets for types that fit - // in bytes32. - - struct Set { - // Storage of set values - bytes32[] _values; - // Position of the value in the `values` array, plus 1 because index 0 - // means a value is not in the set. - mapping(bytes32 => uint256) _indexes; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function _add(Set storage set, bytes32 value) private returns (bool) { - if (!_contains(set, value)) { - set._values.push(value); - // The value is stored at length-1, but we add 1 to all indexes - // and use 0 as a sentinel value - set._indexes[value] = set._values.length; - return true; - } else { - return false; - } - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function _remove(Set storage set, bytes32 value) private returns (bool) { - // We read and store the value's index to prevent multiple reads from the same storage slot - uint256 valueIndex = set._indexes[value]; - - if (valueIndex != 0) { - // Equivalent to contains(set, value) - // To delete an element from the _values array in O(1), we swap the element to delete with the last one in - // the array, and then remove the last element (sometimes called as 'swap and pop'). - // This modifies the order of the array, as noted in {at}. - - uint256 toDeleteIndex = valueIndex - 1; - uint256 lastIndex = set._values.length - 1; - - if (lastIndex != toDeleteIndex) { - bytes32 lastValue = set._values[lastIndex]; - - // Move the last value to the index where the value to delete is - set._values[toDeleteIndex] = lastValue; - // Update the index for the moved value - set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex - } - - // Delete the slot where the moved value was stored - set._values.pop(); - - // Delete the index for the deleted slot - delete set._indexes[value]; - - return true; - } else { - return false; - } - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function _contains(Set storage set, bytes32 value) private view returns (bool) { - return set._indexes[value] != 0; - } - - /** - * @dev Returns the number of values on the set. O(1). - */ - function _length(Set storage set) private view returns (uint256) { - return set._values.length; - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function _at(Set storage set, uint256 index) private view returns (bytes32) { - return set._values[index]; - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function _values(Set storage set) private view returns (bytes32[] memory) { - return set._values; - } - - // Bytes32Set - - struct Bytes32Set { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { - return _add(set._inner, value); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { - return _remove(set._inner, value); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { - return _contains(set._inner, value); - } - - /** - * @dev Returns the number of values in the set. O(1). - */ - function length(Bytes32Set storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { - return _at(set._inner, index); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { - bytes32[] memory store = _values(set._inner); - bytes32[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // AddressSet - - struct AddressSet { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(AddressSet storage set, address value) internal returns (bool) { - return _add(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(AddressSet storage set, address value) internal returns (bool) { - return _remove(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(AddressSet storage set, address value) internal view returns (bool) { - return _contains(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Returns the number of values in the set. O(1). - */ - function length(AddressSet storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(AddressSet storage set, uint256 index) internal view returns (address) { - return address(uint160(uint256(_at(set._inner, index)))); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(AddressSet storage set) internal view returns (address[] memory) { - bytes32[] memory store = _values(set._inner); - address[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // UintSet - - struct UintSet { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(UintSet storage set, uint256 value) internal returns (bool) { - return _add(set._inner, bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(UintSet storage set, uint256 value) internal returns (bool) { - return _remove(set._inner, bytes32(value)); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(UintSet storage set, uint256 value) internal view returns (bool) { - return _contains(set._inner, bytes32(value)); - } - - /** - * @dev Returns the number of values in the set. O(1). - */ - function length(UintSet storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(UintSet storage set, uint256 index) internal view returns (uint256) { - return uint256(_at(set._inner, index)); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(UintSet storage set) internal view returns (uint256[] memory) { - bytes32[] memory store = _values(set._inner); - uint256[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/amb/IAMBUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/amb/IAMBUpgradeable.sol deleted file mode 100644 index 486232a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/amb/IAMBUpgradeable.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/amb/IAMB.sol) -pragma solidity ^0.8.0; - -interface IAMBUpgradeable { - event UserRequestForAffirmation(bytes32 indexed messageId, bytes encodedData); - event UserRequestForSignature(bytes32 indexed messageId, bytes encodedData); - event AffirmationCompleted( - address indexed sender, - address indexed executor, - bytes32 indexed messageId, - bool status - ); - event RelayedMessage(address indexed sender, address indexed executor, bytes32 indexed messageId, bool status); - - function messageSender() external view returns (address); - - function maxGasPerTx() external view returns (uint256); - - function transactionHash() external view returns (bytes32); - - function messageId() external view returns (bytes32); - - function messageSourceChainId() external view returns (bytes32); - - function messageCallStatus(bytes32 _messageId) external view returns (bool); - - function failedMessageDataHash(bytes32 _messageId) external view returns (bytes32); - - function failedMessageReceiver(bytes32 _messageId) external view returns (address); - - function failedMessageSender(bytes32 _messageId) external view returns (address); - - function requireToPassMessage( - address _contract, - bytes calldata _data, - uint256 _gas - ) external returns (bytes32); - - function requireToConfirmMessage( - address _contract, - bytes calldata _data, - uint256 _gas - ) external returns (bytes32); - - function sourceChainId() external view returns (uint256); - - function destinationChainId() external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IArbSysUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IArbSysUpgradeable.sol deleted file mode 100644 index ea2b9bc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IArbSysUpgradeable.sol +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2021-2022, Offchain Labs, Inc. -// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE -// SPDX-License-Identifier: BUSL-1.1 -// OpenZeppelin Contracts (last updated v4.8.0) (vendor/arbitrum/IArbSys.sol) - -pragma solidity >=0.4.21 <0.9.0; - -/** - * @title System level functionality - * @notice For use by contracts to interact with core L2-specific functionality. - * Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. - */ -interface IArbSysUpgradeable { - /** - * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0) - * @return block number as int - */ - function arbBlockNumber() external view returns (uint256); - - /** - * @notice Get Arbitrum block hash (reverts unless currentBlockNum-256 <= arbBlockNum < currentBlockNum) - * @return block hash - */ - function arbBlockHash(uint256 arbBlockNum) external view returns (bytes32); - - /** - * @notice Gets the rollup's unique chain identifier - * @return Chain identifier as int - */ - function arbChainID() external view returns (uint256); - - /** - * @notice Get internal version number identifying an ArbOS build - * @return version number as int - */ - function arbOSVersion() external view returns (uint256); - - /** - * @notice Returns 0 since Nitro has no concept of storage gas - * @return uint 0 - */ - function getStorageGasAvailable() external view returns (uint256); - - /** - * @notice (deprecated) check if current call is top level (meaning it was triggered by an EoA or a L1 contract) - * @dev this call has been deprecated and may be removed in a future release - * @return true if current execution frame is not a call by another L2 contract - */ - function isTopLevelCall() external view returns (bool); - - /** - * @notice map L1 sender contract address to its L2 alias - * @param sender sender address - * @param unused argument no longer used - * @return aliased sender address - */ - function mapL1SenderContractAddressToL2Alias(address sender, address unused) external pure returns (address); - - /** - * @notice check if the caller (of this caller of this) is an aliased L1 contract address - * @return true iff the caller's address is an alias for an L1 contract address - */ - function wasMyCallersAddressAliased() external view returns (bool); - - /** - * @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing - * @return address of the caller's caller, without applying L1 contract address aliasing - */ - function myCallersAddressWithoutAliasing() external view returns (address); - - /** - * @notice Send given amount of Eth to dest from sender. - * This is a convenience function, which is equivalent to calling sendTxToL1 with empty data. - * @param destination recipient address on L1 - * @return unique identifier for this L2-to-L1 transaction. - */ - function withdrawEth(address destination) external payable returns (uint256); - - /** - * @notice Send a transaction to L1 - * @dev it is not possible to execute on the L1 any L2-to-L1 transaction which contains data - * to a contract address without any code (as enforced by the Bridge contract). - * @param destination recipient address on L1 - * @param data (optional) calldata for L1 contract call - * @return a unique identifier for this L2-to-L1 transaction. - */ - function sendTxToL1(address destination, bytes calldata data) external payable returns (uint256); - - /** - * @notice Get send Merkle tree state - * @return size number of sends in the history - * @return root root hash of the send history - * @return partials hashes of partial subtrees in the send history tree - */ - function sendMerkleTreeState() - external - view - returns ( - uint256 size, - bytes32 root, - bytes32[] memory partials - ); - - /** - * @notice creates a send txn from L2 to L1 - * @param position = (level << 192) + leaf = (0 << 192) + leaf = leaf - */ - event L2ToL1Tx( - address caller, - address indexed destination, - uint256 indexed hash, - uint256 indexed position, - uint256 arbBlockNum, - uint256 ethBlockNum, - uint256 timestamp, - uint256 callvalue, - bytes data - ); - - /// @dev DEPRECATED in favour of the new L2ToL1Tx event above after the nitro upgrade - event L2ToL1Transaction( - address caller, - address indexed destination, - uint256 indexed uniqueId, - uint256 indexed batchNumber, - uint256 indexInBatch, - uint256 arbBlockNum, - uint256 ethBlockNum, - uint256 timestamp, - uint256 callvalue, - bytes data - ); - - /** - * @notice logs a merkle branch for proof synthesis - * @param reserved an index meant only to align the 4th index with L2ToL1Transaction's 4th event - * @param hash the merkle hash - * @param position = (level << 192) + leaf - */ - event SendMerkleUpdate(uint256 indexed reserved, bytes32 indexed hash, uint256 indexed position); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IBridgeUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IBridgeUpgradeable.sol deleted file mode 100644 index b16e0a0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IBridgeUpgradeable.sol +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2021-2022, Offchain Labs, Inc. -// For license information, see https://github.com/nitro/blob/master/LICENSE -// SPDX-License-Identifier: BUSL-1.1 -// OpenZeppelin Contracts (last updated v4.8.0) (vendor/arbitrum/IBridge.sol) - -// solhint-disable-next-line compiler-version -pragma solidity >=0.6.9 <0.9.0; - -interface IBridgeUpgradeable { - event MessageDelivered( - uint256 indexed messageIndex, - bytes32 indexed beforeInboxAcc, - address inbox, - uint8 kind, - address sender, - bytes32 messageDataHash, - uint256 baseFeeL1, - uint64 timestamp - ); - - event BridgeCallTriggered(address indexed outbox, address indexed to, uint256 value, bytes data); - - event InboxToggle(address indexed inbox, bool enabled); - - event OutboxToggle(address indexed outbox, bool enabled); - - event SequencerInboxUpdated(address newSequencerInbox); - - function allowedDelayedInboxList(uint256) external returns (address); - - function allowedOutboxList(uint256) external returns (address); - - /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. - function delayedInboxAccs(uint256) external view returns (bytes32); - - /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. - function sequencerInboxAccs(uint256) external view returns (bytes32); - - // OpenZeppelin: changed return type from IOwnable - function rollup() external view returns (address); - - function sequencerInbox() external view returns (address); - - function activeOutbox() external view returns (address); - - function allowedDelayedInboxes(address inbox) external view returns (bool); - - function allowedOutboxes(address outbox) external view returns (bool); - - function sequencerReportedSubMessageCount() external view returns (uint256); - - /** - * @dev Enqueue a message in the delayed inbox accumulator. - * These messages are later sequenced in the SequencerInbox, either - * by the sequencer as part of a normal batch, or by force inclusion. - */ - function enqueueDelayedMessage( - uint8 kind, - address sender, - bytes32 messageDataHash - ) external payable returns (uint256); - - function executeCall( - address to, - uint256 value, - bytes calldata data - ) external returns (bool success, bytes memory returnData); - - function delayedMessageCount() external view returns (uint256); - - function sequencerMessageCount() external view returns (uint256); - - // ---------- onlySequencerInbox functions ---------- - - function enqueueSequencerMessage( - bytes32 dataHash, - uint256 afterDelayedMessagesRead, - uint256 prevMessageCount, - uint256 newMessageCount - ) - external - returns ( - uint256 seqMessageIndex, - bytes32 beforeAcc, - bytes32 delayedAcc, - bytes32 acc - ); - - /** - * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type - * This is done through a separate function entrypoint instead of allowing the sequencer inbox - * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either - * every delayed inbox or every sequencer inbox call. - */ - function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum); - - // ---------- onlyRollupOrOwner functions ---------- - - function setSequencerInbox(address _sequencerInbox) external; - - function setDelayedInbox(address inbox, bool enabled) external; - - function setOutbox(address inbox, bool enabled) external; - - // ---------- initializer ---------- - - // OpenZeppelin: changed rollup_ type from IOwnable - function initialize(address rollup_) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IDelayedMessageProviderUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IDelayedMessageProviderUpgradeable.sol deleted file mode 100644 index 0dc69d6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IDelayedMessageProviderUpgradeable.sol +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2021-2022, Offchain Labs, Inc. -// For license information, see https://github.com/nitro/blob/master/LICENSE -// SPDX-License-Identifier: BUSL-1.1 -// OpenZeppelin Contracts (last updated v4.8.0) (vendor/arbitrum/IDelayedMessageProvider.sol) - -// solhint-disable-next-line compiler-version -pragma solidity >=0.6.9 <0.9.0; - -interface IDelayedMessageProviderUpgradeable { - /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator - event InboxMessageDelivered(uint256 indexed messageNum, bytes data); - - /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator - /// same as InboxMessageDelivered but the batch data is available in tx.input - event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IInboxUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IInboxUpgradeable.sol deleted file mode 100644 index e2c9d22..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IInboxUpgradeable.sol +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2021-2022, Offchain Labs, Inc. -// For license information, see https://github.com/nitro/blob/master/LICENSE -// SPDX-License-Identifier: BUSL-1.1 -// OpenZeppelin Contracts (last updated v4.8.0) (vendor/arbitrum/IInbox.sol) - -// solhint-disable-next-line compiler-version -pragma solidity >=0.6.9 <0.9.0; - -import "./IBridgeUpgradeable.sol"; -import "./IDelayedMessageProviderUpgradeable.sol"; - -interface IInboxUpgradeable is IDelayedMessageProviderUpgradeable { - function bridge() external view returns (IBridgeUpgradeable); - - // OpenZeppelin: changed return type from ISequencerInbox - function sequencerInbox() external view returns (address); - - /** - * @notice Send a generic L2 message to the chain - * @dev This method is an optimization to avoid having to emit the entirety of the messageData in a log. Instead validators are expected to be able to parse the data from the transaction's input - * @param messageData Data of the message being sent - */ - function sendL2MessageFromOrigin(bytes calldata messageData) external returns (uint256); - - /** - * @notice Send a generic L2 message to the chain - * @dev This method can be used to send any type of message that doesn't require L1 validation - * @param messageData Data of the message being sent - */ - function sendL2Message(bytes calldata messageData) external returns (uint256); - - function sendL1FundedUnsignedTransaction( - uint256 gasLimit, - uint256 maxFeePerGas, - uint256 nonce, - address to, - bytes calldata data - ) external payable returns (uint256); - - function sendL1FundedContractTransaction( - uint256 gasLimit, - uint256 maxFeePerGas, - address to, - bytes calldata data - ) external payable returns (uint256); - - function sendUnsignedTransaction( - uint256 gasLimit, - uint256 maxFeePerGas, - uint256 nonce, - address to, - uint256 value, - bytes calldata data - ) external returns (uint256); - - function sendContractTransaction( - uint256 gasLimit, - uint256 maxFeePerGas, - address to, - uint256 value, - bytes calldata data - ) external returns (uint256); - - /** - * @notice Get the L1 fee for submitting a retryable - * @dev This fee can be paid by funds already in the L2 aliased address or by the current message value - * @dev This formula may change in the future, to future proof your code query this method instead of inlining!! - * @param dataLength The length of the retryable's calldata, in bytes - * @param baseFee The block basefee when the retryable is included in the chain, if 0 current block.basefee will be used - */ - function calculateRetryableSubmissionFee(uint256 dataLength, uint256 baseFee) external view returns (uint256); - - /** - * @notice Deposit eth from L1 to L2 to address of the sender if sender is an EOA, and to its aliased address if the sender is a contract - * @dev This does not trigger the fallback function when receiving in the L2 side. - * Look into retryable tickets if you are interested in this functionality. - * @dev This function should not be called inside contract constructors - */ - function depositEth() external payable returns (uint256); - - /** - * @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts - * @dev all msg.value will deposited to callValueRefundAddress on L2 - * @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error - * @param to destination L2 contract address - * @param l2CallValue call value for retryable L2 message - * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee - * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance - * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled - * @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) - * @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) - * @param data ABI encoded data of L2 message - * @return unique message number of the retryable transaction - */ - function createRetryableTicket( - address to, - uint256 l2CallValue, - uint256 maxSubmissionCost, - address excessFeeRefundAddress, - address callValueRefundAddress, - uint256 gasLimit, - uint256 maxFeePerGas, - bytes calldata data - ) external payable returns (uint256); - - /** - * @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts - * @dev Same as createRetryableTicket, but does not guarantee that submission will succeed by requiring the needed funds - * come from the deposit alone, rather than falling back on the user's L2 balance - * @dev Advanced usage only (does not rewrite aliases for excessFeeRefundAddress and callValueRefundAddress). - * createRetryableTicket method is the recommended standard. - * @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error - * @param to destination L2 contract address - * @param l2CallValue call value for retryable L2 message - * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee - * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance - * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled - * @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) - * @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) - * @param data ABI encoded data of L2 message - * @return unique message number of the retryable transaction - */ - function unsafeCreateRetryableTicket( - address to, - uint256 l2CallValue, - uint256 maxSubmissionCost, - address excessFeeRefundAddress, - address callValueRefundAddress, - uint256 gasLimit, - uint256 maxFeePerGas, - bytes calldata data - ) external payable returns (uint256); - - // ---------- onlyRollupOrOwner functions ---------- - - /// @notice pauses all inbox functionality - function pause() external; - - /// @notice unpauses all inbox functionality - function unpause() external; - - // ---------- initializer ---------- - - /** - * @dev function to be called one time during the inbox upgrade process - * this is used to fix the storage slots - */ - function postUpgradeInit(IBridgeUpgradeable _bridge) external; - - // OpenZeppelin: changed _sequencerInbox type from ISequencerInbox - function initialize(IBridgeUpgradeable _bridge, address _sequencerInbox) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IOutboxUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IOutboxUpgradeable.sol deleted file mode 100644 index 0aaf180..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/arbitrum/IOutboxUpgradeable.sol +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2021-2022, Offchain Labs, Inc. -// For license information, see https://github.com/nitro/blob/master/LICENSE -// SPDX-License-Identifier: BUSL-1.1 -// OpenZeppelin Contracts (last updated v4.8.0) (vendor/arbitrum/IOutbox.sol) - -// solhint-disable-next-line compiler-version -pragma solidity >=0.6.9 <0.9.0; - -import "./IBridgeUpgradeable.sol"; - -interface IOutboxUpgradeable { - event SendRootUpdated(bytes32 indexed blockHash, bytes32 indexed outputRoot); - event OutBoxTransactionExecuted( - address indexed to, - address indexed l2Sender, - uint256 indexed zero, - uint256 transactionIndex - ); - - function rollup() external view returns (address); // the rollup contract - - function bridge() external view returns (IBridgeUpgradeable); // the bridge contract - - function spent(uint256) external view returns (bytes32); // packed spent bitmap - - function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash - - // solhint-disable-next-line func-name-mixedcase - function OUTBOX_VERSION() external view returns (uint128); // the outbox version - - function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external; - - /// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account - /// When the return value is zero, that means this is a system message - /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies - function l2ToL1Sender() external view returns (address); - - /// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active - function l2ToL1Block() external view returns (uint256); - - /// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active - function l2ToL1EthBlock() external view returns (uint256); - - /// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active - function l2ToL1Timestamp() external view returns (uint256); - - /// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active - function l2ToL1OutputId() external view returns (bytes32); - - /** - * @notice Executes a messages in an Outbox entry. - * @dev Reverts if dispute period hasn't expired, since the outbox entry - * is only created once the rollup confirms the respective assertion. - * @dev it is not possible to execute any L2-to-L1 transaction which contains data - * to a contract address without any code (as enforced by the Bridge contract). - * @param proof Merkle proof of message inclusion in send root - * @param index Merkle path to message - * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1) - * @param to destination address for L1 contract call - * @param l2Block l2 block number at which sendTxToL1 call was made - * @param l1Block l1 block number at which sendTxToL1 call was made - * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made - * @param value wei in L1 message - * @param data abi-encoded L1 message data - */ - function executeTransaction( - bytes32[] calldata proof, - uint256 index, - address l2Sender, - address to, - uint256 l2Block, - uint256 l1Block, - uint256 l2Timestamp, - uint256 value, - bytes calldata data - ) external; - - /** - * @dev function used to simulate the result of a particular function call from the outbox - * it is useful for things such as gas estimates. This function includes all costs except for - * proof validation (which can be considered offchain as a somewhat of a fixed cost - it's - * not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation). - * We can't include the cost of proof validation since this is intended to be used to simulate txs - * that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend - * to confirm a pending merkle root, but that would be less practical for integrating with tooling. - * It is only possible to trigger it when the msg sender is address zero, which should be impossible - * unless under simulation in an eth_call or eth_estimateGas - */ - function executeTransactionSimulation( - uint256 index, - address l2Sender, - address to, - uint256 l2Block, - uint256 l1Block, - uint256 l2Timestamp, - uint256 value, - bytes calldata data - ) external; - - /** - * @param index Merkle path to message - * @return true if the message has been spent - */ - function isSpent(uint256 index) external view returns (bool); - - function calculateItemHash( - address l2Sender, - address to, - uint256 l2Block, - uint256 l1Block, - uint256 l2Timestamp, - uint256 value, - bytes calldata data - ) external pure returns (bytes32); - - function calculateMerkleRoot( - bytes32[] memory proof, - uint256 path, - bytes32 item - ) external pure returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/compound/ICompoundTimelockUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/compound/ICompoundTimelockUpgradeable.sol deleted file mode 100644 index 250b831..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/compound/ICompoundTimelockUpgradeable.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/compound/ICompoundTimelock.sol) - -pragma solidity ^0.8.0; - -/** - * https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[Compound's timelock] interface - */ -interface ICompoundTimelockUpgradeable { - event NewAdmin(address indexed newAdmin); - event NewPendingAdmin(address indexed newPendingAdmin); - event NewDelay(uint256 indexed newDelay); - event CancelTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - event ExecuteTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - event QueueTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - - receive() external payable; - - // solhint-disable-next-line func-name-mixedcase - function GRACE_PERIOD() external view returns (uint256); - - // solhint-disable-next-line func-name-mixedcase - function MINIMUM_DELAY() external view returns (uint256); - - // solhint-disable-next-line func-name-mixedcase - function MAXIMUM_DELAY() external view returns (uint256); - - function admin() external view returns (address); - - function pendingAdmin() external view returns (address); - - function delay() external view returns (uint256); - - function queuedTransactions(bytes32) external view returns (bool); - - function setDelay(uint256) external; - - function acceptAdmin() external; - - function setPendingAdmin(address) external; - - function queueTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) external returns (bytes32); - - function cancelTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) external; - - function executeTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) external payable returns (bytes memory); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/compound/LICENSE b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/compound/LICENSE deleted file mode 100644 index 7da2324..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/compound/LICENSE +++ /dev/null @@ -1,11 +0,0 @@ -Copyright 2020 Compound Labs, Inc. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/optimism/ICrossDomainMessengerUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/optimism/ICrossDomainMessengerUpgradeable.sol deleted file mode 100644 index 96f3b14..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/optimism/ICrossDomainMessengerUpgradeable.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/optimism/ICrossDomainMessenger.sol) -pragma solidity >0.5.0 <0.9.0; - -/** - * @title ICrossDomainMessenger - */ -interface ICrossDomainMessengerUpgradeable { - /********** - * Events * - **********/ - - event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); - event RelayedMessage(bytes32 indexed msgHash); - event FailedRelayedMessage(bytes32 indexed msgHash); - - /************* - * Variables * - *************/ - - function xDomainMessageSender() external view returns (address); - - /******************** - * Public Functions * - ********************/ - - /** - * Sends a cross domain message to the target messenger. - * @param _target Target contract address. - * @param _message Message to send to the target. - * @param _gasLimit Gas limit for the provided message. - */ - function sendMessage( - address _target, - bytes calldata _message, - uint32 _gasLimit - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/optimism/LICENSE b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/optimism/LICENSE deleted file mode 100644 index 6a7da52..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/optimism/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright 2020-2021 Optimism - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/polygon/IFxMessageProcessorUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/polygon/IFxMessageProcessorUpgradeable.sol deleted file mode 100644 index 8cc8396..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/contracts/vendor/polygon/IFxMessageProcessorUpgradeable.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/polygon/IFxMessageProcessor.sol) -pragma solidity ^0.8.0; - -interface IFxMessageProcessorUpgradeable { - function processMessageFromRoot( - uint256 stateId, - address rootMessageSender, - bytes calldata data - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat.config.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat.config.js deleted file mode 100644 index 4dbff0e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat.config.js +++ /dev/null @@ -1,106 +0,0 @@ -/// ENVVAR -// - CI: output gas report to file instead of stdout -// - COVERAGE: enable coverage report -// - ENABLE_GAS_REPORT: enable gas report -// - COMPILE_MODE: production modes enables optimizations (default: development) -// - COMPILE_VERSION: compiler version (default: 0.8.9) -// - COINMARKETCAP: coinmarkercat api key for USD value in gas report - -const fs = require('fs'); -const path = require('path'); -const argv = require('yargs/yargs')() - .env('') - .options({ - coverage: { - type: 'boolean', - default: false, - }, - gas: { - alias: 'enableGasReport', - type: 'boolean', - default: false, - }, - gasReport: { - alias: 'enableGasReportPath', - type: 'string', - implies: 'gas', - default: undefined, - }, - mode: { - alias: 'compileMode', - type: 'string', - choices: [ 'production', 'development' ], - default: 'development', - }, - ir: { - alias: 'enableIR', - type: 'boolean', - default: false, - }, - compiler: { - alias: 'compileVersion', - type: 'string', - default: '0.8.13', - }, - coinmarketcap: { - alias: 'coinmarketcapApiKey', - type: 'string', - }, - }) - .argv; - -require('@nomiclabs/hardhat-truffle5'); -require('hardhat-ignore-warnings'); - -require('solidity-docgen'); - -if (argv.gas) { - require('hardhat-gas-reporter'); -} - -for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) { - require(path.join(__dirname, 'hardhat', f)); -} - -const withOptimizations = argv.gas || argv.compileMode === 'production'; - -/** - * @type import('hardhat/config').HardhatUserConfig - */ -module.exports = { - solidity: { - version: argv.compiler, - settings: { - optimizer: { - enabled: withOptimizations, - runs: 200, - }, - viaIR: withOptimizations && argv.ir, - }, - }, - warnings: { - '*': { - 'code-size': withOptimizations, - 'unused-param': !argv.coverage, // coverage causes unused-param warnings - default: 'error', - }, - }, - networks: { - hardhat: { - blockGasLimit: 10000000, - allowUnlimitedContractSize: !withOptimizations, - }, - }, - gasReporter: { - showMethodSig: true, - currency: 'USD', - outputFile: argv.gasReport, - coinmarketcap: argv.coinmarketcap, - }, - docgen: require('./docs/config'), -}; - -if (argv.coverage) { - require('solidity-coverage'); - module.exports.networks.hardhat.initialBaseFeePerGas = 0; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/env-artifacts.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/env-artifacts.js deleted file mode 100644 index 141f0fe..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/env-artifacts.js +++ /dev/null @@ -1,20 +0,0 @@ -const { HardhatError } = require('hardhat/internal/core/errors'); - -extendEnvironment(env => { - const artifactsRequire = env.artifacts.require; - - env.artifacts.require = (name) => { - for (const suffix of ['UpgradeableWithInit', 'Upgradeable', '']) { - try { - return artifactsRequire(name + suffix); - } catch (e) { - if (HardhatError.isHardhatError(e) && e.number === 700 && suffix !== '') { - continue; - } else { - throw e; - } - } - } - throw new Error('Unreachable'); - }; -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/env-contract.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/env-contract.js deleted file mode 100644 index 74d54cf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/env-contract.js +++ /dev/null @@ -1,10 +0,0 @@ -extendEnvironment(env => { - const { contract } = env; - - env.contract = function (name, body) { - // remove the default account from the accounts list used in tests, in order - // to protect tests against accidentally passing due to the contract - // deployer being used subsequently as function caller - contract(name, accounts => body(accounts.slice(1))); - }; -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/ignore-unreachable-warnings.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/ignore-unreachable-warnings.js deleted file mode 100644 index c9d3c36..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/ignore-unreachable-warnings.js +++ /dev/null @@ -1,47 +0,0 @@ -// Warnings about unreachable code are emitted with a source location that corresponds to the unreachable code. -// We have some testing contracts that purposely cause unreachable code, but said code is in the library contracts, and -// with hardhat-ignore-warnings we are not able to selectively ignore them without potentially ignoring relevant -// warnings that we don't want to miss. -// Thus, we need to handle these warnings separately. We force Hardhat to compile them in a separate compilation job and -// then ignore the warnings about unreachable code that come from that compilation job. - -const { task } = require('hardhat/config'); -const { - TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE, - TASK_COMPILE_SOLIDITY_COMPILE, -} = require('hardhat/builtin-tasks/task-names'); - -const marker = Symbol('unreachable'); -const markedCache = new WeakMap(); - -task(TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE, async (params, _, runSuper) => { - const job = await runSuper(params); - // If the file is in the unreachable directory, we make a copy of the config and mark it, which will cause it to get - // compiled separately (along with the other marked files). - if (params.file.sourceName.startsWith('contracts/mocks/') && /\bunreachable\b/.test(params.file.sourceName)) { - const originalConfig = job.solidityConfig; - let markedConfig = markedCache.get(originalConfig); - if (markedConfig === undefined) { - markedConfig = { ...originalConfig, [marker]: true }; - markedCache.set(originalConfig, markedConfig); - } - job.solidityConfig = markedConfig; - } - return job; -}); - -const W_UNREACHABLE_CODE = '5740'; - -task(TASK_COMPILE_SOLIDITY_COMPILE, async (params, _, runSuper) => { - const marked = params.compilationJob.solidityConfig[marker]; - const result = await runSuper(params); - if (marked) { - result.output = { - ...result.output, - errors: result.output.errors?.filter( - e => e.severity !== 'warning' || e.errorCode !== W_UNREACHABLE_CODE, - ), - }; - } - return result; -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/skip-foundry-tests.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/skip-foundry-tests.js deleted file mode 100644 index b803028..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/skip-foundry-tests.js +++ /dev/null @@ -1,7 +0,0 @@ -const { subtask } = require('hardhat/config'); -const { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } = require('hardhat/builtin-tasks/task-names'); - -subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS) - .setAction(async (_, __, runSuper) => - (await runSuper()).filter((path) => !path.endsWith('.t.sol')), - ); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/task-get-compiler-input.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/task-get-compiler-input.js deleted file mode 100644 index 64c8fc6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/task-get-compiler-input.js +++ /dev/null @@ -1,10 +0,0 @@ -// adds storageLayout to solc outputSelection, necessary for storage gaps - -const { internalTask } = require('hardhat/config'); -const { TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT } = require('hardhat/builtin-tasks/task-names'); - -internalTask(TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT, async (args, bre, runSuper) => { - const input = await runSuper(); - input.settings.outputSelection['*']['*'].push('storageLayout'); - return input; -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/task-test-get-files.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/task-test-get-files.js deleted file mode 100644 index 573d1d6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/hardhat/task-test-get-files.js +++ /dev/null @@ -1,19 +0,0 @@ -// ignores the proxy tests - -const { internalTask } = require('hardhat/config'); - -const { TASK_TEST_GET_TEST_FILES } = require('hardhat/builtin-tasks/task-names'); -const glob = require('glob'); -const path = require('path'); -const { promisify } = require('util'); - -internalTask(TASK_TEST_GET_TEST_FILES) - .setAction(async ({ testFiles }, { config }) => { - if (testFiles.length !== 0) { - return testFiles; - } - return await promisify(glob)( - path.join(config.paths.tests, '**/*.js'), - { ignore: [path.join(config.paths.tests, 'proxy/**/*')] }, - ); - }); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/icon.svg b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/icon.svg deleted file mode 100644 index 8840fab..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/icon.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - OZ_icon_color - Created with Sketch. - - - - - - - - \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.github/workflows/ci.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.github/workflows/ci.yml deleted file mode 100644 index 96b2336..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.github/workflows/ci.yml +++ /dev/null @@ -1,92 +0,0 @@ -name: CI - -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Print forge version - run: forge --version - - # Backwards compatibility checks. - - name: Check compatibility with 0.8.0 - if: always() - run: forge build --skip test --use solc:0.8.0 - - - name: Check compatibility with 0.7.6 - if: always() - run: forge build --skip test --use solc:0.7.6 - - - name: Check compatibility with 0.7.0 - if: always() - run: forge build --skip test --use solc:0.7.0 - - - name: Check compatibility with 0.6.12 - if: always() - run: forge build --skip test --use solc:0.6.12 - - - name: Check compatibility with 0.6.2 - if: always() - run: forge build --skip test --use solc:0.6.2 - - # via-ir compilation time checks. - - name: Measure compilation time of Test with 0.8.17 --via-ir - if: always() - run: forge build --skip test --contracts test/compilation/CompilationTest.sol --use solc:0.8.17 --via-ir - - - name: Measure compilation time of TestBase with 0.8.17 --via-ir - if: always() - run: forge build --skip test --contracts test/compilation/CompilationTestBase.sol --use solc:0.8.17 --via-ir - - - name: Measure compilation time of Script with 0.8.17 --via-ir - if: always() - run: forge build --skip test --contracts test/compilation/CompilationScript.sol --use solc:0.8.17 --via-ir - - - name: Measure compilation time of ScriptBase with 0.8.17 --via-ir - if: always() - run: forge build --skip test --contracts test/compilation/CompilationScriptBase.sol --use solc:0.8.17 --via-ir - - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Print forge version - run: forge --version - - - name: Run tests - run: forge test -vvv - - fmt: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Print forge version - run: forge --version - - - name: Check formatting - run: forge fmt --check diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.gitignore b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.gitignore deleted file mode 100644 index 756106d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -cache/ -out/ -.vscode -.idea diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.gitmodules b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.gitmodules deleted file mode 100644 index e124719..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/ds-test"] - path = lib/ds-test - url = https://github.com/dapphub/ds-test diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/LICENSE-APACHE b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/LICENSE-APACHE deleted file mode 100644 index cf01a49..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/LICENSE-APACHE +++ /dev/null @@ -1,203 +0,0 @@ -Copyright Contributors to Forge Standard Library - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/LICENSE-MIT b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/LICENSE-MIT deleted file mode 100644 index 28f9830..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright Contributors to Forge Standard Library - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE O THE USE OR OTHER -DEALINGS IN THE SOFTWARE.R diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/README.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/README.md deleted file mode 100644 index 8494a7d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/README.md +++ /dev/null @@ -1,250 +0,0 @@ -# Forge Standard Library • [![CI status](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml/badge.svg)](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml) - -Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. - -**Learn how to use Forge-Std with the [📖 Foundry Book (Forge-Std Guide)](https://book.getfoundry.sh/forge/forge-std.html).** - -## Install - -```bash -forge install foundry-rs/forge-std -``` - -## Contracts -### stdError - -This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler builtin errors. - -See the contract itself for all error codes. - -#### Example usage - -```solidity - -import "forge-std/Test.sol"; - -contract TestContract is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } -} - -contract ErrorsTest { - function arithmeticError(uint256 a) public { - uint256 a = a - 100; - } -} -``` - -### stdStorage - -This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can *always* find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The one _major_ caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (`bytes32(0)`). - -This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth. - -I.e.: -```solidity -struct T { - // depth 0 - uint256 a; - // depth 1 - uint256 b; -} -``` - -#### Example usage - -```solidity -import "forge-std/Test.sol"; - -contract TestContract is Test { - using stdStorage for StdStorage; - - Storage test; - - function setUp() public { - test = new Storage(); - } - - function testFindExists() public { - // Lets say we want to find the slot for the public - // variable `exists`. We just pass in the function selector - // to the `find` command - uint256 slot = stdstore.target(address(test)).sig("exists()").find(); - assertEq(slot, 0); - } - - function testWriteExists() public { - // Lets say we want to write to the slot for the public - // variable `exists`. We just pass in the function selector - // to the `checked_write` command - stdstore.target(address(test)).sig("exists()").checked_write(100); - assertEq(test.exists(), 100); - } - - // It supports arbitrary storage layouts, like assembly based storage locations - function testFindHidden() public { - // `hidden` is a random hash of a bytes, iteration through slots would - // not find it. Our mechanism does - // Also, you can use the selector instead of a string - uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find(); - assertEq(slot, uint256(keccak256("my.random.var"))); - } - - // If targeting a mapping, you have to pass in the keys necessary to perform the find - // i.e.: - function testFindMapping() public { - uint256 slot = stdstore - .target(address(test)) - .sig(test.map_addr.selector) - .with_key(address(this)) - .find(); - // in the `Storage` constructor, we wrote that this address' value was 1 in the map - // so when we load the slot, we expect it to be 1 - assertEq(uint(vm.load(address(test), bytes32(slot))), 1); - } - - // If the target is a struct, you can specify the field depth: - function testFindStruct() public { - // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. - uint256 slot_for_a_field = stdstore - .target(address(test)) - .sig(test.basicStruct.selector) - .depth(0) - .find(); - - uint256 slot_for_b_field = stdstore - .target(address(test)) - .sig(test.basicStruct.selector) - .depth(1) - .find(); - - assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1); - assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2); - } -} - -// A complex storage contract -contract Storage { - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - constructor() { - map_addr[msg.sender] = 1; - } - - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - // mapping(address => Packed) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basicStruct = UnpackedStruct({ - a: 1, - b: 2 - }); - - function hidden() public view returns (bytes32 t) { - // an extremely hidden storage slot - bytes32 slot = keccak256("my.random.var"); - assembly { - t := sload(slot) - } - } -} -``` - -### stdCheats - -This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for address that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. - - -#### Example usage: -```solidity - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; - -// Inherit the stdCheats -contract StdCheatsTest is Test { - Bar test; - function setUp() public { - test = new Bar(); - } - - function testHoax() public { - // we call `hoax`, which gives the target address - // eth and then calls `prank` - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - - // overloaded to allow you to specify how much eth to - // initialize the address with - hoax(address(1337), 1); - test.bar{value: 1}(address(1337)); - } - - function testStartHoax() public { - // we call `startHoax`, which gives the target address - // eth and then calls `startPrank` - // - // it is also overloaded so that you can specify an eth amount - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } -} - -contract Bar { - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } -} -``` - -### Std Assertions - -Expand upon the assertion functions from the `DSTest` library. - -### `console.log` - -Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). -It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console2.sol"; -... -console2.log(someValue); -``` - -If you need compatibility with Hardhat, you must use the standard `console.sol` instead. -Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. - -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console.sol"; -... -console.log(someValue); -``` - -## License - -Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/foundry.toml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/foundry.toml deleted file mode 100644 index 36e4e63..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/foundry.toml +++ /dev/null @@ -1,21 +0,0 @@ -[profile.default] -fs_permissions = [{ access = "read-write", path = "./"}] - -[rpc_endpoints] -# The RPC URLs are modified versions of the default for testing initialization. -mainnet = "https://mainnet.infura.io/v3/16a8be88795540b9b3903d8de0f7baa5" # Different API key. -optimism_goerli = "https://goerli.optimism.io/" # Adds a trailing slash. -arbitrum_one_goerli = "https://goerli-rollup.arbitrum.io/rpc/" # Adds a trailing slash. -needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" - -[fmt] -# These are all the `forge fmt` defaults. -line_length = 120 -tab_width = 4 -bracket_spacing = false -int_types = 'long' -multiline_func_header = 'attributes_first' -quote_style = 'double' -number_underscore = 'preserve' -single_line_statement_blocks = 'preserve' -ignore = ["src/console.sol", "src/console2.sol"] \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/.github/workflows/build.yml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/.github/workflows/build.yml deleted file mode 100644 index a2c31df..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/.github/workflows/build.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "Build" -on: - pull_request: - push: -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v18 - with: - nix_path: nixpkgs=channel:nixos-unstable - extra_nix_config: | - access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} - - - name: setup dapp binary cache - uses: cachix/cachix-action@v12 - with: - name: dapp - - - name: install dapptools - run: nix profile install github:dapphub/dapptools#dapp --accept-flake-config - - - name: install foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: test with solc-0.5.17 - run: dapp --use solc-0.5.17 test -v - - - name: test with solc-0.6.11 - run: dapp --use solc-0.6.11 test -v - - - name: test with solc-0.7.6 - run: dapp --use solc-0.7.6 test -v - - - name: test with solc-0.8.18 - run: dapp --use solc-0.8.18 test -v - - - name: Run tests with foundry - run: forge test -vvv - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/.gitignore b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/.gitignore deleted file mode 100644 index 462a994..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/.dapple -/build -/out -/cache/ diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/LICENSE b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/Makefile b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/Makefile deleted file mode 100644 index 661dac4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all:; dapp build - -test: - -dapp --use solc:0.4.23 build - -dapp --use solc:0.4.26 build - -dapp --use solc:0.5.17 build - -dapp --use solc:0.6.12 build - -dapp --use solc:0.7.5 build - -demo: - DAPP_SRC=demo dapp --use solc:0.7.5 build - -hevm dapp-test --verbose 3 - -.PHONY: test demo diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/default.nix b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/default.nix deleted file mode 100644 index cf65419..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ solidityPackage, dappsys }: solidityPackage { - name = "ds-test"; - src = ./src; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/demo/demo.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/demo/demo.sol deleted file mode 100644 index f3bb48e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/demo/demo.sol +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.5.0; - -import "../src/test.sol"; - -contract DemoTest is DSTest { - function test_this() public pure { - require(true); - } - function test_logs() public { - emit log("-- log(string)"); - emit log("a string"); - - emit log("-- log_named_uint(string, uint)"); - emit log_named_uint("uint", 512); - - emit log("-- log_named_int(string, int)"); - emit log_named_int("int", -512); - - emit log("-- log_named_address(string, address)"); - emit log_named_address("address", address(this)); - - emit log("-- log_named_bytes32(string, bytes32)"); - emit log_named_bytes32("bytes32", "a string"); - - emit log("-- log_named_bytes(string, bytes)"); - emit log_named_bytes("bytes", hex"cafefe"); - - emit log("-- log_named_string(string, string)"); - emit log_named_string("string", "a string"); - - emit log("-- log_named_decimal_uint(string, uint, uint)"); - emit log_named_decimal_uint("decimal uint", 1.0e18, 18); - - emit log("-- log_named_decimal_int(string, int, uint)"); - emit log_named_decimal_int("decimal int", -1.0e18, 18); - } - event log_old_named_uint(bytes32,uint); - function test_old_logs() public { - emit log_old_named_uint("key", 500); - emit log_named_bytes32("bkey", "val"); - } - function test_trace() public view { - this.echo("string 1", "string 2"); - } - function test_multiline() public { - emit log("a multiline\\nstring"); - emit log("a multiline string"); - emit log_bytes("a string"); - emit log_bytes("a multiline\nstring"); - emit log_bytes("a multiline\\nstring"); - emit logs(hex"0000"); - emit log_named_bytes("0x0000", hex"0000"); - emit logs(hex"ff"); - } - function echo(string memory s1, string memory s2) public pure - returns (string memory, string memory) - { - return (s1, s2); - } - - function prove_this(uint x) public { - emit log_named_uint("sym x", x); - assertGt(x + 1, 0); - } - - function test_logn() public { - assembly { - log0(0x01, 0x02) - log1(0x01, 0x02, 0x03) - log2(0x01, 0x02, 0x03, 0x04) - log3(0x01, 0x02, 0x03, 0x04, 0x05) - } - } - - event MyEvent(uint, uint indexed, uint, uint indexed); - function test_events() public { - emit MyEvent(1, 2, 3, 4); - } - - function test_asserts() public { - string memory err = "this test has failed!"; - emit log("## assertTrue(bool)\n"); - assertTrue(false); - emit log("\n"); - assertTrue(false, err); - - emit log("\n## assertEq(address,address)\n"); - assertEq(address(this), msg.sender); - emit log("\n"); - assertEq(address(this), msg.sender, err); - - emit log("\n## assertEq32(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(uint,uint)\n"); - assertEq(uint(0), 1); - emit log("\n"); - assertEq(uint(0), 1, err); - - emit log("\n## assertEq(int,int)\n"); - assertEq(-1, -2); - emit log("\n"); - assertEq(-1, -2, err); - - emit log("\n## assertEqDecimal(int,int,uint)\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertEqDecimal(uint,uint,uint)\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGt(uint,uint)\n"); - assertGt(uint(0), 0); - emit log("\n"); - assertGt(uint(0), 0, err); - - emit log("\n## assertGt(int,int)\n"); - assertGt(-1, -1); - emit log("\n"); - assertGt(-1, -1, err); - - emit log("\n## assertGtDecimal(int,int,uint)\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGtDecimal(uint,uint,uint)\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGe(uint,uint)\n"); - assertGe(uint(0), 1); - emit log("\n"); - assertGe(uint(0), 1, err); - - emit log("\n## assertGe(int,int)\n"); - assertGe(-1, 0); - emit log("\n"); - assertGe(-1, 0, err); - - emit log("\n## assertGeDecimal(int,int,uint)\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGeDecimal(uint,uint,uint)\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertLt(uint,uint)\n"); - assertLt(uint(0), 0); - emit log("\n"); - assertLt(uint(0), 0, err); - - emit log("\n## assertLt(int,int)\n"); - assertLt(-1, -1); - emit log("\n"); - assertLt(-1, -1, err); - - emit log("\n## assertLtDecimal(int,int,uint)\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLtDecimal(uint,uint,uint)\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertLe(uint,uint)\n"); - assertLe(uint(1), 0); - emit log("\n"); - assertLe(uint(1), 0, err); - - emit log("\n## assertLe(int,int)\n"); - assertLe(0, -1); - emit log("\n"); - assertLe(0, -1, err); - - emit log("\n## assertLeDecimal(int,int,uint)\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLeDecimal(uint,uint,uint)\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertEq(string,string)\n"); - string memory s1 = "string 1"; - string memory s2 = "string 2"; - assertEq(s1, s2); - emit log("\n"); - assertEq(s1, s2, err); - - emit log("\n## assertEq0(bytes,bytes)\n"); - assertEq0(hex"abcdef01", hex"abcdef02"); - emit log("\n"); - assertEq0(hex"abcdef01", hex"abcdef02", err); - } -} - -contract DemoTestWithSetUp { - function setUp() public { - } - function test_pass() public pure { - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/package.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/package.json deleted file mode 100644 index 4802ada..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ds-test", - "version": "1.0.0", - "description": "Assertions, equality checks and other test helpers ", - "bugs": "https://github.com/dapphub/ds-test/issues", - "license": "GPL-3.0", - "author": "Contributors to ds-test", - "files": [ - "src/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/dapphub/ds-test.git" - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/test.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/test.sol deleted file mode 100644 index de504d3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/test.sol +++ /dev/null @@ -1,469 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pragma solidity >=0.5.0; - -contract DSTest { - event log (string); - event logs (bytes); - - event log_address (address); - event log_bytes32 (bytes32); - event log_int (int); - event log_uint (uint); - event log_bytes (bytes); - event log_string (string); - - event log_named_address (string key, address val); - event log_named_bytes32 (string key, bytes32 val); - event log_named_decimal_int (string key, int val, uint decimals); - event log_named_decimal_uint (string key, uint val, uint decimals); - event log_named_int (string key, int val); - event log_named_uint (string key, uint val); - event log_named_bytes (string key, bytes val); - event log_named_string (string key, string val); - - bool public IS_TEST = true; - bool private _failed; - - address constant HEVM_ADDRESS = - address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); - - modifier mayRevert() { _; } - modifier testopts(string memory) { _; } - - function failed() public returns (bool) { - if (_failed) { - return _failed; - } else { - bool globalFailed = false; - if (hasHEVMContext()) { - (, bytes memory retdata) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("load(address,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed")) - ) - ); - globalFailed = abi.decode(retdata, (bool)); - } - return globalFailed; - } - } - - function fail() internal virtual { - if (hasHEVMContext()) { - (bool status, ) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("store(address,bytes32,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x01))) - ) - ); - status; // Silence compiler warnings - } - _failed = true; - } - - function hasHEVMContext() internal view returns (bool) { - uint256 hevmCodeSize = 0; - assembly { - hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) - } - return hevmCodeSize > 0; - } - - modifier logs_gas() { - uint startGas = gasleft(); - _; - uint endGas = gasleft(); - emit log_named_uint("gas", startGas - endGas); - } - - function assertTrue(bool condition) internal { - if (!condition) { - emit log("Error: Assertion Failed"); - fail(); - } - } - - function assertTrue(bool condition, string memory err) internal { - if (!condition) { - emit log_named_string("Error", err); - assertTrue(condition); - } - } - - function assertEq(address a, address b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [address]"); - emit log_named_address(" Left", a); - emit log_named_address(" Right", b); - fail(); - } - } - function assertEq(address a, address b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes32 a, bytes32 b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [bytes32]"); - emit log_named_bytes32(" Left", a); - emit log_named_bytes32(" Right", b); - fail(); - } - } - function assertEq(bytes32 a, bytes32 b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - function assertEq32(bytes32 a, bytes32 b) internal { - assertEq(a, b); - } - function assertEq32(bytes32 a, bytes32 b, string memory err) internal { - assertEq(a, b, err); - } - - function assertEq(int a, int b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - fail(); - } - } - function assertEq(int a, int b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEq(uint a, uint b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - fail(); - } - } - function assertEq(uint a, uint b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEqDecimal(int a, int b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - fail(); - } - } - function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - function assertEqDecimal(uint a, uint b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - fail(); - } - } - function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - - function assertGt(uint a, uint b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGt(uint a, uint b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGt(int a, int b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGt(int a, int b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGtDecimal(int a, int b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - function assertGtDecimal(uint a, uint b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - - function assertGe(uint a, uint b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGe(uint a, uint b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGe(int a, int b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGe(int a, int b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGeDecimal(int a, int b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - function assertGeDecimal(uint a, uint b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertLt(uint a, uint b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLt(uint a, uint b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLt(int a, int b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLt(int a, int b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLtDecimal(int a, int b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - function assertLtDecimal(uint a, uint b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - - function assertLe(uint a, uint b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLe(uint a, uint b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLe(int a, int b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLe(int a, int b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLeDecimal(int a, int b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - function assertLeDecimal(uint a, uint b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - - function assertEq(string memory a, string memory b) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log("Error: a == b not satisfied [string]"); - emit log_named_string(" Left", a); - emit log_named_string(" Right", b); - fail(); - } - } - function assertEq(string memory a, string memory b, string memory err) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { - ok = true; - if (a.length == b.length) { - for (uint i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - ok = false; - } - } - } else { - ok = false; - } - } - function assertEq0(bytes memory a, bytes memory b) internal { - if (!checkEq0(a, b)) { - emit log("Error: a == b not satisfied [bytes]"); - emit log_named_bytes(" Left", a); - emit log_named_bytes(" Right", b); - fail(); - } - } - function assertEq0(bytes memory a, bytes memory b, string memory err) internal { - if (!checkEq0(a, b)) { - emit log_named_string("Error", err); - assertEq0(a, b); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/test.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/test.t.sol deleted file mode 100644 index 996f52f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/test.t.sol +++ /dev/null @@ -1,313 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.5.0; - -import {DSTest} from "./test.sol"; - -contract DemoTest is DSTest { - - // --- assertTrue --- - - function testAssertTrue() public { - assertTrue(true, "msg"); - assertTrue(true); - } - function testFailAssertTrue() public { - assertTrue(false); - } - function testFailAssertTrueWithMsg() public { - assertTrue(false, "msg"); - } - - // --- assertEq (Addr) --- - - function testAssertEqAddr() public { - assertEq(address(0x0), address(0x0), "msg"); - assertEq(address(0x0), address(0x0)); - } - function testFailAssertEqAddr() public { - assertEq(address(0x0), address(0x1)); - } - function testFailAssertEqAddrWithMsg() public { - assertEq(address(0x0), address(0x1), "msg"); - } - - // --- assertEq (Bytes32) --- - - function testAssertEqBytes32() public { - assertEq(bytes32("hi"), bytes32("hi"), "msg"); - assertEq(bytes32("hi"), bytes32("hi")); - } - function testFailAssertEqBytes32() public { - assertEq(bytes32("hi"), bytes32("ho")); - } - function testFailAssertEqBytes32WithMsg() public { - assertEq(bytes32("hi"), bytes32("ho"), "msg"); - } - - // --- assertEq (Int) --- - - function testAssertEqInt() public { - assertEq(-1, -1, "msg"); - assertEq(-1, -1); - } - function testFailAssertEqInt() public { - assertEq(-1, -2); - } - function testFailAssertEqIntWithMsg() public { - assertEq(-1, -2, "msg"); - } - - // --- assertEq (UInt) --- - - function testAssertEqUInt() public { - assertEq(uint(1), uint(1), "msg"); - assertEq(uint(1), uint(1)); - } - function testFailAssertEqUInt() public { - assertEq(uint(1), uint(2)); - } - function testFailAssertEqUIntWithMsg() public { - assertEq(uint(1), uint(2), "msg"); - } - - // --- assertEqDecimal (Int) --- - - function testAssertEqDecimalInt() public { - assertEqDecimal(-1, -1, 18, "msg"); - assertEqDecimal(-1, -1, 18); - } - function testFailAssertEqDecimalInt() public { - assertEqDecimal(-1, -2, 18); - } - function testFailAssertEqDecimalIntWithMsg() public { - assertEqDecimal(-1, -2, 18, "msg"); - } - - // --- assertEqDecimal (UInt) --- - - function testAssertEqDecimalUInt() public { - assertEqDecimal(uint(1), uint(1), 18, "msg"); - assertEqDecimal(uint(1), uint(1), 18); - } - function testFailAssertEqDecimalUInt() public { - assertEqDecimal(uint(1), uint(2), 18); - } - function testFailAssertEqDecimalUIntWithMsg() public { - assertEqDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertGt (UInt) --- - - function testAssertGtUInt() public { - assertGt(uint(2), uint(1), "msg"); - assertGt(uint(3), uint(2)); - } - function testFailAssertGtUInt() public { - assertGt(uint(1), uint(2)); - } - function testFailAssertGtUIntWithMsg() public { - assertGt(uint(1), uint(2), "msg"); - } - - // --- assertGt (Int) --- - - function testAssertGtInt() public { - assertGt(-1, -2, "msg"); - assertGt(-1, -3); - } - function testFailAssertGtInt() public { - assertGt(-2, -1); - } - function testFailAssertGtIntWithMsg() public { - assertGt(-2, -1, "msg"); - } - - // --- assertGtDecimal (UInt) --- - - function testAssertGtDecimalUInt() public { - assertGtDecimal(uint(2), uint(1), 18, "msg"); - assertGtDecimal(uint(3), uint(2), 18); - } - function testFailAssertGtDecimalUInt() public { - assertGtDecimal(uint(1), uint(2), 18); - } - function testFailAssertGtDecimalUIntWithMsg() public { - assertGtDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertGtDecimal (Int) --- - - function testAssertGtDecimalInt() public { - assertGtDecimal(-1, -2, 18, "msg"); - assertGtDecimal(-1, -3, 18); - } - function testFailAssertGtDecimalInt() public { - assertGtDecimal(-2, -1, 18); - } - function testFailAssertGtDecimalIntWithMsg() public { - assertGtDecimal(-2, -1, 18, "msg"); - } - - // --- assertGe (UInt) --- - - function testAssertGeUInt() public { - assertGe(uint(2), uint(1), "msg"); - assertGe(uint(2), uint(2)); - } - function testFailAssertGeUInt() public { - assertGe(uint(1), uint(2)); - } - function testFailAssertGeUIntWithMsg() public { - assertGe(uint(1), uint(2), "msg"); - } - - // --- assertGe (Int) --- - - function testAssertGeInt() public { - assertGe(-1, -2, "msg"); - assertGe(-1, -1); - } - function testFailAssertGeInt() public { - assertGe(-2, -1); - } - function testFailAssertGeIntWithMsg() public { - assertGe(-2, -1, "msg"); - } - - // --- assertGeDecimal (UInt) --- - - function testAssertGeDecimalUInt() public { - assertGeDecimal(uint(2), uint(1), 18, "msg"); - assertGeDecimal(uint(2), uint(2), 18); - } - function testFailAssertGeDecimalUInt() public { - assertGeDecimal(uint(1), uint(2), 18); - } - function testFailAssertGeDecimalUIntWithMsg() public { - assertGeDecimal(uint(1), uint(2), 18, "msg"); - } - - // --- assertGeDecimal (Int) --- - - function testAssertGeDecimalInt() public { - assertGeDecimal(-1, -2, 18, "msg"); - assertGeDecimal(-1, -2, 18); - } - function testFailAssertGeDecimalInt() public { - assertGeDecimal(-2, -1, 18); - } - function testFailAssertGeDecimalIntWithMsg() public { - assertGeDecimal(-2, -1, 18, "msg"); - } - - // --- assertLt (UInt) --- - - function testAssertLtUInt() public { - assertLt(uint(1), uint(2), "msg"); - assertLt(uint(1), uint(3)); - } - function testFailAssertLtUInt() public { - assertLt(uint(2), uint(2)); - } - function testFailAssertLtUIntWithMsg() public { - assertLt(uint(3), uint(2), "msg"); - } - - // --- assertLt (Int) --- - - function testAssertLtInt() public { - assertLt(-2, -1, "msg"); - assertLt(-1, 0); - } - function testFailAssertLtInt() public { - assertLt(-1, -2); - } - function testFailAssertLtIntWithMsg() public { - assertLt(-1, -1, "msg"); - } - - // --- assertLtDecimal (UInt) --- - - function testAssertLtDecimalUInt() public { - assertLtDecimal(uint(1), uint(2), 18, "msg"); - assertLtDecimal(uint(2), uint(3), 18); - } - function testFailAssertLtDecimalUInt() public { - assertLtDecimal(uint(1), uint(1), 18); - } - function testFailAssertLtDecimalUIntWithMsg() public { - assertLtDecimal(uint(2), uint(1), 18, "msg"); - } - - // --- assertLtDecimal (Int) --- - - function testAssertLtDecimalInt() public { - assertLtDecimal(-2, -1, 18, "msg"); - assertLtDecimal(-2, -1, 18); - } - function testFailAssertLtDecimalInt() public { - assertLtDecimal(-2, -2, 18); - } - function testFailAssertLtDecimalIntWithMsg() public { - assertLtDecimal(-1, -2, 18, "msg"); - } - - // --- assertLe (UInt) --- - - function testAssertLeUInt() public { - assertLe(uint(1), uint(2), "msg"); - assertLe(uint(1), uint(1)); - } - function testFailAssertLeUInt() public { - assertLe(uint(4), uint(2)); - } - function testFailAssertLeUIntWithMsg() public { - assertLe(uint(3), uint(2), "msg"); - } - - // --- assertLe (Int) --- - - function testAssertLeInt() public { - assertLe(-2, -1, "msg"); - assertLe(-1, -1); - } - function testFailAssertLeInt() public { - assertLe(-1, -2); - } - function testFailAssertLeIntWithMsg() public { - assertLe(-1, -3, "msg"); - } - - // --- assertLeDecimal (UInt) --- - - function testAssertLeDecimalUInt() public { - assertLeDecimal(uint(1), uint(2), 18, "msg"); - assertLeDecimal(uint(2), uint(2), 18); - } - function testFailAssertLeDecimalUInt() public { - assertLeDecimal(uint(1), uint(0), 18); - } - function testFailAssertLeDecimalUIntWithMsg() public { - assertLeDecimal(uint(1), uint(0), 18, "msg"); - } - - // --- assertLeDecimal (Int) --- - - function testAssertLeDecimalInt() public { - assertLeDecimal(-2, -1, 18, "msg"); - assertLeDecimal(-2, -2, 18); - } - function testFailAssertLeDecimalInt() public { - assertLeDecimal(-2, -3, 18); - } - function testFailAssertLeDecimalIntWithMsg() public { - assertLeDecimal(-1, -2, 18, "msg"); - } - - // --- fail override --- - - // ensure that fail can be overridden - function fail() internal override { - super.fail(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/package.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/package.json deleted file mode 100644 index 96003f7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "forge-std", - "version": "1.5.0", - "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", - "homepage": "https://book.getfoundry.sh/forge/forge-std", - "bugs": "https://github.com/foundry-rs/forge-std/issues", - "license": "(Apache-2.0 OR MIT)", - "author": "Contributors to Forge Standard Library", - "files": [ - "src/*" - ], - "repository": { - "type": "git", - "url": "https://github.com/foundry-rs/forge-std.git" - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Base.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Base.sol deleted file mode 100644 index 83c5c1c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Base.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {StdStorage} from "./StdStorage.sol"; -import {Vm, VmSafe} from "./Vm.sol"; - -abstract contract CommonBase { - // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. - address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); - // console.sol and console2.sol work by executing a staticcall to this address. - address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; - // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38. - address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256("foundry default caller")))); - // Address of the test contract, deployed by the DEFAULT_SENDER. - address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; - // Deterministic deployment address of the Multicall3 contract. - address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; - - uint256 internal constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - Vm internal constant vm = Vm(VM_ADDRESS); - StdStorage internal stdstore; -} - -abstract contract TestBase is CommonBase {} - -abstract contract ScriptBase is CommonBase { - // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. - address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - - VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Script.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Script.sol deleted file mode 100644 index bffccad..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Script.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -// 💬 ABOUT -// Standard Library's default Script. - -// 🧩 MODULES -import {ScriptBase} from "./Base.sol"; -import {console} from "./console.sol"; -import {console2} from "./console2.sol"; -import {StdChains} from "./StdChains.sol"; -import {StdCheatsSafe} from "./StdCheats.sol"; -import {stdJson} from "./StdJson.sol"; -import {stdMath} from "./StdMath.sol"; -import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {VmSafe} from "./Vm.sol"; - -// 📦 BOILERPLATE -import {ScriptBase} from "./Base.sol"; - -// ⭐️ SCRIPT -abstract contract Script is StdChains, StdCheatsSafe, StdUtils, ScriptBase { - // Note: IS_SCRIPT() must return true. - bool public IS_SCRIPT = true; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdAssertions.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdAssertions.sol deleted file mode 100644 index 198a1ba..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdAssertions.sol +++ /dev/null @@ -1,376 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {DSTest} from "ds-test/test.sol"; -import {stdMath} from "./StdMath.sol"; - -abstract contract StdAssertions is DSTest { - event log_array(uint256[] val); - event log_array(int256[] val); - event log_array(address[] val); - event log_named_array(string key, uint256[] val); - event log_named_array(string key, int256[] val); - event log_named_array(string key, address[] val); - - function fail(string memory err) internal virtual { - emit log_named_string("Error", err); - fail(); - } - - function assertFalse(bool data) internal virtual { - assertTrue(!data); - } - - function assertFalse(bool data, string memory err) internal virtual { - assertTrue(!data, err); - } - - function assertEq(bool a, bool b) internal virtual { - if (a != b) { - emit log("Error: a == b not satisfied [bool]"); - emit log_named_string(" Left", a ? "true" : "false"); - emit log_named_string(" Right", b ? "true" : "false"); - fail(); - } - } - - function assertEq(bool a, bool b, string memory err) internal virtual { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes memory a, bytes memory b) internal virtual { - assertEq0(a, b); - } - - function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual { - assertEq0(a, b, err); - } - - function assertEq(uint256[] memory a, uint256[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [uint[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(int256[] memory a, int256[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [int[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(address[] memory a, address[] memory b) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log("Error: a == b not satisfied [address[]]"); - emit log_named_array(" Left", a); - emit log_named_array(" Right", b); - fail(); - } - } - - function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual { - if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - // Legacy helper - function assertEqUint(uint256 a, uint256 b) internal virtual { - assertEq(uint256(a), uint256(b)); - } - - function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbs(a, b, maxDelta); - } - } - - function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); - emit log_named_decimal_uint(" Delta", delta, decimals); - fail(); - } - } - - function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err) - internal - virtual - { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - } - - function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - emit log_named_uint(" Max Delta", maxDelta); - emit log_named_uint(" Delta", delta); - fail(); - } - } - - function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbs(a, b, maxDelta); - } - } - - function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); - emit log_named_decimal_uint(" Delta", delta, decimals); - fail(); - } - } - - function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err) - internal - virtual - { - uint256 delta = stdMath.delta(a, b); - - if (delta > maxDelta) { - emit log_named_string("Error", err); - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - } - - function assertApproxEqRel( - uint256 a, - uint256 b, - uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% - ) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_uint(" Left", a); - emit log_named_uint(" Right", b); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta, 18); - emit log_named_decimal_uint(" % Delta", percentDelta, 18); - fail(); - } - } - - function assertApproxEqRel( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - string memory err - ) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRel(a, b, maxPercentDelta); - } - } - - function assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals - ) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [uint]"); - emit log_named_decimal_uint(" Left", a, decimals); - emit log_named_decimal_uint(" Right", b, decimals); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta, 18); - emit log_named_decimal_uint(" % Delta", percentDelta, 18); - fail(); - } - } - - function assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% - uint256 decimals, - string memory err - ) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - } - - function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_int(" Left", a); - emit log_named_int(" Right", b); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta, 18); - emit log_named_decimal_uint(" % Delta", percentDelta, 18); - fail(); - } - } - - function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRel(a, b, maxPercentDelta); - } - } - - function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual { - if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log("Error: a ~= b not satisfied [int]"); - emit log_named_decimal_int(" Left", a, decimals); - emit log_named_decimal_int(" Right", b, decimals); - emit log_named_decimal_uint(" Max % Delta", maxPercentDelta, 18); - emit log_named_decimal_uint(" % Delta", percentDelta, 18); - fail(); - } - } - - function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err) - internal - virtual - { - if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. - - uint256 percentDelta = stdMath.percentDelta(a, b); - - if (percentDelta > maxPercentDelta) { - emit log_named_string("Error", err); - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - } - - function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { - assertEqCall(target, callDataA, target, callDataB, true); - } - - function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) - internal - virtual - { - assertEqCall(targetA, callDataA, targetB, callDataB, true); - } - - function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) - internal - virtual - { - assertEqCall(target, callDataA, target, callDataB, strictRevertData); - } - - function assertEqCall( - address targetA, - bytes memory callDataA, - address targetB, - bytes memory callDataB, - bool strictRevertData - ) internal virtual { - (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); - (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); - - if (successA && successB) { - assertEq(returnDataA, returnDataB, "Call return data does not match"); - } - - if (!successA && !successB && strictRevertData) { - assertEq(returnDataA, returnDataB, "Call revert data does not match"); - } - - if (!successA && successB) { - emit log("Error: Calls were not equal"); - emit log_named_bytes(" Left call revert data", returnDataA); - emit log_named_bytes(" Right call return data", returnDataB); - fail(); - } - - if (successA && !successB) { - emit log("Error: Calls were not equal"); - emit log_named_bytes(" Left call return data", returnDataA); - emit log_named_bytes(" Right call revert data", returnDataB); - fail(); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdChains.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdChains.sol deleted file mode 100644 index b1f0e6d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdChains.sol +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {VmSafe} from "./Vm.sol"; - -/** - * StdChains provides information about EVM compatible chains that can be used in scripts/tests. - * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are - * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of - * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the - * alias used in this contract, which can be found as the first argument to the - * `setChainWithDefaultRpcUrl` call in the `initialize` function. - * - * There are two main ways to use this contract: - * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or - * `setChain(string memory chainAlias, Chain memory chain)` - * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. - * - * The first time either of those are used, chains are initialized with the default set of RPC URLs. - * This is done in `initialize`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in - * `defaultRpcUrls`. - * - * The `setChain` function is straightforward, and it simply saves off the given chain data. - * - * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say - * we want to retrieve `mainnet`'s RPC URL: - * - If you haven't set any mainnet chain info with `setChain`, you haven't specified that - * chain in `foundry.toml` and no env var is set, the default data and RPC URL will be returned. - * - If you have set a mainnet RPC URL in `foundry.toml` it will return that, if valid (e.g. if - * a URL is given or if an environment variable is given and that environment variable exists). - * Otherwise, the default data is returned. - * - If you specified data with `setChain` it will return that. - * - * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. - */ -abstract contract StdChains { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - bool private initialized; - - struct ChainData { - string name; - uint256 chainId; - string rpcUrl; - } - - struct Chain { - // The chain name. - string name; - // The chain's Chain ID. - uint256 chainId; - // The chain's alias. (i.e. what gets specified in `foundry.toml`). - string chainAlias; - // A default RPC endpoint for this chain. - // NOTE: This default RPC URL is included for convenience to facilitate quick tests and - // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy - // usage as you will be throttled and this is a disservice to others who need this endpoint. - string rpcUrl; - } - - // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. - mapping(string => Chain) private chains; - // Maps from the chain's alias to it's default RPC URL. - mapping(string => string) private defaultRpcUrls; - // Maps from a chain ID to it's alias. - mapping(uint256 => string) private idToAlias; - - bool private fallbackToDefaultRpcUrls = true; - - // The RPC URL will be fetched from config or defaultRpcUrls if possible. - function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { - require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); - - initialize(); - chain = chains[chainAlias]; - require( - chain.chainId != 0, - string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) - ); - - chain = getChainWithUpdatedRpcUrl(chainAlias, chain); - } - - function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { - require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); - initialize(); - string memory chainAlias = idToAlias[chainId]; - - chain = chains[chainAlias]; - - require( - chain.chainId != 0, - string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) - ); - - chain = getChainWithUpdatedRpcUrl(chainAlias, chain); - } - - // set chain info, with priority to argument's rpcUrl field. - function setChain(string memory chainAlias, ChainData memory chain) internal virtual { - require( - bytes(chainAlias).length != 0, - "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." - ); - - require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); - - initialize(); - string memory foundAlias = idToAlias[chain.chainId]; - - require( - bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), - string( - abi.encodePacked( - "StdChains setChain(string,ChainData): Chain ID ", - vm.toString(chain.chainId), - " already used by \"", - foundAlias, - "\"." - ) - ) - ); - - uint256 oldChainId = chains[chainAlias].chainId; - delete idToAlias[oldChainId]; - - chains[chainAlias] = - Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); - idToAlias[chain.chainId] = chainAlias; - } - - // set chain info, with priority to argument's rpcUrl field. - function setChain(string memory chainAlias, Chain memory chain) internal virtual { - setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); - } - - function _toUpper(string memory str) private pure returns (string memory) { - bytes memory strb = bytes(str); - bytes memory copy = new bytes(strb.length); - for (uint256 i = 0; i < strb.length; i++) { - bytes1 b = strb[i]; - if (b >= 0x61 && b <= 0x7A) { - copy[i] = bytes1(uint8(b) - 32); - } else { - copy[i] = b; - } - } - return string(copy); - } - - // lookup rpcUrl, in descending order of priority: - // current -> config (foundry.toml) -> environment variable -> default - function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) { - if (bytes(chain.rpcUrl).length == 0) { - try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { - chain.rpcUrl = configRpcUrl; - } catch (bytes memory err) { - string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); - if (fallbackToDefaultRpcUrls) { - chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); - } else { - chain.rpcUrl = vm.envString(envName); - } - // distinguish 'not found' from 'cannot read' - bytes memory notFoundError = - abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); - if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, err), mload(err)) - } - } - } - } - return chain; - } - - function setFallbackToDefaultRpcUrls(bool useDefault) internal { - fallbackToDefaultRpcUrls = useDefault; - } - - function initialize() private { - if (initialized) return; - - initialized = true; - - // If adding an RPC here, make sure to test the default RPC URL in `testRpcs` - setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); - setChainWithDefaultRpcUrl( - "mainnet", ChainData("Mainnet", 1, "https://mainnet.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b") - ); - setChainWithDefaultRpcUrl( - "goerli", ChainData("Goerli", 5, "https://goerli.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b") - ); - setChainWithDefaultRpcUrl( - "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b") - ); - setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); - setChainWithDefaultRpcUrl("optimism_goerli", ChainData("Optimism Goerli", 420, "https://goerli.optimism.io")); - setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl( - "arbitrum_one_goerli", ChainData("Arbitrum One Goerli", 421613, "https://goerli-rollup.arbitrum.io/rpc") - ); - setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); - setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); - setChainWithDefaultRpcUrl( - "polygon_mumbai", ChainData("Polygon Mumbai", 80001, "https://rpc-mumbai.maticvigil.com") - ); - setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); - setChainWithDefaultRpcUrl( - "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") - ); - setChainWithDefaultRpcUrl( - "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") - ); - setChainWithDefaultRpcUrl( - "bnb_smart_chain_testnet", - ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") - ); - setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); - } - - // set chain info, with priority to chainAlias' rpc url in foundry.toml - function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { - string memory rpcUrl = chain.rpcUrl; - defaultRpcUrls[chainAlias] = rpcUrl; - chain.rpcUrl = ""; - setChain(chainAlias, chain); - chain.rpcUrl = rpcUrl; // restore argument - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdCheats.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdCheats.sol deleted file mode 100644 index 126d831..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdCheats.sol +++ /dev/null @@ -1,624 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {Vm} from "./Vm.sol"; - -abstract contract StdCheatsSafe { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - bool private gasMeteringOff; - - // Data structures to parse Transaction objects from the broadcast artifact - // that conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawTx1559 { - string[] arguments; - address contractAddress; - string contractName; - // json value name = function - string functionSig; - bytes32 hash; - // json value name = tx - RawTx1559Detail txDetail; - // json value name = type - string opcode; - } - - struct RawTx1559Detail { - AccessList[] accessList; - bytes data; - address from; - bytes gas; - bytes nonce; - address to; - bytes txType; - bytes value; - } - - struct Tx1559 { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - bytes32 hash; - Tx1559Detail txDetail; - string opcode; - } - - struct Tx1559Detail { - AccessList[] accessList; - bytes data; - address from; - uint256 gas; - uint256 nonce; - address to; - uint256 txType; - uint256 value; - } - - // Data structures to parse Transaction objects from the broadcast artifact - // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct TxLegacy { - string[] arguments; - address contractAddress; - string contractName; - string functionSig; - string hash; - string opcode; - TxDetailLegacy transaction; - } - - struct TxDetailLegacy { - AccessList[] accessList; - uint256 chainId; - bytes data; - address from; - uint256 gas; - uint256 gasPrice; - bytes32 hash; - uint256 nonce; - bytes1 opcode; - bytes32 r; - bytes32 s; - uint256 txType; - address to; - uint8 v; - uint256 value; - } - - struct AccessList { - address accessAddress; - bytes32[] storageKeys; - } - - // Data structures to parse Receipt objects from the broadcast artifact. - // The Raw structs is what is parsed from the JSON - // and then converted to the one that is used by the user for better UX. - - struct RawReceipt { - bytes32 blockHash; - bytes blockNumber; - address contractAddress; - bytes cumulativeGasUsed; - bytes effectiveGasPrice; - address from; - bytes gasUsed; - RawReceiptLog[] logs; - bytes logsBloom; - bytes status; - address to; - bytes32 transactionHash; - bytes transactionIndex; - } - - struct Receipt { - bytes32 blockHash; - uint256 blockNumber; - address contractAddress; - uint256 cumulativeGasUsed; - uint256 effectiveGasPrice; - address from; - uint256 gasUsed; - ReceiptLog[] logs; - bytes logsBloom; - uint256 status; - address to; - bytes32 transactionHash; - uint256 transactionIndex; - } - - // Data structures to parse the entire broadcast artifact, assuming the - // transactions conform to EIP1559. - - struct EIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - Receipt[] receipts; - uint256 timestamp; - Tx1559[] transactions; - TxReturn[] txReturns; - } - - struct RawEIP1559ScriptArtifact { - string[] libraries; - string path; - string[] pending; - RawReceipt[] receipts; - TxReturn[] txReturns; - uint256 timestamp; - RawTx1559[] transactions; - } - - struct RawReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - bytes blockNumber; - bytes data; - bytes logIndex; - bool removed; - bytes32[] topics; - bytes32 transactionHash; - bytes transactionIndex; - bytes transactionLogIndex; - } - - struct ReceiptLog { - // json value = address - address logAddress; - bytes32 blockHash; - uint256 blockNumber; - bytes data; - uint256 logIndex; - bytes32[] topics; - uint256 transactionIndex; - uint256 transactionLogIndex; - bool removed; - } - - struct TxReturn { - string internalType; - string value; - } - - function assumeNoPrecompiles(address addr) internal virtual { - // Assembly required since `block.chainid` was introduced in 0.8.0. - uint256 chainId; - assembly { - chainId := chainid() - } - assumeNoPrecompiles(addr, chainId); - } - - function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual { - // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific - // address), but the same rationale for excluding them applies so we include those too. - - // These should be present on all EVM-compatible chains. - vm.assume(addr < address(0x1) || addr > address(0x9)); - - // forgefmt: disable-start - if (chainId == 10 || chainId == 420) { - // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 - vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); - } else if (chainId == 42161 || chainId == 421613) { - // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains - vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); - } else if (chainId == 43114 || chainId == 43113) { - // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 - vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); - vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); - vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); - } - // forgefmt: disable-end - } - - function readEIP1559ScriptArtifact(string memory path) - internal - view - virtual - returns (EIP1559ScriptArtifact memory) - { - string memory data = vm.readFile(path); - bytes memory parsedData = vm.parseJson(data); - RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); - EIP1559ScriptArtifact memory artifact; - artifact.libraries = rawArtifact.libraries; - artifact.path = rawArtifact.path; - artifact.timestamp = rawArtifact.timestamp; - artifact.pending = rawArtifact.pending; - artifact.txReturns = rawArtifact.txReturns; - artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); - artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); - return artifact; - } - - function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { - Tx1559[] memory txs = new Tx1559[](rawTxs.length); - for (uint256 i; i < rawTxs.length; i++) { - txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); - } - return txs; - } - - function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { - Tx1559 memory transaction; - transaction.arguments = rawTx.arguments; - transaction.contractName = rawTx.contractName; - transaction.functionSig = rawTx.functionSig; - transaction.hash = rawTx.hash; - transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); - transaction.opcode = rawTx.opcode; - return transaction; - } - - function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) - internal - pure - virtual - returns (Tx1559Detail memory) - { - Tx1559Detail memory txDetail; - txDetail.data = rawDetail.data; - txDetail.from = rawDetail.from; - txDetail.to = rawDetail.to; - txDetail.nonce = _bytesToUint(rawDetail.nonce); - txDetail.txType = _bytesToUint(rawDetail.txType); - txDetail.value = _bytesToUint(rawDetail.value); - txDetail.gas = _bytesToUint(rawDetail.gas); - txDetail.accessList = rawDetail.accessList; - return txDetail; - } - - function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); - RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); - return rawToConvertedEIPTx1559s(rawTxs); - } - - function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); - return rawToConvertedEIPTx1559(rawTx); - } - - // Analogous to readTransactions, but for receipts. - function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { - string memory deployData = vm.readFile(path); - bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); - RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); - return rawToConvertedReceipts(rawReceipts); - } - - function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { - string memory deployData = vm.readFile(path); - string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); - bytes memory parsedDeployData = vm.parseJson(deployData, key); - RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); - return rawToConvertedReceipt(rawReceipt); - } - - function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { - Receipt[] memory receipts = new Receipt[](rawReceipts.length); - for (uint256 i; i < rawReceipts.length; i++) { - receipts[i] = rawToConvertedReceipt(rawReceipts[i]); - } - return receipts; - } - - function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { - Receipt memory receipt; - receipt.blockHash = rawReceipt.blockHash; - receipt.to = rawReceipt.to; - receipt.from = rawReceipt.from; - receipt.contractAddress = rawReceipt.contractAddress; - receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); - receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); - receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); - receipt.status = _bytesToUint(rawReceipt.status); - receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); - receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); - receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); - receipt.logsBloom = rawReceipt.logsBloom; - receipt.transactionHash = rawReceipt.transactionHash; - return receipt; - } - - function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) - internal - pure - virtual - returns (ReceiptLog[] memory) - { - ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); - for (uint256 i; i < rawLogs.length; i++) { - logs[i].logAddress = rawLogs[i].logAddress; - logs[i].blockHash = rawLogs[i].blockHash; - logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); - logs[i].data = rawLogs[i].data; - logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); - logs[i].topics = rawLogs[i].topics; - logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); - logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); - logs[i].removed = rawLogs[i].removed; - } - return logs; - } - - // Deploy a contract by fetching the contract bytecode from - // the artifacts directory - // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` - function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); - } - - function deployCode(string memory what) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); - } - - /// @dev deploy contract with value on construction - function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); - } - - function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { - bytes memory bytecode = vm.getCode(what); - /// @solidity memory-safe-assembly - assembly { - addr := create(val, add(bytecode, 0x20), mload(bytecode)) - } - - require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); - } - - // creates a labeled address and the corresponding private key - function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { - privateKey = uint256(keccak256(abi.encodePacked(name))); - addr = vm.addr(privateKey); - vm.label(addr, name); - } - - // creates a labeled address - function makeAddr(string memory name) internal virtual returns (address addr) { - (addr,) = makeAddrAndKey(name); - } - - function deriveRememberKey(string memory mnemonic, uint32 index) - internal - virtual - returns (address who, uint256 privateKey) - { - privateKey = vm.deriveKey(mnemonic, index); - who = vm.rememberKey(privateKey); - } - - function _bytesToUint(bytes memory b) private pure returns (uint256) { - require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); - return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); - } - - function isFork() internal view virtual returns (bool status) { - try vm.activeFork() { - status = true; - } catch (bytes memory) {} - } - - modifier skipWhenForking() { - if (!isFork()) { - _; - } - } - - modifier skipWhenNotForking() { - if (isFork()) { - _; - } - } - - modifier noGasMetering() { - vm.pauseGasMetering(); - // To prevent turning gas monitoring back on with nested functions that use this modifier, - // we check if gasMetering started in the off position. If it did, we don't want to turn - // it back on until we exit the top level function that used the modifier - // - // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. - // funcA will have `gasStartedOff` as false, funcB will have it as true, - // so we only turn metering back on at the end of the funcA - bool gasStartedOff = gasMeteringOff; - gasMeteringOff = true; - - _; - - // if gas metering was on when this modifier was called, turn it back on at the end - if (!gasStartedOff) { - gasMeteringOff = false; - vm.resumeGasMetering(); - } - } - - // a cheat for fuzzing addresses that are payable only - // see https://github.com/foundry-rs/foundry/issues/3631 - function assumePayable(address addr) internal virtual { - (bool success,) = payable(addr).call{value: 0}(""); - vm.assume(success); - } -} - -// Wrappers around cheatcodes to avoid footguns -abstract contract StdCheats is StdCheatsSafe { - using stdStorage for StdStorage; - - StdStorage private stdstore; - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - // Skip forward or rewind time by the specified number of seconds - function skip(uint256 time) internal virtual { - vm.warp(block.timestamp + time); - } - - function rewind(uint256 time) internal virtual { - vm.warp(block.timestamp - time); - } - - // Setup a prank from an address that has some ether - function hoax(address msgSender) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.prank(msgSender); - } - - function hoax(address msgSender, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.prank(msgSender); - } - - function hoax(address msgSender, address origin) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.prank(msgSender, origin); - } - - function hoax(address msgSender, address origin, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.prank(msgSender, origin); - } - - // Start perpetual prank from an address that has some ether - function startHoax(address msgSender) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.startPrank(msgSender); - } - - function startHoax(address msgSender, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.startPrank(msgSender); - } - - // Start perpetual prank from an address that has some ether - // tx.origin is set to the origin parameter - function startHoax(address msgSender, address origin) internal virtual { - vm.deal(msgSender, 1 << 128); - vm.startPrank(msgSender, origin); - } - - function startHoax(address msgSender, address origin, uint256 give) internal virtual { - vm.deal(msgSender, give); - vm.startPrank(msgSender, origin); - } - - function changePrank(address msgSender) internal virtual { - vm.stopPrank(); - vm.startPrank(msgSender); - } - - // The same as Vm's `deal` - // Use the alternative signature for ERC20 tokens - function deal(address to, uint256 give) internal virtual { - vm.deal(to, give); - } - - // Set the balance of an account for any ERC20 token - // Use the alternative signature to update `totalSupply` - function deal(address token, address to, uint256 give) internal virtual { - deal(token, to, give, false); - } - - // Set the balance of an account for any ERC1155 token - // Use the alternative signature to update `totalSupply` - function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { - dealERC1155(token, to, id, give, false); - } - - function deal(address token, address to, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd)); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0x18160ddd).checked_write(totSup); - } - } - - function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { - // get current balance - (, bytes memory balData) = token.call(abi.encodeWithSelector(0x00fdd58e, to, id)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); - - // update total supply - if (adjust) { - (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0xbd85b039, id)); - require( - totSupData.length != 0, - "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." - ); - uint256 totSup = abi.decode(totSupData, (uint256)); - if (give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); - } - } - - function dealERC721(address token, address to, uint256 id) internal virtual { - // check if token id is already minted and the actual owner. - (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); - require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); - - // get owner current balance - (, bytes memory fromBalData) = token.call(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); - uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); - - // get new user current balance - (, bytes memory toBalData) = token.call(abi.encodeWithSelector(0x70a08231, to)); - uint256 toPrevBal = abi.decode(toBalData, (uint256)); - - // update balances - stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); - stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); - - // update owner - stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdError.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdError.sol deleted file mode 100644 index a302191..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdError.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT -// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test -pragma solidity >=0.6.2 <0.9.0; - -library stdError { - bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); - bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); - bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); - bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); - bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); - bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); - bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); - bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); - bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdInvariant.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdInvariant.sol deleted file mode 100644 index efa1129..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdInvariant.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -contract StdInvariant { - struct FuzzSelector { - address addr; - bytes4[] selectors; - } - - address[] private _excludedContracts; - address[] private _excludedSenders; - address[] private _targetedContracts; - address[] private _targetedSenders; - - string[] private _excludedArtifacts; - string[] private _targetedArtifacts; - - FuzzSelector[] private _targetedArtifactSelectors; - FuzzSelector[] private _targetedSelectors; - - // Functions for users: - // These are intended to be called in tests. - - function excludeContract(address newExcludedContract_) internal { - _excludedContracts.push(newExcludedContract_); - } - - function excludeSender(address newExcludedSender_) internal { - _excludedSenders.push(newExcludedSender_); - } - - function excludeArtifact(string memory newExcludedArtifact_) internal { - _excludedArtifacts.push(newExcludedArtifact_); - } - - function targetArtifact(string memory newTargetedArtifact_) internal { - _targetedArtifacts.push(newTargetedArtifact_); - } - - function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal { - _targetedArtifactSelectors.push(newTargetedArtifactSelector_); - } - - function targetContract(address newTargetedContract_) internal { - _targetedContracts.push(newTargetedContract_); - } - - function targetSelector(FuzzSelector memory newTargetedSelector_) internal { - _targetedSelectors.push(newTargetedSelector_); - } - - function targetSender(address newTargetedSender_) internal { - _targetedSenders.push(newTargetedSender_); - } - - // Functions for forge: - // These are called by forge to run invariant tests and don't need to be called in tests. - - function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { - excludedArtifacts_ = _excludedArtifacts; - } - - function excludeContracts() public view returns (address[] memory excludedContracts_) { - excludedContracts_ = _excludedContracts; - } - - function excludeSenders() public view returns (address[] memory excludedSenders_) { - excludedSenders_ = _excludedSenders; - } - - function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { - targetedArtifacts_ = _targetedArtifacts; - } - - function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) { - targetedArtifactSelectors_ = _targetedArtifactSelectors; - } - - function targetContracts() public view returns (address[] memory targetedContracts_) { - targetedContracts_ = _targetedContracts; - } - - function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { - targetedSelectors_ = _targetedSelectors; - } - - function targetSenders() public view returns (address[] memory targetedSenders_) { - targetedSenders_ = _targetedSenders; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdJson.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdJson.sol deleted file mode 100644 index 014e6b1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdJson.sol +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.0 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {VmSafe} from "./Vm.sol"; - -// Helpers for parsing and writing JSON files -// To parse: -// ``` -// using stdJson for string; -// string memory json = vm.readFile("some_peth"); -// json.parseUint(""); -// ``` -// To write: -// ``` -// using stdJson for string; -// string memory json = "deploymentArtifact"; -// Contract contract = new Contract(); -// json.serialize("contractAddress", address(contract)); -// json = json.serialize("deploymentTimes", uint(1)); -// // store the stringified JSON to the 'json' variable we have been using as a key -// // as we won't need it any longer -// string memory json2 = "finalArtifact"; -// string memory final = json2.serialize("depArtifact", json); -// final.write(""); -// ``` - -library stdJson { - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { - return vm.parseJson(json, key); - } - - function readUint(string memory json, string memory key) internal returns (uint256) { - return vm.parseJsonUint(json, key); - } - - function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) { - return vm.parseJsonUintArray(json, key); - } - - function readInt(string memory json, string memory key) internal returns (int256) { - return vm.parseJsonInt(json, key); - } - - function readIntArray(string memory json, string memory key) internal returns (int256[] memory) { - return vm.parseJsonIntArray(json, key); - } - - function readBytes32(string memory json, string memory key) internal returns (bytes32) { - return vm.parseJsonBytes32(json, key); - } - - function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) { - return vm.parseJsonBytes32Array(json, key); - } - - function readString(string memory json, string memory key) internal returns (string memory) { - return vm.parseJsonString(json, key); - } - - function readStringArray(string memory json, string memory key) internal returns (string[] memory) { - return vm.parseJsonStringArray(json, key); - } - - function readAddress(string memory json, string memory key) internal returns (address) { - return vm.parseJsonAddress(json, key); - } - - function readAddressArray(string memory json, string memory key) internal returns (address[] memory) { - return vm.parseJsonAddressArray(json, key); - } - - function readBool(string memory json, string memory key) internal returns (bool) { - return vm.parseJsonBool(json, key); - } - - function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) { - return vm.parseJsonBoolArray(json, key); - } - - function readBytes(string memory json, string memory key) internal returns (bytes memory) { - return vm.parseJsonBytes(json, key); - } - - function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) { - return vm.parseJsonBytesArray(json, key); - } - - function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bool[] memory value) - internal - returns (string memory) - { - return vm.serializeBool(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, uint256[] memory value) - internal - returns (string memory) - { - return vm.serializeUint(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, int256[] memory value) - internal - returns (string memory) - { - return vm.serializeInt(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, address[] memory value) - internal - returns (string memory) - { - return vm.serializeAddress(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes32[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes32(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, bytes[] memory value) - internal - returns (string memory) - { - return vm.serializeBytes(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function serialize(string memory jsonKey, string memory key, string[] memory value) - internal - returns (string memory) - { - return vm.serializeString(jsonKey, key, value); - } - - function write(string memory jsonKey, string memory path) internal { - vm.writeJson(jsonKey, path); - } - - function write(string memory jsonKey, string memory path, string memory valueKey) internal { - vm.writeJson(jsonKey, path, valueKey); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdMath.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdMath.sol deleted file mode 100644 index 459523b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdMath.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -library stdMath { - int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; - - function abs(int256 a) internal pure returns (uint256) { - // Required or it will fail when `a = type(int256).min` - if (a == INT256_MIN) { - return 57896044618658097711785492504343953926634992332820282019728792003956564819968; - } - - return uint256(a > 0 ? a : -a); - } - - function delta(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? a - b : b - a; - } - - function delta(int256 a, int256 b) internal pure returns (uint256) { - // a and b are of the same sign - // this works thanks to two's complement, the left-most bit is the sign bit - if ((a ^ b) > -1) { - return delta(abs(a), abs(b)); - } - - // a and b are of opposite signs - return abs(a) + abs(b); - } - - function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - - return absDelta * 1e18 / b; - } - - function percentDelta(int256 a, int256 b) internal pure returns (uint256) { - uint256 absDelta = delta(a, b); - uint256 absB = abs(b); - - return absDelta * 1e18 / absB; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdStorage.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdStorage.sol deleted file mode 100644 index 73a5ceb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdStorage.sol +++ /dev/null @@ -1,327 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -import {Vm} from "./Vm.sol"; - -struct StdStorage { - mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; - mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds; - bytes32[] _keys; - bytes4 _sig; - uint256 _depth; - address _target; - bytes32 _set; -} - -library stdStorageSafe { - event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); - event WARNING_UninitedSlot(address who, uint256 slot); - - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return bytes4(keccak256(bytes(sigStr))); - } - - /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against - // slot complexity: - // if flat, will be bytes32(uint256(uint)); - // if map, will be keccak256(abi.encode(key, uint(slot))); - // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); - // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); - function find(StdStorage storage self) internal returns (uint256) { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - // calldata to test against - if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - vm.record(); - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - (bytes32[] memory reads,) = vm.accesses(address(who)); - if (reads.length == 1) { - bytes32 curr = vm.load(who, reads[0]); - if (curr == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[0])); - } - if (fdat != curr) { - require( - false, - "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." - ); - } - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - } else if (reads.length > 1) { - for (uint256 i = 0; i < reads.length; i++) { - bytes32 prev = vm.load(who, reads[i]); - if (prev == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[i])); - } - // store - vm.store(who, reads[i], bytes32(hex"1337")); - bool success; - bytes memory rdat; - { - (success, rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - - if (success && fdat == bytes32(hex"1337")) { - // we found which of the slots is the actual one - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - vm.store(who, reads[i], prev); - break; - } - vm.store(who, reads[i], prev); - } - } else { - revert("stdStorage find(StdStorage): No storage use detected for target."); - } - - require( - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], - "stdStorage find(StdStorage): Slot(s) not found." - ); - - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - self._target = _target; - return self; - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - self._sig = _sig; - return self; - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - self._sig = sigs(_sig); - return self; - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - self._keys.push(bytes32(uint256(uint160(who)))); - return self; - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - self._keys.push(bytes32(amt)); - return self; - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - self._keys.push(key); - return self; - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - self._depth = _depth; - return self; - } - - function read(StdStorage storage self) private returns (bytes memory) { - address t = self._target; - uint256 s = find(self); - return abi.encode(vm.load(t, bytes32(s))); - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return abi.decode(read(self), (bytes32)); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - int256 v = read_int(self); - if (v == 0) return false; - if (v == 1) return true; - revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - } - - function read_address(StdStorage storage self) internal returns (address) { - return abi.decode(read(self), (address)); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return abi.decode(read(self), (uint256)); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return abi.decode(read(self), (int256)); - } - - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} - -library stdStorage { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - function sigs(string memory sigStr) internal pure returns (bytes4) { - return stdStorageSafe.sigs(sigStr); - } - - function find(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.find(self); - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - return stdStorageSafe.target(self, _target); - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - return stdStorageSafe.sig(self, _sig); - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, who); - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, amt); - } - - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - return stdStorageSafe.with_key(self, key); - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - return stdStorageSafe.depth(self, _depth); - } - - function checked_write(StdStorage storage self, address who) internal { - checked_write(self, bytes32(uint256(uint160(who)))); - } - - function checked_write(StdStorage storage self, uint256 amt) internal { - checked_write(self, bytes32(amt)); - } - - function checked_write(StdStorage storage self, bool write) internal { - bytes32 t; - /// @solidity memory-safe-assembly - assembly { - t := write - } - checked_write(self, t); - } - - function checked_write(StdStorage storage self, bytes32 set) internal { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - find(self); - } - bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]); - - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32 * field_depth); - } - bytes32 curr = vm.load(who, slot); - - if (fdat != curr) { - require( - false, - "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." - ); - } - vm.store(who, slot, set); - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - } - - function read_bytes32(StdStorage storage self) internal returns (bytes32) { - return stdStorageSafe.read_bytes32(self); - } - - function read_bool(StdStorage storage self) internal returns (bool) { - return stdStorageSafe.read_bool(self); - } - - function read_address(StdStorage storage self) internal returns (address) { - return stdStorageSafe.read_address(self); - } - - function read_uint(StdStorage storage self) internal returns (uint256) { - return stdStorageSafe.read_uint(self); - } - - function read_int(StdStorage storage self) internal returns (int256) { - return stdStorageSafe.read_int(self); - } - - // Private function so needs to be copied over - function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint256 i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - // Private function so needs to be copied over - function flatten(bytes32[] memory b) private pure returns (bytes memory) { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - /// @solidity memory-safe-assembly - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdStyle.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdStyle.sol deleted file mode 100644 index 46f4e81..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdStyle.sol +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -import {Vm} from "./Vm.sol"; - -library StdStyle { - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); - - string constant RED = "\u001b[91m"; - string constant GREEN = "\u001b[92m"; - string constant YELLOW = "\u001b[93m"; - string constant BLUE = "\u001b[94m"; - string constant MAGENTA = "\u001b[95m"; - string constant CYAN = "\u001b[96m"; - string constant BOLD = "\u001b[1m"; - string constant DIM = "\u001b[2m"; - string constant ITALIC = "\u001b[3m"; - string constant UNDERLINE = "\u001b[4m"; - string constant INVERSE = "\u001b[7m"; - string constant RESET = "\u001b[0m"; - - function styleConcat(string memory style, string memory self) private pure returns (string memory) { - return string(abi.encodePacked(style, self, RESET)); - } - - function red(string memory self) internal pure returns (string memory) { - return styleConcat(RED, self); - } - - function red(uint256 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(int256 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(address self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function red(bool self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function redBytes(bytes memory self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function redBytes32(bytes32 self) internal pure returns (string memory) { - return red(vm.toString(self)); - } - - function green(string memory self) internal pure returns (string memory) { - return styleConcat(GREEN, self); - } - - function green(uint256 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(int256 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(address self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function green(bool self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function greenBytes(bytes memory self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function greenBytes32(bytes32 self) internal pure returns (string memory) { - return green(vm.toString(self)); - } - - function yellow(string memory self) internal pure returns (string memory) { - return styleConcat(YELLOW, self); - } - - function yellow(uint256 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(int256 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(address self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellow(bool self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellowBytes(bytes memory self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function yellowBytes32(bytes32 self) internal pure returns (string memory) { - return yellow(vm.toString(self)); - } - - function blue(string memory self) internal pure returns (string memory) { - return styleConcat(BLUE, self); - } - - function blue(uint256 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(int256 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(address self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blue(bool self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blueBytes(bytes memory self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function blueBytes32(bytes32 self) internal pure returns (string memory) { - return blue(vm.toString(self)); - } - - function magenta(string memory self) internal pure returns (string memory) { - return styleConcat(MAGENTA, self); - } - - function magenta(uint256 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(int256 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(address self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magenta(bool self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magentaBytes(bytes memory self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function magentaBytes32(bytes32 self) internal pure returns (string memory) { - return magenta(vm.toString(self)); - } - - function cyan(string memory self) internal pure returns (string memory) { - return styleConcat(CYAN, self); - } - - function cyan(uint256 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(int256 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(address self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyan(bool self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyanBytes(bytes memory self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function cyanBytes32(bytes32 self) internal pure returns (string memory) { - return cyan(vm.toString(self)); - } - - function bold(string memory self) internal pure returns (string memory) { - return styleConcat(BOLD, self); - } - - function bold(uint256 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(int256 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(address self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function bold(bool self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function boldBytes(bytes memory self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function boldBytes32(bytes32 self) internal pure returns (string memory) { - return bold(vm.toString(self)); - } - - function dim(string memory self) internal pure returns (string memory) { - return styleConcat(DIM, self); - } - - function dim(uint256 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(int256 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(address self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dim(bool self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dimBytes(bytes memory self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function dimBytes32(bytes32 self) internal pure returns (string memory) { - return dim(vm.toString(self)); - } - - function italic(string memory self) internal pure returns (string memory) { - return styleConcat(ITALIC, self); - } - - function italic(uint256 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(int256 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(address self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italic(bool self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italicBytes(bytes memory self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function italicBytes32(bytes32 self) internal pure returns (string memory) { - return italic(vm.toString(self)); - } - - function underline(string memory self) internal pure returns (string memory) { - return styleConcat(UNDERLINE, self); - } - - function underline(uint256 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(int256 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(address self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underline(bool self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underlineBytes(bytes memory self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function underlineBytes32(bytes32 self) internal pure returns (string memory) { - return underline(vm.toString(self)); - } - - function inverse(string memory self) internal pure returns (string memory) { - return styleConcat(INVERSE, self); - } - - function inverse(uint256 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(int256 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(address self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverse(bool self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverseBytes(bytes memory self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } - - function inverseBytes32(bytes32 self) internal pure returns (string memory) { - return inverse(vm.toString(self)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdUtils.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdUtils.sol deleted file mode 100644 index f68d11f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/StdUtils.sol +++ /dev/null @@ -1,189 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import {IMulticall3} from "./interfaces/IMulticall3.sol"; -// TODO Remove import. -import {VmSafe} from "./Vm.sol"; - -abstract contract StdUtils { - /*////////////////////////////////////////////////////////////////////////// - CONSTANTS - //////////////////////////////////////////////////////////////////////////*/ - - IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); - VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); - address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; - uint256 private constant INT256_MIN_ABS = - 57896044618658097711785492504343953926634992332820282019728792003956564819968; - uint256 private constant UINT256_MAX = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; - - // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. - address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; - - /*////////////////////////////////////////////////////////////////////////// - INTERNAL FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { - require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); - // If x is between min and max, return x directly. This is to ensure that dictionary values - // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 - if (x >= min && x <= max) return x; - - uint256 size = max - min + 1; - - // If the value is 0, 1, 2, 3, warp that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. - // This helps ensure coverage of the min/max values. - if (x <= 3 && size > x) return min + x; - if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); - - // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. - if (x > max) { - uint256 diff = x - max; - uint256 rem = diff % size; - if (rem == 0) return max; - result = min + rem - 1; - } else if (x < min) { - uint256 diff = min - x; - uint256 rem = diff % size; - if (rem == 0) return min; - result = max - rem + 1; - } - } - - function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) { - result = _bound(x, min, max); - console2_log("Bound Result", result); - } - - function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) { - require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); - - // Shifting all int256 values to uint256 to use _bound function. The range of two types are: - // int256 : -(2**255) ~ (2**255 - 1) - // uint256: 0 ~ (2**256 - 1) - // So, add 2**255, INT256_MIN_ABS to the integer values. - // - // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. - // So, use `~uint256(x) + 1` instead. - uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); - uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); - uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); - - uint256 y = _bound(_x, _min, _max); - - // To move it back to int256 value, subtract INT256_MIN_ABS at here. - result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); - console2_log("Bound result", vm.toString(result)); - } - - function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { - require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); - return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); - } - - /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce - /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol) - function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { - // forgefmt: disable-start - // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0. - // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it. - if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))); - if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))); - - // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length. - if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))); - if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))); - if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)))); - // forgefmt: disable-end - - // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp - // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) - // We assume nobody can have a nonce large enough to require more than 32 bytes. - return addressFromLast20Bytes( - keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) - ); - } - - function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) - internal - pure - virtual - returns (address) - { - return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash))); - } - - /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer - function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { - return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY); - } - - /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments - /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode - function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { - return hashInitCode(creationCode, ""); - } - - /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 - /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode - /// @param args the ABI-encoded arguments to the constructor of C - function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { - return keccak256(abi.encodePacked(creationCode, args)); - } - - // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. - function getTokenBalances(address token, address[] memory addresses) - internal - virtual - returns (uint256[] memory balances) - { - uint256 tokenCodeSize; - assembly { - tokenCodeSize := extcodesize(token) - } - require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); - - // ABI encode the aggregate call to Multicall3. - uint256 length = addresses.length; - IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); - for (uint256 i = 0; i < length; ++i) { - // 0x70a08231 = bytes4("balanceOf(address)")) - calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); - } - - // Make the aggregate call. - (, bytes[] memory returnData) = multicall.aggregate(calls); - - // ABI decode the return data and return the balances. - balances = new uint256[](length); - for (uint256 i = 0; i < length; ++i) { - balances[i] = abi.decode(returnData[i], (uint256)); - } - } - - /*////////////////////////////////////////////////////////////////////////// - PRIVATE FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { - return address(uint160(uint256(bytesValue))); - } - - // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. - - function console2_log(string memory p0, uint256 p1) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - status; - } - - function console2_log(string memory p0, string memory p1) private view { - (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,string)", p0, p1)); - status; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Test.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Test.sol deleted file mode 100644 index 9ff5cb8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Test.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -// 💬 ABOUT -// Standard Library's default Test - -// 🧩 MODULES -import {console} from "./console.sol"; -import {console2} from "./console2.sol"; -import {StdAssertions} from "./StdAssertions.sol"; -import {StdChains} from "./StdChains.sol"; -import {StdCheats} from "./StdCheats.sol"; -import {stdError} from "./StdError.sol"; -import {StdInvariant} from "./StdInvariant.sol"; -import {stdJson} from "./StdJson.sol"; -import {stdMath} from "./StdMath.sol"; -import {StdStorage, stdStorage} from "./StdStorage.sol"; -import {StdUtils} from "./StdUtils.sol"; -import {Vm} from "./Vm.sol"; -import {StdStyle} from "./StdStyle.sol"; - -// 📦 BOILERPLATE -import {TestBase} from "./Base.sol"; -import {DSTest} from "ds-test/test.sol"; - -// ⭐️ TEST -abstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase { -// Note: IS_TEST() must return true. -// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76. -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Vm.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Vm.sol deleted file mode 100644 index 99d54e0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/Vm.sol +++ /dev/null @@ -1,409 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -// Cheatcodes are marked as view/pure/none using the following rules: -// 0. A call's observable behaviour includes its return value, logs, reverts and state writes, -// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc), -// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`, -// 3. Otherwise you're `pure`. - -interface VmSafe { - struct Log { - bytes32[] topics; - bytes data; - address emitter; - } - - struct Rpc { - string key; - string url; - } - - struct FsMetadata { - bool isDir; - bool isSymlink; - uint256 length; - bool readOnly; - uint256 modified; - uint256 accessed; - uint256 created; - } - - // Loads a storage slot from an address - function load(address target, bytes32 slot) external view returns (bytes32 data); - // Signs data - function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); - // Gets the address for a given private key - function addr(uint256 privateKey) external pure returns (address keyAddr); - // Gets the nonce of an account - function getNonce(address account) external view returns (uint64 nonce); - // Performs a foreign function call via the terminal - function ffi(string[] calldata commandInput) external returns (bytes memory result); - // Sets environment variables - function setEnv(string calldata name, string calldata value) external; - // Reads environment variables, (name) => (value) - function envBool(string calldata name) external view returns (bool value); - function envUint(string calldata name) external view returns (uint256 value); - function envInt(string calldata name) external view returns (int256 value); - function envAddress(string calldata name) external view returns (address value); - function envBytes32(string calldata name) external view returns (bytes32 value); - function envString(string calldata name) external view returns (string memory value); - function envBytes(string calldata name) external view returns (bytes memory value); - // Reads environment variables as arrays - function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); - function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); - function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); - function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); - function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); - function envString(string calldata name, string calldata delim) external view returns (string[] memory value); - function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); - // Read environment variables with default value - function envOr(string calldata name, bool defaultValue) external returns (bool value); - function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value); - function envOr(string calldata name, int256 defaultValue) external returns (int256 value); - function envOr(string calldata name, address defaultValue) external returns (address value); - function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value); - function envOr(string calldata name, string calldata defaultValue) external returns (string memory value); - function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value); - // Read environment variables as arrays with default value - function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) - external - returns (bool[] memory value); - function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) - external - returns (uint256[] memory value); - function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) - external - returns (int256[] memory value); - function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) - external - returns (address[] memory value); - function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) - external - returns (bytes32[] memory value); - function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) - external - returns (string[] memory value); - function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) - external - returns (bytes[] memory value); - // Records all storage reads and writes - function record() external; - // Gets all accessed reads and write slot from a recording session, for a given address - function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); - // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file - function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); - // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file - function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); - // Labels an address in call traces - function label(address account, string calldata newLabel) external; - // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain - function broadcast() external; - // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain - function broadcast(address signer) external; - // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain - function broadcast(uint256 privateKey) external; - // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain - function startBroadcast() external; - // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain - function startBroadcast(address signer) external; - // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain - function startBroadcast(uint256 privateKey) external; - // Stops collecting onchain transactions - function stopBroadcast() external; - // Reads the entire content of file to string - function readFile(string calldata path) external view returns (string memory data); - // Reads the entire content of file as binary. Path is relative to the project root. - function readFileBinary(string calldata path) external view returns (bytes memory data); - // Get the path of the current project root - function projectRoot() external view returns (string memory path); - // Get the metadata for a file/directory - function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata); - // Reads next line of file to string - function readLine(string calldata path) external view returns (string memory line); - // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. - function writeFile(string calldata path, string calldata data) external; - // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. - // Path is relative to the project root. - function writeFileBinary(string calldata path, bytes calldata data) external; - // Writes line to file, creating a file if it does not exist. - function writeLine(string calldata path, string calldata data) external; - // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. - function closeFile(string calldata path) external; - // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases: - // - Path points to a directory. - // - The file doesn't exist. - // - The user lacks permissions to remove the file. - function removeFile(string calldata path) external; - // Convert values to a string - function toString(address value) external pure returns (string memory stringifiedValue); - function toString(bytes calldata value) external pure returns (string memory stringifiedValue); - function toString(bytes32 value) external pure returns (string memory stringifiedValue); - function toString(bool value) external pure returns (string memory stringifiedValue); - function toString(uint256 value) external pure returns (string memory stringifiedValue); - function toString(int256 value) external pure returns (string memory stringifiedValue); - // Convert values from a string - function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); - function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); - function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); - function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); - function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); - function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); - // Record all the transaction logs - function recordLogs() external; - // Gets all the recorded logs - function getRecordedLogs() external returns (Log[] memory logs); - // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index} - function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); - // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index} - function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) - external - pure - returns (uint256 privateKey); - // Adds a private key to the local forge wallet and returns the address - function rememberKey(uint256 privateKey) external returns (address keyAddr); - // - // parseJson - // - // ---- - // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects - // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in - // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that - // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded - // as tuples, with the attributes in the order in which they are defined. - // For example: json = { 'a': 1, 'b': 0xa4tb......3xs} - // a: uint256 - // b: address - // To decode that json, we need to define a struct or a tuple as follows: - // struct json = { uint256 a; address b; } - // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to - // decode the tuple in that order, and thus fail. - // ---- - // Given a string of JSON, return it as ABI-encoded - function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); - function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); - - // The following parseJson cheatcodes will do type coercion, for the type that they indicate. - // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12' - // and hex numbers '0xEF'. - // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not - // a JSON object. - function parseJsonUint(string calldata, string calldata) external returns (uint256); - function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory); - function parseJsonInt(string calldata, string calldata) external returns (int256); - function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory); - function parseJsonBool(string calldata, string calldata) external returns (bool); - function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory); - function parseJsonAddress(string calldata, string calldata) external returns (address); - function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory); - function parseJsonString(string calldata, string calldata) external returns (string memory); - function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory); - function parseJsonBytes(string calldata, string calldata) external returns (bytes memory); - function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory); - function parseJsonBytes32(string calldata, string calldata) external returns (bytes32); - function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory); - - // Serialize a key and value to a JSON object stored in-memory that can be later written to a file - // It returns the stringified version of the specific JSON file up to that moment. - function serializeBool(string calldata objectKey, string calldata valueKey, bool value) - external - returns (string memory json); - function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) - external - returns (string memory json); - function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) - external - returns (string memory json); - function serializeAddress(string calldata objectKey, string calldata valueKey, address value) - external - returns (string memory json); - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) - external - returns (string memory json); - function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) - external - returns (string memory json); - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) - external - returns (string memory json); - - function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) - external - returns (string memory json); - function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) - external - returns (string memory json); - function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) - external - returns (string memory json); - function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) - external - returns (string memory json); - function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) - external - returns (string memory json); - function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) - external - returns (string memory json); - function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) - external - returns (string memory json); - - // - // writeJson - // - // ---- - // Write a serialized JSON object to a file. If the file exists, it will be overwritten. - // Let's assume we want to write the following JSON to a file: - // - // { "boolean": true, "number": 342, "object": { "title": "finally json serialization" } } - // - // ``` - // string memory json1 = "some key"; - // vm.serializeBool(json1, "boolean", true); - // vm.serializeBool(json1, "number", uint256(342)); - // json2 = "some other key"; - // string memory output = vm.serializeString(json2, "title", "finally json serialization"); - // string memory finalJson = vm.serialize(json1, "object", output); - // vm.writeJson(finalJson, "./output/example.json"); - // ``` - // The critical insight is that every invocation of serialization will return the stringified version of the JSON - // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version - // to serialize them as values to another JSON object. - // - // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..) - // will find the object in-memory that is keyed by "some key". - function writeJson(string calldata json, string calldata path) external; - // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = - // This is useful to replace a specific value of a JSON file, without having to parse the entire thing - function writeJson(string calldata json, string calldata path, string calldata valueKey) external; - // Returns the RPC url for the given alias - function rpcUrl(string calldata rpcAlias) external view returns (string memory json); - // Returns all rpc urls and their aliases `[alias, url][]` - function rpcUrls() external view returns (string[2][] memory urls); - // Returns all rpc urls and their aliases as structs. - function rpcUrlStructs() external view returns (Rpc[] memory urls); - // If the condition is false, discard this run's fuzz inputs and generate new ones. - function assume(bool condition) external pure; - // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. - function pauseGasMetering() external; - // Resumes gas metering (i.e. gas usage is counted again). Noop if already on. - function resumeGasMetering() external; -} - -interface Vm is VmSafe { - // Sets block.timestamp - function warp(uint256 newTimestamp) external; - // Sets block.height - function roll(uint256 newHeight) external; - // Sets block.basefee - function fee(uint256 newBasefee) external; - // Sets block.difficulty - function difficulty(uint256 newDifficulty) external; - // Sets block.chainid - function chainId(uint256 newChainId) external; - // Stores a value to an address' storage slot. - function store(address target, bytes32 slot, bytes32 value) external; - // Sets the nonce of an account; must be higher than the current nonce of the account - function setNonce(address account, uint64 newNonce) external; - // Sets the *next* call's msg.sender to be the input address - function prank(address msgSender) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called - function startPrank(address msgSender) external; - // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input - function prank(address msgSender, address txOrigin) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input - function startPrank(address msgSender, address txOrigin) external; - // Resets subsequent calls' msg.sender to be `address(this)` - function stopPrank() external; - // Sets an address' balance - function deal(address account, uint256 newBalance) external; - // Sets an address' code - function etch(address target, bytes calldata newRuntimeBytecode) external; - // Expects an error on next call - function expectRevert(bytes calldata revertData) external; - function expectRevert(bytes4 revertData) external; - function expectRevert() external; - // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). - // Call this function, then emit an event, then call a function. Internally after the call, we check if - // logs were emitted in the expected order with the expected topics and data (as specified by the booleans) - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; - function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) - external; - // Mocks a call to an address, returning specified data. - // Calldata can either be strict or a partial match, e.g. if you only - // pass a Solidity selector to the expected calldata, then the entire Solidity - // function will be mocked. - function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; - // Mocks a call to an address with a specific msg.value, returning specified data. - // Calldata match takes precedence over msg.value in case of ambiguity. - function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; - // Clears all mocked calls - function clearMockedCalls() external; - // Expects a call to an address with the specified calldata. - // Calldata can either be a strict or a partial match - function expectCall(address callee, bytes calldata data) external; - // Expects a call to an address with the specified msg.value and calldata - function expectCall(address callee, uint256 msgValue, bytes calldata data) external; - // Expect a call to an address with the specified msg.value, gas, and calldata. - function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; - // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas. - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; - // Sets block.coinbase - function coinbase(address newCoinbase) external; - // Snapshot the current state of the evm. - // Returns the id of the snapshot that was created. - // To revert a snapshot use `revertTo` - function snapshot() external returns (uint256 snapshotId); - // Revert the state of the EVM to a previous snapshot - // Takes the snapshot id to revert to. - // This deletes the snapshot and all snapshots taken after the given snapshot id. - function revertTo(uint256 snapshotId) external returns (bool success); - // Creates a new fork with the given endpoint and block and returns the identifier of the fork - function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); - // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork - function createFork(string calldata urlOrAlias) external returns (uint256 forkId); - // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction, - // and returns the identifier of the fork - function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); - // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); - // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before - // the transaction, returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); - // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork - function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); - // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. - function selectFork(uint256 forkId) external; - /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. - function activeFork() external view returns (uint256 forkId); - // Updates the currently active fork to given block number - // This is similar to `roll` but for the currently active fork - function rollFork(uint256 blockNumber) external; - // Updates the currently active fork to given transaction - // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block - function rollFork(bytes32 txHash) external; - // Updates the given fork to given block number - function rollFork(uint256 forkId, uint256 blockNumber) external; - // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block - function rollFork(uint256 forkId, bytes32 txHash) external; - // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup - // Meaning, changes made to the state of this account will be kept when switching forks - function makePersistent(address account) external; - function makePersistent(address account0, address account1) external; - function makePersistent(address account0, address account1, address account2) external; - function makePersistent(address[] calldata accounts) external; - // Revokes persistent status from the address, previously added via `makePersistent` - function revokePersistent(address account) external; - function revokePersistent(address[] calldata accounts) external; - // Returns true if the account is marked as persistent - function isPersistent(address account) external view returns (bool persistent); - // In forking mode, explicitly grant the given address cheatcode access - function allowCheatcodes(address account) external; - // Fetches the given transaction from the active fork and executes it on the current state - function transact(bytes32 txHash) external; - // Fetches the given transaction from the given fork and executes it on the current state - function transact(uint256 forkId, bytes32 txHash) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/console.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/console.sol deleted file mode 100644 index ad57e53..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/console.sol +++ /dev/null @@ -1,1533 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -library console { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _sendLogPayload(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal view { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); - } - - function logUint(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function logString(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function log(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); - } - - function log(uint p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); - } - - function log(uint p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); - } - - function log(uint p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); - } - - function log(string memory p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); - } - - function log(bool p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); - } - - function log(address p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); - } - - function log(uint p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); - } - - function log(uint p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); - } - - function log(uint p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); - } - - function log(uint p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); - } - - function log(uint p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); - } - - function log(uint p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); - } - - function log(uint p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); - } - - function log(uint p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); - } - - function log(uint p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); - } - - function log(uint p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); - } - - function log(uint p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); - } - - function log(bool p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); - } - - function log(bool p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); - } - - function log(bool p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); - } - - function log(address p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); - } - - function log(address p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); - } - - function log(address p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/console2.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/console2.sol deleted file mode 100644 index 8596233..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/console2.sol +++ /dev/null @@ -1,1546 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should -/// use `int256` and `uint256`. This modified version fixes that. This version is recommended -/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in -/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`. -/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178 -library console2 { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _sendLogPayload(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - /// @solidity memory-safe-assembly - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal view { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int256 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function logUint(uint256 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function logString(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint256 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); - } - - function log(int256 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); - } - - function log(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint256 p0, uint256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); - } - - function log(uint256 p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); - } - - function log(uint256 p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); - } - - function log(uint256 p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); - } - - function log(string memory p0, uint256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); - } - - function log(string memory p0, int256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); - } - - function log(bool p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint256 p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); - } - - function log(address p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint256 p0, uint256 p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); - } - - function log(uint256 p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); - } - - function log(uint256 p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); - } - - function log(uint256 p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint256 p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); - } - - function log(bool p0, uint256 p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); - } - - function log(address p0, uint256 p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint256 p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, uint256 p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint256 p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint256 p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint256 p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint256 p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint256 p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint256 p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC1155.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC1155.sol deleted file mode 100644 index f7dd2b4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC1155.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC165.sol"; - -/// @title ERC-1155 Multi Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-1155 -/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. -interface IERC1155 is IERC165 { - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_id` argument MUST be the token type being transferred. - /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferSingle( - address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value - ); - - /// @dev - /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). - /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). - /// - The `_from` argument MUST be the address of the holder whose balance is decreased. - /// - The `_to` argument MUST be the address of the recipient whose balance is increased. - /// - The `_ids` argument MUST be the list of tokens being transferred. - /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. - /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). - /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). - event TransferBatch( - address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values - ); - - /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. - /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". - event URI(string _value, uint256 indexed _id); - - /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. - /// - MUST revert on any other error. - /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). - /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _id ID of the token type - /// @param _value Transfer amount - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` - function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; - - /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). - /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). - /// - MUST revert if `_to` is the zero address. - /// - MUST revert if length of `_ids` is not the same as length of `_values`. - /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. - /// - MUST revert on any other error. - /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). - /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). - /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). - /// @param _from Source address - /// @param _to Target address - /// @param _ids IDs of each token type (order and length must match _values array) - /// @param _values Transfer amounts per token type (order and length must match _ids array) - /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` - function safeBatchTransferFrom( - address _from, - address _to, - uint256[] calldata _ids, - uint256[] calldata _values, - bytes calldata _data - ) external; - - /// @notice Get the balance of an account's tokens. - /// @param _owner The address of the token holder - /// @param _id ID of the token - /// @return The _owner's balance of the token type requested - function balanceOf(address _owner, uint256 _id) external view returns (uint256); - - /// @notice Get the balance of multiple account/token pairs - /// @param _owners The addresses of the token holders - /// @param _ids ID of the tokens - /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) - function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) - external - view - returns (uint256[] memory); - - /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. - /// @dev MUST emit the ApprovalForAll event on success. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Queries the approval status of an operator for a given owner. - /// @param _owner The owner of the tokens - /// @param _operator Address of authorized operator - /// @return True if the operator is approved, false if not - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC165.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC165.sol deleted file mode 100644 index 9af4bf8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC165.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -interface IERC165 { - /// @notice Query if a contract implements an interface - /// @param interfaceID The interface identifier, as specified in ERC-165 - /// @dev Interface identification is specified in ERC-165. This function - /// uses less than 30,000 gas. - /// @return `true` if the contract implements `interfaceID` and - /// `interfaceID` is not 0xffffffff, `false` otherwise - function supportsInterface(bytes4 interfaceID) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC20.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC20.sol deleted file mode 100644 index ba40806..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC20.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -/// @dev Interface of the ERC20 standard as defined in the EIP. -/// @dev This includes the optional name, symbol, and decimals metadata. -interface IERC20 { - /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). - event Transfer(address indexed from, address indexed to, uint256 value); - - /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` - /// is the new allowance. - event Approval(address indexed owner, address indexed spender, uint256 value); - - /// @notice Returns the amount of tokens in existence. - function totalSupply() external view returns (uint256); - - /// @notice Returns the amount of tokens owned by `account`. - function balanceOf(address account) external view returns (uint256); - - /// @notice Moves `amount` tokens from the caller's account to `to`. - function transfer(address to, uint256 amount) external returns (bool); - - /// @notice Returns the remaining number of tokens that `spender` is allowed - /// to spend on behalf of `owner` - function allowance(address owner, address spender) external view returns (uint256); - - /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. - /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - function approve(address spender, uint256 amount) external returns (bool); - - /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. - /// `amount` is then deducted from the caller's allowance. - function transferFrom(address from, address to, uint256 amount) external returns (bool); - - /// @notice Returns the name of the token. - function name() external view returns (string memory); - - /// @notice Returns the symbol of the token. - function symbol() external view returns (string memory); - - /// @notice Returns the decimals places of the token. - function decimals() external view returns (uint8); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC4626.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC4626.sol deleted file mode 100644 index bfe3a11..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC4626.sol +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC20.sol"; - -/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in -/// https://eips.ethereum.org/EIPS/eip-4626 -interface IERC4626 is IERC20 { - event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares - ); - - /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. - /// @dev - /// - MUST be an ERC-20 token contract. - /// - MUST NOT revert. - function asset() external view returns (address assetTokenAddress); - - /// @notice Returns the total amount of the underlying asset that is “managed” by Vault. - /// @dev - /// - SHOULD include any compounding that occurs from yield. - /// - MUST be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT revert. - function totalAssets() external view returns (uint256 totalManagedAssets); - - /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToShares(uint256 assets) external view returns (uint256 shares); - - /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal - /// scenario where all the conditions are met. - /// @dev - /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - /// - MUST NOT show any variations depending on the caller. - /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - /// - MUST NOT revert. - /// - /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - /// from. - function convertToAssets(uint256 shares) external view returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, - /// through a deposit call. - /// @dev - /// - MUST return a limited value if receiver is subject to some deposit limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. - /// - MUST NOT revert. - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit - /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called - /// in the same transaction. - /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the - /// deposit would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewDeposit(uint256 assets) external view returns (uint256 shares); - - /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// deposit execution, and are accounted for during deposit. - /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - - /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. - /// @dev - /// - MUST return a limited value if receiver is subject to some mint limit. - /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. - /// - MUST NOT revert. - function maxMint(address receiver) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given - /// current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call - /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the - /// same transaction. - /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint - /// would be accepted, regardless if the user has enough tokens approved, etc. - /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by minting. - function previewMint(uint256 shares) external view returns (uint256 assets); - - /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. - /// @dev - /// - MUST emit the Deposit event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint - /// execution, and are accounted for during mint. - /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not - /// approving enough underlying tokens to the Vault contract, etc). - /// - /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - function mint(uint256 shares, address receiver) external returns (uint256 assets); - - /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the - /// Vault, through a withdraw call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST NOT revert. - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw - /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if - /// called - /// in the same transaction. - /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though - /// the withdrawal would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by depositing. - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - - /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// withdraw execution, and are accounted for during withdraw. - /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); - - /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, - /// through a redeem call. - /// @dev - /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. - /// - MUST NOT revert. - function maxRedeem(address owner) external view returns (uint256 maxShares); - - /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, - /// given current on-chain conditions. - /// @dev - /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call - /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the - /// same transaction. - /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the - /// redemption would be accepted, regardless if the user has enough shares, etc. - /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - /// - MUST NOT revert. - /// - /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in - /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. - function previewRedeem(uint256 shares) external view returns (uint256 assets); - - /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. - /// @dev - /// - MUST emit the Withdraw event. - /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - /// redeem execution, and are accounted for during redeem. - /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner - /// not having enough shares, etc). - /// - /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - /// Those methods should be performed separately. - function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC721.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC721.sol deleted file mode 100644 index 0a16f45..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IERC721.sol +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2; - -import "./IERC165.sol"; - -/// @title ERC-721 Non-Fungible Token Standard -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. -interface IERC721 is IERC165 { - /// @dev This emits when ownership of any NFT changes by any mechanism. - /// This event emits when NFTs are created (`from` == 0) and destroyed - /// (`to` == 0). Exception: during contract creation, any number of NFTs - /// may be created and assigned without emitting Transfer. At the time of - /// any transfer, the approved address for that NFT (if any) is reset to none. - event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); - - /// @dev This emits when the approved address for an NFT is changed or - /// reaffirmed. The zero address indicates there is no approved address. - /// When a Transfer event emits, this also indicates that the approved - /// address for that NFT (if any) is reset to none. - event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); - - /// @dev This emits when an operator is enabled or disabled for an owner. - /// The operator can manage all NFTs of the owner. - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - - /// @notice Count all NFTs assigned to an owner - /// @dev NFTs assigned to the zero address are considered invalid, and this - /// function throws for queries about the zero address. - /// @param _owner An address for whom to query the balance - /// @return The number of NFTs owned by `_owner`, possibly zero - function balanceOf(address _owner) external view returns (uint256); - - /// @notice Find the owner of an NFT - /// @dev NFTs assigned to zero address are considered invalid, and queries - /// about them do throw. - /// @param _tokenId The identifier for an NFT - /// @return The address of the owner of the NFT - function ownerOf(uint256 _tokenId) external view returns (address); - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. When transfer is complete, this function - /// checks if `_to` is a smart contract (code size > 0). If so, it calls - /// `onERC721Received` on `_to` and throws if the return value is not - /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - /// @param data Additional data with no specified format, sent in call to `_to` - function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; - - /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev This works identically to the other function with an extra data parameter, - /// except this function just sets data to "". - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE - /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE - /// THEY MAY BE PERMANENTLY LOST - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function transferFrom(address _from, address _to, uint256 _tokenId) external payable; - - /// @notice Change or reaffirm the approved address for an NFT - /// @dev The zero address indicates there is no approved address. - /// Throws unless `msg.sender` is the current NFT owner, or an authorized - /// operator of the current owner. - /// @param _approved The new approved NFT controller - /// @param _tokenId The NFT to approve - function approve(address _approved, uint256 _tokenId) external payable; - - /// @notice Enable or disable approval for a third party ("operator") to manage - /// all of `msg.sender`'s assets - /// @dev Emits the ApprovalForAll event. The contract MUST allow - /// multiple operators per owner. - /// @param _operator Address to add to the set of authorized operators - /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external; - - /// @notice Get the approved address for a single NFT - /// @dev Throws if `_tokenId` is not a valid NFT. - /// @param _tokenId The NFT to find the approved address for - /// @return The approved address for this NFT, or the zero address if there is none - function getApproved(uint256 _tokenId) external view returns (address); - - /// @notice Query if an address is an authorized operator for another address - /// @param _owner The address that owns the NFTs - /// @param _operator The address that acts on behalf of the owner - /// @return True if `_operator` is an approved operator for `_owner`, false otherwise - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} - -/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. -interface IERC721TokenReceiver { - /// @notice Handle the receipt of an NFT - /// @dev The ERC721 smart contract calls this function on the recipient - /// after a `transfer`. This function MAY throw to revert and reject the - /// transfer. Return of other than the magic value MUST result in the - /// transaction being reverted. - /// Note: the contract address is always the message sender. - /// @param _operator The address which called `safeTransferFrom` function - /// @param _from The address which previously owned the token - /// @param _tokenId The NFT identifier which is being transferred - /// @param _data Additional data with no specified format - /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - /// unless throwing - function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) - external - returns (bytes4); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. -interface IERC721Metadata is IERC721 { - /// @notice A descriptive name for a collection of NFTs in this contract - function name() external view returns (string memory _name); - - /// @notice An abbreviated name for NFTs in this contract - function symbol() external view returns (string memory _symbol); - - /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. - /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC - /// 3986. The URI may point to a JSON file that conforms to the "ERC721 - /// Metadata JSON Schema". - function tokenURI(uint256 _tokenId) external view returns (string memory); -} - -/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension -/// @dev See https://eips.ethereum.org/EIPS/eip-721 -/// Note: the ERC-165 identifier for this interface is 0x780e9d63. -interface IERC721Enumerable is IERC721 { - /// @notice Count NFTs tracked by this contract - /// @return A count of valid NFTs tracked by this contract, where each one of - /// them has an assigned and queryable owner not equal to the zero address - function totalSupply() external view returns (uint256); - - /// @notice Enumerate valid NFTs - /// @dev Throws if `_index` >= `totalSupply()`. - /// @param _index A counter less than `totalSupply()` - /// @return The token identifier for the `_index`th NFT, - /// (sort order not specified) - function tokenByIndex(uint256 _index) external view returns (uint256); - - /// @notice Enumerate NFTs assigned to an owner - /// @dev Throws if `_index` >= `balanceOf(_owner)` or if - /// `_owner` is the zero address, representing invalid NFTs. - /// @param _owner An address where we are interested in NFTs owned by them - /// @param _index A counter less than `balanceOf(_owner)` - /// @return The token identifier for the `_index`th NFT assigned to `_owner`, - /// (sort order not specified) - function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IMulticall3.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IMulticall3.sol deleted file mode 100644 index 0d031b7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/interfaces/IMulticall3.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -interface IMulticall3 { - struct Call { - address target; - bytes callData; - } - - struct Call3 { - address target; - bool allowFailure; - bytes callData; - } - - struct Call3Value { - address target; - bool allowFailure; - uint256 value; - bytes callData; - } - - struct Result { - bool success; - bytes returnData; - } - - function aggregate(Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes[] memory returnData); - - function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); - - function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); - - function blockAndAggregate(Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); - - function getBasefee() external view returns (uint256 basefee); - - function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); - - function getBlockNumber() external view returns (uint256 blockNumber); - - function getChainId() external view returns (uint256 chainid); - - function getCurrentBlockCoinbase() external view returns (address coinbase); - - function getCurrentBlockDifficulty() external view returns (uint256 difficulty); - - function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); - - function getCurrentBlockTimestamp() external view returns (uint256 timestamp); - - function getEthBalance(address addr) external view returns (uint256 balance); - - function getLastBlockHash() external view returns (bytes32 blockHash); - - function tryAggregate(bool requireSuccess, Call[] calldata calls) - external - payable - returns (Result[] memory returnData); - - function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) - external - payable - returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdAssertions.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdAssertions.t.sol deleted file mode 100644 index 2922780..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdAssertions.t.sol +++ /dev/null @@ -1,954 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdAssertionsTest is Test { - string constant CUSTOM_ERROR = "guh!"; - - bool constant EXPECT_PASS = false; - bool constant EXPECT_FAIL = true; - - bool constant SHOULD_REVERT = true; - bool constant SHOULD_RETURN = false; - - bool constant STRICT_REVERT_DATA = true; - bool constant NON_STRICT_REVERT_DATA = false; - - TestTest t = new TestTest(); - - /*////////////////////////////////////////////////////////////////////////// - FAIL(STRING) - //////////////////////////////////////////////////////////////////////////*/ - - function testShouldFail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._fail(CUSTOM_ERROR); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_FALSE - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertFalse_Pass() external { - t._assertFalse(false, EXPECT_PASS); - } - - function testAssertFalse_Fail() external { - vm.expectEmit(false, false, false, true); - emit log("Error: Assertion Failed"); - t._assertFalse(true, EXPECT_FAIL); - } - - function testAssertFalse_Err_Pass() external { - t._assertFalse(false, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertFalse_Err_Fail() external { - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertFalse(true, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(BOOL) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_Bool_Pass(bool a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testAssertEq_Bool_Fail(bool a, bool b) external { - vm.assume(a != b); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [bool]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_BoolErr_Pass(bool a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertEq_BoolErr_Fail(bool a, bool b) external { - vm.assume(a != b); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(BYTES) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_Bytes_Pass(bytes calldata a) external { - t._assertEq(a, a, EXPECT_PASS); - } - - function testAssertEq_Bytes_Fail(bytes calldata a, bytes calldata b) external { - vm.assume(keccak256(a) != keccak256(b)); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [bytes]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_BytesErr_Pass(bytes calldata a) external { - t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertEq_BytesErr_Fail(bytes calldata a, bytes calldata b) external { - vm.assume(keccak256(a) != keccak256(b)); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(ARRAY) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEq_UintArr_Pass(uint256 e0, uint256 e1, uint256 e2) public { - uint256[] memory a = new uint256[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - uint256[] memory b = new uint256[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_IntArr_Pass(int256 e0, int256 e1, int256 e2) public { - int256[] memory a = new int256[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - int256[] memory b = new int256[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_AddressArr_Pass(address e0, address e1, address e2) public { - address[] memory a = new address[](3); - a[0] = e0; - a[1] = e1; - a[2] = e2; - address[] memory b = new address[](3); - b[0] = e0; - b[1] = e1; - b[2] = e2; - - t._assertEq(a, b, EXPECT_PASS); - } - - function testAssertEq_UintArr_FailEl(uint256 e1) public { - vm.assume(e1 != 0); - uint256[] memory a = new uint256[](3); - uint256[] memory b = new uint256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_IntArr_FailEl(int256 e1) public { - vm.assume(e1 != 0); - int256[] memory a = new int256[](3); - int256[] memory b = new int256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_AddressArr_FailEl(address e1) public { - vm.assume(e1 != address(0)); - address[] memory a = new address[](3); - address[] memory b = new address[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_UintArrErr_FailEl(uint256 e1) public { - vm.assume(e1 != 0); - uint256[] memory a = new uint256[](3); - uint256[] memory b = new uint256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_IntArrErr_FailEl(int256 e1) public { - vm.assume(e1 != 0); - int256[] memory a = new int256[](3); - int256[] memory b = new int256[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_AddressArrErr_FailEl(address e1) public { - vm.assume(e1 != address(0)); - address[] memory a = new address[](3); - address[] memory b = new address[](3); - b[1] = e1; - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_UintArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - uint256[] memory a = new uint256[](lenA); - uint256[] memory b = new uint256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_IntArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - int256[] memory a = new int256[](lenA); - int256[] memory b = new int256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_AddressArr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - address[] memory a = new address[](lenA); - address[] memory b = new address[](lenB); - - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, EXPECT_FAIL); - } - - function testAssertEq_UintArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - uint256[] memory a = new uint256[](lenA); - uint256[] memory b = new uint256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [uint[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_IntArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - int256[] memory a = new int256[](lenA); - int256[] memory b = new int256[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [int[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - function testAssertEq_AddressArrErr_FailLen(uint256 lenA, uint256 lenB) public { - vm.assume(lenA != lenB); - vm.assume(lenA <= 10000); - vm.assume(lenB <= 10000); - address[] memory a = new address[](lenA); - address[] memory b = new address[](lenB); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - vm.expectEmit(false, false, false, true); - emit log("Error: a == b not satisfied [address[]]"); - t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEqUint() public { - assertEqUint(uint8(1), uint128(1)); - assertEqUint(uint64(2), uint64(2)); - } - - function testFailAssertEqUint() public { - assertEqUint(uint64(1), uint96(2)); - assertEqUint(uint160(3), uint160(4)); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbs_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testAssertApproxEqAbs_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); - } - - function testAssertApproxEqAbs_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbs_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS_DECIMAL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbsDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqAbsDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbs_Int_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); - } - - function testAssertApproxEqAbs_Int_Fail(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); - } - - function testAssertApproxEqAbs_IntErr_Pass(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbs_IntErr_Fail(int256 a, int256 b, uint256 maxDelta) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_ABS_DECIMAL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqAbsDecimal_Int_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_Int_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqAbsDecimal_IntErr_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) <= maxDelta); - - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqAbsDecimal_IntErr_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) - external - { - vm.assume(stdMath.delta(a, b) > maxDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRel_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); - } - - function testAssertApproxEqRel_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); - } - - function testAssertApproxEqRel_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRel_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL_DECIMAL(UINT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRelDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [uint]"); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqRelDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) - external - { - vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRel_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); - } - - function testAssertApproxEqRel_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); - } - - function testAssertApproxEqRel_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRel_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - APPROX_EQ_REL_DECIMAL(INT) - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertApproxEqRelDecimal_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log("Error: a ~= b not satisfied [int]"); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); - } - - function testAssertApproxEqRelDecimal_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); - - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); - } - - function testAssertApproxEqRelDecimal_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) - external - { - vm.assume(b != 0); - vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); - - vm.expectEmit(false, false, false, true); - emit log_named_string("Error", CUSTOM_ERROR); - t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); - } - - /*////////////////////////////////////////////////////////////////////////// - ASSERT_EQ_CALL - //////////////////////////////////////////////////////////////////////////*/ - - function testAssertEqCall_Return_Pass( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnData, - bool strictRevertData - ) external { - address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); - - t._assertEqCall(targetA, targetB, callDataA, callDataB, returnData, returnData, strictRevertData, EXPECT_PASS); - } - - function testAssertEqCall_Return_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData - ) external { - vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); - - address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); - - vm.expectEmit(true, true, true, true); - emit log_named_string("Error", "Call return data does not match"); - t._assertEqCall(targetA, targetB, callDataA, callDataB, returnDataA, returnDataB, strictRevertData, EXPECT_FAIL); - } - - function testAssertEqCall_Revert_Pass( - bytes memory callDataA, - bytes memory callDataB, - bytes memory revertDataA, - bytes memory revertDataB - ) external { - address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); - address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); - - t._assertEqCall( - targetA, targetB, callDataA, callDataB, revertDataA, revertDataB, NON_STRICT_REVERT_DATA, EXPECT_PASS - ); - } - - function testAssertEqCall_Revert_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory revertDataA, - bytes memory revertDataB - ) external { - vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); - - address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); - address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); - - vm.expectEmit(true, true, true, true); - emit log_named_string("Error", "Call revert data does not match"); - t._assertEqCall( - targetA, targetB, callDataA, callDataB, revertDataA, revertDataB, STRICT_REVERT_DATA, EXPECT_FAIL - ); - } - - function testAssertEqCall_Fail( - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData - ) external { - address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); - address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); - - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Left call return data", returnDataA); - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Right call revert data", returnDataB); - t._assertEqCall(targetA, targetB, callDataA, callDataB, returnDataA, returnDataB, strictRevertData, EXPECT_FAIL); - - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Left call revert data", returnDataB); - vm.expectEmit(true, true, true, true); - emit log_named_bytes(" Right call return data", returnDataA); - t._assertEqCall(targetB, targetA, callDataB, callDataA, returnDataB, returnDataA, strictRevertData, EXPECT_FAIL); - } -} - -contract TestTest is Test { - modifier expectFailure(bool expectFail) { - bool preState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); - _; - bool postState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); - - if (preState == true) { - return; - } - - if (expectFail) { - require(postState == true, "expected failure not triggered"); - - // unwind the expected failure - vm.store(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x00))); - } else { - require(postState == false, "unexpected failure was triggered"); - } - } - - function _fail(string memory err) external expectFailure(true) { - fail(err); - } - - function _assertFalse(bool data, bool expectFail) external expectFailure(expectFail) { - assertFalse(data); - } - - function _assertFalse(bool data, string memory err, bool expectFail) external expectFailure(expectFail) { - assertFalse(data, err); - } - - function _assertEq(bool a, bool b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(bool a, bool b, string memory err, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b, err); - } - - function _assertEq(bytes memory a, bytes memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(bytes memory a, bytes memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(uint256[] memory a, uint256[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(int256[] memory a, int256[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(address[] memory a, address[] memory b, bool expectFail) external expectFailure(expectFail) { - assertEq(a, b); - } - - function _assertEq(uint256[] memory a, uint256[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(int256[] memory a, int256[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertEq(address[] memory a, address[] memory b, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertEq(a, b, err); - } - - function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta); - } - - function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta, err); - } - - function _assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - - function _assertApproxEqAbsDecimal( - uint256 a, - uint256 b, - uint256 maxDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); - } - - function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta); - } - - function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbs(a, b, maxDelta, err); - } - - function _assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals); - } - - function _assertApproxEqAbsDecimal( - int256 a, - int256 b, - uint256 maxDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); - } - - function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta); - } - - function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta, err); - } - - function _assertApproxEqRelDecimal(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - - function _assertApproxEqRelDecimal( - uint256 a, - uint256 b, - uint256 maxPercentDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); - } - - function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta); - } - - function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRel(a, b, maxPercentDelta, err); - } - - function _assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) - external - expectFailure(expectFail) - { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); - } - - function _assertApproxEqRelDecimal( - int256 a, - int256 b, - uint256 maxPercentDelta, - uint256 decimals, - string memory err, - bool expectFail - ) external expectFailure(expectFail) { - assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); - } - - function _assertEqCall( - address targetA, - address targetB, - bytes memory callDataA, - bytes memory callDataB, - bytes memory returnDataA, - bytes memory returnDataB, - bool strictRevertData, - bool expectFail - ) external expectFailure(expectFail) { - assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); - } -} - -contract TestMockCall { - bytes returnData; - bool shouldRevert; - - constructor(bytes memory returnData_, bool shouldRevert_) { - returnData = returnData_; - shouldRevert = shouldRevert_; - } - - fallback() external payable { - bytes memory returnData_ = returnData; - - if (shouldRevert) { - assembly { - revert(add(returnData_, 0x20), mload(returnData_)) - } - } else { - assembly { - return(add(returnData_, 0x20), mload(returnData_)) - } - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdChains.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdChains.t.sol deleted file mode 100644 index c2b215d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdChains.t.sol +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdChainsTest is Test { - function testChainRpcInitialization() public { - // RPCs specified in `foundry.toml` should be updated. - assertEq(getChain(1).rpcUrl, "https://mainnet.infura.io/v3/16a8be88795540b9b3903d8de0f7baa5"); - assertEq(getChain("optimism_goerli").rpcUrl, "https://goerli.optimism.io/"); - assertEq(getChain("arbitrum_one_goerli").rpcUrl, "https://goerli-rollup.arbitrum.io/rpc/"); - - // Environment variables should be the next fallback - assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); - vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); - assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); - vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); - - // Cannot override RPCs defined in `foundry.toml` - vm.setEnv("MAINNET_RPC_URL", "myoverride2"); - assertEq(getChain("mainnet").rpcUrl, "https://mainnet.infura.io/v3/16a8be88795540b9b3903d8de0f7baa5"); - - // Other RPCs should remain unchanged. - assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); - assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/f4a0bdad42674adab5fc0ac077ffab2b"); - } - - function testRpc(string memory rpcAlias) internal { - string memory rpcUrl = getChain(rpcAlias).rpcUrl; - vm.createSelectFork(rpcUrl); - } - - // Ensure we can connect to the default RPC URL for each chain. - function testRpcs() public { - testRpc("mainnet"); - testRpc("goerli"); - testRpc("sepolia"); - testRpc("optimism"); - testRpc("optimism_goerli"); - testRpc("arbitrum_one"); - testRpc("arbitrum_one_goerli"); - testRpc("arbitrum_nova"); - testRpc("polygon"); - testRpc("polygon_mumbai"); - testRpc("avalanche"); - testRpc("avalanche_fuji"); - testRpc("bnb_smart_chain"); - testRpc("bnb_smart_chain_testnet"); - testRpc("gnosis_chain"); - } - - function testChainNoDefault() public { - vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); - getChain("does_not_exist"); - } - - function testSetChainFirstFails() public { - vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); - setChain("anvil2", ChainData("Anvil", 31337, "URL")); - } - - function testChainBubbleUp() public { - setChain("needs_undefined_env_var", ChainData("", 123456789, "")); - vm.expectRevert( - "Failed to resolve env var `UNDEFINED_RPC_URL_PLACEHOLDER` in `${UNDEFINED_RPC_URL_PLACEHOLDER}`: environment variable not found" - ); - getChain("needs_undefined_env_var"); - } - - function testCannotSetChain_ChainIdExists() public { - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - - vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); - - setChain("another_custom_chain", ChainData("", 123456789, "")); - } - - function testSetChain() public { - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - Chain memory customChain = getChain("custom_chain"); - assertEq(customChain.name, "Custom Chain"); - assertEq(customChain.chainId, 123456789); - assertEq(customChain.chainAlias, "custom_chain"); - assertEq(customChain.rpcUrl, "https://custom.chain/"); - Chain memory chainById = getChain(123456789); - assertEq(chainById.name, customChain.name); - assertEq(chainById.chainId, customChain.chainId); - assertEq(chainById.chainAlias, customChain.chainAlias); - assertEq(chainById.rpcUrl, customChain.rpcUrl); - customChain.name = "Another Custom Chain"; - customChain.chainId = 987654321; - setChain("another_custom_chain", customChain); - Chain memory anotherCustomChain = getChain("another_custom_chain"); - assertEq(anotherCustomChain.name, "Another Custom Chain"); - assertEq(anotherCustomChain.chainId, 987654321); - assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); - assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); - // Verify the first chain data was not overwritten - chainById = getChain(123456789); - assertEq(chainById.name, "Custom Chain"); - assertEq(chainById.chainId, 123456789); - } - - function testSetNoEmptyAlias() public { - vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); - setChain("", ChainData("", 123456789, "")); - } - - function testSetNoChainId0() public { - vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); - setChain("alias", ChainData("", 0, "")); - } - - function testGetNoChainId0() public { - vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); - getChain(0); - } - - function testGetNoEmptyAlias() public { - vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); - getChain(""); - } - - function testChainIdNotFound() public { - vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); - getChain("no_such_alias"); - } - - function testChainAliasNotFound() public { - vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); - getChain(321); - } - - function testSetChain_ExistingOne() public { - setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); - assertEq(getChain(123456789).chainId, 123456789); - - setChain("custom_chain", ChainData("Modified Chain", 999999999, "https://modified.chain/")); - vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); - getChain(123456789); - - Chain memory modifiedChain = getChain(999999999); - assertEq(modifiedChain.name, "Modified Chain"); - assertEq(modifiedChain.chainId, 999999999); - assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); - } - - function testDontUseDefaultRpcUrl() public { - // Should error if default RPCs flag is set to false. - setFallbackToDefaultRpcUrls(false); - vm.expectRevert( - "Failed to get environment variable `ANVIL_RPC_URL` as type `string`: environment variable not found" - ); - getChain(31337); - vm.expectRevert( - "Failed to get environment variable `SEPOLIA_RPC_URL` as type `string`: environment variable not found" - ); - getChain("sepolia"); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdCheats.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdCheats.t.sol deleted file mode 100644 index 6ec8e0d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdCheats.t.sol +++ /dev/null @@ -1,401 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdCheats.sol"; -import "../src/Test.sol"; -import "../src/StdJson.sol"; - -contract StdCheatsTest is Test { - Bar test; - - using stdJson for string; - - function setUp() public { - test = new Bar(); - } - - function testSkip() public { - vm.warp(100); - skip(25); - assertEq(block.timestamp, 125); - } - - function testRewind() public { - vm.warp(100); - rewind(25); - assertEq(block.timestamp, 75); - } - - function testHoax() public { - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - } - - function testHoaxOrigin() public { - hoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - } - - function testHoaxDifferentAddresses() public { - hoax(address(1337), address(7331)); - test.origin{value: 100}(address(1337), address(7331)); - } - - function testStartHoax() public { - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testStartHoaxOrigin() public { - startHoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - test.origin{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testChangePrank() public { - vm.startPrank(address(1337)); - test.bar(address(1337)); - changePrank(address(0xdead)); - test.bar(address(0xdead)); - changePrank(address(1337)); - test.bar(address(1337)); - vm.stopPrank(); - } - - function testMakeAddrEquivalence() public { - (address addr,) = makeAddrAndKey("1337"); - assertEq(makeAddr("1337"), addr); - } - - function testMakeAddrSigning() public { - (address addr, uint256 key) = makeAddrAndKey("1337"); - bytes32 hash = keccak256("some_message"); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); - assertEq(ecrecover(hash, v, r, s), addr); - } - - function testDeal() public { - deal(address(this), 1 ether); - assertEq(address(this).balance, 1 ether); - } - - function testDealToken() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18); - assertEq(barToken.balanceOf(address(this)), 10000e18); - } - - function testDealTokenAdjustTotalSupply() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18, true); - assertEq(barToken.balanceOf(address(this)), 10000e18); - assertEq(barToken.totalSupply(), 20000e18); - deal(bar, address(this), 0, true); - assertEq(barToken.balanceOf(address(this)), 0); - assertEq(barToken.totalSupply(), 10000e18); - } - - function testDealERC1155Token() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, false); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - } - - function testDealERC1155TokenAdjustTotalSupply() public { - BarERC1155 barToken = new BarERC1155(); - address bar = address(barToken); - dealERC1155(bar, address(this), 0, 10000e18, true); - assertEq(barToken.balanceOf(address(this), 0), 10000e18); - assertEq(barToken.totalSupply(0), 20000e18); - dealERC1155(bar, address(this), 0, 0, true); - assertEq(barToken.balanceOf(address(this), 0), 0); - assertEq(barToken.totalSupply(0), 10000e18); - } - - function testDealERC721Token() public { - BarERC721 barToken = new BarERC721(); - address bar = address(barToken); - dealERC721(bar, address(2), 1); - assertEq(barToken.balanceOf(address(2)), 1); - assertEq(barToken.balanceOf(address(1)), 0); - dealERC721(bar, address(1), 2); - assertEq(barToken.balanceOf(address(1)), 1); - assertEq(barToken.balanceOf(bar), 1); - } - - function testDeployCode() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function testDeployCodeNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar"); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - } - - function testDeployCodeVal() public { - address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - function testDeployCodeValNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); - assertEq(string(getCode(deployed)), string(getCode(address(test)))); - assertEq(deployed.balance, 1 ether); - } - - // We need this so we can call "this.deployCode" rather than "deployCode" directly - function deployCodeHelper(string memory what) external { - deployCode(what); - } - - function testDeployCodeFail() public { - vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); - this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); - } - - function getCode(address who) internal view returns (bytes memory o_code) { - /// @solidity memory-safe-assembly - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(who) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(who, add(o_code, 0x20), 0, size) - } - } - - function testDeriveRememberKey() public { - string memory mnemonic = "test test test test test test test test test test test junk"; - - (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); - assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); - } - - function testBytesToUint() public { - assertEq(3, bytesToUint_test(hex"03")); - assertEq(2, bytesToUint_test(hex"02")); - assertEq(255, bytesToUint_test(hex"ff")); - assertEq(29625, bytesToUint_test(hex"73b9")); - } - - function testParseJsonTxDetail() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - string memory json = vm.readFile(path); - bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); - RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); - Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); - assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); - assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); - assertEq( - txDetail.data, - hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" - ); - assertEq(txDetail.nonce, 3); - assertEq(txDetail.txType, 2); - assertEq(txDetail.gas, 29625); - assertEq(txDetail.value, 0); - } - - function testReadEIP1559Transaction() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 0; - Tx1559 memory transaction = readTx1559(path, index); - transaction; - } - - function testReadEIP1559Transactions() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Tx1559[] memory transactions = readTx1559s(path); - transactions; - } - - function testReadReceipt() public { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - uint256 index = 5; - Receipt memory receipt = readReceipt(path, index); - assertEq( - receipt.logsBloom, - hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" - ); - } - - function testReadReceipts() public view { - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); - Receipt[] memory receipts = readReceipts(path); - receipts; - } - - function testGasMeteringModifier() public { - uint256 gas_start_normal = gasleft(); - addInLoop(); - uint256 gas_used_normal = gas_start_normal - gasleft(); - - uint256 gas_start_single = gasleft(); - addInLoopNoGas(); - uint256 gas_used_single = gas_start_single - gasleft(); - - uint256 gas_start_double = gasleft(); - addInLoopNoGasNoGas(); - uint256 gas_used_double = gas_start_double - gasleft(); - - emit log_named_uint("Normal gas", gas_used_normal); - emit log_named_uint("Single modifier gas", gas_used_single); - emit log_named_uint("Double modifier gas", gas_used_double); - assertTrue(gas_used_double + gas_used_single < gas_used_normal); - } - - function addInLoop() internal pure returns (uint256) { - uint256 b; - for (uint256 i; i < 10000; i++) { - b += i; - } - return b; - } - - function addInLoopNoGas() internal noGasMetering returns (uint256) { - return addInLoop(); - } - - function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { - return addInLoopNoGas(); - } - - function bytesToUint_test(bytes memory b) private pure returns (uint256) { - uint256 number; - for (uint256 i = 0; i < b.length; i++) { - number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); - } - return number; - } - - function testAssumeNoPrecompiles(address addr) external { - assumeNoPrecompiles(addr, getChain("optimism_goerli").chainId); - assertTrue( - addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) - || addr > address(0x4200000000000000000000000000000000000800) - ); - } - - function testAssumePayable() external { - // all should revert since these addresses are not payable - - // VM address - vm.expectRevert(); - assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - - // Console address - vm.expectRevert(); - assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); - - // Create2Deployer - vm.expectRevert(); - assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); - } - - function testAssumePayable(address addr) external { - assumePayable(addr); - assertTrue( - addr != 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D && addr != 0x000000000000000000636F6e736F6c652e6c6f67 - && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C - ); - } -} - -contract Bar { - constructor() payable { - /// `DEAL` STDCHEAT - totalSupply = 10000e18; - balanceOf[address(this)] = totalSupply; - } - - /// `HOAX` STDCHEATS - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } - - function origin(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedSender, "!prank"); - } - - function origin(address expectedSender, address expectedOrigin) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedOrigin, "!prank"); - } - - /// `DEAL` STDCHEAT - mapping(address => uint256) public balanceOf; - uint256 public totalSupply; -} - -contract BarERC1155 { - constructor() payable { - /// `DEALERC1155` STDCHEAT - _totalSupply[0] = 10000e18; - _balances[0][address(this)] = _totalSupply[0]; - } - - function balanceOf(address account, uint256 id) public view virtual returns (uint256) { - return _balances[id][account]; - } - - function totalSupply(uint256 id) public view virtual returns (uint256) { - return _totalSupply[id]; - } - - /// `DEALERC1155` STDCHEAT - mapping(uint256 => mapping(address => uint256)) private _balances; - mapping(uint256 => uint256) private _totalSupply; -} - -contract BarERC721 { - constructor() payable { - /// `DEALERC721` STDCHEAT - _owners[1] = address(1); - _balances[address(1)] = 1; - _owners[2] = address(this); - _owners[3] = address(this); - _balances[address(this)] = 2; - } - - function balanceOf(address owner) public view virtual returns (uint256) { - return _balances[owner]; - } - - function ownerOf(uint256 tokenId) public view virtual returns (address) { - address owner = _owners[tokenId]; - return owner; - } - - mapping(uint256 => address) private _owners; - mapping(address => uint256) private _balances; -} - -contract RevertingContract { - constructor() { - revert(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdError.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdError.t.sol deleted file mode 100644 index ccd3efa..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdError.t.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import "../src/StdError.sol"; -import "../src/Test.sol"; - -contract StdErrorsTest is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectAssertion() public { - vm.expectRevert(stdError.assertionError); - test.assertionError(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } - - function testExpectDiv() public { - vm.expectRevert(stdError.divisionError); - test.divError(0); - } - - function testExpectMod() public { - vm.expectRevert(stdError.divisionError); - test.modError(0); - } - - function testExpectEnum() public { - vm.expectRevert(stdError.enumConversionError); - test.enumConversion(1); - } - - function testExpectEncodeStg() public { - vm.expectRevert(stdError.encodeStorageError); - test.encodeStgError(); - } - - function testExpectPop() public { - vm.expectRevert(stdError.popError); - test.pop(); - } - - function testExpectOOB() public { - vm.expectRevert(stdError.indexOOBError); - test.indexOOBError(1); - } - - function testExpectMem() public { - vm.expectRevert(stdError.memOverflowError); - test.mem(); - } - - function testExpectIntern() public { - vm.expectRevert(stdError.zeroVarError); - test.intern(); - } -} - -contract ErrorsTest { - enum T {T1} - - uint256[] public someArr; - bytes someBytes; - - function assertionError() public pure { - assert(false); - } - - function arithmeticError(uint256 a) public pure { - a -= 100; - } - - function divError(uint256 a) public pure { - 100 / a; - } - - function modError(uint256 a) public pure { - 100 % a; - } - - function enumConversion(uint256 a) public pure { - T(a); - } - - function encodeStgError() public { - /// @solidity memory-safe-assembly - assembly { - sstore(someBytes.slot, 1) - } - keccak256(someBytes); - } - - function pop() public { - someArr.pop(); - } - - function indexOOBError(uint256 a) public pure { - uint256[] memory t = new uint256[](0); - t[a]; - } - - function mem() public pure { - uint256 l = 2 ** 256 / 32; - new uint256[](l); - } - - function intern() public returns (uint256) { - function(uint256) internal returns (uint256) x; - x(2); - return 7; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdMath.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdMath.t.sol deleted file mode 100644 index 95037ea..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdMath.t.sol +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -import "../src/StdMath.sol"; -import "../src/Test.sol"; - -contract StdMathTest is Test { - function testGetAbs() external { - assertEq(stdMath.abs(-50), 50); - assertEq(stdMath.abs(50), 50); - assertEq(stdMath.abs(-1337), 1337); - assertEq(stdMath.abs(0), 0); - - assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); - assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); - } - - function testGetAbs_Fuzz(int256 a) external { - uint256 manualAbs = getAbs(a); - - uint256 abs = stdMath.abs(a); - - assertEq(abs, manualAbs); - } - - function testGetDelta_Uint() external { - assertEq(stdMath.delta(uint256(0), uint256(0)), 0); - assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); - assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); - assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); - assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); - - assertEq(stdMath.delta(0, uint256(0)), 0); - assertEq(stdMath.delta(1337, uint256(0)), 1337); - assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); - assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); - assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); - - assertEq(stdMath.delta(1337, uint256(1337)), 0); - assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); - assertEq(stdMath.delta(5000, uint256(1250)), 3750); - } - - function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external { - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function testGetDelta_Int() external { - assertEq(stdMath.delta(int256(0), int256(0)), 0); - assertEq(stdMath.delta(int256(0), int256(1337)), 1337); - assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); - assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); - assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); - - assertEq(stdMath.delta(0, int256(0)), 0); - assertEq(stdMath.delta(1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); - assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); - assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); - - assertEq(stdMath.delta(-0, int256(0)), 0); - assertEq(stdMath.delta(-1337, int256(0)), 1337); - assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(int256(0), -0), 0); - assertEq(stdMath.delta(int256(0), -1337), 1337); - assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); - assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); - - assertEq(stdMath.delta(1337, int256(1337)), 0); - assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); - assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); - assertEq(stdMath.delta(5000, int256(1250)), 3750); - } - - function testGetDelta_Int_Fuzz(int256 a, int256 b) external { - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 delta = stdMath.delta(a, b); - - assertEq(delta, manualDelta); - } - - function testGetPercentDelta_Uint() external { - assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); - assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); - assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); - assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); - assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMath.percentDelta(uint256(1), 0); - } - - function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external { - vm.assume(b != 0); - uint256 manualDelta; - if (a > b) { - manualDelta = a - b; - } else { - manualDelta = b - a; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / b; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - function testGetPercentDelta_Int() external { - assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); - assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); - assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); - - assertEq(stdMath.percentDelta(1337, int256(1337)), 0); - assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); - assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); - - assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down - assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(2500, int256(2500)), 0); - assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); - assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); - - vm.expectRevert(stdError.divisionError); - stdMath.percentDelta(int256(1), 0); - } - - function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external { - vm.assume(b != 0); - uint256 absA = getAbs(a); - uint256 absB = getAbs(b); - uint256 absDelta = absA > absB ? absA - absB : absB - absA; - - uint256 manualDelta; - if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { - manualDelta = absDelta; - } - // (a < 0 && b >= 0) || (a >= 0 && b < 0) - else { - manualDelta = absA + absB; - } - - uint256 manualPercentDelta = manualDelta * 1e18 / absB; - uint256 percentDelta = stdMath.percentDelta(a, b); - - assertEq(percentDelta, manualPercentDelta); - } - - /*////////////////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////////////////*/ - - function getAbs(int256 a) private pure returns (uint256) { - if (a < 0) { - return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); - } - - return uint256(a); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdStorage.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdStorage.t.sol deleted file mode 100644 index d4c563a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdStorage.t.sol +++ /dev/null @@ -1,283 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/StdStorage.sol"; -import "../src/Test.sol"; - -contract StdStorageTest is Test { - using stdStorage for StdStorage; - - StorageTest internal test; - - function setUp() public { - test = new StorageTest(); - } - - function testStorageHidden() public { - assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); - } - - function testStorageObvious() public { - assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); - } - - function testStorageCheckedWriteHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); - assertEq(uint256(test.hidden()), 100); - } - - function testStorageCheckedWriteObvious() public { - stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); - assertEq(test.exists(), 100); - } - - function testStorageMapStructA() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); - } - - function testStorageMapStructB() public { - uint256 slot = - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); - } - - function testStorageDeepMap() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( - address(this) - ).find(); - assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); - } - - function testStorageCheckedWriteDeepMap() public { - stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) - .checked_write(100); - assertEq(100, test.deep_map(address(this), address(this))); - } - - function testStorageDeepMapStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(0).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), - bytes32(slot) - ); - } - - function testStorageDeepMapStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) - .with_key(address(this)).depth(1).find(); - assertEq( - bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), - bytes32(slot) - ); - } - - function testStorageCheckedWriteDeepMapStructA() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(100, a); - assertEq(0, b); - } - - function testStorageCheckedWriteDeepMapStructB() public { - stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( - address(this) - ).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(0, a); - assertEq(100, b); - } - - function testStorageCheckedWriteMapStructA() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 100); - assertEq(b, 0); - } - - function testStorageCheckedWriteMapStructB() public { - stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 0); - assertEq(b, 100); - } - - function testStorageStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); - assertEq(uint256(7), slot); - } - - function testStorageStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); - assertEq(uint256(7) + 1, slot); - } - - function testStorageCheckedWriteStructA() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 100); - assertEq(b, 1337); - } - - function testStorageCheckedWriteStructB() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 1337); - assertEq(b, 100); - } - - function testStorageMapAddrFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); - assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); - } - - function testStorageMapUintFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); - assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); - } - - function testStorageCheckedWriteMapUint() public { - stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); - assertEq(100, test.map_uint(100)); - } - - function testStorageCheckedWriteMapAddr() public { - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); - assertEq(100, test.map_addr(address(this))); - } - - function testStorageCheckedWriteMapBool() public { - stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); - assertTrue(test.map_bool(address(this))); - } - - function testFailStorageCheckedWriteMapPacked() public { - // expect PackedSlot error but not external call so cant expectRevert - stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337))) - .checked_write(100); - } - - function testStorageCheckedWriteMapPackedSuccess() public { - uint256 full = test.map_packed(address(1337)); - // keep upper 128, set lower 128 to 1337 - full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; - stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( - full - ); - assertEq(1337, test.read_struct_lower(address(1337))); - } - - function testFailStorageConst() public { - // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); - stdstore.target(address(test)).sig("const()").find(); - } - - function testFailStorageNativePack() public { - stdstore.target(address(test)).sig(test.tA.selector).find(); - stdstore.target(address(test)).sig(test.tB.selector).find(); - - // these both would fail - stdstore.target(address(test)).sig(test.tC.selector).find(); - stdstore.target(address(test)).sig(test.tD.selector).find(); - } - - function testStorageReadBytes32() public { - bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); - assertEq(val, hex"1337"); - } - - function testStorageReadBool_False() public { - bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); - assertEq(val, false); - } - - function testStorageReadBool_True() public { - bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); - assertEq(val, true); - } - - function testStorageReadBool_Revert() public { - vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); - this.readNonBoolValue(); - } - - function readNonBoolValue() public { - stdstore.target(address(test)).sig(test.tE.selector).read_bool(); - } - - function testStorageReadAddress() public { - address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); - assertEq(val, address(1337)); - } - - function testStorageReadUint() public { - uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); - assertEq(val, 1); - } - - function testStorageReadInt() public { - int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); - assertEq(val, type(int256).min); - } -} - -contract StorageTest { - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - mapping(uint256 => uint256) public map_uint; - mapping(address => uint256) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basic; - - uint248 public tA; - bool public tB; - - bool public tC = false; - uint248 public tD = 1; - - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - mapping(address => bool) public map_bool; - - bytes32 public tE = hex"1337"; - address public tF = address(1337); - int256 public tG = type(int256).min; - bool public tH = true; - - constructor() { - basic = UnpackedStruct({a: 1337, b: 1337}); - - uint256 two = (1 << 128) | 1; - map_packed[msg.sender] = two; - map_packed[address(uint160(1337))] = 1 << 128; - } - - function read_struct_upper(address who) public view returns (uint256) { - return map_packed[who] >> 128; - } - - function read_struct_lower(address who) public view returns (uint256) { - return map_packed[who] & ((1 << 128) - 1); - } - - function hidden() public view returns (bytes32 t) { - bytes32 slot = keccak256("my.random.var"); - /// @solidity memory-safe-assembly - assembly { - t := sload(slot) - } - } - - function const() public pure returns (bytes32 t) { - t = bytes32(hex"1337"); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdStyle.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdStyle.t.sol deleted file mode 100644 index e63ed68..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdStyle.t.sol +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdStyleTest is Test { - function testStyleColor() public view { - console2.log(StdStyle.red("StdStyle.red String Test")); - console2.log(StdStyle.red(uint256(10e18))); - console2.log(StdStyle.red(int256(-10e18))); - console2.log(StdStyle.red(true)); - console2.log(StdStyle.red(address(0))); - console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); - console2.log(StdStyle.green("StdStyle.green String Test")); - console2.log(StdStyle.green(uint256(10e18))); - console2.log(StdStyle.green(int256(-10e18))); - console2.log(StdStyle.green(true)); - console2.log(StdStyle.green(address(0))); - console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); - console2.log(StdStyle.yellow("StdStyle.yellow String Test")); - console2.log(StdStyle.yellow(uint256(10e18))); - console2.log(StdStyle.yellow(int256(-10e18))); - console2.log(StdStyle.yellow(true)); - console2.log(StdStyle.yellow(address(0))); - console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); - console2.log(StdStyle.blue("StdStyle.blue String Test")); - console2.log(StdStyle.blue(uint256(10e18))); - console2.log(StdStyle.blue(int256(-10e18))); - console2.log(StdStyle.blue(true)); - console2.log(StdStyle.blue(address(0))); - console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); - console2.log(StdStyle.magenta("StdStyle.magenta String Test")); - console2.log(StdStyle.magenta(uint256(10e18))); - console2.log(StdStyle.magenta(int256(-10e18))); - console2.log(StdStyle.magenta(true)); - console2.log(StdStyle.magenta(address(0))); - console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); - console2.log(StdStyle.cyan("StdStyle.cyan String Test")); - console2.log(StdStyle.cyan(uint256(10e18))); - console2.log(StdStyle.cyan(int256(-10e18))); - console2.log(StdStyle.cyan(true)); - console2.log(StdStyle.cyan(address(0))); - console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); - } - - function testStyleFontWeight() public view { - console2.log(StdStyle.bold("StdStyle.bold String Test")); - console2.log(StdStyle.bold(uint256(10e18))); - console2.log(StdStyle.bold(int256(-10e18))); - console2.log(StdStyle.bold(address(0))); - console2.log(StdStyle.bold(true)); - console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); - console2.log(StdStyle.dim("StdStyle.dim String Test")); - console2.log(StdStyle.dim(uint256(10e18))); - console2.log(StdStyle.dim(int256(-10e18))); - console2.log(StdStyle.dim(address(0))); - console2.log(StdStyle.dim(true)); - console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); - console2.log(StdStyle.italic("StdStyle.italic String Test")); - console2.log(StdStyle.italic(uint256(10e18))); - console2.log(StdStyle.italic(int256(-10e18))); - console2.log(StdStyle.italic(address(0))); - console2.log(StdStyle.italic(true)); - console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); - console2.log(StdStyle.underline("StdStyle.underline String Test")); - console2.log(StdStyle.underline(uint256(10e18))); - console2.log(StdStyle.underline(int256(-10e18))); - console2.log(StdStyle.underline(address(0))); - console2.log(StdStyle.underline(true)); - console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); - console2.log(StdStyle.inverse("StdStyle.inverse String Test")); - console2.log(StdStyle.inverse(uint256(10e18))); - console2.log(StdStyle.inverse(int256(-10e18))); - console2.log(StdStyle.inverse(address(0))); - console2.log(StdStyle.inverse(true)); - console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); - console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); - } - - function testStyleCombined() public view { - console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); - console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); - console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); - console2.log(StdStyle.blue(StdStyle.underline(address(0)))); - console2.log(StdStyle.magenta(StdStyle.inverse(true))); - } - - function testStyleCustom() public view { - console2.log(h1("Custom Style 1")); - console2.log(h2("Custom Style 2")); - } - - function h1(string memory a) private pure returns (string memory) { - return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); - } - - function h2(string memory a) private pure returns (string memory) { - return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdUtils.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdUtils.t.sol deleted file mode 100644 index a085b19..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/StdUtils.t.sol +++ /dev/null @@ -1,297 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -import "../src/Test.sol"; - -contract StdUtilsMock is StdUtils { - // We deploy a mock version so we can properly test expected reverts. - function getTokenBalances_(address token, address[] memory addresses) - external - returns (uint256[] memory balances) - { - return getTokenBalances(token, addresses); - } -} - -contract StdUtilsTest is Test { - /*////////////////////////////////////////////////////////////////////////// - BOUND UINT - //////////////////////////////////////////////////////////////////////////*/ - - function testBound() public { - assertEq(bound(uint256(5), 0, 4), 0); - assertEq(bound(uint256(0), 69, 69), 69); - assertEq(bound(uint256(0), 68, 69), 68); - assertEq(bound(uint256(10), 150, 190), 174); - assertEq(bound(uint256(300), 2800, 3200), 3107); - assertEq(bound(uint256(9999), 1337, 6666), 4669); - } - - function testBound_WithinRange() public { - assertEq(bound(uint256(51), 50, 150), 51); - assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); - assertEq(bound(uint256(149), 50, 150), 149); - assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); - } - - function testBound_EdgeCoverage() public { - assertEq(bound(uint256(0), 50, 150), 50); - assertEq(bound(uint256(1), 50, 150), 51); - assertEq(bound(uint256(2), 50, 150), 52); - assertEq(bound(uint256(3), 50, 150), 53); - assertEq(bound(type(uint256).max, 50, 150), 150); - assertEq(bound(type(uint256).max - 1, 50, 150), 149); - assertEq(bound(type(uint256).max - 2, 50, 150), 148); - assertEq(bound(type(uint256).max - 3, 50, 150), 147); - } - - function testBound_DistributionIsEven(uint256 min, uint256 size) public { - size = size % 100 + 1; - min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); - uint256 max = min + size - 1; - uint256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + i, min, max); - assertEq(result, min + (i - 1) % size); - // x < min - result = bound(min - i, min, max); - assertEq(result, max - (i - 1) % size); - } - } - - function testBound(uint256 num, uint256 min, uint256 max) public { - if (min > max) (min, max) = (max, min); - - uint256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function testBoundUint256Max() public { - assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); - assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); - } - - function testCannotBoundMaxLessThanMin() public { - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - bound(uint256(5), 100, 10); - } - - function testCannotBoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); - bound(num, min, max); - } - - /*////////////////////////////////////////////////////////////////////////// - BOUND INT - //////////////////////////////////////////////////////////////////////////*/ - - function testBoundInt() public { - assertEq(bound(-3, 0, 4), 2); - assertEq(bound(0, -69, -69), -69); - assertEq(bound(0, -69, -68), -68); - assertEq(bound(-10, 150, 190), 154); - assertEq(bound(-300, 2800, 3200), 2908); - assertEq(bound(9999, -1337, 6666), 1995); - } - - function testBoundInt_WithinRange() public { - assertEq(bound(51, -50, 150), 51); - assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); - assertEq(bound(149, -50, 150), 149); - assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); - } - - function testBoundInt_EdgeCoverage() public { - assertEq(bound(type(int256).min, -50, 150), -50); - assertEq(bound(type(int256).min + 1, -50, 150), -49); - assertEq(bound(type(int256).min + 2, -50, 150), -48); - assertEq(bound(type(int256).min + 3, -50, 150), -47); - assertEq(bound(type(int256).min, 10, 150), 10); - assertEq(bound(type(int256).min + 1, 10, 150), 11); - assertEq(bound(type(int256).min + 2, 10, 150), 12); - assertEq(bound(type(int256).min + 3, 10, 150), 13); - - assertEq(bound(type(int256).max, -50, 150), 150); - assertEq(bound(type(int256).max - 1, -50, 150), 149); - assertEq(bound(type(int256).max - 2, -50, 150), 148); - assertEq(bound(type(int256).max - 3, -50, 150), 147); - assertEq(bound(type(int256).max, -50, -10), -10); - assertEq(bound(type(int256).max - 1, -50, -10), -11); - assertEq(bound(type(int256).max - 2, -50, -10), -12); - assertEq(bound(type(int256).max - 3, -50, -10), -13); - } - - function testBoundInt_DistributionIsEven(int256 min, uint256 size) public { - size = size % 100 + 1; - min = bound(min, -int256(size / 2), int256(size - size / 2)); - int256 max = min + int256(size) - 1; - int256 result; - - for (uint256 i = 1; i <= size * 4; ++i) { - // x > max - result = bound(max + int256(i), min, max); - assertEq(result, min + int256((i - 1) % size)); - // x < min - result = bound(min - int256(i), min, max); - assertEq(result, max - int256((i - 1) % size)); - } - } - - function testBoundInt(int256 num, int256 min, int256 max) public { - if (min > max) (min, max) = (max, min); - - int256 result = bound(num, min, max); - - assertGe(result, min); - assertLe(result, max); - assertEq(result, bound(result, min, max)); - if (num >= min && num <= max) assertEq(result, num); - } - - function testBoundIntInt256Max() public { - assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); - assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); - } - - function testBoundIntInt256Min() public { - assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); - assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); - } - - function testCannotBoundIntMaxLessThanMin() public { - vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); - bound(-5, 100, 10); - } - - function testCannotBoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { - vm.assume(min > max); - vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); - bound(num, min, max); - } - - /*////////////////////////////////////////////////////////////////////////// - BYTES TO UINT - //////////////////////////////////////////////////////////////////////////*/ - - function testBytesToUint() external { - bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - bytes memory two = hex"02"; - bytes memory millionEther = hex"d3c21bcecceda1000000"; - - assertEq(bytesToUint(maxUint), type(uint256).max); - assertEq(bytesToUint(two), 2); - assertEq(bytesToUint(millionEther), 1_000_000 ether); - } - - function testCannotConvertGT32Bytes() external { - bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); - bytesToUint(thirty3Bytes); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function testComputeCreateAddress() external { - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - uint256 nonce = 14; - address createAddress = computeCreateAddress(deployer, nonce); - assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); - } - - /*////////////////////////////////////////////////////////////////////////// - COMPUTE CREATE2 ADDRESS - //////////////////////////////////////////////////////////////////////////*/ - - function testComputeCreate2Address() external { - bytes32 salt = bytes32(uint256(31415)); - bytes32 initcodeHash = keccak256(abi.encode(0x6080)); - address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; - address create2Address = computeCreate2Address(salt, initcodeHash, deployer); - assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); - } - - function testComputeCreate2AddressWithDefaultDeployer() external { - bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; - bytes32 initcodeHash = hashInitCode(hex"6080", ""); - assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); - address create2Address = computeCreate2Address(salt, initcodeHash); - assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); - } -} - -contract StdUtilsForkTest is Test { - /*////////////////////////////////////////////////////////////////////////// - GET TOKEN BALANCES - //////////////////////////////////////////////////////////////////////////*/ - - address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; - address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; - address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; - address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; - - address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; - address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; - address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; - - function setUp() public { - // All tests of the `getTokenBalances` method are fork tests using live contracts. - vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); - } - - function testCannotGetTokenBalances_NonTokenContract() external { - // We deploy a mock version so we can properly test the revert. - StdUtilsMock stdUtils = new StdUtilsMock(); - - // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, - // so the `balanceOf` call should revert. - address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); - address[] memory addresses = new address[](1); - addresses[0] = USDC_HOLDER_0; - - vm.expectRevert("Multicall3: call failed"); - stdUtils.getTokenBalances_(token, addresses); - } - - function testCannotGetTokenBalances_EOA() external { - address eoa = vm.addr({privateKey: 1}); - address[] memory addresses = new address[](1); - addresses[0] = USDC_HOLDER_0; - vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); - getTokenBalances(eoa, addresses); - } - - function testGetTokenBalances_Empty() external { - address[] memory addresses = new address[](0); - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances.length, 0); - } - - function testGetTokenBalances_USDC() external { - address[] memory addresses = new address[](2); - addresses[0] = USDC_HOLDER_0; - addresses[1] = USDC_HOLDER_1; - uint256[] memory balances = getTokenBalances(USDC, addresses); - assertEq(balances[0], 159_000_000_000_000); - assertEq(balances[1], 131_350_000_000_000); - } - - function testGetTokenBalances_SHIB() external { - address[] memory addresses = new address[](3); - addresses[0] = SHIB_HOLDER_0; - addresses[1] = SHIB_HOLDER_1; - addresses[2] = SHIB_HOLDER_2; - uint256[] memory balances = getTokenBalances(SHIB, addresses); - assertEq(balances[0], 3_323_256_285_484.42e18); - assertEq(balances[1], 1_271_702_771_149.99999928e18); - assertEq(balances[2], 606_357_106_247e18); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationScript.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationScript.sol deleted file mode 100644 index e205cff..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationScript.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Script.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationScript is Script {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationScriptBase.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationScriptBase.sol deleted file mode 100644 index ce8e0e9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationScriptBase.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Script.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationScriptBase is ScriptBase {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationTest.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationTest.sol deleted file mode 100644 index 9beeafe..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationTest.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Test.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationTest is Test {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationTestBase.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationTestBase.sol deleted file mode 100644 index e993535..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/compilation/CompilationTestBase.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.6.2 <0.9.0; - -pragma experimental ABIEncoderV2; - -import "../../src/Test.sol"; - -// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing -// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 -contract CompilationTestBase is TestBase {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/fixtures/broadcast.log.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/fixtures/broadcast.log.json deleted file mode 100644 index 0a0200b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/test/fixtures/broadcast.log.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "transactions": [ - { - "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", - "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0x73b9", - "value": "0x0", - "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", - "nonce": "0x3", - "accessList": [] - } - }, - { - "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "function": "inc():(uint256)", - "arguments": [], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "gas": "0xdcb2", - "value": "0x0", - "data": "0x371303c0", - "nonce": "0x4", - "accessList": [] - } - }, - { - "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "type": "CALL", - "contractName": "Test", - "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "function": "t(uint256):(uint256)", - "arguments": ["1"], - "tx": { - "type": "0x02", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "gas": "0x8599", - "value": "0x0", - "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", - "nonce": "0x5", - "accessList": [] - } - } - ], - "receipts": [ - { - "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", - "transactionIndex": "0x0", - "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", - "blockNumber": "0x1", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x13f3a", - "gasUsed": "0x13f3a", - "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", - "transactionIndex": "0x0", - "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", - "blockNumber": "0x2", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": null, - "cumulativeGasUsed": "0x45d80", - "gasUsed": "0x45d80", - "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", - "transactionIndex": "0x0", - "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", - "blockNumber": "0x3", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", - "cumulativeGasUsed": "0x45feb", - "gasUsed": "0x45feb", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", - "transactionIndex": "0x0", - "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", - "blockNumber": "0x4", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0x5905", - "gasUsed": "0x5905", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", - "transactionIndex": "0x0", - "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", - "blockNumber": "0x5", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", - "cumulativeGasUsed": "0xa9c4", - "gasUsed": "0xa9c4", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x0", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "cumulativeGasUsed": "0x66c5", - "gasUsed": "0x66c5", - "contractAddress": null, - "logs": [ - { - "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", - "topics": [ - "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", - "blockNumber": "0x6", - "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", - "transactionIndex": "0x1", - "logIndex": "0x0", - "transactionLogIndex": "0x0", - "removed": false - } - ], - "status": "0x1", - "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", - "effectiveGasPrice": "0xee6b2800" - }, - { - "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", - "transactionIndex": "0x0", - "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", - "blockNumber": "0x7", - "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "to": "0x0000000000000000000000000000000000001337", - "cumulativeGasUsed": "0x5208", - "gasUsed": "0x5208", - "contractAddress": null, - "logs": [], - "status": "0x1", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "effectiveGasPrice": "0xee6b2800" - } - ], - "libraries": [ - "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" - ], - "pending": [], - "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", - "returns": {}, - "timestamp": 1655140035 -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/logo.svg b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/logo.svg deleted file mode 100644 index f1e14c2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/logo.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/netlify.toml b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/netlify.toml deleted file mode 100644 index 0447f41..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/netlify.toml +++ /dev/null @@ -1,3 +0,0 @@ -[build] -command = "npm run docs" -publish = "build/site" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/package-lock.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/package-lock.json deleted file mode 100644 index 237e0f2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/package-lock.json +++ /dev/null @@ -1,28620 +0,0 @@ -{ - "name": "openzeppelin-solidity", - "version": "4.8.3", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "openzeppelin-solidity", - "version": "4.8.3", - "license": "MIT", - "bin": { - "openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js" - }, - "devDependencies": { - "@nomicfoundation/hardhat-network-helpers": "^1.0.3", - "@nomiclabs/hardhat-truffle5": "^2.0.5", - "@nomiclabs/hardhat-web3": "^2.0.0", - "@openzeppelin/docs-utils": "^0.1.3", - "@openzeppelin/test-helpers": "^0.5.13", - "chai": "^4.2.0", - "eslint": "^7.32.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-mocha": "^10.0.3", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.2.0", - "eth-sig-util": "^3.0.0", - "ethereumjs-util": "^7.0.7", - "ethereumjs-wallet": "^1.0.1", - "glob": "^8.0.3", - "graphlib": "^2.1.8", - "hardhat": "^2.9.1", - "hardhat-gas-reporter": "^1.0.4", - "hardhat-ignore-warnings": "^0.2.0", - "keccak256": "^1.0.2", - "lodash.startcase": "^4.4.0", - "lodash.zip": "^4.2.0", - "merkletreejs": "^0.2.13", - "micromatch": "^4.0.2", - "prettier": "^2.3.0", - "prettier-plugin-solidity": "^1.0.0-beta.16", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "solhint": "^3.3.6", - "solidity-ast": "^0.4.25", - "solidity-coverage": "^0.8.0", - "solidity-docgen": "^0.6.0-beta.29", - "web3": "^1.3.0", - "yargs": "^17.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/runtime": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", - "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@ensdomains/address-encoder": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz", - "integrity": "sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==", - "dev": true, - "dependencies": { - "bech32": "^1.1.3", - "blakejs": "^1.1.0", - "bn.js": "^4.11.8", - "bs58": "^4.0.1", - "crypto-addr-codec": "^0.1.7", - "nano-base32": "^1.0.1", - "ripemd160": "^2.0.2" - } - }, - "node_modules/@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "deprecated": "Please use @ensdomains/ens-contracts", - "dev": true, - "dependencies": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - } - }, - "node_modules/@ensdomains/ensjs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@ensdomains/ensjs/-/ensjs-2.1.0.tgz", - "integrity": "sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.4.4", - "@ensdomains/address-encoder": "^0.1.7", - "@ensdomains/ens": "0.4.5", - "@ensdomains/resolver": "0.2.4", - "content-hash": "^2.5.2", - "eth-ens-namehash": "^2.0.8", - "ethers": "^5.0.13", - "js-sha3": "^0.8.0" - } - }, - "node_modules/@ensdomains/ensjs/node_modules/ethers": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.0.tgz", - "integrity": "sha512-5Xhzp2ZQRi0Em+0OkOcRHxPzCfoBfgtOQA+RUylSkuHbhTEaQklnYi2hsWbRgs3ztJsXVXd9VKBcO1ScWL8YfA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.0", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.0", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.0", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "deprecated": "Please use @ensdomains/ens-contracts", - "dev": true - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", - "dev": true, - "dependencies": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" - } - }, - "node_modules/@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bignumber/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.0.tgz", - "integrity": "sha512-MG6oHSQHd4ebvJrleEQQ4HhVu8Ichr0RDYEfHzsVAVjHNM+w36x9wp9r+hf1JstMXtseXDtkiVoARAG6M959AA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.0.tgz", - "integrity": "sha512-+TTrrINMzZ0aXtlwO/95uhAggKm4USLm1PbeCBR/3XZ7+Oey+3pMyddzZEyRhizHpy1HXV0FRWRMI1O3EGYibA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.0.tgz", - "integrity": "sha512-ApHcbbj+muRASVDSCl/tgxaH2LBkRMEYfLOLVa0COipx0+nlu0QKet7U2lEg0vdkh8XRSLf2nd1f1Uk9SrVSGA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@frangio/servbot": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@frangio/servbot/-/servbot-0.2.5.tgz", - "integrity": "sha512-ogja4iAPZ1VwM5MU3C1ZhB88358F0PGbmSTGOkIZwOyLaDoMHIqOVCnavHjR7DV5h+oAI4Z4KDqlam3myQUrmg==", - "dev": true, - "engines": { - "node": ">=12.x", - "pnpm": "7.5.1" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/@noble/hashes": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", - "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@noble/secp256k1": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", - "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nomicfoundation/ethereumjs-block": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz", - "integrity": "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-tx": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-blockchain": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz", - "integrity": "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-ethash": "^2.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "abstract-level": "^1.0.3", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "level": "^8.0.0", - "lru-cache": "^5.1.1", - "memory-level": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-common": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz", - "integrity": "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "crc-32": "^1.2.0" - } - }, - "node_modules/@nomicfoundation/ethereumjs-ethash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz", - "integrity": "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "abstract-level": "^1.0.3", - "bigint-crypto-utils": "^3.0.23", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-evm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz", - "integrity": "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "@types/async-eventemitter": "^0.2.1", - "async-eventemitter": "^0.2.4", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-rlp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz", - "integrity": "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==", - "dev": true, - "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-statemanager": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz", - "integrity": "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "functional-red-black-tree": "^1.0.1" - } - }, - "node_modules/@nomicfoundation/ethereumjs-trie": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz", - "integrity": "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-tx": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz", - "integrity": "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-util": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz", - "integrity": "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-rlp": "^4.0.0-beta.2", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/ethereumjs-vm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz", - "integrity": "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==", - "dev": true, - "dependencies": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-evm": "^1.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-tx": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "@types/async-eventemitter": "^0.2.1", - "async-eventemitter": "^0.2.4", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.6.tgz", - "integrity": "sha512-a35iVD4ycF6AoTfllAnKm96IPIzzHpgKX/ep4oKc2bsUKFfMlacWdyntgC/7d5blyCTXfFssgNAvXDZfzNWVGQ==", - "dev": true, - "dependencies": { - "ethereumjs-util": "^7.1.4" - }, - "peerDependencies": { - "hardhat": "^2.9.5" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.0.3.tgz", - "integrity": "sha512-VFMiOQvsw7nx5bFmrmVp2Q9rhIjw2AFST4DYvWVVO9PMHPE23BY2+kyfrQ4J3xCMFC8fcBbGLt7l4q7m1SlTqg==", - "dev": true, - "engines": { - "node": ">= 12" - }, - "optionalDependencies": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.0.3", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.0.3", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.0.3" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.0.3.tgz", - "integrity": "sha512-W+bIiNiZmiy+MTYFZn3nwjyPUO6wfWJ0lnXx2zZrM8xExKObMrhCh50yy8pQING24mHfpPFCn89wEB/iG7vZDw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.0.3.tgz", - "integrity": "sha512-HuJd1K+2MgmFIYEpx46uzwEFjvzKAI765mmoMxy4K+Aqq1p+q7hHRlsFU2kx3NB8InwotkkIq3A5FLU1sI1WDw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.0.3.tgz", - "integrity": "sha512-2cR8JNy23jZaO/vZrsAnWCsO73asU7ylrHIe0fEsXbZYqBP9sMr+/+xP3CELDHJxUbzBY8zqGvQt1ULpyrG+Kw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.0.3.tgz", - "integrity": "sha512-Eyv50EfYbFthoOb0I1568p+eqHGLwEUhYGOxcRNywtlTE9nj+c+MT1LA53HnxD9GsboH4YtOOmJOulrjG7KtbA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.0.3.tgz", - "integrity": "sha512-V8grDqI+ivNrgwEt2HFdlwqV2/EQbYAdj3hbOvjrA8Qv+nq4h9jhQUxFpegYMDtpU8URJmNNlXgtfucSrAQwtQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.0.3.tgz", - "integrity": "sha512-uRfVDlxtwT1vIy7MAExWAkRD4r9M79zMG7S09mCrWUn58DbLs7UFl+dZXBX0/8FTGYWHhOT/1Etw1ZpAf5DTrg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.0.3.tgz", - "integrity": "sha512-8HPwYdLbhcPpSwsE0yiU/aZkXV43vlXT2ycH+XlOjWOnLfH8C41z0njK8DHRtEFnp4OVN6E7E5lHBBKDZXCliA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.0.3.tgz", - "integrity": "sha512-5WWcT6ZNvfCuxjlpZOY7tdvOqT1kIQYlDF9Q42wMpZ5aTm4PvjdCmFDDmmTvyXEBJ4WTVmY5dWNWaxy8h/E28g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.0.3.tgz", - "integrity": "sha512-P/LWGZwWkyjSwkzq6skvS2wRc3gabzAbk6Akqs1/Iiuggql2CqdLBkcYWL5Xfv3haynhL+2jlNkak+v2BTZI4A==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.0.3.tgz", - "integrity": "sha512-4AcTtLZG1s/S5mYAIr/sdzywdNwJpOcdStGF3QMBzEt+cGn3MchMaS9b1gyhb2KKM2c39SmPF5fUuWq1oBSQZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nomiclabs/hardhat-truffle5": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.7.tgz", - "integrity": "sha512-Pw8451IUZp1bTp0QqCHCYfCHs66sCnyxPcaorapu9mfOV9xnZsVaFdtutnhNEiXdiZwbed7LFKpRsde4BjFwig==", - "dev": true, - "dependencies": { - "@nomiclabs/truffle-contract": "^4.2.23", - "@types/chai": "^4.2.0", - "chai": "^4.2.0", - "ethereumjs-util": "^7.1.4", - "fs-extra": "^7.0.1" - }, - "peerDependencies": { - "@nomiclabs/hardhat-web3": "^2.0.0", - "hardhat": "^2.6.4", - "web3": "^1.0.0-beta.36" - } - }, - "node_modules/@nomiclabs/hardhat-web3": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz", - "integrity": "sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==", - "dev": true, - "dependencies": { - "@types/bignumber.js": "^5.0.0" - }, - "peerDependencies": { - "hardhat": "^2.0.0", - "web3": "^1.0.0-beta.36" - } - }, - "node_modules/@nomiclabs/truffle-contract": { - "version": "4.5.10", - "resolved": "https://registry.npmjs.org/@nomiclabs/truffle-contract/-/truffle-contract-4.5.10.tgz", - "integrity": "sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ==", - "dev": true, - "dependencies": { - "@ensdomains/ensjs": "^2.0.1", - "@truffle/blockchain-utils": "^0.1.3", - "@truffle/contract-schema": "^3.4.7", - "@truffle/debug-utils": "^6.0.22", - "@truffle/error": "^0.1.0", - "@truffle/interface-adapter": "^0.5.16", - "bignumber.js": "^7.2.1", - "ethereum-ens": "^0.8.0", - "ethers": "^4.0.0-beta.1", - "source-map-support": "^0.5.19" - }, - "peerDependencies": { - "web3": "^1.2.1", - "web3-core-helpers": "^1.2.1", - "web3-core-promievent": "^1.2.1", - "web3-eth-abi": "^1.2.1", - "web3-utils": "^1.2.1" - } - }, - "node_modules/@openzeppelin/contract-loader": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contract-loader/-/contract-loader-0.6.3.tgz", - "integrity": "sha512-cOFIjBjwbGgZhDZsitNgJl0Ye1rd5yu/Yx5LMgeq3u0ZYzldm4uObzHDFq4gjDdoypvyORjjJa3BlFA7eAnVIg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "fs-extra": "^8.1.0" - } - }, - "node_modules/@openzeppelin/contract-loader/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@openzeppelin/docs-utils": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/docs-utils/-/docs-utils-0.1.3.tgz", - "integrity": "sha512-O/iJ4jEi5ryNc/T74G9gbnFwQ8QaQ2bpAVoYXLPknZJyK52GEAvxC12UMP33KodTNV3rMzeeQrSBIdI8skjDJg==", - "dev": true, - "dependencies": { - "@frangio/servbot": "^0.2.5", - "chalk": "^3.0.0", - "chokidar": "^3.5.3", - "env-paths": "^2.2.0", - "find-up": "^4.1.0", - "is-port-reachable": "^3.0.0", - "js-yaml": "^3.13.1", - "lodash.startcase": "^4.4.0", - "minimist": "^1.2.0" - }, - "bin": { - "oz-docs": "oz-docs.js" - } - }, - "node_modules/@openzeppelin/test-helpers": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/@openzeppelin/test-helpers/-/test-helpers-0.5.16.tgz", - "integrity": "sha512-T1EvspSfH1qQO/sgGlskLfYVBbqzJR23SZzYl/6B2JnT4EhThcI85UpvDk0BkLWKaDScQTabGHt4GzHW+3SfZg==", - "dev": true, - "dependencies": { - "@openzeppelin/contract-loader": "^0.6.2", - "@truffle/contract": "^4.0.35", - "ansi-colors": "^3.2.3", - "chai": "^4.2.0", - "chai-bn": "^0.2.1", - "ethjs-abi": "^0.2.1", - "lodash.flatten": "^4.4.0", - "semver": "^5.6.0", - "web3": "^1.2.5", - "web3-utils": "^1.2.5" - } - }, - "node_modules/@openzeppelin/test-helpers/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@scure/bip32": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", - "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.1.1", - "@noble/secp256k1": "~1.6.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/@scure/bip39": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", - "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.1.1", - "@scure/base": "~1.1.0" - } - }, - "node_modules/@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dev": true, - "dependencies": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dev": true, - "dependencies": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dev": true, - "dependencies": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@solidity-parser/parser": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", - "integrity": "sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==", - "dev": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@truffle/abi-utils": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.3.1.tgz", - "integrity": "sha512-tieaDgwDm2IH1wJuVF/waREVFvzXHSF6AkQfd71DQwpwnrl/9I1iKu+1WpQyFqxu+6WMfCYhzMEbssQBt4Zniw==", - "dev": true, - "dependencies": { - "change-case": "3.0.2", - "fast-check": "3.1.1", - "web3-utils": "1.7.4" - } - }, - "node_modules/@truffle/abi-utils/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/abi-utils/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/blockchain-utils": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@truffle/blockchain-utils/-/blockchain-utils-0.1.4.tgz", - "integrity": "sha512-HegAo5A8UX9vE8dtceBRgCY207gOb9wj54c8mNOOWHcFpkyJz7kZYGo44As6Imh10/0hD2j7vHQ56Jf+uszJ3A==", - "dev": true - }, - "node_modules/@truffle/codec": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.14.4.tgz", - "integrity": "sha512-il9dFzALUbd1JMPOVcxnIjTQ1fiJEPHfBYbqVQfWZfzAN0Kw+x1eaKunIU+NvrNRycvkXk4itWUTui5sMlXBBA==", - "dev": true, - "dependencies": { - "@truffle/abi-utils": "^0.3.1", - "@truffle/compile-common": "^0.8.0", - "big.js": "^6.0.3", - "bn.js": "^5.1.3", - "cbor": "^5.2.0", - "debug": "^4.3.1", - "lodash": "^4.17.21", - "semver": "7.3.7", - "utf8": "^3.0.0", - "web3-utils": "1.7.4" - } - }, - "node_modules/@truffle/codec/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/codec/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/compile-common": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.8.0.tgz", - "integrity": "sha512-3mtEC73dQODTI3/ZwonunVHyPS2BGexXSBIv4pOgMrWwnZPcHlo2+IW2+m2At/DnZehL78bkF993Vti2pJfx6Q==", - "dev": true, - "dependencies": { - "@truffle/error": "^0.1.1", - "colors": "1.4.0" - } - }, - "node_modules/@truffle/contract": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.6.0.tgz", - "integrity": "sha512-FxSR7WtV1q+1AKHhJmsbd360qFFjtkGPQeJfaDcn7wlOPG+axW9iLqLSUTlRpFkPKJnUILg2FujNM965rIQJtg==", - "dev": true, - "dependencies": { - "@ensdomains/ensjs": "^2.1.0", - "@truffle/blockchain-utils": "^0.1.4", - "@truffle/contract-schema": "^3.4.9", - "@truffle/debug-utils": "^6.0.34", - "@truffle/error": "^0.1.1", - "@truffle/interface-adapter": "^0.5.21", - "bignumber.js": "^7.2.1", - "debug": "^4.3.1", - "ethers": "^4.0.32", - "web3": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "node_modules/@truffle/contract-schema": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.9.tgz", - "integrity": "sha512-nhYMXWbUs6dMYHL1f8DTkRk/uo1sADK0yeSYXo/p/7nqnjlHzqrr75BBsKbB7OFIVT05des+GFNQJqBaRZVdxQ==", - "dev": true, - "dependencies": { - "ajv": "^6.10.0", - "debug": "^4.3.1" - } - }, - "node_modules/@truffle/contract/node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/contract/node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/contract/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/@truffle/contract/node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@truffle/contract/node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@truffle/contract/node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@truffle/contract/node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/contract/node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/@truffle/contract/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/@truffle/contract/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/contract/node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/@truffle/contract/node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "node_modules/@truffle/contract/node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@truffle/contract/node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@truffle/contract/node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/contract/node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/@truffle/contract/node_modules/web3": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", - "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.7.4", - "web3-core": "1.7.4", - "web3-eth": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-shh": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-bzz": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", - "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", - "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-requestmanager": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-helpers": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", - "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-method": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", - "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", - "dev": true, - "dependencies": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-promievent": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", - "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-requestmanager": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", - "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.4", - "web3-providers-http": "1.7.4", - "web3-providers-ipc": "1.7.4", - "web3-providers-ws": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-subscriptions": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", - "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core/node_modules/bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", - "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", - "dev": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-accounts": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-eth-ens": "1.7.4", - "web3-eth-iban": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-abi": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", - "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-accounts": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", - "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-contract": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", - "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-ens": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", - "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-iban": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", - "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-iban/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/contract/node_modules/web3-eth-personal": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", - "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-net": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", - "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", - "dev": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-providers-http": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", - "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.7.4", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-providers-ipc": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", - "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-providers-ws": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", - "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-shh": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", - "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-net": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-utils/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/debug-utils": { - "version": "6.0.34", - "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.34.tgz", - "integrity": "sha512-GbGnC9ESJXYHjzQKOV6yeFzvXDnW1yIvpfHXyc4PMDnnFoqX2OxP8mGmMzFKW2Uhqg89wl4GMPLuxycMkodWrw==", - "dev": true, - "dependencies": { - "@truffle/codec": "^0.14.4", - "@trufflesuite/chromafi": "^3.0.0", - "bn.js": "^5.1.3", - "chalk": "^2.4.2", - "debug": "^4.3.1", - "highlightjs-solidity": "^2.0.5" - } - }, - "node_modules/@truffle/debug-utils/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/debug-utils/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/debug-utils/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/debug-utils/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@truffle/debug-utils/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@truffle/debug-utils/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@truffle/debug-utils/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/debug-utils/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/error": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.1.tgz", - "integrity": "sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.21.tgz", - "integrity": "sha512-2ltbu3upsWS0TAQu1kLQc048XlXNmDkCzH6iebX4dg3VBB+l7oG/pu5+/kl8t+LRfzGoEMLKwOQt7vk0Vm3PNA==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.7.4" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/eth-lib/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", - "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.7.4", - "web3-core": "1.7.4", - "web3-eth": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-shh": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-bzz": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", - "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", - "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-requestmanager": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-helpers": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", - "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-method": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", - "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", - "dev": true, - "dependencies": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-promievent": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", - "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-requestmanager": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", - "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.4", - "web3-providers-http": "1.7.4", - "web3-providers-ipc": "1.7.4", - "web3-providers-ws": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-subscriptions": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", - "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", - "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", - "dev": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-accounts": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-eth-ens": "1.7.4", - "web3-eth-iban": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-abi": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", - "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-accounts": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", - "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-contract": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", - "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-ens": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", - "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-iban": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", - "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-personal": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", - "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-net": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", - "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", - "dev": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-providers-http": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", - "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.7.4", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-providers-ipc": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", - "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-providers-ws": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", - "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-shh": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", - "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-net": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@trufflesuite/chromafi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz", - "integrity": "sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==", - "dev": true, - "dependencies": { - "camelcase": "^4.1.0", - "chalk": "^2.3.2", - "cheerio": "^1.0.0-rc.2", - "detect-indent": "^5.0.0", - "highlight.js": "^10.4.1", - "lodash.merge": "^4.6.2", - "strip-ansi": "^4.0.0", - "strip-indent": "^2.0.0" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@trufflesuite/chromafi/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@types/async-eventemitter": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", - "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", - "dev": true - }, - "node_modules/@types/bignumber.js": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz", - "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==", - "deprecated": "This is a stub types definition for bignumber.js (https://github.com/MikeMcl/bignumber.js/). bignumber.js provides its own type definitions, so you don't need @types/bignumber.js installed!", - "dev": true, - "dependencies": { - "bignumber.js": "*" - } - }, - "node_modules/@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "node_modules/@types/chai": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", - "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", - "dev": true - }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.7.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.17.tgz", - "integrity": "sha512-0UyfUnt02zIuqp7yC8RYtDkp/vo8bFaQ13KkSEvUAohPOAlnVNbj5Fi3fgPSuwzakS+EvvnnZ4x9y7i6ASaSPQ==", - "dev": true - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/abortcontroller-polyfill": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz", - "integrity": "sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==", - "dev": true - }, - "node_modules/abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/abstract-level/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/address": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", - "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true, - "engines": { - "node": ">=0.3.0" - } - }, - "node_modules/aes-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", - "dev": true - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.4.2" - } - }, - "node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/antlr4": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", - "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", - "dev": true - }, - "node_modules/antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.reduce": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", - "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/ast-parents": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", - "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", - "dev": true - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "dev": true, - "dependencies": { - "async": "^2.4.0" - } - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "node_modules/big-integer": { - "version": "1.6.36", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", - "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/big.js": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz", - "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/bigjs" - } - }, - "node_modules/bigint-crypto-utils": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.6.tgz", - "integrity": "sha512-k5ljSLHx94jQTW3+18KEfxLJR8/XFBHqhfhEGF48qT8p/jL6EdiG7oNOiiIRGMFh2wEP8kaCXZbVd+5dYkngUg==", - "dev": true, - "dependencies": { - "bigint-mod-arith": "^3.1.0" - }, - "engines": { - "node": ">=10.4.0" - } - }, - "node_modules/bigint-mod-arith": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.1.tgz", - "integrity": "sha512-SzFqdncZKXq5uh3oLFZXmzaZEMDsA7ml9l53xKaVGO6/+y26xNwAaTQEg2R+D+d07YduLbKi0dni3YPsR51UDQ==", - "dev": true, - "engines": { - "node": ">=10.4.0" - } - }, - "node_modules/bignumber.js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/body-parser/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", - "dev": true, - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-rsa/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-reverse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", - "integrity": "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==", - "dev": true - }, - "node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-callsite/node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "node_modules/catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dev": true, - "dependencies": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/cbor/node_modules/bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-bn": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/chai-bn/-/chai-bn-0.2.2.tgz", - "integrity": "sha512-MzjelH0p8vWn65QKmEq/DLBG1Hle4WeyqT79ANhXZhn/UxRWO0OogkAxi5oGGtfzwU9bZR8mvbvYdoqNVWQwFg==", - "dev": true, - "peerDependencies": { - "bn.js": "^4.11.0", - "chai": "^4.0.0" - } - }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/change-case": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.0.2.tgz", - "integrity": "sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==", - "dev": true, - "dependencies": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dev": true, - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" - } - }, - "node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true - }, - "node_modules/classic-level": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", - "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "~2.0.0", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "dependencies": { - "restore-cursor": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - }, - "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "colors": "^1.1.2" - } - }, - "node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, - "node_modules/commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/constant-case": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", - "integrity": "sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==", - "dev": true, - "dependencies": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, - "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "node_modules/cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", - "dev": true - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dev": true, - "dependencies": { - "node-fetch": "2.6.7" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-addr-codec": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz", - "integrity": "sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg==", - "dev": true, - "dependencies": { - "base-x": "^3.0.8", - "big-integer": "1.6.36", - "blakejs": "^1.1.0", - "bs58": "^4.0.1", - "ripemd160-min": "0.0.6", - "safe-buffer": "^5.2.0", - "sha3": "^2.1.1" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", - "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==", - "dev": true - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", - "dev": true, - "dependencies": { - "heap": ">= 0.2.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", - "dev": true, - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", - "integrity": "sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "dev": true - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/emoji-regex": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", - "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/enquirer/node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "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", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "dependencies": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=0.12.0" - }, - "optionalDependencies": { - "source-map": "~0.2.0" - } - }, - "node_modules/escodegen/node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peerDependencies": { - "eslint": "^7.12.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1 || ^5.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/eslint-plugin-mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz", - "integrity": "sha512-xLqqWUF17llsogVOC+8C6/jvQ+4IoOREbN7ZCHuOHuD6cT5cDD4h7f2LgsZuzMAiwswWE21tO7ExaknHVDrSkw==", - "dev": true, - "dependencies": { - "eslint-utils": "^3.0.0", - "rambda": "^7.1.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-mocha/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", - "dev": true, - "dependencies": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "node_modules/eth-ens-namehash/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "node_modules/eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "peerDependencies": { - "@codechecks/client": "^0.1.0" - }, - "peerDependenciesMeta": { - "@codechecks/client": { - "optional": true - } - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/eth-gas-reporter/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eth-gas-reporter/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eth-gas-reporter/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eth-gas-reporter/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/eth-gas-reporter/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/eth-gas-reporter/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/eth-gas-reporter/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/eth-gas-reporter/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/eth-gas-reporter/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/eth-lib/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/eth-lib/node_modules/ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "node_modules/eth-sig-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-3.0.1.tgz", - "integrity": "sha512-0Us50HiGGvZgjtWTyAI/+qTzYPMLy5Q451D0Xy68bxq1QMWdoOddDwGvsqcFT27uohKgalM9z/yxplyt+mY2iQ==", - "deprecated": "Deprecated in favor of '@metamask/eth-sig-util'", - "dev": true, - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.0" - } - }, - "node_modules/eth-sig-util/node_modules/ethereumjs-util": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", - "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dev": true, - "dependencies": { - "js-sha3": "^0.8.0" - } - }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethereum-ens": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/ethereum-ens/-/ethereum-ens-0.8.0.tgz", - "integrity": "sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==", - "dev": true, - "dependencies": { - "bluebird": "^3.4.7", - "eth-ens-namehash": "^2.0.0", - "js-sha3": "^0.5.7", - "pako": "^1.0.4", - "underscore": "^1.8.3", - "web3": "^1.0.0-beta.34" - } - }, - "node_modules/ethereum-ens/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/ethereumjs-wallet": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-1.0.2.tgz", - "integrity": "sha512-CCWV4RESJgRdHIvFciVQFnCHfqyhXWchTPlkfp28Qc53ufs+doi5I/cV2+xeK9+qEo25XCWfP9MiL+WEPAZfdA==", - "dev": true, - "dependencies": { - "aes-js": "^3.1.2", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^7.1.2", - "randombytes": "^2.1.0", - "scrypt-js": "^3.0.1", - "utf8": "^3.0.0", - "uuid": "^8.3.2" - } - }, - "node_modules/ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "dependencies": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "node_modules/ethers/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "node_modules/ethers/node_modules/hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/ethers/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "node_modules/ethers/node_modules/scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "node_modules/ethers/node_modules/setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true - }, - "node_modules/ethers/node_modules/uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true - }, - "node_modules/ethjs-abi": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz", - "integrity": "sha512-g2AULSDYI6nEJyJaEVEXtTimRY2aPC2fi7ddSy0W+LXvEVL8Fe1y76o43ecbgdUKwZD+xsmEgX1yJr1Ia3r1IA==", - "dev": true, - "dependencies": { - "bn.js": "4.11.6", - "js-sha3": "0.5.5", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-abi/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - }, - "node_modules/ethjs-abi/node_modules/js-sha3": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", - "integrity": "sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA==", - "dev": true - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dev": true, - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/express/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/express/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-check": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.1.1.tgz", - "integrity": "sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA==", - "dev": true, - "dependencies": { - "pure-rand": "^5.0.1" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/form-data-encoder": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", - "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", - "dev": true - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "bin": { - "testrpc-sc": "index.js" - } - }, - "node_modules/ghost-testrpc/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ghost-testrpc/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ghost-testrpc/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/globby/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globby/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/got": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", - "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "form-data-encoder": "1.7.1", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - } - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.11.1.tgz", - "integrity": "sha512-7FoyfKjBs97GHNpQejHecJBBcRPOEhAE3VkjSWXB3GeeiXefWbw+zhRVOjI4eCsUUt7PyNFAdWje/lhnBT9fig==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "^4.0.0-rc.3", - "@nomicfoundation/ethereumjs-blockchain": "^6.0.0-rc.3", - "@nomicfoundation/ethereumjs-common": "^3.0.0-rc.3", - "@nomicfoundation/ethereumjs-evm": "^1.0.0-rc.3", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0-rc.3", - "@nomicfoundation/ethereumjs-statemanager": "^1.0.0-rc.3", - "@nomicfoundation/ethereumjs-trie": "^5.0.0-rc.3", - "@nomicfoundation/ethereumjs-tx": "^4.0.0-rc.3", - "@nomicfoundation/ethereumjs-util": "^8.0.0-rc.3", - "@nomicfoundation/ethereumjs-vm": "^6.0.0-rc.3", - "@nomicfoundation/solidity-analyzer": "^0.0.3", - "@sentry/node": "^5.18.1", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^1.0.3", - "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "keccak": "^3.0.2", - "lodash": "^4.17.11", - "mnemonist": "^0.38.0", - "mocha": "^10.0.0", - "p-map": "^4.0.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "tsort": "0.0.1", - "undici": "^5.4.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "bin": { - "hardhat": "internal/cli/cli.js" - }, - "engines": { - "node": "^14.0.0 || ^16.0.0 || ^18.0.0" - }, - "peerDependencies": { - "ts-node": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", - "dev": true, - "dependencies": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.25", - "sha1": "^1.1.1" - }, - "peerDependencies": { - "hardhat": "^2.0.2" - } - }, - "node_modules/hardhat-ignore-warnings": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/hardhat-ignore-warnings/-/hardhat-ignore-warnings-0.2.0.tgz", - "integrity": "sha512-fetYwdpjAg6pl7oxOAL0yZQTKt/87KgDV5P7sEoIORXaoqCBvRGcGAQLJZ8hCiWNZ+vZKYw/9oVVZVlFcOxZTw==", - "dev": true, - "dependencies": { - "minimatch": "^5.1.0", - "node-interval-tree": "^2.0.1", - "solidity-comments": "^0.0.2" - } - }, - "node_modules/hardhat-ignore-warnings/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/hardhat-ignore-warnings/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hardhat/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/hardhat/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/hardhat/node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "node_modules/hardhat/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/hardhat/node_modules/ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" - } - }, - "node_modules/hardhat/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/hardhat/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/hardhat/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/require-from-string": { - "version": "2.0.2", - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hardhat/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hardhat/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/hardhat/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/hardhat/node_modules/solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/hardhat/node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/hardhat/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/header-case": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", - "integrity": "sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" - } - }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true - }, - "node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/highlightjs-solidity": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.5.tgz", - "integrity": "sha512-ReXxQSGQkODMUgHcWzVSnfDCDrL2HshOYgw3OlIYmfHeRzUPkfJTUIp95pK4CmbiNG2eMTOmNLpfCz9Zq7Cwmg==", - "dev": true - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" - } - }, - "node_modules/http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", - "dev": true - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/http2-wrapper": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", - "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "dev": true, - "dependencies": { - "punycode": "2.1.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immutable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", - "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/inquirer/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "dependencies": { - "fp-ts": "^1.0.0" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-callable": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.5.tgz", - "integrity": "sha512-ZIWRujF6MvYGkEuHMYtFRkL2wAtFw89EHfKlXrkPkjQZZRWeh9L1q3SV13NIfHnqxugjLvAOkEHx9mb1zcMnEw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-lower-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", - "integrity": "sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-port-reachable": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-3.1.0.tgz", - "integrity": "sha512-vjc0SSRNZ32s9SbZBzGaiP6YVB+xglLShhgZD/FHMZUXBvQWaV9CtzgeVhjccFJrI6RAMV+LX7NYxueW/A8W5A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "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==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-upper-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", - "integrity": "sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==", - "dev": true, - "dependencies": { - "upper-case": "^1.1.0" - } - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - } - }, - "node_modules/keccak256/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/keccak256/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/keyv": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", - "integrity": "sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dev": true, - "dependencies": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/level" - } - }, - "node_modules/level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/level-transcoder/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", - "dev": true - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "node_modules/lodash.zip": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", - "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", - "dev": true - }, - "node_modules/lower-case-first": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", - "integrity": "sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.2" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "node_modules/mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memory-level": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", - "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", - "dev": true, - "dependencies": { - "abstract-level": "^1.0.0", - "functional-red-black-tree": "^1.0.1", - "module-error": "^1.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/merkletreejs": { - "version": "0.2.32", - "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.2.32.tgz", - "integrity": "sha512-TostQBiwYRIwSE5++jGmacu3ODcKAgqb0Y/pnIohXS7sWxh1gCkSptbmF1a43faehRDpcHf7J/kv0Ml2D/zblQ==", - "dev": true, - "dependencies": { - "bignumber.js": "^9.0.1", - "buffer-reverse": "^1.0.1", - "crypto-js": "^3.1.9-1", - "treeify": "^1.1.0", - "web3-utils": "^1.3.4" - }, - "engines": { - "node": ">= 7.6.0" - } - }, - "node_modules/merkletreejs/node_modules/bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", - "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", - "dev": true, - "dependencies": { - "mkdirp": "*" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "dependencies": { - "obliterator": "^2.0.0" - } - }, - "node_modules/mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", - "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", - "dev": true - }, - "node_modules/module-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", - "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "varint": "^5.0.0" - } - }, - "node_modules/multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - } - }, - "node_modules/multihashes/node_modules/multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true - }, - "node_modules/nano-base32": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nano-base32/-/nano-base32-1.0.1.tgz", - "integrity": "sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==", - "dev": true - }, - "node_modules/nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-macros": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", - "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.1" - } - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "dependencies": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node_modules/node-environment-flags/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", - "dev": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-interval-tree": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-interval-tree/-/node-interval-tree-2.0.1.tgz", - "integrity": "sha512-KodzC8le4U8LOmCvn1wSyIY8eplzRSjsLMzs0EjLteCXWDjRpCTzrjtQ4t8jh3w3r6OIglha1zChzjRYMVwuLA==", - "dev": true, - "dependencies": { - "shallowequal": "^1.1.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", - "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", - "dev": true, - "dependencies": { - "array.prototype.reduce": "^1.0.4", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "node_modules/oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", - "dev": true, - "dependencies": { - "http-https": "^1.0.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true - }, - "node_modules/parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", - "dev": true - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/parse5": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz", - "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==", - "dev": true, - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dev": true, - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", - "integrity": "sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==", - "dev": true, - "dependencies": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" - } - }, - "node_modules/path-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", - "integrity": "sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-plugin-solidity": { - "version": "1.0.0-beta.24", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.24.tgz", - "integrity": "sha512-6JlV5BBTWzmDSq4kZ9PTXc3eLOX7DF5HpbqmmaF+kloyUwOZbJ12hIYsUaZh2fVgZdV2t0vWcvY6qhILhlzgqg==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.14.3", - "emoji-regex": "^10.1.0", - "escape-string-regexp": "^4.0.0", - "semver": "^7.3.7", - "solidity-comments-extractor": "^0.0.7", - "string-width": "^4.2.3" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "prettier": "^2.3.0" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/prettier-plugin-solidity/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.2.0.tgz", - "integrity": "sha512-+CMAlLHqwRYwBMXKCP+o8ns7DN+xHDUiI+0nArsiJ9y+kJVPLFxEaSw6Ha9s9H0tftxg2Yzl25wqj9G7m5wLZg==", - "dev": true, - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.3.tgz", - "integrity": "sha512-9N8x1h8dptBQpHyC7aZMS+iNOAm97WMGY0AFrguU1cpfW3I5jINkWe5BIY5md0ofy+1TCIELsVcm/GJXZSaPbw==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rambda": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.2.1.tgz", - "integrity": "sha512-Wswj8ZvzdI3VhaGPkZAxaCTwuMmGtgWt7Zxsgyo4P+iTmVnkojvyWaOep5q3ZjMIecW0wtQa66GWxaKkZ24RAA==", - "dev": true - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "dev": true, - "dependencies": { - "minimatch": "3.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/recursive-readdir/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "dependencies": { - "req-from": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/responselike/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/ripemd160-min": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/ripemd160-min/-/ripemd160-min-0.0.6.tgz", - "integrity": "sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/rlp/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "dependencies": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "istanbul": "lib/cli.js" - } - }, - "node_modules/sc-istanbul/node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "node_modules/sc-istanbul/node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sc-istanbul/node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true - }, - "node_modules/sc-istanbul/node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/sc-istanbul/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/send/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/sentence-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", - "integrity": "sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dev": true, - "dependencies": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "dependencies": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sha3": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-2.1.4.tgz", - "integrity": "sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==", - "dev": true, - "dependencies": { - "buffer": "6.0.3" - } - }, - "node_modules/sha3/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shelljs/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-get/node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/snake-case": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", - "integrity": "sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "dependencies": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - }, - "bin": { - "solcjs": "solcjs" - } - }, - "node_modules/solc/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/solc/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/solc/node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/solc/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/solc/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/solc/node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true - }, - "node_modules/solc/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solc/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, - "node_modules/solc/node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "node_modules/solc/node_modules/yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", - "dev": true, - "dependencies": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "node_modules/solc/node_modules/yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - }, - "node_modules/solhint": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.7.tgz", - "integrity": "sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.14.1", - "ajv": "^6.6.1", - "antlr4": "4.7.1", - "ast-parents": "0.0.1", - "chalk": "^2.4.2", - "commander": "2.18.0", - "cosmiconfig": "^5.0.7", - "eslint": "^5.6.0", - "fast-diff": "^1.1.2", - "glob": "^7.1.3", - "ignore": "^4.0.6", - "js-yaml": "^3.12.0", - "lodash": "^4.17.11", - "semver": "^6.3.0" - }, - "bin": { - "solhint": "solhint.js" - }, - "optionalDependencies": { - "prettier": "^1.14.3" - } - }, - "node_modules/solhint/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/solhint/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/solhint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/solhint/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/solhint/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solhint/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/solhint/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/solhint/node_modules/eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^6.14.0 || ^8.10.0 || >=9.10.0" - } - }, - "node_modules/solhint/node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/solhint/node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/eslint/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solhint/node_modules/espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "dependencies": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/solhint/node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/solhint/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/solhint/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true, - "optional": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/solhint/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/solhint/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/solhint/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/string-width/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/solhint/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/solidity-ast": { - "version": "0.4.35", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", - "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==", - "dev": true - }, - "node_modules/solidity-comments": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments/-/solidity-comments-0.0.2.tgz", - "integrity": "sha512-G+aK6qtyUfkn1guS8uzqUeua1dURwPlcOjoTYW/TwmXAcE7z/1+oGCfZUdMSe4ZMKklNbVZNiG5ibnF8gkkFfw==", - "dev": true, - "engines": { - "node": ">= 12" - }, - "optionalDependencies": { - "solidity-comments-darwin-arm64": "0.0.2", - "solidity-comments-darwin-x64": "0.0.2", - "solidity-comments-freebsd-x64": "0.0.2", - "solidity-comments-linux-arm64-gnu": "0.0.2", - "solidity-comments-linux-arm64-musl": "0.0.2", - "solidity-comments-linux-x64-gnu": "0.0.2", - "solidity-comments-linux-x64-musl": "0.0.2", - "solidity-comments-win32-arm64-msvc": "0.0.2", - "solidity-comments-win32-ia32-msvc": "0.0.2", - "solidity-comments-win32-x64-msvc": "0.0.2" - } - }, - "node_modules/solidity-comments-darwin-arm64": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-darwin-arm64/-/solidity-comments-darwin-arm64-0.0.2.tgz", - "integrity": "sha512-HidWkVLSh7v+Vu0CA7oI21GWP/ZY7ro8g8OmIxE8oTqyMwgMbE8F1yc58Sj682Hj199HCZsjmtn1BE4PCbLiGA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-darwin-x64": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-darwin-x64/-/solidity-comments-darwin-x64-0.0.2.tgz", - "integrity": "sha512-Zjs0Ruz6faBTPT6fBecUt6qh4CdloT8Bwoc0+qxRoTn9UhYscmbPQkUgQEbS0FQPysYqVzzxJB4h1Ofbf4wwtA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "node_modules/solidity-comments-freebsd-x64": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-freebsd-x64/-/solidity-comments-freebsd-x64-0.0.2.tgz", - "integrity": "sha512-8Qe4mpjuAxFSwZJVk7B8gAoLCdbtS412bQzBwk63L8dmlHogvE39iT70aAk3RHUddAppT5RMBunlPUCFYJ3ZTw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-linux-arm64-gnu": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-arm64-gnu/-/solidity-comments-linux-arm64-gnu-0.0.2.tgz", - "integrity": "sha512-spkb0MZZnmrP+Wtq4UxP+nyPAVRe82idOjqndolcNR0S9Xvu4ebwq+LvF4HiUgjTDmeiqYiFZQ8T9KGdLSIoIg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-linux-arm64-musl": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-arm64-musl/-/solidity-comments-linux-arm64-musl-0.0.2.tgz", - "integrity": "sha512-guCDbHArcjE+JDXYkxx5RZzY1YF6OnAKCo+sTC5fstyW/KGKaQJNPyBNWuwYsQiaEHpvhW1ha537IvlGek8GqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-linux-x64-gnu": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-x64-gnu/-/solidity-comments-linux-x64-gnu-0.0.2.tgz", - "integrity": "sha512-zIqLehBK/g7tvrFmQljrfZXfkEeLt2v6wbe+uFu6kH/qAHZa7ybt8Vc0wYcmjo2U0PeBm15d79ee3AkwbIjFdQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-linux-x64-musl": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-x64-musl/-/solidity-comments-linux-x64-musl-0.0.2.tgz", - "integrity": "sha512-R9FeDloVlFGTaVkOlELDVC7+1Tjx5WBPI5L8r0AGOPHK3+jOcRh6sKYpI+VskSPDc3vOO46INkpDgUXrKydlIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-win32-arm64-msvc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-win32-arm64-msvc/-/solidity-comments-win32-arm64-msvc-0.0.2.tgz", - "integrity": "sha512-QnWJoCQcJj+rnutULOihN9bixOtYWDdF5Rfz9fpHejL1BtNjdLW1om55XNVHGAHPqBxV4aeQQ6OirKnp9zKsug==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-win32-ia32-msvc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-win32-ia32-msvc/-/solidity-comments-win32-ia32-msvc-0.0.2.tgz", - "integrity": "sha512-vUg4nADtm/NcOtlIymG23NWJUSuMsvX15nU7ynhGBsdKtt8xhdP3C/zA6vjDk8Jg+FXGQL6IHVQ++g/7rSQi0w==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-comments-win32-x64-msvc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-win32-x64-msvc/-/solidity-comments-win32-x64-msvc-0.0.2.tgz", - "integrity": "sha512-36j+KUF4V/y0t3qatHm/LF5sCUCBx2UndxE1kq5bOzh/s+nQgatuyB+Pd5BfuPQHdWu2KaExYe20FlAa6NL7+Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/solidity-coverage": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", - "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.14.1", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "difflib": "^0.2.4", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "mocha": "7.1.2", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.6" - }, - "bin": { - "solidity-coverage": "plugins/bin.js" - }, - "peerDependencies": { - "hardhat": "^2.11.0" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" - } - }, - "node_modules/solidity-coverage/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/solidity-coverage/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/solidity-coverage/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/solidity-coverage/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/solidity-coverage/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-coverage/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/solidity-coverage/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/solidity-coverage/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/solidity-coverage/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/solidity-coverage/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/solidity-coverage/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/solidity-coverage/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/solidity-coverage/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/solidity-coverage/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/solidity-coverage/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/solidity-coverage/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/solidity-coverage/node_modules/mocha": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", - "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", - "dev": true, - "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/solidity-coverage/node_modules/mocha/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/solidity-coverage/node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/solidity-coverage/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/solidity-coverage/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-coverage/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/solidity-coverage/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/solidity-coverage/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/solidity-coverage/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/solidity-coverage/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-docgen": { - "version": "0.6.0-beta.29", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.6.0-beta.29.tgz", - "integrity": "sha512-63p3w6wj1WFhhC8pXTI3bz5qUTFuGmLNHFnwwpjZ6Qv8dF2WGDt0pg1rbA6c3bL/A4d0ATN66Mte1saGKVWdHg==", - "dev": true, - "dependencies": { - "handlebars": "^4.7.7", - "solidity-ast": "^0.4.31" - }, - "peerDependencies": { - "hardhat": "^2.8.0" - } - }, - "node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dev": true, - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stacktrace-parser/node_modules/type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/swap-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", - "integrity": "sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" - } - }, - "node_modules/swarm-js": { - "version": "0.1.42", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", - "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^11.8.5", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - } - }, - "node_modules/swarm-js/node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/swarm-js/node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/swarm-js/node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/swarm-js/node_modules/got": { - "version": "11.8.5", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", - "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/swarm-js/node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/swarm-js/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/swarm-js/node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "dependencies": { - "get-port": "^3.1.0" - } - }, - "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/table/node_modules/require-from-string": { - "version": "2.0.2", - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", - "dev": true - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "dependencies": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/title-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", - "integrity": "sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/uglify-js": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz", - "integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/underscore": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz", - "integrity": "sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==", - "dev": true - }, - "node_modules/undici": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.10.0.tgz", - "integrity": "sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==", - "dev": true, - "engines": { - "node": ">=12.18" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", - "dev": true - }, - "node_modules/upper-case-first": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", - "integrity": "sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==", - "dev": true, - "dependencies": { - "upper-case": "^1.1.1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", - "dev": true - }, - "node_modules/utf-8-validate": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", - "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true - }, - "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/web3": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.5.tgz", - "integrity": "sha512-3jHZTWyXt975AOXgnZKayiSWDLpoSKk9fZtLk1hURQtt7AdSbXPT8AK9ooBCm0Dt3GYaOeNcHGaiHC3gtyqhLg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.7.5", - "web3-core": "1.7.5", - "web3-eth": "1.7.5", - "web3-eth-personal": "1.7.5", - "web3-net": "1.7.5", - "web3-shh": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.5.tgz", - "integrity": "sha512-Z53sY0YK/losqjJncmL4vP0zZI9r6tiXg6o7R6e1JD2Iy7FH3serQvU+qXmPjqEBzsnhf8wTG+YcBPB3RHpr0Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "12.1.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/web3-core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.5.tgz", - "integrity": "sha512-UgOWXZr1fR/3cUQJKWbfMwRxj1/N7o6RSd/dHqdXBlOD+62EjNZItFmLRg5veq5kp9YfXzrNw9bnDkXfsL+nKQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-core-requestmanager": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-helpers": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.5.tgz", - "integrity": "sha512-lDDjTks6Q6aNUO87RYrY2xub3UWTKr/RIWxpHJODEqkLxZS1dWdyliJ6aIx3031VQwsNT5HE7NvABe/t0p3iDQ==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-method": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.5.tgz", - "integrity": "sha512-ApTvq1Llzlbxmy0n4L7QaE6NodIsR80VJqk8qN4kLg30SGznt/pNJFebryLI2kpyDmxSgj1TjEWzmHJBp6FhYg==", - "dev": true, - "dependencies": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.5", - "web3-core-promievent": "1.7.5", - "web3-core-subscriptions": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-promievent": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.5.tgz", - "integrity": "sha512-uZ1VRErVuhiLtHlyt3oEH/JSvAf6bWPndChHR9PG7i1Zfqm6ZVCeM91ICTPmiL8ddsGQOxASpnJk4vhApcTIww==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-requestmanager": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.5.tgz", - "integrity": "sha512-3KpfxW/wVH4mgwWEsSJGHKrtRVoijWlDxtUrm17xgtqRNZ2mFolifKnHAUKa0fY48C9CrxmcCiMIi3W4G6WYRw==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.5", - "web3-providers-http": "1.7.5", - "web3-providers-ipc": "1.7.5", - "web3-providers-ws": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-subscriptions": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.5.tgz", - "integrity": "sha512-YK6utQ7Wwjbe4XZOIA8quWGBPi1lFDS1A+jQYwxKKrCvm6BloBNc3FhvrcSYlDhLe/kOy8+2Je8i9amndgT4ww==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/web3-core/node_modules/bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/web3-eth": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.5.tgz", - "integrity": "sha512-BucjvqZyDWYkGlsFX+OnOBub0YutlC1KZiNGibdmvtNX0NQK+8iw1uzAoL9yTTwCSszL7lnkFe8N+HCOl9B4Dw==", - "dev": true, - "dependencies": { - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-core-subscriptions": "1.7.5", - "web3-eth-abi": "1.7.5", - "web3-eth-accounts": "1.7.5", - "web3-eth-contract": "1.7.5", - "web3-eth-ens": "1.7.5", - "web3-eth-iban": "1.7.5", - "web3-eth-personal": "1.7.5", - "web3-net": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-abi": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.5.tgz", - "integrity": "sha512-qWHvF7sayxql9BD1yqK9sZRLBQ66eJzGeaU53Y1PRq2iFPrhY6NUWxQ3c3ps0rg+dyObvRbloviWpKXcS4RE/A==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.5.tgz", - "integrity": "sha512-AzMLoTj3RGwKpyp3x3TtHrEeU4VpR99iMOD6NKrWSDumS6QEi0lCo+y7QZhdTlINw3iIA3SFIdvbAOO4NCHSDg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/web3-eth-contract": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.5.tgz", - "integrity": "sha512-qab7NPJRKRlTs58ozsqK8YIEwWpxIm3vD/okSIKBGkFx5gIHWW+vGmMh5PDSfefLJM9rCd+T+Lc0LYvtME7uqg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-core-promievent": "1.7.5", - "web3-core-subscriptions": "1.7.5", - "web3-eth-abi": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.5.tgz", - "integrity": "sha512-k1Q0msdRv/wac2egpZBIwG3n/sa/KdrVmVJvFm471gLTL4xfUizV5qJjkDVf+ikf9JyDvWJTs5eWNUUbOFIw/A==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-promievent": "1.7.5", - "web3-eth-abi": "1.7.5", - "web3-eth-contract": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-iban": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.5.tgz", - "integrity": "sha512-mn2W5t/1IpL8OZvzAabLKT4kvwRnZSJ9K0tctndl9sDNWkfITYQibEEhUaNNA50Q5fJKgVudHI/m0gwIVTyG8Q==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-iban/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/web3-eth-personal": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.5.tgz", - "integrity": "sha512-txh2P/eN8I4AOUKFi9++KKddoD0tWfCuu9Y1Kc41jSRbk6smO88Fum0KWNmYFYhSCX2qiknS1DfqsONl3igoKQ==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-net": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/web3-net": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.5.tgz", - "integrity": "sha512-xwuCb2YWw49PmW81AJQ/G+Xi2ikRsYyZXSgyPt4LmZuKjiqg/6kSdK8lZvUi3Pi3wM+QDBXbpr73M/WEkW0KvA==", - "dev": true, - "dependencies": { - "web3-core": "1.7.5", - "web3-core-method": "1.7.5", - "web3-utils": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-http": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.5.tgz", - "integrity": "sha512-vPgr4Kzy0M3CHtoP/Bh7qwK/D9h2fhjpoqctdMWVJseOfeTgfOphCKN0uwV8w2VpZgDPXA8aeTdBx5OjmDdStA==", - "dev": true, - "dependencies": { - "abortcontroller-polyfill": "^1.7.3", - "cross-fetch": "^3.1.4", - "es6-promise": "^4.2.8", - "web3-core-helpers": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ipc": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.5.tgz", - "integrity": "sha512-aNHx+RAROzO+apDEzy8Zncj78iqWBadIXtpmFDg7uiTn8i+oO+IcP1Yni7jyzkltsysVJHgHWG4kPx50ANCK3Q==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ws": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.5.tgz", - "integrity": "sha512-9uJNVVkIGC8PmM9kNbgPth56HDMSSsxZh3ZEENdwO3LNWemaADiQYUDCsD/dMVkn0xsGLHP5dgAy4Q5msqySLg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.5", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.5.tgz", - "integrity": "sha512-aCIWJyLMH5H76OybU4ZpUCJ93yNOPATGhJ+KboRPU8QZDzS2CcVhtEzyl27bbvw+rSnVroMLqBgTXBB4mmKI7A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.7.5", - "web3-core-method": "1.7.5", - "web3-core-subscriptions": "1.7.5", - "web3-net": "1.7.5" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.5.tgz", - "integrity": "sha512-9AqNOziQky4wNQadEwEfHiBdOZqopIHzQQVzmvvv6fJwDSMhP+khqmAZC7YTiGjs0MboyZ8tWNivqSO1699XQw==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, - "node_modules/which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", - "dev": true, - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dev": true, - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", - "dev": true, - "dependencies": { - "cookiejar": "^2.1.1" - } - }, - "node_modules/xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", - "dev": true, - "engines": { - "node": ">=0.10.32" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", - "dev": true - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/runtime": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", - "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@ensdomains/address-encoder": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz", - "integrity": "sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==", - "dev": true, - "requires": { - "bech32": "^1.1.3", - "blakejs": "^1.1.0", - "bn.js": "^4.11.8", - "bs58": "^4.0.1", - "crypto-addr-codec": "^0.1.7", - "nano-base32": "^1.0.1", - "ripemd160": "^2.0.2" - } - }, - "@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "dev": true, - "requires": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - } - }, - "@ensdomains/ensjs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@ensdomains/ensjs/-/ensjs-2.1.0.tgz", - "integrity": "sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==", - "dev": true, - "requires": { - "@babel/runtime": "^7.4.4", - "@ensdomains/address-encoder": "^0.1.7", - "@ensdomains/ens": "0.4.5", - "@ensdomains/resolver": "0.2.4", - "content-hash": "^2.5.2", - "eth-ens-namehash": "^2.0.8", - "ethers": "^5.0.13", - "js-sha3": "^0.8.0" - }, - "dependencies": { - "ethers": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.0.tgz", - "integrity": "sha512-5Xhzp2ZQRi0Em+0OkOcRHxPzCfoBfgtOQA+RUylSkuHbhTEaQklnYi2hsWbRgs3ztJsXVXd9VKBcO1ScWL8YfA==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.0", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.0", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.0", - "@ethersproject/wordlists": "5.7.0" - } - } - } - }, - "@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" - } - }, - "@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" - } - }, - "@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - }, - "dependencies": { - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - } - } - }, - "@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true - }, - "@ethersproject/networks": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.0.tgz", - "integrity": "sha512-MG6oHSQHd4ebvJrleEQQ4HhVu8Ichr0RDYEfHzsVAVjHNM+w36x9wp9r+hf1JstMXtseXDtkiVoARAG6M959AA==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/providers": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.0.tgz", - "integrity": "sha512-+TTrrINMzZ0aXtlwO/95uhAggKm4USLm1PbeCBR/3XZ7+Oey+3pMyddzZEyRhizHpy1HXV0FRWRMI1O3EGYibA==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - }, - "dependencies": { - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "requires": {} - } - } - }, - "@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "@ethersproject/web": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.0.tgz", - "integrity": "sha512-ApHcbbj+muRASVDSCl/tgxaH2LBkRMEYfLOLVa0COipx0+nlu0QKet7U2lEg0vdkh8XRSLf2nd1f1Uk9SrVSGA==", - "dev": true, - "requires": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@frangio/servbot": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@frangio/servbot/-/servbot-0.2.5.tgz", - "integrity": "sha512-ogja4iAPZ1VwM5MU3C1ZhB88358F0PGbmSTGOkIZwOyLaDoMHIqOVCnavHjR7DV5h+oAI4Z4KDqlam3myQUrmg==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "requires": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "@noble/hashes": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", - "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", - "dev": true - }, - "@noble/secp256k1": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", - "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@nomicfoundation/ethereumjs-block": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz", - "integrity": "sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-tx": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3" - } - }, - "@nomicfoundation/ethereumjs-blockchain": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz", - "integrity": "sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-ethash": "^2.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "abstract-level": "^1.0.3", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "level": "^8.0.0", - "lru-cache": "^5.1.1", - "memory-level": "^1.0.0" - } - }, - "@nomicfoundation/ethereumjs-common": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz", - "integrity": "sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "crc-32": "^1.2.0" - } - }, - "@nomicfoundation/ethereumjs-ethash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz", - "integrity": "sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "abstract-level": "^1.0.3", - "bigint-crypto-utils": "^3.0.23", - "ethereum-cryptography": "0.1.3" - } - }, - "@nomicfoundation/ethereumjs-evm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz", - "integrity": "sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "@types/async-eventemitter": "^0.2.1", - "async-eventemitter": "^0.2.4", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - } - }, - "@nomicfoundation/ethereumjs-rlp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz", - "integrity": "sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==", - "dev": true - }, - "@nomicfoundation/ethereumjs-statemanager": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz", - "integrity": "sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "functional-red-black-tree": "^1.0.1" - } - }, - "@nomicfoundation/ethereumjs-trie": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz", - "integrity": "sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3", - "readable-stream": "^3.6.0" - } - }, - "@nomicfoundation/ethereumjs-tx": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz", - "integrity": "sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "ethereum-cryptography": "0.1.3" - } - }, - "@nomicfoundation/ethereumjs-util": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz", - "integrity": "sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-rlp": "^4.0.0-beta.2", - "ethereum-cryptography": "0.1.3" - } - }, - "@nomicfoundation/ethereumjs-vm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz", - "integrity": "sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==", - "dev": true, - "requires": { - "@nomicfoundation/ethereumjs-block": "^4.0.0", - "@nomicfoundation/ethereumjs-blockchain": "^6.0.0", - "@nomicfoundation/ethereumjs-common": "^3.0.0", - "@nomicfoundation/ethereumjs-evm": "^1.0.0", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0", - "@nomicfoundation/ethereumjs-statemanager": "^1.0.0", - "@nomicfoundation/ethereumjs-trie": "^5.0.0", - "@nomicfoundation/ethereumjs-tx": "^4.0.0", - "@nomicfoundation/ethereumjs-util": "^8.0.0", - "@types/async-eventemitter": "^0.2.1", - "async-eventemitter": "^0.2.4", - "debug": "^4.3.3", - "ethereum-cryptography": "0.1.3", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "rustbn.js": "~0.2.0" - } - }, - "@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.6.tgz", - "integrity": "sha512-a35iVD4ycF6AoTfllAnKm96IPIzzHpgKX/ep4oKc2bsUKFfMlacWdyntgC/7d5blyCTXfFssgNAvXDZfzNWVGQ==", - "dev": true, - "requires": { - "ethereumjs-util": "^7.1.4" - } - }, - "@nomicfoundation/solidity-analyzer": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.0.3.tgz", - "integrity": "sha512-VFMiOQvsw7nx5bFmrmVp2Q9rhIjw2AFST4DYvWVVO9PMHPE23BY2+kyfrQ4J3xCMFC8fcBbGLt7l4q7m1SlTqg==", - "dev": true, - "requires": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.0.3", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.0.3", - "@nomicfoundation/solidity-analyzer-freebsd-x64": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.0.3", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": "0.0.3", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.0.3" - } - }, - "@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.0.3.tgz", - "integrity": "sha512-W+bIiNiZmiy+MTYFZn3nwjyPUO6wfWJ0lnXx2zZrM8xExKObMrhCh50yy8pQING24mHfpPFCn89wEB/iG7vZDw==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.0.3.tgz", - "integrity": "sha512-HuJd1K+2MgmFIYEpx46uzwEFjvzKAI765mmoMxy4K+Aqq1p+q7hHRlsFU2kx3NB8InwotkkIq3A5FLU1sI1WDw==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-freebsd-x64": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.0.3.tgz", - "integrity": "sha512-2cR8JNy23jZaO/vZrsAnWCsO73asU7ylrHIe0fEsXbZYqBP9sMr+/+xP3CELDHJxUbzBY8zqGvQt1ULpyrG+Kw==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.0.3.tgz", - "integrity": "sha512-Eyv50EfYbFthoOb0I1568p+eqHGLwEUhYGOxcRNywtlTE9nj+c+MT1LA53HnxD9GsboH4YtOOmJOulrjG7KtbA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.0.3.tgz", - "integrity": "sha512-V8grDqI+ivNrgwEt2HFdlwqV2/EQbYAdj3hbOvjrA8Qv+nq4h9jhQUxFpegYMDtpU8URJmNNlXgtfucSrAQwtQ==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.0.3.tgz", - "integrity": "sha512-uRfVDlxtwT1vIy7MAExWAkRD4r9M79zMG7S09mCrWUn58DbLs7UFl+dZXBX0/8FTGYWHhOT/1Etw1ZpAf5DTrg==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.0.3.tgz", - "integrity": "sha512-8HPwYdLbhcPpSwsE0yiU/aZkXV43vlXT2ycH+XlOjWOnLfH8C41z0njK8DHRtEFnp4OVN6E7E5lHBBKDZXCliA==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.0.3.tgz", - "integrity": "sha512-5WWcT6ZNvfCuxjlpZOY7tdvOqT1kIQYlDF9Q42wMpZ5aTm4PvjdCmFDDmmTvyXEBJ4WTVmY5dWNWaxy8h/E28g==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.0.3.tgz", - "integrity": "sha512-P/LWGZwWkyjSwkzq6skvS2wRc3gabzAbk6Akqs1/Iiuggql2CqdLBkcYWL5Xfv3haynhL+2jlNkak+v2BTZI4A==", - "dev": true, - "optional": true - }, - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.0.3.tgz", - "integrity": "sha512-4AcTtLZG1s/S5mYAIr/sdzywdNwJpOcdStGF3QMBzEt+cGn3MchMaS9b1gyhb2KKM2c39SmPF5fUuWq1oBSQZQ==", - "dev": true, - "optional": true - }, - "@nomiclabs/hardhat-truffle5": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.7.tgz", - "integrity": "sha512-Pw8451IUZp1bTp0QqCHCYfCHs66sCnyxPcaorapu9mfOV9xnZsVaFdtutnhNEiXdiZwbed7LFKpRsde4BjFwig==", - "dev": true, - "requires": { - "@nomiclabs/truffle-contract": "^4.2.23", - "@types/chai": "^4.2.0", - "chai": "^4.2.0", - "ethereumjs-util": "^7.1.4", - "fs-extra": "^7.0.1" - } - }, - "@nomiclabs/hardhat-web3": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz", - "integrity": "sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==", - "dev": true, - "requires": { - "@types/bignumber.js": "^5.0.0" - } - }, - "@nomiclabs/truffle-contract": { - "version": "4.5.10", - "resolved": "https://registry.npmjs.org/@nomiclabs/truffle-contract/-/truffle-contract-4.5.10.tgz", - "integrity": "sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ==", - "dev": true, - "requires": { - "@ensdomains/ensjs": "^2.0.1", - "@truffle/blockchain-utils": "^0.1.3", - "@truffle/contract-schema": "^3.4.7", - "@truffle/debug-utils": "^6.0.22", - "@truffle/error": "^0.1.0", - "@truffle/interface-adapter": "^0.5.16", - "bignumber.js": "^7.2.1", - "ethereum-ens": "^0.8.0", - "ethers": "^4.0.0-beta.1", - "source-map-support": "^0.5.19" - } - }, - "@openzeppelin/contract-loader": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contract-loader/-/contract-loader-0.6.3.tgz", - "integrity": "sha512-cOFIjBjwbGgZhDZsitNgJl0Ye1rd5yu/Yx5LMgeq3u0ZYzldm4uObzHDFq4gjDdoypvyORjjJa3BlFA7eAnVIg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "fs-extra": "^8.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "@openzeppelin/docs-utils": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/docs-utils/-/docs-utils-0.1.3.tgz", - "integrity": "sha512-O/iJ4jEi5ryNc/T74G9gbnFwQ8QaQ2bpAVoYXLPknZJyK52GEAvxC12UMP33KodTNV3rMzeeQrSBIdI8skjDJg==", - "dev": true, - "requires": { - "@frangio/servbot": "^0.2.5", - "chalk": "^3.0.0", - "chokidar": "^3.5.3", - "env-paths": "^2.2.0", - "find-up": "^4.1.0", - "is-port-reachable": "^3.0.0", - "js-yaml": "^3.13.1", - "lodash.startcase": "^4.4.0", - "minimist": "^1.2.0" - } - }, - "@openzeppelin/test-helpers": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/@openzeppelin/test-helpers/-/test-helpers-0.5.16.tgz", - "integrity": "sha512-T1EvspSfH1qQO/sgGlskLfYVBbqzJR23SZzYl/6B2JnT4EhThcI85UpvDk0BkLWKaDScQTabGHt4GzHW+3SfZg==", - "dev": true, - "requires": { - "@openzeppelin/contract-loader": "^0.6.2", - "@truffle/contract": "^4.0.35", - "ansi-colors": "^3.2.3", - "chai": "^4.2.0", - "chai-bn": "^0.2.1", - "ethjs-abi": "^0.2.1", - "lodash.flatten": "^4.4.0", - "semver": "^5.6.0", - "web3": "^1.2.5", - "web3-utils": "^1.2.5" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true - }, - "@scure/bip32": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", - "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", - "dev": true, - "requires": { - "@noble/hashes": "~1.1.1", - "@noble/secp256k1": "~1.6.0", - "@scure/base": "~1.1.0" - } - }, - "@scure/bip39": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", - "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", - "dev": true, - "requires": { - "@noble/hashes": "~1.1.1", - "@scure/base": "~1.1.0" - } - }, - "@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dev": true, - "requires": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dev": true, - "requires": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - } - }, - "@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true - }, - "@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dev": true, - "requires": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true - }, - "@solidity-parser/parser": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", - "integrity": "sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.1" - } - }, - "@truffle/abi-utils": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.3.1.tgz", - "integrity": "sha512-tieaDgwDm2IH1wJuVF/waREVFvzXHSF6AkQfd71DQwpwnrl/9I1iKu+1WpQyFqxu+6WMfCYhzMEbssQBt4Zniw==", - "dev": true, - "requires": { - "change-case": "3.0.2", - "fast-check": "3.1.1", - "web3-utils": "1.7.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "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" - } - } - } - }, - "@truffle/blockchain-utils": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@truffle/blockchain-utils/-/blockchain-utils-0.1.4.tgz", - "integrity": "sha512-HegAo5A8UX9vE8dtceBRgCY207gOb9wj54c8mNOOWHcFpkyJz7kZYGo44As6Imh10/0hD2j7vHQ56Jf+uszJ3A==", - "dev": true - }, - "@truffle/codec": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.14.4.tgz", - "integrity": "sha512-il9dFzALUbd1JMPOVcxnIjTQ1fiJEPHfBYbqVQfWZfzAN0Kw+x1eaKunIU+NvrNRycvkXk4itWUTui5sMlXBBA==", - "dev": true, - "requires": { - "@truffle/abi-utils": "^0.3.1", - "@truffle/compile-common": "^0.8.0", - "big.js": "^6.0.3", - "bn.js": "^5.1.3", - "cbor": "^5.2.0", - "debug": "^4.3.1", - "lodash": "^4.17.21", - "semver": "7.3.7", - "utf8": "^3.0.0", - "web3-utils": "1.7.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "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" - } - } - } - }, - "@truffle/compile-common": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.8.0.tgz", - "integrity": "sha512-3mtEC73dQODTI3/ZwonunVHyPS2BGexXSBIv4pOgMrWwnZPcHlo2+IW2+m2At/DnZehL78bkF993Vti2pJfx6Q==", - "dev": true, - "requires": { - "@truffle/error": "^0.1.1", - "colors": "1.4.0" - } - }, - "@truffle/contract": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.6.0.tgz", - "integrity": "sha512-FxSR7WtV1q+1AKHhJmsbd360qFFjtkGPQeJfaDcn7wlOPG+axW9iLqLSUTlRpFkPKJnUILg2FujNM965rIQJtg==", - "dev": true, - "requires": { - "@ensdomains/ensjs": "^2.1.0", - "@truffle/blockchain-utils": "^0.1.4", - "@truffle/contract-schema": "^3.4.9", - "@truffle/debug-utils": "^6.0.34", - "@truffle/error": "^0.1.1", - "@truffle/interface-adapter": "^0.5.21", - "bignumber.js": "^7.2.1", - "debug": "^4.3.1", - "ethers": "^4.0.32", - "web3": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "web3": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", - "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", - "dev": true, - "requires": { - "web3-bzz": "1.7.4", - "web3-core": "1.7.4", - "web3-eth": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-shh": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-bzz": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", - "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - } - }, - "web3-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", - "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-requestmanager": "1.7.4", - "web3-utils": "1.7.4" - }, - "dependencies": { - "bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true - } - } - }, - "web3-core-helpers": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", - "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", - "dev": true, - "requires": { - "web3-eth-iban": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-core-method": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", - "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", - "dev": true, - "requires": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-core-promievent": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", - "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", - "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.4", - "web3-providers-http": "1.7.4", - "web3-providers-ipc": "1.7.4", - "web3-providers-ws": "1.7.4" - } - }, - "web3-core-subscriptions": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", - "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4" - } - }, - "web3-eth": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", - "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-accounts": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-eth-ens": "1.7.4", - "web3-eth-iban": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-abi": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", - "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.4" - } - }, - "web3-eth-accounts": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", - "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-contract": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", - "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-ens": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", - "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-iban": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", - "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "web3-eth-personal": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", - "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-net": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", - "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-providers-http": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", - "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", - "dev": true, - "requires": { - "web3-core-helpers": "1.7.4", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", - "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.4" - } - }, - "web3-providers-ws": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", - "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", - "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-net": "1.7.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - } - } - }, - "@truffle/contract-schema": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.9.tgz", - "integrity": "sha512-nhYMXWbUs6dMYHL1f8DTkRk/uo1sADK0yeSYXo/p/7nqnjlHzqrr75BBsKbB7OFIVT05des+GFNQJqBaRZVdxQ==", - "dev": true, - "requires": { - "ajv": "^6.10.0", - "debug": "^4.3.1" - } - }, - "@truffle/debug-utils": { - "version": "6.0.34", - "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.34.tgz", - "integrity": "sha512-GbGnC9ESJXYHjzQKOV6yeFzvXDnW1yIvpfHXyc4PMDnnFoqX2OxP8mGmMzFKW2Uhqg89wl4GMPLuxycMkodWrw==", - "dev": true, - "requires": { - "@truffle/codec": "^0.14.4", - "@trufflesuite/chromafi": "^3.0.0", - "bn.js": "^5.1.3", - "chalk": "^2.4.2", - "debug": "^4.3.1", - "highlightjs-solidity": "^2.0.5" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@truffle/error": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.1.tgz", - "integrity": "sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==", - "dev": true - }, - "@truffle/interface-adapter": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.21.tgz", - "integrity": "sha512-2ltbu3upsWS0TAQu1kLQc048XlXNmDkCzH6iebX4dg3VBB+l7oG/pu5+/kl8t+LRfzGoEMLKwOQt7vk0Vm3PNA==", - "dev": true, - "requires": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.7.4" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "web3": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", - "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", - "dev": true, - "requires": { - "web3-bzz": "1.7.4", - "web3-core": "1.7.4", - "web3-eth": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-shh": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-bzz": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", - "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - } - }, - "web3-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", - "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-requestmanager": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-core-helpers": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", - "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", - "dev": true, - "requires": { - "web3-eth-iban": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-core-method": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", - "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", - "dev": true, - "requires": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-core-promievent": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", - "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", - "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.4", - "web3-providers-http": "1.7.4", - "web3-providers-ipc": "1.7.4", - "web3-providers-ws": "1.7.4" - } - }, - "web3-core-subscriptions": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", - "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4" - } - }, - "web3-eth": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", - "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-accounts": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-eth-ens": "1.7.4", - "web3-eth-iban": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-abi": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", - "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.4" - } - }, - "web3-eth-accounts": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", - "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-contract": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", - "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-ens": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", - "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-iban": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", - "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.4" - } - }, - "web3-eth-personal": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", - "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-net": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", - "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-providers-http": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", - "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", - "dev": true, - "requires": { - "web3-core-helpers": "1.7.4", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", - "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.4" - } - }, - "web3-providers-ws": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", - "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", - "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-net": "1.7.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "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" - } - } - } - }, - "@trufflesuite/chromafi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz", - "integrity": "sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "chalk": "^2.3.2", - "cheerio": "^1.0.0-rc.2", - "detect-indent": "^5.0.0", - "highlight.js": "^10.4.1", - "lodash.merge": "^4.6.2", - "strip-ansi": "^4.0.0", - "strip-indent": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@types/async-eventemitter": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz", - "integrity": "sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==", - "dev": true - }, - "@types/bignumber.js": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz", - "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==", - "dev": true, - "requires": { - "bignumber.js": "*" - } - }, - "@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "@types/chai": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", - "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", - "dev": true - }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true - }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "@types/node": { - "version": "18.7.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.17.tgz", - "integrity": "sha512-0UyfUnt02zIuqp7yC8RYtDkp/vo8bFaQ13KkSEvUAohPOAlnVNbj5Fi3fgPSuwzakS+EvvnnZ4x9y7i6ASaSPQ==", - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "abortcontroller-polyfill": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz", - "integrity": "sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==", - "dev": true - }, - "abstract-level": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", - "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "catering": "^2.1.0", - "is-buffer": "^2.0.5", - "level-supports": "^4.0.0", - "level-transcoder": "^1.0.1", - "module-error": "^1.0.1", - "queue-microtask": "^1.2.3" - }, - "dependencies": { - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } - } - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "address": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", - "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", - "dev": true - }, - "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true - }, - "aes-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, - "optional": true - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "antlr4": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", - "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", - "dev": true - }, - "antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true - }, - "array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.reduce": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", - "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - } - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "ast-parents": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", - "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "dev": true, - "requires": { - "async": "^2.4.0" - } - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - } - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "big-integer": { - "version": "1.6.36", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", - "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", - "dev": true - }, - "big.js": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz", - "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==", - "dev": true - }, - "bigint-crypto-utils": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.6.tgz", - "integrity": "sha512-k5ljSLHx94jQTW3+18KEfxLJR8/XFBHqhfhEGF48qT8p/jL6EdiG7oNOiiIRGMFh2wEP8kaCXZbVd+5dYkngUg==", - "dev": true, - "requires": { - "bigint-mod-arith": "^3.1.0" - } - }, - "bigint-mod-arith": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.1.tgz", - "integrity": "sha512-SzFqdncZKXq5uh3oLFZXmzaZEMDsA7ml9l53xKaVGO6/+y26xNwAaTQEg2R+D+d07YduLbKi0dni3YPsR51UDQ==", - "dev": true - }, - "bignumber.js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "browser-level": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", - "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", - "dev": true, - "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.1", - "module-error": "^1.0.2", - "run-parallel-limit": "^1.1.0" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-reverse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", - "integrity": "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==", - "dev": true - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "dev": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, - "cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", - "dev": true - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true - } - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "catering": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", - "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", - "dev": true - }, - "cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - }, - "dependencies": { - "bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true - } - } - }, - "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chai-bn": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/chai-bn/-/chai-bn-0.2.2.tgz", - "integrity": "sha512-MzjelH0p8vWn65QKmEq/DLBG1Hle4WeyqT79ANhXZhn/UxRWO0OogkAxi5oGGtfzwU9bZR8mvbvYdoqNVWQwFg==", - "dev": true, - "requires": {} - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "change-case": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.0.2.tgz", - "integrity": "sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==", - "dev": true, - "requires": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true - }, - "cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dev": true, - "requires": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - } - }, - "cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "dev": true, - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true - }, - "classic-level": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz", - "integrity": "sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==", - "dev": true, - "requires": { - "abstract-level": "^1.0.2", - "catering": "^2.1.0", - "module-error": "^1.0.1", - "napi-macros": "~2.0.0", - "node-gyp-build": "^4.3.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, - "commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "constant-case": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", - "integrity": "sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==", - "dev": true, - "requires": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" - } - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "dependencies": { - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true - } - } - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dev": true, - "requires": { - "node-fetch": "2.6.7" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true - }, - "crypto-addr-codec": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz", - "integrity": "sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "big-integer": "1.6.36", - "blakejs": "^1.1.0", - "bs58": "^4.0.1", - "ripemd160-min": "0.0.6", - "safe-buffer": "^5.2.0", - "sha3": "^2.1.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", - "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==", - "dev": true - }, - "css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", - "dev": true - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - } - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true - }, - "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true - }, - "detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", - "dev": true, - "requires": { - "heap": ">= 0.2.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - } - }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true - }, - "domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "requires": { - "domelementtype": "^2.3.0" - } - }, - "domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", - "dev": true, - "requires": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" - } - }, - "dot-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", - "integrity": "sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "emoji-regex": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", - "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true - } - } - }, - "entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", - "dev": true - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "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", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "requires": {} - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", - "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "eslint-plugin-mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz", - "integrity": "sha512-xLqqWUF17llsogVOC+8C6/jvQ+4IoOREbN7ZCHuOHuD6cT5cDD4h7f2LgsZuzMAiwswWE21tO7ExaknHVDrSkw==", - "dev": true, - "requires": { - "eslint-utils": "^3.0.0", - "rambda": "^7.1.0" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true - }, - "eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", - "dev": true, - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - }, - "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - } - } - }, - "eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", - "dev": true, - "requires": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } - }, - "eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "eth-sig-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-3.0.1.tgz", - "integrity": "sha512-0Us50HiGGvZgjtWTyAI/+qTzYPMLy5Q451D0Xy68bxq1QMWdoOddDwGvsqcFT27uohKgalM9z/yxplyt+mY2iQ==", - "dev": true, - "requires": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", - "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dev": true, - "requires": { - "js-sha3": "^0.8.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereum-ens": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/ethereum-ens/-/ethereum-ens-0.8.0.tgz", - "integrity": "sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==", - "dev": true, - "requires": { - "bluebird": "^3.4.7", - "eth-ens-namehash": "^2.0.0", - "js-sha3": "^0.5.7", - "pako": "^1.0.4", - "underscore": "^1.8.3", - "web3": "^1.0.0-beta.34" - }, - "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - } - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "ethereumjs-wallet": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-1.0.2.tgz", - "integrity": "sha512-CCWV4RESJgRdHIvFciVQFnCHfqyhXWchTPlkfp28Qc53ufs+doi5I/cV2+xeK9+qEo25XCWfP9MiL+WEPAZfdA==", - "dev": true, - "requires": { - "aes-js": "^3.1.2", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^7.1.2", - "randombytes": "^2.1.0", - "scrypt-js": "^3.0.1", - "utf8": "^3.0.0", - "uuid": "^8.3.2" - } - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - }, - "dependencies": { - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "dev": true - } - } - }, - "ethjs-abi": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz", - "integrity": "sha512-g2AULSDYI6nEJyJaEVEXtTimRY2aPC2fi7ddSy0W+LXvEVL8Fe1y76o43ecbgdUKwZD+xsmEgX1yJr1Ia3r1IA==", - "dev": true, - "requires": { - "bn.js": "4.11.6", - "js-sha3": "0.5.5", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - }, - "js-sha3": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", - "integrity": "sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA==", - "dev": true - } - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dev": true, - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", - "dev": true, - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "requires": { - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true - }, - "fast-check": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.1.1.tgz", - "integrity": "sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA==", - "dev": true, - "requires": { - "pure-rand": "^5.0.1" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - } - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "form-data-encoder": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", - "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", - "dev": true - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - } - } - }, - "got": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", - "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.6.0", - "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "form-data-encoder": "1.7.1", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "hardhat": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.11.1.tgz", - "integrity": "sha512-7FoyfKjBs97GHNpQejHecJBBcRPOEhAE3VkjSWXB3GeeiXefWbw+zhRVOjI4eCsUUt7PyNFAdWje/lhnBT9fig==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/ethereumjs-block": "^4.0.0-rc.3", - "@nomicfoundation/ethereumjs-blockchain": "^6.0.0-rc.3", - "@nomicfoundation/ethereumjs-common": "^3.0.0-rc.3", - "@nomicfoundation/ethereumjs-evm": "^1.0.0-rc.3", - "@nomicfoundation/ethereumjs-rlp": "^4.0.0-rc.3", - "@nomicfoundation/ethereumjs-statemanager": "^1.0.0-rc.3", - "@nomicfoundation/ethereumjs-trie": "^5.0.0-rc.3", - "@nomicfoundation/ethereumjs-tx": "^4.0.0-rc.3", - "@nomicfoundation/ethereumjs-util": "^8.0.0-rc.3", - "@nomicfoundation/ethereumjs-vm": "^6.0.0-rc.3", - "@nomicfoundation/solidity-analyzer": "^0.0.3", - "@sentry/node": "^5.18.1", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^1.0.3", - "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "keccak": "^3.0.2", - "lodash": "^4.17.11", - "mnemonist": "^0.38.0", - "mocha": "^10.0.0", - "p-map": "^4.0.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "tsort": "0.0.1", - "undici": "^5.4.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "ethereum-cryptography": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", - "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", - "dev": true, - "requires": { - "@noble/hashes": "1.1.2", - "@noble/secp256k1": "1.6.3", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "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==", - "dev": true - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", - "dev": true, - "requires": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.25", - "sha1": "^1.1.1" - } - }, - "hardhat-ignore-warnings": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/hardhat-ignore-warnings/-/hardhat-ignore-warnings-0.2.0.tgz", - "integrity": "sha512-fetYwdpjAg6pl7oxOAL0yZQTKt/87KgDV5P7sEoIORXaoqCBvRGcGAQLJZ8hCiWNZ+vZKYw/9oVVZVlFcOxZTw==", - "dev": true, - "requires": { - "minimatch": "^5.1.0", - "node-interval-tree": "^2.0.1", - "solidity-comments": "^0.0.2" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "header-case": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", - "integrity": "sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" - } - }, - "heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true - }, - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "dev": true - }, - "highlightjs-solidity": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.5.tgz", - "integrity": "sha512-ReXxQSGQkODMUgHcWzVSnfDCDrL2HshOYgw3OlIYmfHeRzUPkfJTUIp95pK4CmbiNG2eMTOmNLpfCz9Zq7Cwmg==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", - "dev": true, - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" - } - }, - "http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "requires": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "dependencies": { - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", - "dev": true - }, - "http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "requires": { - "@types/node": "^10.0.3" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "http2-wrapper": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", - "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "dev": true, - "requires": { - "punycode": "2.1.0" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "immutable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", - "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true - }, - "io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "requires": { - "fp-ts": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - }, - "is-callable": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.5.tgz", - "integrity": "sha512-ZIWRujF6MvYGkEuHMYtFRkL2wAtFw89EHfKlXrkPkjQZZRWeh9L1q3SV13NIfHnqxugjLvAOkEHx9mb1zcMnEw==", - "dev": true - }, - "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true - }, - "is-lower-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", - "integrity": "sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==", - "dev": true, - "requires": { - "lower-case": "^1.1.0" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-port-reachable": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-3.1.0.tgz", - "integrity": "sha512-vjc0SSRNZ32s9SbZBzGaiP6YVB+xglLShhgZD/FHMZUXBvQWaV9CtzgeVhjccFJrI6RAMV+LX7NYxueW/A8W5A==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "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==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-upper-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", - "integrity": "sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==", - "dev": true, - "requires": { - "upper-case": "^1.1.0" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - } - }, - "keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "dev": true, - "requires": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } - } - }, - "keyv": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", - "integrity": "sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "level": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", - "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", - "dev": true, - "requires": { - "browser-level": "^1.0.1", - "classic-level": "^1.2.0" - } - }, - "level-supports": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", - "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", - "dev": true - }, - "level-transcoder": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", - "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "module-error": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "lodash.zip": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", - "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", - "dev": true, - "requires": { - "get-func-name": "^2.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", - "dev": true - }, - "lower-case-first": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", - "integrity": "sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==", - "dev": true, - "requires": { - "lower-case": "^1.1.2" - } - }, - "lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "dev": true - }, - "lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true - }, - "memory-level": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz", - "integrity": "sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==", - "dev": true, - "requires": { - "abstract-level": "^1.0.0", - "functional-red-black-tree": "^1.0.1", - "module-error": "^1.0.1" - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "merkletreejs": { - "version": "0.2.32", - "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.2.32.tgz", - "integrity": "sha512-TostQBiwYRIwSE5++jGmacu3ODcKAgqb0Y/pnIohXS7sWxh1gCkSptbmF1a43faehRDpcHf7J/kv0Ml2D/zblQ==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.1", - "buffer-reverse": "^1.0.1", - "crypto-js": "^3.1.9-1", - "treeify": "^1.1.0", - "web3-utils": "^1.3.4" - }, - "dependencies": { - "bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", - "dev": true, - "requires": { - "mkdirp": "*" - } - }, - "mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "requires": { - "obliterator": "^2.0.0" - } - }, - "mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", - "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", - "dev": true - }, - "module-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", - "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "dev": true, - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true - }, - "nano-base32": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nano-base32/-/nano-base32-1.0.1.tgz", - "integrity": "sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==", - "dev": true - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", - "dev": true - }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true - }, - "napi-macros": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", - "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", - "dev": true - }, - "node-interval-tree": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-interval-tree/-/node-interval-tree-2.0.1.tgz", - "integrity": "sha512-KodzC8le4U8LOmCvn1wSyIY8eplzRSjsLMzs0EjLteCXWDjRpCTzrjtQ4t8jh3w3r6OIglha1zChzjRYMVwuLA==", - "dev": true, - "requires": { - "shallowequal": "^1.1.0" - } - }, - "nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "dev": true - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", - "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", - "dev": true, - "requires": { - "array.prototype.reduce": "^1.0.4", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", - "dev": true, - "requires": { - "http-https": "^1.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true - }, - "parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse5": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz", - "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==", - "dev": true, - "requires": { - "entities": "^4.4.0" - } - }, - "parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dev": true, - "requires": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascal-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", - "integrity": "sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==", - "dev": true, - "requires": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" - } - }, - "path-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", - "integrity": "sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "dev": true - }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true - }, - "prettier-plugin-solidity": { - "version": "1.0.0-beta.24", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.24.tgz", - "integrity": "sha512-6JlV5BBTWzmDSq4kZ9PTXc3eLOX7DF5HpbqmmaF+kloyUwOZbJ12hIYsUaZh2fVgZdV2t0vWcvY6qhILhlzgqg==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.14.3", - "emoji-regex": "^10.1.0", - "escape-string-regexp": "^4.0.0", - "semver": "^7.3.7", - "solidity-comments-extractor": "^0.0.7", - "string-width": "^4.2.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - } - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.2.0.tgz", - "integrity": "sha512-+CMAlLHqwRYwBMXKCP+o8ns7DN+xHDUiI+0nArsiJ9y+kJVPLFxEaSw6Ha9s9H0tftxg2Yzl25wqj9G7m5wLZg==", - "dev": true, - "requires": { - "asap": "~2.0.6" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", - "dev": true - }, - "pure-rand": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.3.tgz", - "integrity": "sha512-9N8x1h8dptBQpHyC7aZMS+iNOAm97WMGY0AFrguU1cpfW3I5jINkWe5BIY5md0ofy+1TCIELsVcm/GJXZSaPbw==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true - }, - "rambda": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.2.1.tgz", - "integrity": "sha512-Wswj8ZvzdI3VhaGPkZAxaCTwuMmGtgWt7Zxsgyo4P+iTmVnkojvyWaOep5q3ZjMIecW0wtQa66GWxaKkZ24RAA==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "dev": true, - "requires": { - "minimatch": "3.0.4" - }, - "dependencies": { - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "requires": { - "req-from": "^2.0.0" - } - }, - "req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true - } - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - }, - "dependencies": { - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "ripemd160-min": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/ripemd160-min/-/ripemd160-min-0.0.6.tgz", - "integrity": "sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==", - "dev": true - }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "requires": { - "bn.js": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "sentence-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", - "integrity": "sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dev": true, - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "requires": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - } - }, - "sha3": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-2.1.4.tgz", - "integrity": "sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==", - "dev": true, - "requires": { - "buffer": "6.0.3" - }, - "dependencies": { - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } - } - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true - }, - "simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "dev": true, - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - }, - "dependencies": { - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - } - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - } - } - }, - "snake-case": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", - "integrity": "sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", - "dev": true, - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - } - } - }, - "solhint": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.7.tgz", - "integrity": "sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.14.1", - "ajv": "^6.6.1", - "antlr4": "4.7.1", - "ast-parents": "0.0.1", - "chalk": "^2.4.2", - "commander": "2.18.0", - "cosmiconfig": "^5.0.7", - "eslint": "^5.6.0", - "fast-diff": "^1.1.2", - "glob": "^7.1.3", - "ignore": "^4.0.6", - "js-yaml": "^3.12.0", - "lodash": "^4.17.11", - "prettier": "^1.14.3", - "semver": "^6.3.0" - }, - "dependencies": { - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true, - "optional": true - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "solidity-ast": { - "version": "0.4.35", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", - "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==", - "dev": true - }, - "solidity-comments": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments/-/solidity-comments-0.0.2.tgz", - "integrity": "sha512-G+aK6qtyUfkn1guS8uzqUeua1dURwPlcOjoTYW/TwmXAcE7z/1+oGCfZUdMSe4ZMKklNbVZNiG5ibnF8gkkFfw==", - "dev": true, - "requires": { - "solidity-comments-darwin-arm64": "0.0.2", - "solidity-comments-darwin-x64": "0.0.2", - "solidity-comments-freebsd-x64": "0.0.2", - "solidity-comments-linux-arm64-gnu": "0.0.2", - "solidity-comments-linux-arm64-musl": "0.0.2", - "solidity-comments-linux-x64-gnu": "0.0.2", - "solidity-comments-linux-x64-musl": "0.0.2", - "solidity-comments-win32-arm64-msvc": "0.0.2", - "solidity-comments-win32-ia32-msvc": "0.0.2", - "solidity-comments-win32-x64-msvc": "0.0.2" - } - }, - "solidity-comments-darwin-arm64": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-darwin-arm64/-/solidity-comments-darwin-arm64-0.0.2.tgz", - "integrity": "sha512-HidWkVLSh7v+Vu0CA7oI21GWP/ZY7ro8g8OmIxE8oTqyMwgMbE8F1yc58Sj682Hj199HCZsjmtn1BE4PCbLiGA==", - "dev": true, - "optional": true - }, - "solidity-comments-darwin-x64": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-darwin-x64/-/solidity-comments-darwin-x64-0.0.2.tgz", - "integrity": "sha512-Zjs0Ruz6faBTPT6fBecUt6qh4CdloT8Bwoc0+qxRoTn9UhYscmbPQkUgQEbS0FQPysYqVzzxJB4h1Ofbf4wwtA==", - "dev": true, - "optional": true - }, - "solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "solidity-comments-freebsd-x64": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-freebsd-x64/-/solidity-comments-freebsd-x64-0.0.2.tgz", - "integrity": "sha512-8Qe4mpjuAxFSwZJVk7B8gAoLCdbtS412bQzBwk63L8dmlHogvE39iT70aAk3RHUddAppT5RMBunlPUCFYJ3ZTw==", - "dev": true, - "optional": true - }, - "solidity-comments-linux-arm64-gnu": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-arm64-gnu/-/solidity-comments-linux-arm64-gnu-0.0.2.tgz", - "integrity": "sha512-spkb0MZZnmrP+Wtq4UxP+nyPAVRe82idOjqndolcNR0S9Xvu4ebwq+LvF4HiUgjTDmeiqYiFZQ8T9KGdLSIoIg==", - "dev": true, - "optional": true - }, - "solidity-comments-linux-arm64-musl": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-arm64-musl/-/solidity-comments-linux-arm64-musl-0.0.2.tgz", - "integrity": "sha512-guCDbHArcjE+JDXYkxx5RZzY1YF6OnAKCo+sTC5fstyW/KGKaQJNPyBNWuwYsQiaEHpvhW1ha537IvlGek8GqA==", - "dev": true, - "optional": true - }, - "solidity-comments-linux-x64-gnu": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-x64-gnu/-/solidity-comments-linux-x64-gnu-0.0.2.tgz", - "integrity": "sha512-zIqLehBK/g7tvrFmQljrfZXfkEeLt2v6wbe+uFu6kH/qAHZa7ybt8Vc0wYcmjo2U0PeBm15d79ee3AkwbIjFdQ==", - "dev": true, - "optional": true - }, - "solidity-comments-linux-x64-musl": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-x64-musl/-/solidity-comments-linux-x64-musl-0.0.2.tgz", - "integrity": "sha512-R9FeDloVlFGTaVkOlELDVC7+1Tjx5WBPI5L8r0AGOPHK3+jOcRh6sKYpI+VskSPDc3vOO46INkpDgUXrKydlIw==", - "dev": true, - "optional": true - }, - "solidity-comments-win32-arm64-msvc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-win32-arm64-msvc/-/solidity-comments-win32-arm64-msvc-0.0.2.tgz", - "integrity": "sha512-QnWJoCQcJj+rnutULOihN9bixOtYWDdF5Rfz9fpHejL1BtNjdLW1om55XNVHGAHPqBxV4aeQQ6OirKnp9zKsug==", - "dev": true, - "optional": true - }, - "solidity-comments-win32-ia32-msvc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-win32-ia32-msvc/-/solidity-comments-win32-ia32-msvc-0.0.2.tgz", - "integrity": "sha512-vUg4nADtm/NcOtlIymG23NWJUSuMsvX15nU7ynhGBsdKtt8xhdP3C/zA6vjDk8Jg+FXGQL6IHVQ++g/7rSQi0w==", - "dev": true, - "optional": true - }, - "solidity-comments-win32-x64-msvc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-win32-x64-msvc/-/solidity-comments-win32-x64-msvc-0.0.2.tgz", - "integrity": "sha512-36j+KUF4V/y0t3qatHm/LF5sCUCBx2UndxE1kq5bOzh/s+nQgatuyB+Pd5BfuPQHdWu2KaExYe20FlAa6NL7+Q==", - "dev": true, - "optional": true - }, - "solidity-coverage": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", - "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.14.1", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "difflib": "^0.2.4", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "mocha": "7.1.2", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.6" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", - "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } - }, - "solidity-docgen": { - "version": "0.6.0-beta.29", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.6.0-beta.29.tgz", - "integrity": "sha512-63p3w6wj1WFhhC8pXTI3bz5qUTFuGmLNHFnwwpjZ6Qv8dF2WGDt0pg1rbA6c3bL/A4d0ATN66Mte1saGKVWdHg==", - "dev": true, - "requires": { - "handlebars": "^4.7.7", - "solidity-ast": "^0.4.31" - } - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - } - } - }, - "stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dev": true, - "requires": { - "type-fest": "^0.7.1" - }, - "dependencies": { - "type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true - } - } - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "swap-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", - "integrity": "sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" - } - }, - "swarm-js": { - "version": "0.1.42", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", - "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^11.8.5", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, - "dependencies": { - "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "got": { - "version": "11.8.5", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", - "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, - "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true - } - } - }, - "sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "requires": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - } - }, - "sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "requires": { - "get-port": "^3.1.0" - } - }, - "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - } - }, - "testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "dev": true - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - } - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true - }, - "title-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", - "integrity": "sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", - "dev": true - }, - "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "uglify-js": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.0.tgz", - "integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==", - "dev": true, - "optional": true - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "underscore": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz", - "integrity": "sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==", - "dev": true - }, - "undici": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.10.0.tgz", - "integrity": "sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==", - "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", - "dev": true - }, - "upper-case-first": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", - "integrity": "sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==", - "dev": true, - "requires": { - "upper-case": "^1.1.1" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", - "dev": true - }, - "utf-8-validate": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", - "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "dev": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true - }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.5.tgz", - "integrity": "sha512-3jHZTWyXt975AOXgnZKayiSWDLpoSKk9fZtLk1hURQtt7AdSbXPT8AK9ooBCm0Dt3GYaOeNcHGaiHC3gtyqhLg==", - "dev": true, - "requires": { - "web3-bzz": "1.7.5", - "web3-core": "1.7.5", - "web3-eth": "1.7.5", - "web3-eth-personal": "1.7.5", - "web3-net": "1.7.5", - "web3-shh": "1.7.5", - "web3-utils": "1.7.5" - } - }, - "web3-bzz": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.5.tgz", - "integrity": "sha512-Z53sY0YK/losqjJncmL4vP0zZI9r6tiXg6o7R6e1JD2Iy7FH3serQvU+qXmPjqEBzsnhf8wTG+YcBPB3RHpr0Q==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "12.1.0", - "swarm-js": "^0.1.40" - }, - "dependencies": { - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - } - } - }, - "web3-core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.5.tgz", - "integrity": "sha512-UgOWXZr1fR/3cUQJKWbfMwRxj1/N7o6RSd/dHqdXBlOD+62EjNZItFmLRg5veq5kp9YfXzrNw9bnDkXfsL+nKQ==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-core-requestmanager": "1.7.5", - "web3-utils": "1.7.5" - }, - "dependencies": { - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "bignumber.js": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", - "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", - "dev": true - } - } - }, - "web3-core-helpers": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.5.tgz", - "integrity": "sha512-lDDjTks6Q6aNUO87RYrY2xub3UWTKr/RIWxpHJODEqkLxZS1dWdyliJ6aIx3031VQwsNT5HE7NvABe/t0p3iDQ==", - "dev": true, - "requires": { - "web3-eth-iban": "1.7.5", - "web3-utils": "1.7.5" - } - }, - "web3-core-method": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.5.tgz", - "integrity": "sha512-ApTvq1Llzlbxmy0n4L7QaE6NodIsR80VJqk8qN4kLg30SGznt/pNJFebryLI2kpyDmxSgj1TjEWzmHJBp6FhYg==", - "dev": true, - "requires": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.5", - "web3-core-promievent": "1.7.5", - "web3-core-subscriptions": "1.7.5", - "web3-utils": "1.7.5" - } - }, - "web3-core-promievent": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.5.tgz", - "integrity": "sha512-uZ1VRErVuhiLtHlyt3oEH/JSvAf6bWPndChHR9PG7i1Zfqm6ZVCeM91ICTPmiL8ddsGQOxASpnJk4vhApcTIww==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.5.tgz", - "integrity": "sha512-3KpfxW/wVH4mgwWEsSJGHKrtRVoijWlDxtUrm17xgtqRNZ2mFolifKnHAUKa0fY48C9CrxmcCiMIi3W4G6WYRw==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.5", - "web3-providers-http": "1.7.5", - "web3-providers-ipc": "1.7.5", - "web3-providers-ws": "1.7.5" - } - }, - "web3-core-subscriptions": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.5.tgz", - "integrity": "sha512-YK6utQ7Wwjbe4XZOIA8quWGBPi1lFDS1A+jQYwxKKrCvm6BloBNc3FhvrcSYlDhLe/kOy8+2Je8i9amndgT4ww==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.5" - } - }, - "web3-eth": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.5.tgz", - "integrity": "sha512-BucjvqZyDWYkGlsFX+OnOBub0YutlC1KZiNGibdmvtNX0NQK+8iw1uzAoL9yTTwCSszL7lnkFe8N+HCOl9B4Dw==", - "dev": true, - "requires": { - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-core-subscriptions": "1.7.5", - "web3-eth-abi": "1.7.5", - "web3-eth-accounts": "1.7.5", - "web3-eth-contract": "1.7.5", - "web3-eth-ens": "1.7.5", - "web3-eth-iban": "1.7.5", - "web3-eth-personal": "1.7.5", - "web3-net": "1.7.5", - "web3-utils": "1.7.5" - } - }, - "web3-eth-abi": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.5.tgz", - "integrity": "sha512-qWHvF7sayxql9BD1yqK9sZRLBQ66eJzGeaU53Y1PRq2iFPrhY6NUWxQ3c3ps0rg+dyObvRbloviWpKXcS4RE/A==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.5" - } - }, - "web3-eth-accounts": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.5.tgz", - "integrity": "sha512-AzMLoTj3RGwKpyp3x3TtHrEeU4VpR99iMOD6NKrWSDumS6QEi0lCo+y7QZhdTlINw3iIA3SFIdvbAOO4NCHSDg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-utils": "1.7.5" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - } - } - }, - "web3-eth-contract": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.5.tgz", - "integrity": "sha512-qab7NPJRKRlTs58ozsqK8YIEwWpxIm3vD/okSIKBGkFx5gIHWW+vGmMh5PDSfefLJM9rCd+T+Lc0LYvtME7uqg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-core-promievent": "1.7.5", - "web3-core-subscriptions": "1.7.5", - "web3-eth-abi": "1.7.5", - "web3-utils": "1.7.5" - } - }, - "web3-eth-ens": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.5.tgz", - "integrity": "sha512-k1Q0msdRv/wac2egpZBIwG3n/sa/KdrVmVJvFm471gLTL4xfUizV5qJjkDVf+ikf9JyDvWJTs5eWNUUbOFIw/A==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-promievent": "1.7.5", - "web3-eth-abi": "1.7.5", - "web3-eth-contract": "1.7.5", - "web3-utils": "1.7.5" - } - }, - "web3-eth-iban": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.5.tgz", - "integrity": "sha512-mn2W5t/1IpL8OZvzAabLKT4kvwRnZSJ9K0tctndl9sDNWkfITYQibEEhUaNNA50Q5fJKgVudHI/m0gwIVTyG8Q==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.5" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "web3-eth-personal": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.5.tgz", - "integrity": "sha512-txh2P/eN8I4AOUKFi9++KKddoD0tWfCuu9Y1Kc41jSRbk6smO88Fum0KWNmYFYhSCX2qiknS1DfqsONl3igoKQ==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.7.5", - "web3-core-helpers": "1.7.5", - "web3-core-method": "1.7.5", - "web3-net": "1.7.5", - "web3-utils": "1.7.5" - }, - "dependencies": { - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - } - } - }, - "web3-net": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.5.tgz", - "integrity": "sha512-xwuCb2YWw49PmW81AJQ/G+Xi2ikRsYyZXSgyPt4LmZuKjiqg/6kSdK8lZvUi3Pi3wM+QDBXbpr73M/WEkW0KvA==", - "dev": true, - "requires": { - "web3-core": "1.7.5", - "web3-core-method": "1.7.5", - "web3-utils": "1.7.5" - } - }, - "web3-providers-http": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.5.tgz", - "integrity": "sha512-vPgr4Kzy0M3CHtoP/Bh7qwK/D9h2fhjpoqctdMWVJseOfeTgfOphCKN0uwV8w2VpZgDPXA8aeTdBx5OjmDdStA==", - "dev": true, - "requires": { - "abortcontroller-polyfill": "^1.7.3", - "cross-fetch": "^3.1.4", - "es6-promise": "^4.2.8", - "web3-core-helpers": "1.7.5" - } - }, - "web3-providers-ipc": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.5.tgz", - "integrity": "sha512-aNHx+RAROzO+apDEzy8Zncj78iqWBadIXtpmFDg7uiTn8i+oO+IcP1Yni7jyzkltsysVJHgHWG4kPx50ANCK3Q==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.5" - } - }, - "web3-providers-ws": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.5.tgz", - "integrity": "sha512-9uJNVVkIGC8PmM9kNbgPth56HDMSSsxZh3ZEENdwO3LNWemaADiQYUDCsD/dMVkn0xsGLHP5dgAy4Q5msqySLg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.5", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.5.tgz", - "integrity": "sha512-aCIWJyLMH5H76OybU4ZpUCJ93yNOPATGhJ+KboRPU8QZDzS2CcVhtEzyl27bbvw+rSnVroMLqBgTXBB4mmKI7A==", - "dev": true, - "requires": { - "web3-core": "1.7.5", - "web3-core-method": "1.7.5", - "web3-core-subscriptions": "1.7.5", - "web3-net": "1.7.5" - } - }, - "web3-utils": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.5.tgz", - "integrity": "sha512-9AqNOziQky4wNQadEwEfHiBdOZqopIHzQQVzmvvv6fJwDSMhP+khqmAZC7YTiGjs0MboyZ8tWNivqSO1699XQw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, - "which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "requires": {} - }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dev": true, - "requires": { - "xhr-request": "^1.1.0" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", - "dev": true, - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/package.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/package.json deleted file mode 100644 index eaf8639..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/package.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "private": true, - "name": "openzeppelin-solidity", - "description": "Secure Smart Contract library for Solidity", - "version": "4.8.3", - "files": [ - "/contracts/**/*.sol", - "/build/contracts/*.json", - "!/contracts/mocks/**/*" - ], - "bin": { - "openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js" - }, - "scripts": { - "compile": "hardhat compile", - "coverage": "env COVERAGE=true hardhat coverage", - "docs": "npm run prepare-docs && oz-docs", - "docs:watch": "oz-docs watch contracts 'docs/templates' docs/config.js", - "prepare-docs": "scripts/prepare-docs.sh", - "lint": "npm run lint:js && npm run lint:sol", - "lint:fix": "npm run lint:js:fix && npm run lint:sol:fix", - "lint:js": "eslint --ignore-path .gitignore .", - "lint:js:fix": "eslint --ignore-path .gitignore . --fix", - "lint:sol": "solhint 'contracts/**/*.sol' && prettier -c 'contracts/**/*.sol'", - "lint:sol:fix": "prettier --write \"contracts/**/*.sol\"", - "clean": "hardhat clean && rimraf build contracts/build", - "prepare": "scripts/prepare.sh", - "prepack": "scripts/prepack.sh", - "generate": "scripts/generate/run.js", - "release": "scripts/release/release.sh", - "version": "scripts/release/version.sh", - "test": "hardhat test", - "test:inheritance": "scripts/checks/inheritance-ordering.js artifacts/build-info/*", - "test:generation": "scripts/checks/generation.sh", - "gas-report": "env ENABLE_GAS_REPORT=true npm run test", - "slither": "npm run clean && slither . --detect reentrancy-eth,reentrancy-no-eth,reentrancy-unlimited-gas" - }, - "repository": { - "type": "git", - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git" - }, - "keywords": [ - "solidity", - "ethereum", - "smart", - "contracts", - "security", - "zeppelin" - ], - "author": "OpenZeppelin Community ", - "license": "MIT", - "bugs": { - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues" - }, - "homepage": "https://openzeppelin.com/contracts/", - "devDependencies": { - "@nomicfoundation/hardhat-network-helpers": "^1.0.3", - "@nomiclabs/hardhat-truffle5": "^2.0.5", - "@nomiclabs/hardhat-web3": "^2.0.0", - "@openzeppelin/docs-utils": "^0.1.3", - "@openzeppelin/test-helpers": "^0.5.13", - "chai": "^4.2.0", - "eslint": "^7.32.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-mocha": "^10.0.3", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.2.0", - "eth-sig-util": "^3.0.0", - "ethereumjs-util": "^7.0.7", - "ethereumjs-wallet": "^1.0.1", - "glob": "^8.0.3", - "graphlib": "^2.1.8", - "hardhat": "^2.9.1", - "hardhat-gas-reporter": "^1.0.4", - "hardhat-ignore-warnings": "^0.2.0", - "keccak256": "^1.0.2", - "lodash.startcase": "^4.4.0", - "lodash.zip": "^4.2.0", - "merkletreejs": "^0.2.13", - "micromatch": "^4.0.2", - "prettier": "^2.3.0", - "prettier-plugin-solidity": "^1.0.0-beta.16", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "solhint": "^3.3.6", - "solidity-ast": "^0.4.25", - "solidity-coverage": "^0.8.0", - "solidity-docgen": "^0.6.0-beta.29", - "web3": "^1.3.0", - "yargs": "^17.0.0" - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/renovate.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/renovate.json deleted file mode 100644 index 0ec3e85..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/renovate.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": [ - "github>OpenZeppelin/code-style" - ], - "packageRules": [ - { - "extends": ["packages:eslint"], - "enabled": false - } - ] -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/compareGasReports.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/compareGasReports.js deleted file mode 100755 index 5e3a0e7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/compareGasReports.js +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const chalk = require('chalk'); -const { argv } = require('yargs') - .env() - .options({ - style: { - type: 'string', - choices: [ 'shell', 'markdown' ], - default: 'shell', - }, - }); - -// Deduce base tx cost from the percentage denominator -const BASE_TX_COST = 21000; - -// Utilities -function sum (...args) { - return args.reduce((a, b) => a + b, 0); -} - -function average (...args) { - return sum(...args) / args.length; -} - -function variation (current, previous, offset = 0) { - return { - value: current, - delta: current - previous, - prcnt: 100 * (current - previous) / (previous - offset), - }; -} - -// Report class -class Report { - // Read report file - static load (filepath) { - return JSON.parse(fs.readFileSync(filepath, 'utf8')); - } - - // Compare two reports - static compare (update, ref, opts = { hideEqual: true }) { - if (JSON.stringify(update.config.metadata) !== JSON.stringify(ref.config.metadata)) { - throw new Error('Reports produced with non matching metadata'); - } - - const deployments = update.info.deployments - .map(contract => Object.assign( - contract, - { previousVersion: ref.info.deployments.find(({ name }) => name === contract.name) }, - )) - .filter(contract => contract.gasData?.length && contract.previousVersion?.gasData?.length) - .flatMap(contract => [{ - contract: contract.name, - method: '[bytecode length]', - avg: variation(contract.bytecode.length / 2 - 1, contract.previousVersion.bytecode.length / 2 - 1), - }, { - contract: contract.name, - method: '[construction cost]', - avg: variation( - ...[contract.gasData, contract.previousVersion.gasData].map(x => Math.round(average(...x))), - BASE_TX_COST), - }]) - .sort((a, b) => `${a.contract}:${a.method}`.localeCompare(`${b.contract}:${b.method}`)); - - const methods = Object.keys(update.info.methods) - .filter(key => ref.info.methods[key]) - .filter(key => update.info.methods[key].numberOfCalls > 0) - .filter(key => update.info.methods[key].numberOfCalls === ref.info.methods[key].numberOfCalls) - .map(key => ({ - contract: ref.info.methods[key].contract, - method: ref.info.methods[key].fnSig, - min: variation(...[update, ref].map(x => Math.min(...x.info.methods[key].gasData)), BASE_TX_COST), - max: variation(...[update, ref].map(x => Math.max(...x.info.methods[key].gasData)), BASE_TX_COST), - avg: variation(...[update, ref].map(x => Math.round(average(...x.info.methods[key].gasData))), BASE_TX_COST), - })) - .sort((a, b) => `${a.contract}:${a.method}`.localeCompare(`${b.contract}:${b.method}`)); - - return [].concat(deployments, methods) - .filter(row => !opts.hideEqual || row.min?.delta || row.max?.delta || row.avg?.delta); - } -} - -// Display -function center (text, length) { - return text.padStart((text.length + length) / 2).padEnd(length); -} - -function plusSign (num) { - return num > 0 ? '+' : ''; -} - -function formatCellShell (cell) { - const format = chalk[cell?.delta > 0 ? 'red' : cell?.delta < 0 ? 'green' : 'reset']; - return [ - format((!isFinite(cell?.value) ? '-' : cell.value.toString()).padStart(8)), - format((!isFinite(cell?.delta) ? '-' : plusSign(cell.delta) + cell.delta.toString()).padStart(8)), - format((!isFinite(cell?.prcnt) ? '-' : plusSign(cell.prcnt) + cell.prcnt.toFixed(2) + '%').padStart(8)), - ]; -} - -function formatCmpShell (rows) { - const contractLength = Math.max(8, ...rows.map(({ contract }) => contract.length)); - const methodLength = Math.max(7, ...rows.map(({ method }) => method.length)); - - const COLS = [ - { txt: '', length: 0 }, - { txt: 'Contract', length: contractLength }, - { txt: 'Method', length: methodLength }, - { txt: 'Min', length: 30 }, - { txt: 'Max', length: 30 }, - { txt: 'Avg', length: 30 }, - { txt: '', length: 0 }, - ]; - const HEADER = COLS.map(entry => chalk.bold(center(entry.txt, entry.length || 0))).join(' | ').trim(); - const SEPARATOR = COLS.map(({ length }) => length > 0 ? '-'.repeat(length + 2) : '').join('|').trim(); - - return [ - '', - HEADER, - ...rows.map(entry => [ - '', - chalk.grey(entry.contract.padEnd(contractLength)), - entry.method.padEnd(methodLength), - ...formatCellShell(entry.min), - ...formatCellShell(entry.max), - ...formatCellShell(entry.avg), - '', - ].join(' | ').trim()), - '', - ].join(`\n${SEPARATOR}\n`).trim(); -} - -function alignPattern (align) { - switch (align) { - case 'left': - case undefined: - return ':-'; - case 'right': - return '-:'; - case 'center': - return ':-:'; - } -} - -function trend (value) { - return value > 0 - ? ':x:' - : value < 0 - ? ':heavy_check_mark:' - : ':heavy_minus_sign:'; -} - -function formatCellMarkdown (cell) { - return [ - (!isFinite(cell?.value) ? '-' : cell.value.toString()), - (!isFinite(cell?.delta) ? '-' : plusSign(cell.delta) + cell.delta.toString()), - (!isFinite(cell?.prcnt) ? '-' : plusSign(cell.prcnt) + cell.prcnt.toFixed(2) + '%' + trend(cell.delta)), - ]; -} - -function formatCmpMarkdown (rows) { - const COLS = [ - { txt: '' }, - { txt: 'Contract', align: 'left' }, - { txt: 'Method', align: 'left' }, - { txt: 'Min', align: 'right' }, - { txt: '(+/-)', align: 'right' }, - { txt: '%', align: 'right' }, - { txt: 'Max', align: 'right' }, - { txt: '(+/-)', align: 'right' }, - { txt: '%', align: 'right' }, - { txt: 'Avg', align: 'right' }, - { txt: '(+/-)', align: 'right' }, - { txt: '%', align: 'right' }, - { txt: '' }, - ]; - const HEADER = COLS.map(entry => entry.txt).join(' | ').trim(); - const SEPARATOR = COLS.map(entry => entry.txt ? alignPattern(entry.align) : '').join('|').trim(); - - return [ - '# Changes to gas costs', - '', - HEADER, - SEPARATOR, - rows.map(entry => [ - '', - entry.contract, - entry.method, - ...formatCellMarkdown(entry.min), - ...formatCellMarkdown(entry.max), - ...formatCellMarkdown(entry.avg), - '', - ].join(' | ').trim()).join('\n'), - '', - ].join('\n').trim(); -} - -// MAIN -const report = Report.compare(Report.load(argv._[0]), Report.load(argv._[1])); - -switch (argv.style) { -case 'markdown': - console.log(formatCmpMarkdown(report)); - break; -case 'shell': -default: - console.log(formatCmpShell(report)); - break; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/generation.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/generation.sh deleted file mode 100755 index 00d609f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/generation.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -npm run generate -git diff -R --exit-code diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/inheritance-ordering.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/inheritance-ordering.js deleted file mode 100755 index 3ade740..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/checks/inheritance-ordering.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node - -const path = require('path'); -const graphlib = require('graphlib'); -const { findAll } = require('solidity-ast/utils'); -const { _: artifacts } = require('yargs').argv; - -for (const artifact of artifacts) { - const { output: solcOutput } = require(path.resolve(__dirname, '../..', artifact)); - - const graph = new graphlib.Graph({ directed: true }); - const names = {}; - const linearized = []; - - for (const source in solcOutput.contracts) { - if (source.includes('/mocks/')) { - continue; - } - - for (const contractDef of findAll('ContractDefinition', solcOutput.sources[source].ast)) { - names[contractDef.id] = contractDef.name; - linearized.push(contractDef.linearizedBaseContracts); - - contractDef.linearizedBaseContracts.forEach((c1, i, contracts) => contracts.slice(i + 1).forEach(c2 => { - graph.setEdge(c1, c2); - })); - } - } - - /// graphlib.alg.findCycles will not find minimal cycles. - /// We are only interested int cycles of lengths 2 (needs proof) - graph.nodes().forEach((x, i, nodes) => nodes - .slice(i + 1) - .filter(y => graph.hasEdge(x, y) && graph.hasEdge(y, x)) - .forEach(y => { - console.log(`Conflict between ${names[x]} and ${names[y]} detected in the following dependency chains:`); - linearized - .filter(chain => chain.includes(parseInt(x)) && chain.includes(parseInt(y))) - .forEach(chain => { - const comp = chain.indexOf(parseInt(x)) < chain.indexOf(parseInt(y)) ? '>' : '<'; - console.log(`- ${names[x]} ${comp} ${names[y]} in ${names[chain.find(Boolean)]}`); - // console.log(`- ${names[x]} ${comp} ${names[y]}: ${chain.reverse().map(id => names[id]).join(', ')}`); - }); - process.exitCode = 1; - })); -} - -if (!process.exitCode) { - console.log('Contract ordering is consistent.'); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/gen-nav.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/gen-nav.js deleted file mode 100644 index b39d23e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/gen-nav.js +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env node - -const path = require('path'); -const glob = require('glob'); -const startCase = require('lodash.startcase'); - -const baseDir = process.argv[2]; - -const files = glob.sync(baseDir + '/**/*.adoc').map(f => path.relative(baseDir, f)); - -console.log('.API'); - -function getPageTitle (directory) { - switch (directory) { - case 'metatx': - return 'Meta Transactions'; - case 'common': - return 'Common (Tokens)'; - default: - return startCase(directory); - } -} - -const links = files.map((file) => { - const doc = file.replace(baseDir, ''); - const title = path.parse(file).name; - - return { - xref: `* xref:${doc}[${getPageTitle(title)}]`, - title, - }; -}); - -// Case-insensitive sort based on titles (so 'token/ERC20' gets sorted as 'erc20') -const sortedLinks = links.sort(function (a, b) { - return a.title.toLowerCase().localeCompare(b.title.toLowerCase(), undefined, { numeric: true }); -}); - -for (const link of sortedLinks) { - console.log(link.xref); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/format-lines.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/format-lines.js deleted file mode 100644 index e1f1823..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/format-lines.js +++ /dev/null @@ -1,16 +0,0 @@ -function formatLines (...lines) { - return [...indentEach(0, lines)].join('\n') + '\n'; -} - -function *indentEach (indent, lines) { - for (const line of lines) { - if (Array.isArray(line)) { - yield * indentEach(indent + 1, line); - } else { - const padding = ' '.repeat(indent); - yield * line.split('\n').map(subline => subline === '' ? '' : padding + subline); - } - } -} - -module.exports = formatLines; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/run.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/run.js deleted file mode 100755 index 60dd795..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/run.js +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env node - -const cp = require('child_process'); -const fs = require('fs'); -const path = require('path'); -const format = require('./format-lines'); - -function getVersion (path) { - try { - return fs - .readFileSync(path, 'utf8') - .match(/\/\/ OpenZeppelin Contracts \(last updated v[^)]+\)/)[0]; - } catch (err) { - return null; - } -} - -for (const [ file, template ] of Object.entries({ - // SafeCast - 'utils/math/SafeCast.sol': './templates/SafeCast.js', - 'mocks/SafeCastMock.sol': './templates/SafeCastMock.js', - // EnumerableSet - 'utils/structs/EnumerableSet.sol': './templates/EnumerableSet.js', - 'mocks/EnumerableSetMock.sol': './templates/EnumerableSetMock.js', - // EnumerableMap - 'utils/structs/EnumerableMap.sol': './templates/EnumerableMap.js', - 'mocks/EnumerableMapMock.sol': './templates/EnumerableMapMock.js', - // Checkpoints - 'utils/Checkpoints.sol': './templates/Checkpoints.js', - 'mocks/CheckpointsMock.sol': './templates/CheckpointsMock.js', -})) { - const script = path.relative(path.join(__dirname, '../..'), __filename); - const input = path.join(path.dirname(script), template); - const output = `./contracts/${file}`; - const version = getVersion(output); - const content = format( - '// SPDX-License-Identifier: MIT', - ...(version ? [ version + ` (${file})` ] : []), - `// This file was procedurally generated from ${input}.`, - '', - require(template), - ); - - fs.writeFileSync(output, content); - cp.execFileSync('prettier', ['--write', output]); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/Checkpoints.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/Checkpoints.js deleted file mode 100644 index 01d5c8d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/Checkpoints.js +++ /dev/null @@ -1,303 +0,0 @@ -const format = require('../format-lines'); - -const VALUE_SIZES = [ 224, 160 ]; - -const header = `\ -pragma solidity ^0.8.0; - -import "./math/Math.sol"; -import "./math/SafeCast.sol"; - -/** - * @dev This library defines the \`History\` struct, for checkpointing values as they change at different points in - * time, and later looking up past values by block number. See {Votes} as an example. - * - * To create a history of checkpoints define a variable type \`Checkpoints.History\` in your contract, and store a new - * checkpoint for the current transaction block using the {push} function. - * - * _Available since v4.5._ - */ -`; - -const types = opts => `\ -struct ${opts.historyTypeName} { - ${opts.checkpointTypeName}[] ${opts.checkpointFieldName}; -} - -struct ${opts.checkpointTypeName} { - ${opts.keyTypeName} ${opts.keyFieldName}; - ${opts.valueTypeName} ${opts.valueFieldName}; -} -`; - -/* eslint-disable max-len */ -const operations = opts => `\ -/** - * @dev Pushes a (\`key\`, \`value\`) pair into a ${opts.historyTypeName} so that it is stored as the checkpoint. - * - * Returns previous value and new value. - */ -function push( - ${opts.historyTypeName} storage self, - ${opts.keyTypeName} key, - ${opts.valueTypeName} value -) internal returns (${opts.valueTypeName}, ${opts.valueTypeName}) { - return _insert(self.${opts.checkpointFieldName}, key, value); -} - -/** - * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none. - */ -function lowerLookup(${opts.historyTypeName} storage self, ${opts.keyTypeName} key) internal view returns (${opts.valueTypeName}) { - uint256 len = self.${opts.checkpointFieldName}.length; - uint256 pos = _lowerBinaryLookup(self.${opts.checkpointFieldName}, key, 0, len); - return pos == len ? 0 : _unsafeAccess(self.${opts.checkpointFieldName}, pos).${opts.valueFieldName}; -} - -/** - * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key. - */ -function upperLookup(${opts.historyTypeName} storage self, ${opts.keyTypeName} key) internal view returns (${opts.valueTypeName}) { - uint256 len = self.${opts.checkpointFieldName}.length; - uint256 pos = _upperBinaryLookup(self.${opts.checkpointFieldName}, key, 0, len); - return pos == 0 ? 0 : _unsafeAccess(self.${opts.checkpointFieldName}, pos - 1).${opts.valueFieldName}; -} -`; - -const legacyOperations = opts => `\ -/** - * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one - * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the - * block, the requested block number must be in the past, excluding the current block. - */ -function getAtBlock(${opts.historyTypeName} storage self, uint256 blockNumber) internal view returns (uint256) { - require(blockNumber < block.number, "Checkpoints: block not yet mined"); - uint32 key = SafeCast.toUint32(blockNumber); - - uint256 len = self.${opts.checkpointFieldName}.length; - uint256 pos = _upperBinaryLookup(self.${opts.checkpointFieldName}, key, 0, len); - return pos == 0 ? 0 : _unsafeAccess(self.${opts.checkpointFieldName}, pos - 1).${opts.valueFieldName}; -} - -/** - * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one - * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched - * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of - * checkpoints. - */ -function getAtProbablyRecentBlock(${opts.historyTypeName} storage self, uint256 blockNumber) internal view returns (uint256) { - require(blockNumber < block.number, "Checkpoints: block not yet mined"); - uint32 key = SafeCast.toUint32(blockNumber); - - uint256 len = self.${opts.checkpointFieldName}.length; - - uint256 low = 0; - uint256 high = len; - - if (len > 5) { - uint256 mid = len - Math.sqrt(len); - if (key < _unsafeAccess(self.${opts.checkpointFieldName}, mid)._blockNumber) { - high = mid; - } else { - low = mid + 1; - } - } - - uint256 pos = _upperBinaryLookup(self.${opts.checkpointFieldName}, key, low, high); - - return pos == 0 ? 0 : _unsafeAccess(self.${opts.checkpointFieldName}, pos - 1).${opts.valueFieldName}; -} - -/** - * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block. - * - * Returns previous value and new value. - */ -function push(${opts.historyTypeName} storage self, uint256 value) internal returns (uint256, uint256) { - return _insert(self.${opts.checkpointFieldName}, SafeCast.toUint32(block.number), SafeCast.toUint224(value)); -} - -/** - * @dev Pushes a value onto a History, by updating the latest value using binary operation \`op\`. The new value will - * be set to \`op(latest, delta)\`. - * - * Returns previous value and new value. - */ -function push( - ${opts.historyTypeName} storage self, - function(uint256, uint256) view returns (uint256) op, - uint256 delta -) internal returns (uint256, uint256) { - return push(self, op(latest(self), delta)); -} -`; - -const common = opts => `\ -/** - * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. - */ -function latest(${opts.historyTypeName} storage self) internal view returns (${opts.valueTypeName}) { - uint256 pos = self.${opts.checkpointFieldName}.length; - return pos == 0 ? 0 : _unsafeAccess(self.${opts.checkpointFieldName}, pos - 1).${opts.valueFieldName}; -} - -/** - * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value - * in the most recent checkpoint. - */ -function latestCheckpoint(${opts.historyTypeName} storage self) - internal - view - returns ( - bool exists, - ${opts.keyTypeName} ${opts.keyFieldName}, - ${opts.valueTypeName} ${opts.valueFieldName} - ) -{ - uint256 pos = self.${opts.checkpointFieldName}.length; - if (pos == 0) { - return (false, 0, 0); - } else { - ${opts.checkpointTypeName} memory ckpt = _unsafeAccess(self.${opts.checkpointFieldName}, pos - 1); - return (true, ckpt.${opts.keyFieldName}, ckpt.${opts.valueFieldName}); - } -} - -/** - * @dev Returns the number of checkpoint. - */ -function length(${opts.historyTypeName} storage self) internal view returns (uint256) { - return self.${opts.checkpointFieldName}.length; -} - -/** - * @dev Pushes a (\`key\`, \`value\`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, - * or by updating the last one. - */ -function _insert( - ${opts.checkpointTypeName}[] storage self, - ${opts.keyTypeName} key, - ${opts.valueTypeName} value -) private returns (${opts.valueTypeName}, ${opts.valueTypeName}) { - uint256 pos = self.length; - - if (pos > 0) { - // Copying to memory is important here. - ${opts.checkpointTypeName} memory last = _unsafeAccess(self, pos - 1); - - // Checkpoints keys must be increasing. - require(last.${opts.keyFieldName} <= key, "Checkpoint: invalid key"); - - // Update or push new checkpoint - if (last.${opts.keyFieldName} == key) { - _unsafeAccess(self, pos - 1).${opts.valueFieldName} = value; - } else { - self.push(${opts.checkpointTypeName}({${opts.keyFieldName}: key, ${opts.valueFieldName}: value})); - } - return (last.${opts.valueFieldName}, value); - } else { - self.push(${opts.checkpointTypeName}({${opts.keyFieldName}: key, ${opts.valueFieldName}: value})); - return (0, value); - } -} - -/** - * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or \`high\` if there is none. - * \`low\` and \`high\` define a section where to do the search, with inclusive \`low\` and exclusive \`high\`. - * - * WARNING: \`high\` should not be greater than the array's length. - */ -function _upperBinaryLookup( - ${opts.checkpointTypeName}[] storage self, - ${opts.keyTypeName} key, - uint256 low, - uint256 high -) private view returns (uint256) { - while (low < high) { - uint256 mid = Math.average(low, high); - if (_unsafeAccess(self, mid).${opts.keyFieldName} > key) { - high = mid; - } else { - low = mid + 1; - } - } - return high; -} - -/** - * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or \`high\` if there is none. - * \`low\` and \`high\` define a section where to do the search, with inclusive \`low\` and exclusive \`high\`. - * - * WARNING: \`high\` should not be greater than the array's length. - */ -function _lowerBinaryLookup( - ${opts.checkpointTypeName}[] storage self, - ${opts.keyTypeName} key, - uint256 low, - uint256 high -) private view returns (uint256) { - while (low < high) { - uint256 mid = Math.average(low, high); - if (_unsafeAccess(self, mid).${opts.keyFieldName} < key) { - low = mid + 1; - } else { - high = mid; - } - } - return high; -} - -/** - * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. - */ -function _unsafeAccess(${opts.checkpointTypeName}[] storage self, uint256 pos) - private - pure - returns (${opts.checkpointTypeName} storage result) -{ - assembly { - mstore(0, self.slot) - result.slot := add(keccak256(0, 0x20), pos) - } -} -`; -/* eslint-enable max-len */ - -// OPTIONS -const defaultOpts = (size) => ({ - historyTypeName: `Trace${size}`, - checkpointTypeName: `Checkpoint${size}`, - checkpointFieldName: '_checkpoints', - keyTypeName: `uint${256 - size}`, - keyFieldName: '_key', - valueTypeName: `uint${size}`, - valueFieldName: '_value', -}); - -const OPTS = VALUE_SIZES.map(size => defaultOpts(size)); - -const LEGACY_OPTS = { - ...defaultOpts(224), - historyTypeName: 'History', - checkpointTypeName: 'Checkpoint', - keyFieldName: '_blockNumber', -}; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library Checkpoints {', - [ - // Legacy types & functions - types(LEGACY_OPTS), - legacyOperations(LEGACY_OPTS), - common(LEGACY_OPTS), - // New flavors - ...OPTS.flatMap(opts => [ - types(opts), - operations(opts), - common(opts), - ]), - ], - '}', -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/CheckpointsMock.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/CheckpointsMock.js deleted file mode 100755 index 145f084..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/CheckpointsMock.js +++ /dev/null @@ -1,80 +0,0 @@ -const format = require('../format-lines'); - -const VALUE_SIZES = [ 224, 160 ]; - -const header = `\ -pragma solidity ^0.8.0; - -import "../utils/Checkpoints.sol"; -`; - -const legacy = () => `\ -contract CheckpointsMock { - using Checkpoints for Checkpoints.History; - - Checkpoints.History private _totalCheckpoints; - - function latest() public view returns (uint256) { - return _totalCheckpoints.latest(); - } - - function latestCheckpoint() public view returns (bool, uint256, uint256) { - return _totalCheckpoints.latestCheckpoint(); - } - - function length() public view returns (uint256) { - return _totalCheckpoints.length(); - } - - function push(uint256 value) public returns (uint256, uint256) { - return _totalCheckpoints.push(value); - } - - function getAtBlock(uint256 blockNumber) public view returns (uint256) { - return _totalCheckpoints.getAtBlock(blockNumber); - } - - function getAtProbablyRecentBlock(uint256 blockNumber) public view returns (uint256) { - return _totalCheckpoints.getAtProbablyRecentBlock(blockNumber); - } -} -`; - -const checkpoint = length => `\ -contract Checkpoints${length}Mock { - using Checkpoints for Checkpoints.Trace${length}; - - Checkpoints.Trace${length} private _totalCheckpoints; - - function latest() public view returns (uint${length}) { - return _totalCheckpoints.latest(); - } - - function latestCheckpoint() public view returns (bool, uint${256 - length}, uint${length}) { - return _totalCheckpoints.latestCheckpoint(); - } - - function length() public view returns (uint256) { - return _totalCheckpoints.length(); - } - - function push(uint${256 - length} key, uint${length} value) public returns (uint${length}, uint${length}) { - return _totalCheckpoints.push(key, value); - } - - function lowerLookup(uint${256 - length} key) public view returns (uint${length}) { - return _totalCheckpoints.lowerLookup(key); - } - - function upperLookup(uint${256 - length} key) public view returns (uint${length}) { - return _totalCheckpoints.upperLookup(key); - } -} -`; - -// GENERATE -module.exports = format( - header, - legacy(), - ...VALUE_SIZES.map(checkpoint), -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableMap.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableMap.js deleted file mode 100644 index ca8e0e7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableMap.js +++ /dev/null @@ -1,278 +0,0 @@ -const format = require('../format-lines'); -const { fromBytes32, toBytes32 } = require('./conversion'); - -const TYPES = [ - { name: 'UintToUintMap', keyType: 'uint256', valueType: 'uint256' }, - { name: 'UintToAddressMap', keyType: 'uint256', valueType: 'address' }, - { name: 'AddressToUintMap', keyType: 'address', valueType: 'uint256' }, - { name: 'Bytes32ToUintMap', keyType: 'bytes32', valueType: 'uint256' }, -]; - -/* eslint-disable max-len */ -const header = `\ -pragma solidity ^0.8.0; - -import "./EnumerableSet.sol"; - -/** - * @dev Library for managing an enumerable variant of Solidity's - * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[\`mapping\`] - * type. - * - * Maps have the following properties: - * - * - Entries are added, removed, and checked for existence in constant time - * (O(1)). - * - Entries are enumerated in O(n). No guarantees are made on the ordering. - * - * \`\`\` - * contract Example { - * // Add the library methods - * using EnumerableMap for EnumerableMap.UintToAddressMap; - * - * // Declare a set state variable - * EnumerableMap.UintToAddressMap private myMap; - * } - * \`\`\` - * - * The following map types are supported: - * - * - \`uint256 -> address\` (\`UintToAddressMap\`) since v3.0.0 - * - \`address -> uint256\` (\`AddressToUintMap\`) since v4.6.0 - * - \`bytes32 -> bytes32\` (\`Bytes32ToBytes32Map\`) since v4.6.0 - * - \`uint256 -> uint256\` (\`UintToUintMap\`) since v4.7.0 - * - \`bytes32 -> uint256\` (\`Bytes32ToUintMap\`) since v4.7.0 - * - * [WARNING] - * ==== - * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure - * unusable. - * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. - * - * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an - * array of EnumerableMap. - * ==== - */ -`; -/* eslint-enable max-len */ - -const defaultMap = () => `\ -// To implement this library for multiple types with as little code -// repetition as possible, we write it in terms of a generic Map type with -// bytes32 keys and values. -// The Map implementation uses private functions, and user-facing -// implementations (such as Uint256ToAddressMap) are just wrappers around -// the underlying Map. -// This means that we can only create new EnumerableMaps for types that fit -// in bytes32. - -struct Bytes32ToBytes32Map { - // Storage of keys - EnumerableSet.Bytes32Set _keys; - mapping(bytes32 => bytes32) _values; -} - -/** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ -function set( - Bytes32ToBytes32Map storage map, - bytes32 key, - bytes32 value -) internal returns (bool) { - map._values[key] = value; - return map._keys.add(key); -} - -/** - * @dev Removes a key-value pair from a map. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ -function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return map._keys.remove(key); -} - -/** - * @dev Returns true if the key is in the map. O(1). - */ -function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { - return map._keys.contains(key); -} - -/** - * @dev Returns the number of key-value pairs in the map. O(1). - */ -function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { - return map._keys.length(); -} - -/** - * @dev Returns the key-value pair stored at position \`index\` in the map. O(1). - * - * Note that there are no guarantees on the ordering of entries inside the - * array, and it may change when more entries are added or removed. - * - * Requirements: - * - * - \`index\` must be strictly less than {length}. - */ -function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { - bytes32 key = map._keys.at(index); - return (key, map._values[key]); -} - -/** - * @dev Tries to returns the value associated with \`key\`. O(1). - * Does not revert if \`key\` is not in the map. - */ -function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { - bytes32 value = map._values[key]; - if (value == bytes32(0)) { - return (contains(map, key), bytes32(0)); - } else { - return (true, value); - } -} - -/** - * @dev Returns the value associated with \`key\`. O(1). - * - * Requirements: - * - * - \`key\` must be in the map. - */ -function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { - bytes32 value = map._values[key]; - require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key"); - return value; -} - -/** - * @dev Same as {get}, with a custom error message when \`key\` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ -function get( - Bytes32ToBytes32Map storage map, - bytes32 key, - string memory errorMessage -) internal view returns (bytes32) { - bytes32 value = map._values[key]; - require(value != 0 || contains(map, key), errorMessage); - return value; -} -`; - -const customMap = ({ name, keyType, valueType }) => `\ -// ${name} - -struct ${name} { - Bytes32ToBytes32Map _inner; -} - -/** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ -function set( - ${name} storage map, - ${keyType} key, - ${valueType} value -) internal returns (bool) { - return set(map._inner, ${toBytes32(keyType, 'key')}, ${toBytes32(valueType, 'value')}); -} - -/** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ -function remove(${name} storage map, ${keyType} key) internal returns (bool) { - return remove(map._inner, ${toBytes32(keyType, 'key')}); -} - -/** - * @dev Returns true if the key is in the map. O(1). - */ -function contains(${name} storage map, ${keyType} key) internal view returns (bool) { - return contains(map._inner, ${toBytes32(keyType, 'key')}); -} - -/** - * @dev Returns the number of elements in the map. O(1). - */ -function length(${name} storage map) internal view returns (uint256) { - return length(map._inner); -} - -/** - * @dev Returns the element stored at position \`index\` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - \`index\` must be strictly less than {length}. - */ -function at(${name} storage map, uint256 index) internal view returns (${keyType}, ${valueType}) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (${fromBytes32(keyType, 'key')}, ${fromBytes32(valueType, 'value')}); -} - -/** - * @dev Tries to returns the value associated with \`key\`. O(1). - * Does not revert if \`key\` is not in the map. - */ -function tryGet(${name} storage map, ${keyType} key) internal view returns (bool, ${valueType}) { - (bool success, bytes32 value) = tryGet(map._inner, ${toBytes32(keyType, 'key')}); - return (success, ${fromBytes32(valueType, 'value')}); -} - -/** - * @dev Returns the value associated with \`key\`. O(1). - * - * Requirements: - * - * - \`key\` must be in the map. - */ -function get(${name} storage map, ${keyType} key) internal view returns (${valueType}) { - return ${fromBytes32(valueType, `get(map._inner, ${toBytes32(keyType, 'key')})`)}; -} - -/** - * @dev Same as {get}, with a custom error message when \`key\` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ -function get( - ${name} storage map, - ${keyType} key, - string memory errorMessage -) internal view returns (${valueType}) { - return ${fromBytes32(valueType, `get(map._inner, ${toBytes32(keyType, 'key')}, errorMessage)`)}; -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library EnumerableMap {', - [ - 'using EnumerableSet for EnumerableSet.Bytes32Set;', - '', - defaultMap(), - TYPES.map(details => customMap(details).trimEnd()).join('\n\n'), - ], - '}', -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableMapMock.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableMapMock.js deleted file mode 100755 index ff26a6a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableMapMock.js +++ /dev/null @@ -1,66 +0,0 @@ -const format = require('../format-lines'); - -const TYPES = [ - { name: 'UintToAddressMap', keyType: 'uint256', valueType: 'address' }, - { name: 'AddressToUintMap', keyType: 'address', valueType: 'uint256' }, - { name: 'Bytes32ToBytes32Map', keyType: 'bytes32', valueType: 'bytes32' }, - { name: 'UintToUintMap', keyType: 'uint256', valueType: 'uint256' }, - { name: 'Bytes32ToUintMap', keyType: 'bytes32', valueType: 'uint256' }, -]; - -const header = `\ -pragma solidity ^0.8.0; - -import "../utils/structs/EnumerableMap.sol"; -`; - -const customSetMock = ({ name, keyType, valueType }) => `\ -// ${name} -contract ${name}Mock { - using EnumerableMap for EnumerableMap.${name}; - - event OperationResult(bool result); - - EnumerableMap.${name} private _map; - - function contains(${keyType} key) public view returns (bool) { - return _map.contains(key); - } - - function set(${keyType} key, ${valueType} value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(${keyType} key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (${keyType} key, ${valueType} value) { - return _map.at(index); - } - - function tryGet(${keyType} key) public view returns (bool, ${valueType}) { - return _map.tryGet(key); - } - - function get(${keyType} key) public view returns (${valueType}) { - return _map.get(key); - } - - function getWithMessage(${keyType} key, string calldata errorMessage) public view returns (${valueType}) { - return _map.get(key, errorMessage); - } -} -`; - -// GENERATE -module.exports = format( - header, - ...TYPES.map(details => customSetMock(details)), -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableSet.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableSet.js deleted file mode 100644 index 22178ec..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableSet.js +++ /dev/null @@ -1,253 +0,0 @@ -const format = require('../format-lines'); -const { fromBytes32, toBytes32 } = require('./conversion'); - -const TYPES = [ - { name: 'Bytes32Set', type: 'bytes32' }, - { name: 'AddressSet', type: 'address' }, - { name: 'UintSet', type: 'uint256' }, -]; - -/* eslint-disable max-len */ -const header = `\ -pragma solidity ^0.8.0; - -/** - * @dev Library for managing - * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive - * types. - * - * Sets have the following properties: - * - * - Elements are added, removed, and checked for existence in constant time - * (O(1)). - * - Elements are enumerated in O(n). No guarantees are made on the ordering. - * - * \`\`\` - * contract Example { - * // Add the library methods - * using EnumerableSet for EnumerableSet.AddressSet; - * - * // Declare a set state variable - * EnumerableSet.AddressSet private mySet; - * } - * \`\`\` - * - * As of v3.3.0, sets of type \`bytes32\` (\`Bytes32Set\`), \`address\` (\`AddressSet\`) - * and \`uint256\` (\`UintSet\`) are supported. - * - * [WARNING] - * ==== - * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure - * unusable. - * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. - * - * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an - * array of EnumerableSet. - * ==== - */ -`; -/* eslint-enable max-len */ - -const defaultSet = () => `\ -// To implement this library for multiple types with as little code -// repetition as possible, we write it in terms of a generic Set type with -// bytes32 values. -// The Set implementation uses private functions, and user-facing -// implementations (such as AddressSet) are just wrappers around the -// underlying Set. -// This means that we can only create new EnumerableSets for types that fit -// in bytes32. - -struct Set { - // Storage of set values - bytes32[] _values; - // Position of the value in the \`values\` array, plus 1 because index 0 - // means a value is not in the set. - mapping(bytes32 => uint256) _indexes; -} - -/** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ -function _add(Set storage set, bytes32 value) private returns (bool) { - if (!_contains(set, value)) { - set._values.push(value); - // The value is stored at length-1, but we add 1 to all indexes - // and use 0 as a sentinel value - set._indexes[value] = set._values.length; - return true; - } else { - return false; - } -} - -/** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ -function _remove(Set storage set, bytes32 value) private returns (bool) { - // We read and store the value's index to prevent multiple reads from the same storage slot - uint256 valueIndex = set._indexes[value]; - - if (valueIndex != 0) { - // Equivalent to contains(set, value) - // To delete an element from the _values array in O(1), we swap the element to delete with the last one in - // the array, and then remove the last element (sometimes called as 'swap and pop'). - // This modifies the order of the array, as noted in {at}. - - uint256 toDeleteIndex = valueIndex - 1; - uint256 lastIndex = set._values.length - 1; - - if (lastIndex != toDeleteIndex) { - bytes32 lastValue = set._values[lastIndex]; - - // Move the last value to the index where the value to delete is - set._values[toDeleteIndex] = lastValue; - // Update the index for the moved value - set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex - } - - // Delete the slot where the moved value was stored - set._values.pop(); - - // Delete the index for the deleted slot - delete set._indexes[value]; - - return true; - } else { - return false; - } -} - -/** - * @dev Returns true if the value is in the set. O(1). - */ -function _contains(Set storage set, bytes32 value) private view returns (bool) { - return set._indexes[value] != 0; -} - -/** - * @dev Returns the number of values on the set. O(1). - */ -function _length(Set storage set) private view returns (uint256) { - return set._values.length; -} - -/** - * @dev Returns the value stored at position \`index\` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - \`index\` must be strictly less than {length}. - */ -function _at(Set storage set, uint256 index) private view returns (bytes32) { - return set._values[index]; -} - -/** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ -function _values(Set storage set) private view returns (bytes32[] memory) { - return set._values; -} -`; - -const customSet = ({ name, type }) => `\ -// ${name} - -struct ${name} { - Set _inner; -} - -/** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ -function add(${name} storage set, ${type} value) internal returns (bool) { - return _add(set._inner, ${toBytes32(type, 'value')}); -} - -/** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ -function remove(${name} storage set, ${type} value) internal returns (bool) { - return _remove(set._inner, ${toBytes32(type, 'value')}); -} - -/** - * @dev Returns true if the value is in the set. O(1). - */ -function contains(${name} storage set, ${type} value) internal view returns (bool) { - return _contains(set._inner, ${toBytes32(type, 'value')}); -} - -/** - * @dev Returns the number of values in the set. O(1). - */ -function length(${name} storage set) internal view returns (uint256) { - return _length(set._inner); -} - -/** - * @dev Returns the value stored at position \`index\` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - \`index\` must be strictly less than {length}. - */ -function at(${name} storage set, uint256 index) internal view returns (${type}) { - return ${fromBytes32(type, '_at(set._inner, index)')}; -} - -/** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ -function values(${name} storage set) internal view returns (${type}[] memory) { - bytes32[] memory store = _values(set._inner); - ${type}[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library EnumerableSet {', - [ - defaultSet(), - TYPES.map(details => customSet(details).trimEnd()).join('\n\n'), - ], - '}', -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableSetMock.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableSetMock.js deleted file mode 100755 index fbc9b85..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/EnumerableSetMock.js +++ /dev/null @@ -1,56 +0,0 @@ -const format = require('../format-lines'); - -const TYPES = [ - { name: 'Bytes32Set', type: 'bytes32' }, - { name: 'AddressSet', type: 'address' }, - { name: 'UintSet', type: 'uint256' }, -]; - -const header = `\ -pragma solidity ^0.8.0; - -import "../utils/structs/EnumerableSet.sol"; -`; - -const customSetMock = ({ name, type }) => `\ -// ${name} -contract Enumerable${name}Mock { - using EnumerableSet for EnumerableSet.${name}; - - event OperationResult(bool result); - - EnumerableSet.${name} private _set; - - function contains(${type} value) public view returns (bool) { - return _set.contains(value); - } - - function add(${type} value) public { - bool result = _set.add(value); - emit OperationResult(result); - } - - function remove(${type} value) public { - bool result = _set.remove(value); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _set.length(); - } - - function at(uint256 index) public view returns (${type}) { - return _set.at(index); - } - - function values() public view returns (${type}[] memory) { - return _set.values(); - } -} -`; - -// GENERATE -module.exports = format( - header, - ...TYPES.map(details => customSetMock(details)), -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/SafeCast.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/SafeCast.js deleted file mode 100755 index 8cf1742..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/SafeCast.js +++ /dev/null @@ -1,168 +0,0 @@ -const assert = require('assert'); -const format = require('../format-lines'); -const { range } = require('../../helpers'); - -const LENGTHS = range(8, 256, 8).reverse(); // 248 → 8 (in steps of 8) - -// Returns the version of OpenZeppelin Contracts in which a particular function was introduced. -// This is used in the docs for each function. -const version = (selector, length) => { - switch (selector) { - case 'toUint(uint)': { - switch (length) { - case 8: - case 16: - case 32: - case 64: - case 128: - return '2.5'; - case 96: - case 224: - return '4.2'; - default: - assert(LENGTHS.includes(length)); - return '4.7'; - } - } - case 'toInt(int)': { - switch (length) { - case 8: - case 16: - case 32: - case 64: - case 128: - return '3.1'; - default: - assert(LENGTHS.includes(length)); - return '4.7'; - } - } - case 'toUint(int)': { - switch (length) { - case 256: - return '3.0'; - default: - assert(false); - return; - } - } - case 'toInt(uint)': { - switch (length) { - case 256: - return '3.0'; - default: - assert(false); - return; - } - } - default: - assert(false); - } -}; - -const header = `\ -pragma solidity ^0.8.0; - -/** - * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow - * checks. - * - * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can - * easily result in undesired exploitation or bugs, since developers usually - * assume that overflows raise errors. \`SafeCast\` restores this intuition by - * reverting the transaction when such an operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - * - * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing - * all math on \`uint256\` and \`int256\` and then downcasting. - */ -`; - -const toUintDownCast = length => `\ -/** - * @dev Returns the downcasted uint${length} from uint256, reverting on - * overflow (when the input is greater than largest uint${length}). - * - * Counterpart to Solidity's \`uint${length}\` operator. - * - * Requirements: - * - * - input must fit into ${length} bits - * - * _Available since v${version('toUint(uint)', length)}._ - */ -function toUint${length}(uint256 value) internal pure returns (uint${length}) { - require(value <= type(uint${length}).max, "SafeCast: value doesn't fit in ${length} bits"); - return uint${length}(value); -} -`; - -/* eslint-disable max-len */ -const toIntDownCast = length => `\ -/** - * @dev Returns the downcasted int${length} from int256, reverting on - * overflow (when the input is less than smallest int${length} or - * greater than largest int${length}). - * - * Counterpart to Solidity's \`int${length}\` operator. - * - * Requirements: - * - * - input must fit into ${length} bits - * - * _Available since v${version('toInt(int)', length)}._ - */ -function toInt${length}(int256 value) internal pure returns (int${length} downcasted) { - downcasted = int${length}(value); - require(downcasted == value, "SafeCast: value doesn't fit in ${length} bits"); -} -`; -/* eslint-enable max-len */ - -const toInt = length => `\ -/** - * @dev Converts an unsigned uint${length} into a signed int${length}. - * - * Requirements: - * - * - input must be less than or equal to maxInt${length}. - * - * _Available since v${version('toInt(uint)', length)}._ - */ -function toInt${length}(uint${length} value) internal pure returns (int${length}) { - // Note: Unsafe cast below is okay because \`type(int${length}).max\` is guaranteed to be positive - require(value <= uint${length}(type(int${length}).max), "SafeCast: value doesn't fit in an int${length}"); - return int${length}(value); -} -`; - -const toUint = length => `\ -/** - * @dev Converts a signed int${length} into an unsigned uint${length}. - * - * Requirements: - * - * - input must be greater than or equal to 0. - * - * _Available since v${version('toUint(int)', length)}._ - */ -function toUint${length}(int${length} value) internal pure returns (uint${length}) { - require(value >= 0, "SafeCast: value must be positive"); - return uint${length}(value); -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library SafeCast {', - [ - ...LENGTHS.map(toUintDownCast), - toUint(256), - ...LENGTHS.map(toIntDownCast), - toInt(256), - ], - '}', -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/SafeCastMock.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/SafeCastMock.js deleted file mode 100755 index 196d9b4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/SafeCastMock.js +++ /dev/null @@ -1,50 +0,0 @@ -const format = require('../format-lines'); -const { range } = require('../../helpers'); - -const LENGTHS = range(8, 256, 8).reverse(); // 248 → 8 (in steps of 8) - -const header = `\ -pragma solidity ^0.8.0; - -import "../utils/math/SafeCast.sol"; -`; - -const toInt = length => `\ -function toInt${length}(uint${length} a) public pure returns (int${length}) { - return a.toInt${length}(); -} -`; - -const toUint = length => `\ -function toUint${length}(int${length} a) public pure returns (uint${length}) { - return a.toUint${length}(); -} -`; - -const toIntDownCast = length => `\ -function toInt${length}(int256 a) public pure returns (int${length}) { - return a.toInt${length}(); -} -`; - -const toUintDownCast = length => `\ -function toUint${length}(uint256 a) public pure returns (uint${length}) { - return a.toUint${length}(); -} -`; - -// GENERATE -module.exports = format( - header, - 'contract SafeCastMock {', - [ - 'using SafeCast for uint256;', - 'using SafeCast for int256;', - '', - toUint(256), - ...LENGTHS.map(toUintDownCast), - toInt(256), - ...LENGTHS.map(toIntDownCast), - ].flatMap(fn => fn.split('\n')).slice(0, -1), - '}', -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/conversion.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/conversion.js deleted file mode 100644 index 5c26c68..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/generate/templates/conversion.js +++ /dev/null @@ -1,30 +0,0 @@ -function toBytes32 (type, value) { - switch (type) { - case 'bytes32': - return value; - case 'uint256': - return `bytes32(${value})`; - case 'address': - return `bytes32(uint256(uint160(${value})))`; - default: - throw new Error(`Conversion from ${type} to bytes32 not supported`); - } -} - -function fromBytes32 (type, value) { - switch (type) { - case 'bytes32': - return value; - case 'uint256': - return `uint256(${value})`; - case 'address': - return `address(uint160(uint256(${value})))`; - default: - throw new Error(`Conversion from bytes32 to ${type} not supported`); - } -} - -module.exports = { - toBytes32, - fromBytes32, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/git-user-config.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/git-user-config.sh deleted file mode 100644 index e7b81c3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/git-user-config.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -x - -git config user.name 'github-actions' -git config user.email '41898282+github-actions[bot]@users.noreply.github.com' diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/helpers.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/helpers.js deleted file mode 100644 index cbd0e01..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/helpers.js +++ /dev/null @@ -1,23 +0,0 @@ -function chunk (array, size = 1) { - return Array.range(Math.ceil(array.length / size)).map(i => array.slice(i * size, i * size + size)); -} - -function range (start, stop = undefined, step = 1) { - if (!stop) { stop = start; start = 0; } - return start < stop ? Array(Math.ceil((stop - start) / step)).fill().map((_, i) => start + i * step) : []; -} - -function unique (array, op = x => x) { - return array.filter((obj, i) => array.findIndex(entry => op(obj) === op(entry)) === i); -} - -function zip (...args) { - return Array(Math.max(...args.map(arg => arg.length))).fill(null).map((_, i) => args.map(arg => arg[i])); -} - -module.exports = { - chunk, - range, - unique, - zip, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/migrate-imports.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/migrate-imports.js deleted file mode 100755 index 15c12bc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/migrate-imports.js +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env node - -const { promises: fs } = require('fs'); -const path = require('path'); - -const pathUpdates = { - // 'access/AccessControl.sol': undefined, - // 'access/Ownable.sol': undefined, - 'access/TimelockController.sol': 'governance/TimelockController.sol', - 'cryptography/ECDSA.sol': 'utils/cryptography/ECDSA.sol', - 'cryptography/MerkleProof.sol': 'utils/cryptography/MerkleProof.sol', - 'drafts/EIP712.sol': 'utils/cryptography/EIP712.sol', - 'drafts/ERC20Permit.sol': 'token/ERC20/extensions/draft-ERC20Permit.sol', - 'drafts/IERC20Permit.sol': 'token/ERC20/extensions/draft-IERC20Permit.sol', - 'GSN/Context.sol': 'utils/Context.sol', - // 'GSN/GSNRecipientERC20Fee.sol': undefined, - // 'GSN/GSNRecipientSignature.sol': undefined, - // 'GSN/GSNRecipient.sol': undefined, - // 'GSN/IRelayHub.sol': undefined, - // 'GSN/IRelayRecipient.sol': undefined, - 'introspection/ERC165Checker.sol': 'utils/introspection/ERC165Checker.sol', - 'introspection/ERC165.sol': 'utils/introspection/ERC165.sol', - 'introspection/ERC1820Implementer.sol': 'utils/introspection/ERC1820Implementer.sol', - 'introspection/IERC165.sol': 'utils/introspection/IERC165.sol', - 'introspection/IERC1820Implementer.sol': 'utils/introspection/IERC1820Implementer.sol', - 'introspection/IERC1820Registry.sol': 'utils/introspection/IERC1820Registry.sol', - 'math/Math.sol': 'utils/math/Math.sol', - 'math/SafeMath.sol': 'utils/math/SafeMath.sol', - 'math/SignedSafeMath.sol': 'utils/math/SignedSafeMath.sol', - 'payment/escrow/ConditionalEscrow.sol': 'utils/escrow/ConditionalEscrow.sol', - 'payment/escrow/Escrow.sol': 'utils/escrow/Escrow.sol', - 'payment/escrow/RefundEscrow.sol': 'utils/escrow/RefundEscrow.sol', - 'payment/PaymentSplitter.sol': 'finance/PaymentSplitter.sol', - 'utils/PaymentSplitter.sol': 'finance/PaymentSplitter.sol', - 'payment/PullPayment.sol': 'security/PullPayment.sol', - 'presets/ERC1155PresetMinterPauser.sol': 'token/ERC1155/presets/ERC1155PresetMinterPauser.sol', - 'presets/ERC20PresetFixedSupply.sol': 'token/ERC20/presets/ERC20PresetFixedSupply.sol', - 'presets/ERC20PresetMinterPauser.sol': 'token/ERC20/presets/ERC20PresetMinterPauser.sol', - 'presets/ERC721PresetMinterPauserAutoId.sol': 'token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol', - 'presets/ERC777PresetFixedSupply.sol': 'token/ERC777/presets/ERC777PresetFixedSupply.sol', - // 'proxy/BeaconProxy.sol': 'proxy/beacon/BeaconProxy.sol', - // 'proxy/Clones.sol': undefined, - // 'proxy/IBeacon.sol': 'proxy/beacon/IBeacon.sol', - 'proxy/Initializable.sol': 'proxy/utils/Initializable.sol', - 'utils/Initializable.sol': 'proxy/utils/Initializable.sol', - // 'proxy/ProxyAdmin.sol': 'proxy/transparent/ProxyAdmin.sol', - // 'proxy/Proxy.sol': undefined, - // 'proxy/TransparentUpgradeableProxy.sol': 'proxy/transparent/TransparentUpgradeableProxy.sol', - // 'proxy/UpgradeableBeacon.sol': 'proxy/beacon/UpgradeableBeacon.sol', - // 'proxy/UpgradeableProxy.sol': 'proxy/ERC1967/ERC1967Proxy.sol', - 'token/ERC1155/ERC1155Burnable.sol': 'token/ERC1155/extensions/ERC1155Burnable.sol', - 'token/ERC1155/ERC1155Holder.sol': 'token/ERC1155/utils/ERC1155Holder.sol', - 'token/ERC1155/ERC1155Pausable.sol': 'token/ERC1155/extensions/ERC1155Pausable.sol', - 'token/ERC1155/ERC1155Receiver.sol': 'token/ERC1155/utils/ERC1155Receiver.sol', - // 'token/ERC1155/ERC1155.sol': undefined, - 'token/ERC1155/IERC1155MetadataURI.sol': 'token/ERC1155/extensions/IERC1155MetadataURI.sol', - // 'token/ERC1155/IERC1155Receiver.sol': undefined, - // 'token/ERC1155/IERC1155.sol': undefined, - 'token/ERC20/ERC20Burnable.sol': 'token/ERC20/extensions/ERC20Burnable.sol', - 'token/ERC20/ERC20Capped.sol': 'token/ERC20/extensions/ERC20Capped.sol', - 'token/ERC20/ERC20Pausable.sol': 'token/ERC20/extensions/ERC20Pausable.sol', - 'token/ERC20/ERC20Snapshot.sol': 'token/ERC20/extensions/ERC20Snapshot.sol', - // 'token/ERC20/ERC20.sol': undefined, - // 'token/ERC20/IERC20.sol': undefined, - 'token/ERC20/SafeERC20.sol': 'token/ERC20/utils/SafeERC20.sol', - 'token/ERC20/TokenTimelock.sol': 'token/ERC20/utils/TokenTimelock.sol', - 'token/ERC721/ERC721Burnable.sol': 'token/ERC721/extensions/ERC721Burnable.sol', - 'token/ERC721/ERC721Holder.sol': 'token/ERC721/utils/ERC721Holder.sol', - 'token/ERC721/ERC721Pausable.sol': 'token/ERC721/extensions/ERC721Pausable.sol', - // 'token/ERC721/ERC721.sol': undefined, - 'token/ERC721/IERC721Enumerable.sol': 'token/ERC721/extensions/IERC721Enumerable.sol', - 'token/ERC721/IERC721Metadata.sol': 'token/ERC721/extensions/IERC721Metadata.sol', - // 'token/ERC721/IERC721Receiver.sol': undefined, - // 'token/ERC721/IERC721.sol': undefined, - // 'token/ERC777/ERC777.sol': undefined, - // 'token/ERC777/IERC777Recipient.sol': undefined, - // 'token/ERC777/IERC777Sender.sol': undefined, - // 'token/ERC777/IERC777.sol': undefined, - // 'utils/Address.sol': undefined, - // 'utils/Arrays.sol': undefined, - // 'utils/Context.sol': undefined, - // 'utils/Counters.sol': undefined, - // 'utils/Create2.sol': undefined, - 'utils/EnumerableMap.sol': 'utils/structs/EnumerableMap.sol', - 'utils/EnumerableSet.sol': 'utils/structs/EnumerableSet.sol', - 'utils/Pausable.sol': 'security/Pausable.sol', - 'utils/ReentrancyGuard.sol': 'security/ReentrancyGuard.sol', - 'utils/SafeCast.sol': 'utils/math/SafeCast.sol', - // 'utils/Strings.sol': undefined, -}; - -async function main (paths = [ 'contracts' ]) { - const files = await listFilesRecursively(paths, /\.sol$/); - - const updatedFiles = []; - for (const file of files) { - if (await updateFile(file, updateImportPaths)) { - updatedFiles.push(file); - } - } - - if (updatedFiles.length > 0) { - console.log(`${updatedFiles.length} file(s) were updated`); - for (const c of updatedFiles) { - console.log('-', c); - } - } else { - console.log('No files were updated'); - } -} - -async function listFilesRecursively (paths, filter) { - const queue = paths; - const files = []; - - while (queue.length > 0) { - const top = queue.shift(); - const stat = await fs.stat(top); - if (stat.isFile()) { - if (top.match(filter)) { - files.push(top); - } - } else if (stat.isDirectory()) { - for (const name of await fs.readdir(top)) { - queue.push(path.join(top, name)); - } - } - } - - return files; -} - -async function updateFile (file, update) { - const content = await fs.readFile(file, 'utf8'); - const updatedContent = update(content); - if (updatedContent !== content) { - await fs.writeFile(file, updatedContent); - return true; - } else { - return false; - } -} - -function updateImportPaths (source) { - for (const [ oldPath, newPath ] of Object.entries(pathUpdates)) { - source = source.replace( - path.join('@openzeppelin/contracts', oldPath), - path.join('@openzeppelin/contracts', newPath), - ); - source = source.replace( - path.join('@openzeppelin/contracts-upgradeable', getUpgradeablePath(oldPath)), - path.join('@openzeppelin/contracts-upgradeable', getUpgradeablePath(newPath)), - ); - } - - return source; -} - -function getUpgradeablePath (file) { - const { dir, name, ext } = path.parse(file); - const upgradeableName = name + 'Upgradeable'; - return path.format({ dir, ext, name: upgradeableName }); -} - -module.exports = { - pathUpdates, - updateImportPaths, - getUpgradeablePath, -}; - -if (require.main === module) { - const args = process.argv.length > 2 ? process.argv.slice(2) : undefined; - main(args).catch(e => { - console.error(e); - process.exit(1); - }); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepack.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepack.sh deleted file mode 100755 index 6f1bd4c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepack.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -shopt -s globstar - -# cross platform `mkdir -p` -node -e 'fs.mkdirSync("build/contracts", { recursive: true })' - -cp artifacts/contracts/**/*.json build/contracts -rm build/contracts/*.dbg.json - -node scripts/remove-ignored-artifacts.js diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare-contracts-package.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare-contracts-package.sh deleted file mode 100755 index 3f62fd4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare-contracts-package.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -# cd to the root of the repo -cd "$(git rev-parse --show-toplevel)" - -# avoids re-compilation during publishing of both packages -if [[ ! -v ALREADY_COMPILED ]]; then - npm run clean - npm run prepare - npm run prepack -fi - -cp README.md contracts/ -mkdir contracts/build contracts/build/contracts -cp -r build/contracts/*.json contracts/build/contracts diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare-docs.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare-docs.sh deleted file mode 100755 index 53a996b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare-docs.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit - -OUTDIR="$(node -p 'require("./docs/config.js").outputDir')" - -if [ ! -d node_modules ]; then - npm ci -fi - -rm -rf "$OUTDIR" - -hardhat docgen - -node scripts/gen-nav.js "$OUTDIR" > "$OUTDIR/../nav.adoc" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare.sh deleted file mode 100755 index 7014a70..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/prepare.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if [ "${SKIP_COMPILE:-}" == true ]; then - exit -fi - -npm run clean -env COMPILE_MODE=production npm run compile diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/release.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/release.sh deleted file mode 100755 index af5091b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/release.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env bash - -# Exit script as soon as a command fails. -set -o errexit - -# Default the prerelease version suffix to rc -: ${PRERELEASE_SUFFIX:=rc} - -log() { - # Print to stderr to prevent this from being 'returned' - echo "$@" > /dev/stderr -} - -current_version() { - echo "v$(node --print --eval "require('./package.json').version")" -} - -current_release_branch() { - v="$(current_version)" # 3.3.0-rc.0 - vf="${v%-"$PRERELEASE_SUFFIX".*}" # 3.3.0 - r="${vf%.*}" # 3.3 - echo "release-$r" -} - -assert_current_branch() { - current_branch="$(git symbolic-ref --short HEAD)" - expected_branch="$1" - if [[ "$current_branch" != "$expected_branch" ]]; then - log "Current branch '$current_branch' is not '$expected_branch'" - exit 1 - fi -} - -push_release_branch_and_tag() { - git push upstream "$(current_release_branch)" "$(current_version)" -} - -publish() { - dist_tag="$1" - - log "Publishing @openzeppelin/contracts on npm" - cd contracts - npm publish --tag "$dist_tag" --otp "$(prompt_otp)" - cd .. - - if [[ "$dist_tag" == "latest" ]]; then - npm dist-tag rm --otp "$(prompt_otp)" @openzeppelin/contracts next - fi -} - -push_and_publish() { - dist_tag="$1" - - log "Pushing release branch and tags to upstream" - push_release_branch_and_tag - - publish "$dist_tag" -} - -prompt_otp() { - log -n "Enter npm 2FA token: " - read -r otp - echo "$otp" -} - -environment_check() { - if ! git remote get-url upstream &> /dev/null; then - log "No 'upstream' remote found" - exit 1 - fi - - if npm whoami &> /dev/null; then - log "Will publish as '$(npm whoami)'" - else - log "Not logged in into npm, run 'npm login' first" - exit 1 - fi -} - -environment_check - -if [[ "$*" == "push" ]]; then - push_and_publish next - -elif [[ "$*" == "start minor" ]]; then - log "Creating new minor pre-release" - - assert_current_branch master - - # Create temporary release branch - git checkout -b release-temp - - # This bumps minor and adds prerelease suffix, commits the changes, and tags the commit - npm version preminor --preid="$PRERELEASE_SUFFIX" - - # Rename the release branch - git branch --move "$(current_release_branch)" - - push_and_publish next - -elif [[ "$*" == "start major" ]]; then - log "Creating new major pre-release" - - assert_current_branch master - - # Create temporary release branch - git checkout -b release-temp - - # This bumps major and adds prerelease suffix, commits the changes, and tags the commit - npm version premajor --preid="$PRERELEASE_SUFFIX" - - # Rename the release branch - git branch --move "$(current_release_branch)" - - push_and_publish next - -elif [[ "$*" == "rc" ]]; then - log "Bumping pre-release" - - assert_current_branch "$(current_release_branch)" - - # Bumps prerelease number, commits and tags - npm version prerelease - - push_and_publish next - -elif [[ "$*" == "final" ]]; then - # Update changelog release date, remove prerelease suffix, tag, push to git, publish in npm, remove next dist-tag - log "Creating final release" - - assert_current_branch "$(current_release_branch)" - - # This will remove the prerelease suffix from the version - npm version patch - - push_release_branch_and_tag - - push_and_publish latest - - log "Remember to merge the release branch into master and push upstream" - -else - log "Unknown command: '$*'" - exit 1 -fi diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/synchronize-versions.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/synchronize-versions.js deleted file mode 100755 index 15915a1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/synchronize-versions.js +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node - -// Synchronizes the version in contracts/package.json with the one in package.json. -// This is run automatically when npm version is run. - -const fs = require('fs'); -const cp = require('child_process'); - -setVersion('contracts/package.json'); - -function setVersion (file) { - const json = JSON.parse(fs.readFileSync(file)); - json.version = process.env.npm_package_version; - fs.writeFileSync(file, JSON.stringify(json, null, 2) + '\n'); - cp.execFileSync('git', ['add', file]); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/update-changelog-release-date.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/update-changelog-release-date.js deleted file mode 100755 index c368eb7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/update-changelog-release-date.js +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env node - -// Sets the release date of the current release in the changelog. -// This is run automatically when npm version is run. - -const fs = require('fs'); -const cp = require('child_process'); - -const suffix = process.env.PRERELEASE_SUFFIX || 'rc'; - -const changelog = fs.readFileSync('CHANGELOG.md', 'utf8'); - -// The changelog entry to be updated looks like this: -// ## Unreleased -// We need to add the version and release date in a YYYY-MM-DD format, so that it looks like this: -// ## 2.5.3 (2019-04-25) - -const pkg = require('../../package.json'); -const version = pkg.version.replace(new RegExp('-' + suffix + '\\..*'), ''); - -const header = new RegExp(`^## (Unreleased|${version})$`, 'm'); - -if (!header.test(changelog)) { - console.error('Missing changelog entry'); - process.exit(1); -} - -const newHeader = pkg.version.indexOf(suffix) === -1 - ? `## ${version} (${new Date().toISOString().split('T')[0]})` - : `## ${version}`; - -fs.writeFileSync('CHANGELOG.md', changelog.replace(header, newHeader)); - -cp.execSync('git add CHANGELOG.md', { stdio: 'inherit' }); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/update-comment.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/update-comment.js deleted file mode 100755 index 7baf8c2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/update-comment.js +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env node -const fs = require('fs'); -const proc = require('child_process'); -const semver = require('semver'); -const run = (cmd, ...args) => proc.execFileSync(cmd, args, { encoding: 'utf8' }).trim(); - -const gitStatus = run('git', 'status', '--porcelain', '-uno', 'contracts/**/*.sol'); -if (gitStatus.length > 0) { - console.error('Contracts directory is not clean'); - process.exit(1); -} - -const { version } = require('../../package.json'); - -// Get latest tag according to semver. -const [ tag ] = run('git', 'tag') - .split(/\r?\n/) - .filter(semver.coerce) // check version can be processed - .filter(v => semver.lt(semver.coerce(v), version)) // only consider older tags, ignore current prereleases - .sort(semver.rcompare); - -// Ordering tag → HEAD is important here. -const files = run('git', 'diff', tag, 'HEAD', '--name-only', 'contracts/**/*.sol') - .split(/\r?\n/) - .filter(file => file && !file.match(/mock/i) && fs.existsSync(file)); - -for (const file of files) { - const current = fs.readFileSync(file, 'utf8'); - const updated = current.replace( - /(\/\/ SPDX-License-Identifier:.*)$(\n\/\/ OpenZeppelin Contracts .*$)?/m, - `$1\n// OpenZeppelin Contracts (last updated v${version}) (${file.replace('contracts/', '')})`, - ); - fs.writeFileSync(file, updated); -} - -run('git', 'add', '--update', 'contracts'); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/version.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/version.sh deleted file mode 100755 index 73d3026..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/release/version.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit - -scripts/release/update-changelog-release-date.js -scripts/release/synchronize-versions.js -scripts/release/update-comment.js - -oz-docs update-version diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/remove-ignored-artifacts.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/remove-ignored-artifacts.js deleted file mode 100644 index 2ef2788..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/remove-ignored-artifacts.js +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node - -// This script removes the build artifacts of ignored contracts. - -const fs = require('fs'); -const path = require('path'); -const match = require('micromatch'); - -function readJSON (path) { - return JSON.parse(fs.readFileSync(path)); -} - -const pkgFiles = readJSON('package.json').files; - -// Get only negated patterns. -const ignorePatterns = pkgFiles - .filter(pat => pat.startsWith('!')) -// Remove the negation part. Makes micromatch usage more intuitive. - .map(pat => pat.slice(1)); - -const ignorePatternsSubtrees = ignorePatterns -// Add **/* to ignore all files contained in the directories. - .concat(ignorePatterns.map(pat => path.join(pat, '**/*'))) - .map(p => p.replace(/^\//, '')); - -const artifactsDir = 'build/contracts'; -const buildinfo = 'artifacts/build-info'; -const filenames = fs.readdirSync(buildinfo); - -let n = 0; - -for (const filename of filenames) { - const solcOutput = readJSON(path.join(buildinfo, filename)).output; - for (const sourcePath in solcOutput.contracts) { - const ignore = match.any(sourcePath, ignorePatternsSubtrees); - if (ignore) { - for (const contract in solcOutput.contracts[sourcePath]) { - fs.unlinkSync(path.join(artifactsDir, contract + '.json')); - n += 1; - } - } - } -} - -console.error(`Removed ${n} mock artifacts`); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/update-docs-branch.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/update-docs-branch.js deleted file mode 100644 index 82bb7e0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/update-docs-branch.js +++ /dev/null @@ -1,55 +0,0 @@ -const proc = require('child_process'); -const read = cmd => proc.execSync(cmd, { encoding: 'utf8' }).trim(); -const run = cmd => { proc.execSync(cmd, { stdio: 'inherit' }); }; -const tryRead = cmd => { try { return read(cmd); } catch (e) { return undefined; } }; - -const releaseBranchRegex = /^release-v(?(?\d+)\.(?\d+)(?:\.(?\d+))?)$/; - -const currentBranch = read('git rev-parse --abbrev-ref HEAD'); -const match = currentBranch.match(releaseBranchRegex); - -if (!match) { - console.error('Not currently on a release branch'); - process.exit(1); -} - -if (/-.*$/.test(require('../package.json').version)) { - console.error('Refusing to update docs: prerelease detected'); - process.exit(0); -} - -const current = match.groups; -const docsBranch = `docs-v${current.major}.x`; - -// Fetch remotes and find the docs branch if it exists -run('git fetch --all --no-tags'); -const matchingDocsBranches = tryRead(`git rev-parse --glob='*/${docsBranch}'`); - -if (!matchingDocsBranches) { - // Create the branch - run(`git checkout --orphan ${docsBranch}`); -} else { - const [publishedRef, ...others] = new Set(matchingDocsBranches.split('\n')); - if (others.length > 0) { - console.error( - `Found conflicting ${docsBranch} branches.\n` + - 'Either local branch is outdated or there are multiple matching remote branches.', - ); - process.exit(1); - } - const publishedVersion = JSON.parse(read(`git show ${publishedRef}:package.json`)).version; - const publishedMinor = publishedVersion.match(/\d+\.(?\d+)\.\d+/).groups.minor; - if (current.minor < publishedMinor) { - console.error('Refusing to update docs: newer version is published'); - process.exit(0); - } - - run('git checkout --quiet --detach'); - run(`git reset --soft ${publishedRef}`); - run(`git checkout ${docsBranch}`); -} - -run('npm run prepare-docs'); -run('git add -f docs'); // --force needed because generated docs files are gitignored -run('git commit -m "Update docs"'); -run(`git checkout ${currentBranch}`); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/git-user-config.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/git-user-config.sh deleted file mode 100644 index e7b81c3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/git-user-config.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -x - -git config user.name 'github-actions' -git config user.email '41898282+github-actions[bot]@users.noreply.github.com' diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/merge-upstream.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/merge-upstream.sh deleted file mode 100644 index 211d17f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/merge-upstream.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -: "${REF:="$(git rev-parse --symbolic-full-name HEAD)"}" -: "${BASE_REF:=refs/heads/origin/patches}" - -if [[ "$REF" != refs/heads/* ]]; then - echo "$REF is not a branch" >&2 - exit 1 -elif [[ "$REF" == refs/heads/patches ]]; then - REF=refs/heads/master -fi - -set -x - -input="${REF#refs/heads/}" -upstream="${input#patched/}" -branch="patched/$upstream" -base="${BASE_REF#refs/heads/}" - -git checkout "$branch" 2>/dev/null || git checkout -b "$branch" "$base" --no-track - -git fetch 'https://github.com/OpenZeppelin/openzeppelin-contracts.git' master -merge_base="$(git merge-base "$base" FETCH_HEAD)" - -git fetch 'https://github.com/OpenZeppelin/openzeppelin-contracts.git' "$upstream" -# Check that patches is not ahead of the upstream branch we're merging. -if ! git merge-base --is-ancestor "$merge_base" FETCH_HEAD; then - echo "The patches branch is ahead of $upstream" >&2 - exit 1 -fi -git merge "$base" FETCH_HEAD -m "Merge upstream $upstream into $branch" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/patch/.gitkeep b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/patch/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/transpile-onto.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/transpile-onto.sh deleted file mode 100644 index 891dd8c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/transpile-onto.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if [ $# -lt 1 ]; then - echo "usage: bash $0 [base]" >&2 - exit 1 -fi - -set -x - -target="$1" -base="${2-}" - -bash scripts/upgradeable/transpile.sh - -commit="$(git rev-parse --short HEAD)" -branch="$(git rev-parse --abbrev-ref HEAD)" - -git add contracts - -git checkout --quiet --detach - -if git rev-parse -q --verify "$target"; then - git reset --soft "$target" - git checkout "$target" -else - git checkout --orphan "$target" - if [ -n "$base" ] && git rev-parse -q --verify "$base"; then - git reset --soft "$base" - fi -fi - -if ! git diff --quiet --cached; then - git commit -m "Transpile $commit" -fi - -git checkout "$branch" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/transpile.sh b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/transpile.sh deleted file mode 100644 index 3b30886..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/scripts/upgradeable/transpile.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -x - -npm run compile - -build_info=($(jq -r '.input.sources | keys | if any(test("^contracts/mocks/.*\\bunreachable\\b")) then empty else input_filename end' artifacts/build-info/*)) -build_info_num=${#build_info[@]} - -if [ $build_info_num -ne 1 ]; then - echo "found $build_info_num relevant build info files but expected just 1" - exit 1 -fi - -# -D: delete original and excluded files -# -b: use this build info file -# -i: use included Initializable -# -x: exclude all proxy contracts except Clones library -# -p: emit public initializer -npx @openzeppelin/upgrade-safe-transpiler@latest -D \ - -b "$build_info" \ - -i contracts/proxy/utils/Initializable.sol \ - -x 'contracts/proxy/**/*' \ - -x '!contracts/proxy/Clones.sol' \ - -x '!contracts/proxy/ERC1967/ERC1967Storage.sol' \ - -x '!contracts/proxy/ERC1967/ERC1967Upgrade.sol' \ - -x '!contracts/proxy/utils/UUPSUpgradeable.sol' \ - -x '!contracts/proxy/beacon/IBeacon.sol' \ - -p 'contracts/**/presets/**/*' - -# this is currently no longer used but could be useful again in the future -# for p in scripts/upgradeable/patch/*.patch; do -# git apply "$p" -# done diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/slither.config.json b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/slither.config.json deleted file mode 100644 index 2b61879..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/slither.config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "detectors_to_run": "reentrancy-eth,reentrancy-no-eth,reentrancy-unlimited-gas", - "filter_paths": "contracts/mocks", - "compile_force_framework": "hardhat" -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/TESTING.md b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/TESTING.md deleted file mode 100644 index a5ee932..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/TESTING.md +++ /dev/null @@ -1,3 +0,0 @@ -## Testing - -Unit test are critical to OpenZeppelin Contracts. They help ensure code quality and mitigate against security vulnerabilities. The directory structure within the `/test` directory corresponds to the `/contracts` directory. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControl.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControl.behavior.js deleted file mode 100644 index 53dfa3d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControl.behavior.js +++ /dev/null @@ -1,216 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); - -const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; -const ROLE = web3.utils.soliditySha3('ROLE'); -const OTHER_ROLE = web3.utils.soliditySha3('OTHER_ROLE'); - -function shouldBehaveLikeAccessControl (errorPrefix, admin, authorized, other, otherAdmin, otherAuthorized) { - shouldSupportInterfaces(['AccessControl']); - - describe('default admin', function () { - it('deployer has default admin role', async function () { - expect(await this.accessControl.hasRole(DEFAULT_ADMIN_ROLE, admin)).to.equal(true); - }); - - it('other roles\'s admin is the default admin role', async function () { - expect(await this.accessControl.getRoleAdmin(ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - it('default admin role\'s admin is itself', async function () { - expect(await this.accessControl.getRoleAdmin(DEFAULT_ADMIN_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - }); - - describe('granting', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - }); - - it('non-admin cannot grant role to other accounts', async function () { - await expectRevert( - this.accessControl.grantRole(ROLE, authorized, { from: other }), - `${errorPrefix}: account ${other.toLowerCase()} is missing role ${DEFAULT_ADMIN_ROLE}`, - ); - }); - - it('accounts can be granted a role multiple times', async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - const receipt = await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - expectEvent.notEmitted(receipt, 'RoleGranted'); - }); - }); - - describe('revoking', function () { - it('roles that are not had can be revoked', async function () { - expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false); - - const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin }); - expectEvent.notEmitted(receipt, 'RoleRevoked'); - }); - - context('with granted role', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - }); - - it('admin can revoke role', async function () { - const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin }); - expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: admin }); - - expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false); - }); - - it('non-admin cannot revoke role', async function () { - await expectRevert( - this.accessControl.revokeRole(ROLE, authorized, { from: other }), - `${errorPrefix}: account ${other.toLowerCase()} is missing role ${DEFAULT_ADMIN_ROLE}`, - ); - }); - - it('a role can be revoked multiple times', async function () { - await this.accessControl.revokeRole(ROLE, authorized, { from: admin }); - - const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin }); - expectEvent.notEmitted(receipt, 'RoleRevoked'); - }); - }); - }); - - describe('renouncing', function () { - it('roles that are not had can be renounced', async function () { - const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized }); - expectEvent.notEmitted(receipt, 'RoleRevoked'); - }); - - context('with granted role', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - }); - - it('bearer can renounce role', async function () { - const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized }); - expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: authorized }); - - expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false); - }); - - it('only the sender can renounce their roles', async function () { - await expectRevert( - this.accessControl.renounceRole(ROLE, authorized, { from: admin }), - `${errorPrefix}: can only renounce roles for self`, - ); - }); - - it('a role can be renounced multiple times', async function () { - await this.accessControl.renounceRole(ROLE, authorized, { from: authorized }); - - const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized }); - expectEvent.notEmitted(receipt, 'RoleRevoked'); - }); - }); - }); - - describe('setting role admin', function () { - beforeEach(async function () { - const receipt = await this.accessControl.setRoleAdmin(ROLE, OTHER_ROLE); - expectEvent(receipt, 'RoleAdminChanged', { - role: ROLE, - previousAdminRole: DEFAULT_ADMIN_ROLE, - newAdminRole: OTHER_ROLE, - }); - - await this.accessControl.grantRole(OTHER_ROLE, otherAdmin, { from: admin }); - }); - - it('a role\'s admin role can be changed', async function () { - expect(await this.accessControl.getRoleAdmin(ROLE)).to.equal(OTHER_ROLE); - }); - - it('the new admin can grant roles', async function () { - const receipt = await this.accessControl.grantRole(ROLE, authorized, { from: otherAdmin }); - expectEvent(receipt, 'RoleGranted', { account: authorized, role: ROLE, sender: otherAdmin }); - }); - - it('the new admin can revoke roles', async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: otherAdmin }); - const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: otherAdmin }); - expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: otherAdmin }); - }); - - it('a role\'s previous admins no longer grant roles', async function () { - await expectRevert( - this.accessControl.grantRole(ROLE, authorized, { from: admin }), - `${errorPrefix}: account ${admin.toLowerCase()} is missing role ${OTHER_ROLE}`, - ); - }); - - it('a role\'s previous admins no longer revoke roles', async function () { - await expectRevert( - this.accessControl.revokeRole(ROLE, authorized, { from: admin }), - `${errorPrefix}: account ${admin.toLowerCase()} is missing role ${OTHER_ROLE}`, - ); - }); - }); - - describe('onlyRole modifier', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - }); - - it('do not revert if sender has role', async function () { - await this.accessControl.senderProtected(ROLE, { from: authorized }); - }); - - it('revert if sender doesn\'t have role #1', async function () { - await expectRevert( - this.accessControl.senderProtected(ROLE, { from: other }), - `${errorPrefix}: account ${other.toLowerCase()} is missing role ${ROLE}`, - ); - }); - - it('revert if sender doesn\'t have role #2', async function () { - await expectRevert( - this.accessControl.senderProtected(OTHER_ROLE, { from: authorized }), - `${errorPrefix}: account ${authorized.toLowerCase()} is missing role ${OTHER_ROLE}`, - ); - }); - }); -} - -function shouldBehaveLikeAccessControlEnumerable (errorPrefix, admin, authorized, other, otherAdmin, otherAuthorized) { - shouldSupportInterfaces(['AccessControlEnumerable']); - - describe('enumerating', function () { - it('role bearers can be enumerated', async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - await this.accessControl.grantRole(ROLE, other, { from: admin }); - await this.accessControl.grantRole(ROLE, otherAuthorized, { from: admin }); - await this.accessControl.revokeRole(ROLE, other, { from: admin }); - - const memberCount = await this.accessControl.getRoleMemberCount(ROLE); - expect(memberCount).to.bignumber.equal('2'); - - const bearers = []; - for (let i = 0; i < memberCount; ++i) { - bearers.push(await this.accessControl.getRoleMember(ROLE, i)); - } - - expect(bearers).to.have.members([authorized, otherAuthorized]); - }); - it('role enumeration should be in sync after renounceRole call', async function () { - expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('0'); - await this.accessControl.grantRole(ROLE, admin, { from: admin }); - expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('1'); - await this.accessControl.renounceRole(ROLE, admin, { from: admin }); - expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('0'); - }); - }); -} - -module.exports = { - shouldBehaveLikeAccessControl, - shouldBehaveLikeAccessControlEnumerable, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControl.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControl.test.js deleted file mode 100644 index cd9912a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControl.test.js +++ /dev/null @@ -1,13 +0,0 @@ -const { - shouldBehaveLikeAccessControl, -} = require('./AccessControl.behavior.js'); - -const AccessControlMock = artifacts.require('AccessControlMock'); - -contract('AccessControl', function (accounts) { - beforeEach(async function () { - this.accessControl = await AccessControlMock.new({ from: accounts[0] }); - }); - - shouldBehaveLikeAccessControl('AccessControl', ...accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControlCrossChain.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControlCrossChain.test.js deleted file mode 100644 index cb4f362..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControlCrossChain.test.js +++ /dev/null @@ -1,59 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { BridgeHelper } = require('../helpers/crosschain'); - -const { - shouldBehaveLikeAccessControl, -} = require('./AccessControl.behavior.js'); - -const crossChainRoleAlias = (role) => web3.utils.leftPad( - web3.utils.toHex(web3.utils.toBN(role).xor(web3.utils.toBN(web3.utils.soliditySha3('CROSSCHAIN_ALIAS')))), - 64, -); - -const AccessControlCrossChainMock = artifacts.require('AccessControlCrossChainMock'); - -const ROLE = web3.utils.soliditySha3('ROLE'); - -contract('AccessControl', function (accounts) { - before(async function () { - this.bridge = await BridgeHelper.deploy(); - }); - - beforeEach(async function () { - this.accessControl = await AccessControlCrossChainMock.new({ from: accounts[0] }); - }); - - shouldBehaveLikeAccessControl('AccessControl', ...accounts); - - describe('CrossChain enabled', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, accounts[0], { from: accounts[0] }); - await this.accessControl.grantRole(crossChainRoleAlias(ROLE), accounts[1], { from: accounts[0] }); - }); - - it('check alliassing', async function () { - expect(await this.accessControl.crossChainRoleAlias(ROLE)).to.be.bignumber.equal(crossChainRoleAlias(ROLE)); - }); - - it('Crosschain calls not authorized to non-aliased addresses', async function () { - await expectRevert( - this.bridge.call( - accounts[0], - this.accessControl, - 'senderProtected', - [ ROLE ], - ), - `AccessControl: account ${accounts[0].toLowerCase()} is missing role ${crossChainRoleAlias(ROLE)}`, - ); - }); - - it('Crosschain calls not authorized to non-aliased addresses', async function () { - await this.bridge.call( - accounts[1], - this.accessControl, - 'senderProtected', - [ ROLE ], - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControlEnumerable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControlEnumerable.test.js deleted file mode 100644 index fa5b546..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/AccessControlEnumerable.test.js +++ /dev/null @@ -1,15 +0,0 @@ -const { - shouldBehaveLikeAccessControl, - shouldBehaveLikeAccessControlEnumerable, -} = require('./AccessControl.behavior.js'); - -const AccessControlMock = artifacts.require('AccessControlEnumerableMock'); - -contract('AccessControl', function (accounts) { - beforeEach(async function () { - this.accessControl = await AccessControlMock.new({ from: accounts[0] }); - }); - - shouldBehaveLikeAccessControl('AccessControl', ...accounts); - shouldBehaveLikeAccessControlEnumerable('AccessControl', ...accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/Ownable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/Ownable.test.js deleted file mode 100644 index 894e77c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/Ownable.test.js +++ /dev/null @@ -1,57 +0,0 @@ -const { constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const Ownable = artifacts.require('OwnableMock'); - -contract('Ownable', function (accounts) { - const [ owner, other ] = accounts; - - beforeEach(async function () { - this.ownable = await Ownable.new({ from: owner }); - }); - - it('has an owner', async function () { - expect(await this.ownable.owner()).to.equal(owner); - }); - - describe('transfer ownership', function () { - it('changes owner after transfer', async function () { - const receipt = await this.ownable.transferOwnership(other, { from: owner }); - expectEvent(receipt, 'OwnershipTransferred'); - - expect(await this.ownable.owner()).to.equal(other); - }); - - it('prevents non-owners from transferring', async function () { - await expectRevert( - this.ownable.transferOwnership(other, { from: other }), - 'Ownable: caller is not the owner', - ); - }); - - it('guards ownership against stuck state', async function () { - await expectRevert( - this.ownable.transferOwnership(ZERO_ADDRESS, { from: owner }), - 'Ownable: new owner is the zero address', - ); - }); - }); - - describe('renounce ownership', function () { - it('loses owner after renouncement', async function () { - const receipt = await this.ownable.renounceOwnership({ from: owner }); - expectEvent(receipt, 'OwnershipTransferred'); - - expect(await this.ownable.owner()).to.equal(ZERO_ADDRESS); - }); - - it('prevents non-owners from renouncement', async function () { - await expectRevert( - this.ownable.renounceOwnership({ from: other }), - 'Ownable: caller is not the owner', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/Ownable2Step.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/Ownable2Step.test.js deleted file mode 100644 index 0aeb224..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/access/Ownable2Step.test.js +++ /dev/null @@ -1,57 +0,0 @@ -const { constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; -const { expect } = require('chai'); - -const Ownable2Step = artifacts.require('Ownable2StepMock'); - -contract('Ownable2Step', function (accounts) { - const [owner, accountA, accountB] = accounts; - - beforeEach(async function () { - this.ownable2Step = await Ownable2Step.new({ from: owner }); - }); - - describe('transfer ownership', function () { - it('starting a transfer does not change owner', async function () { - const receipt = await this.ownable2Step.transferOwnership(accountA, { from: owner }); - expectEvent(receipt, 'OwnershipTransferStarted', { previousOwner: owner, newOwner: accountA }); - expect(await this.ownable2Step.owner()).to.equal(owner); - expect(await this.ownable2Step.pendingOwner()).to.equal(accountA); - }); - - it('changes owner after transfer', async function () { - await this.ownable2Step.transferOwnership(accountA, { from: owner }); - const receipt = await this.ownable2Step.acceptOwnership({ from: accountA }); - expectEvent(receipt, 'OwnershipTransferred', { previousOwner: owner, newOwner: accountA }); - expect(await this.ownable2Step.owner()).to.equal(accountA); - expect(await this.ownable2Step.pendingOwner()).to.not.equal(accountA); - }); - - it('changes owner after renouncing ownership', async function () { - await this.ownable2Step.renounceOwnership({ from: owner }); - // If renounceOwnership is removed from parent an alternative is needed ... - // without it is difficult to cleanly renounce with the two step process - // see: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3620#discussion_r957930388 - expect(await this.ownable2Step.owner()).to.equal(ZERO_ADDRESS); - }); - - it('pending owner resets after renouncing ownership', async function () { - await this.ownable2Step.transferOwnership(accountA, { from: owner }); - expect(await this.ownable2Step.pendingOwner()).to.equal(accountA); - await this.ownable2Step.renounceOwnership({ from: owner }); - expect(await this.ownable2Step.pendingOwner()).to.equal(ZERO_ADDRESS); - await expectRevert( - this.ownable2Step.acceptOwnership({ from: accountA }), - 'Ownable2Step: caller is not the new owner', - ); - }); - - it('guards transfer against invalid user', async function () { - await this.ownable2Step.transferOwnership(accountA, { from: owner }); - await expectRevert( - this.ownable2Step.acceptOwnership({ from: accountB }), - 'Ownable2Step: caller is not the new owner', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/crosschain/CrossChainEnabled.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/crosschain/CrossChainEnabled.test.js deleted file mode 100644 index bff9558..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/crosschain/CrossChainEnabled.test.js +++ /dev/null @@ -1,88 +0,0 @@ -const { BridgeHelper } = require('../helpers/crosschain'); -const { expectRevertCustomError } = require('../helpers/customError'); - -function randomAddress () { - return web3.utils.toChecksumAddress(web3.utils.randomHex(20)); -} - -const CrossChainEnabledAMBMock = artifacts.require('CrossChainEnabledAMBMock'); -const CrossChainEnabledArbitrumL1Mock = artifacts.require('CrossChainEnabledArbitrumL1Mock'); -const CrossChainEnabledArbitrumL2Mock = artifacts.require('CrossChainEnabledArbitrumL2Mock'); -const CrossChainEnabledOptimismMock = artifacts.require('CrossChainEnabledOptimismMock'); -const CrossChainEnabledPolygonChildMock = artifacts.require('CrossChainEnabledPolygonChildMock'); - -function shouldBehaveLikeReceiver (sender = randomAddress()) { - it('should reject same-chain calls', async function () { - await expectRevertCustomError( - this.receiver.crossChainRestricted(), - 'NotCrossChainCall()', - ); - - await expectRevertCustomError( - this.receiver.crossChainOwnerRestricted(), - 'NotCrossChainCall()', - ); - }); - - it('should restrict to cross-chain call from a invalid sender', async function () { - await expectRevertCustomError( - this.bridge.call(sender, this.receiver, 'crossChainOwnerRestricted()'), - `InvalidCrossChainSender("${sender}", "${await this.receiver.owner()}")`, - ); - }); - - it('should grant access to cross-chain call from the owner', async function () { - await this.bridge.call( - await this.receiver.owner(), - this.receiver, - 'crossChainOwnerRestricted()', - ); - }); -} - -contract('CrossChainEnabled', function () { - describe('AMB', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('AMB'); - this.receiver = await CrossChainEnabledAMBMock.new(this.bridge.address); - }); - - shouldBehaveLikeReceiver(); - }); - - describe('Arbitrum-L1', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('Arbitrum-L1'); - this.receiver = await CrossChainEnabledArbitrumL1Mock.new(this.bridge.address); - }); - - shouldBehaveLikeReceiver(); - }); - - describe('Arbitrum-L2', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('Arbitrum-L2'); - this.receiver = await CrossChainEnabledArbitrumL2Mock.new(); - }); - - shouldBehaveLikeReceiver(); - }); - - describe('Optimism', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('Optimism'); - this.receiver = await CrossChainEnabledOptimismMock.new(this.bridge.address); - }); - - shouldBehaveLikeReceiver(); - }); - - describe('Polygon-Child', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('Polygon-Child'); - this.receiver = await CrossChainEnabledPolygonChildMock.new(this.bridge.address); - }); - - shouldBehaveLikeReceiver(); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/PaymentSplitter.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/PaymentSplitter.test.js deleted file mode 100644 index 2fa7a26..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/PaymentSplitter.test.js +++ /dev/null @@ -1,217 +0,0 @@ -const { balance, constants, ether, expectEvent, send, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const PaymentSplitter = artifacts.require('PaymentSplitter'); -const Token = artifacts.require('ERC20Mock'); - -contract('PaymentSplitter', function (accounts) { - const [ owner, payee1, payee2, payee3, nonpayee1, payer1 ] = accounts; - - const amount = ether('1'); - - it('rejects an empty set of payees', async function () { - await expectRevert(PaymentSplitter.new([], []), 'PaymentSplitter: no payees'); - }); - - it('rejects more payees than shares', async function () { - await expectRevert(PaymentSplitter.new([payee1, payee2, payee3], [20, 30]), - 'PaymentSplitter: payees and shares length mismatch', - ); - }); - - it('rejects more shares than payees', async function () { - await expectRevert(PaymentSplitter.new([payee1, payee2], [20, 30, 40]), - 'PaymentSplitter: payees and shares length mismatch', - ); - }); - - it('rejects null payees', async function () { - await expectRevert(PaymentSplitter.new([payee1, ZERO_ADDRESS], [20, 30]), - 'PaymentSplitter: account is the zero address', - ); - }); - - it('rejects zero-valued shares', async function () { - await expectRevert(PaymentSplitter.new([payee1, payee2], [20, 0]), - 'PaymentSplitter: shares are 0', - ); - }); - - it('rejects repeated payees', async function () { - await expectRevert(PaymentSplitter.new([payee1, payee1], [20, 30]), - 'PaymentSplitter: account already has shares', - ); - }); - - context('once deployed', function () { - beforeEach(async function () { - this.payees = [payee1, payee2, payee3]; - this.shares = [20, 10, 70]; - - this.contract = await PaymentSplitter.new(this.payees, this.shares); - this.token = await Token.new('MyToken', 'MT', owner, ether('1000')); - }); - - it('has total shares', async function () { - expect(await this.contract.totalShares()).to.be.bignumber.equal('100'); - }); - - it('has payees', async function () { - await Promise.all(this.payees.map(async (payee, index) => { - expect(await this.contract.payee(index)).to.equal(payee); - expect(await this.contract.released(payee)).to.be.bignumber.equal('0'); - expect(await this.contract.releasable(payee)).to.be.bignumber.equal('0'); - })); - }); - - describe('accepts payments', function () { - it('Ether', async function () { - await send.ether(owner, this.contract.address, amount); - - expect(await balance.current(this.contract.address)).to.be.bignumber.equal(amount); - }); - - it('Token', async function () { - await this.token.transfer(this.contract.address, amount, { from: owner }); - - expect(await this.token.balanceOf(this.contract.address)).to.be.bignumber.equal(amount); - }); - }); - - describe('shares', function () { - it('stores shares if address is payee', async function () { - expect(await this.contract.shares(payee1)).to.be.bignumber.not.equal('0'); - }); - - it('does not store shares if address is not payee', async function () { - expect(await this.contract.shares(nonpayee1)).to.be.bignumber.equal('0'); - }); - }); - - describe('release', function () { - describe('Ether', function () { - it('reverts if no funds to claim', async function () { - await expectRevert(this.contract.release(payee1), - 'PaymentSplitter: account is not due payment', - ); - }); - it('reverts if non-payee want to claim', async function () { - await send.ether(payer1, this.contract.address, amount); - await expectRevert(this.contract.release(nonpayee1), - 'PaymentSplitter: account has no shares', - ); - }); - }); - - describe('Token', function () { - it('reverts if no funds to claim', async function () { - await expectRevert(this.contract.release(this.token.address, payee1), - 'PaymentSplitter: account is not due payment', - ); - }); - it('reverts if non-payee want to claim', async function () { - await this.token.transfer(this.contract.address, amount, { from: owner }); - await expectRevert(this.contract.release(this.token.address, nonpayee1), - 'PaymentSplitter: account has no shares', - ); - }); - }); - }); - - describe('tracks releasable and released', function () { - it('Ether', async function () { - await send.ether(payer1, this.contract.address, amount); - const payment = amount.divn(10); - expect(await this.contract.releasable(payee2)).to.be.bignumber.equal(payment); - await this.contract.release(payee2); - expect(await this.contract.releasable(payee2)).to.be.bignumber.equal('0'); - expect(await this.contract.released(payee2)).to.be.bignumber.equal(payment); - }); - - it('Token', async function () { - await this.token.transfer(this.contract.address, amount, { from: owner }); - const payment = amount.divn(10); - expect(await this.contract.releasable(this.token.address, payee2, {})).to.be.bignumber.equal(payment); - await this.contract.release(this.token.address, payee2); - expect(await this.contract.releasable(this.token.address, payee2, {})).to.be.bignumber.equal('0'); - expect(await this.contract.released(this.token.address, payee2)).to.be.bignumber.equal(payment); - }); - }); - - describe('distributes funds to payees', function () { - it('Ether', async function () { - await send.ether(payer1, this.contract.address, amount); - - // receive funds - const initBalance = await balance.current(this.contract.address); - expect(initBalance).to.be.bignumber.equal(amount); - - // distribute to payees - - const tracker1 = await balance.tracker(payee1); - const receipt1 = await this.contract.release(payee1); - const profit1 = await tracker1.delta(); - expect(profit1).to.be.bignumber.equal(ether('0.20')); - expectEvent(receipt1, 'PaymentReleased', { to: payee1, amount: profit1 }); - - const tracker2 = await balance.tracker(payee2); - const receipt2 = await this.contract.release(payee2); - const profit2 = await tracker2.delta(); - expect(profit2).to.be.bignumber.equal(ether('0.10')); - expectEvent(receipt2, 'PaymentReleased', { to: payee2, amount: profit2 }); - - const tracker3 = await balance.tracker(payee3); - const receipt3 = await this.contract.release(payee3); - const profit3 = await tracker3.delta(); - expect(profit3).to.be.bignumber.equal(ether('0.70')); - expectEvent(receipt3, 'PaymentReleased', { to: payee3, amount: profit3 }); - - // end balance should be zero - expect(await balance.current(this.contract.address)).to.be.bignumber.equal('0'); - - // check correct funds released accounting - expect(await this.contract.totalReleased()).to.be.bignumber.equal(initBalance); - }); - - it('Token', async function () { - expect(await this.token.balanceOf(payee1)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOf(payee2)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOf(payee3)).to.be.bignumber.equal('0'); - - await this.token.transfer(this.contract.address, amount, { from: owner }); - - expectEvent( - await this.contract.release(this.token.address, payee1), - 'ERC20PaymentReleased', - { token: this.token.address, to: payee1, amount: ether('0.20') }, - ); - - await this.token.transfer(this.contract.address, amount, { from: owner }); - - expectEvent( - await this.contract.release(this.token.address, payee1), - 'ERC20PaymentReleased', - { token: this.token.address, to: payee1, amount: ether('0.20') }, - ); - - expectEvent( - await this.contract.release(this.token.address, payee2), - 'ERC20PaymentReleased', - { token: this.token.address, to: payee2, amount: ether('0.20') }, - ); - - expectEvent( - await this.contract.release(this.token.address, payee3), - 'ERC20PaymentReleased', - { token: this.token.address, to: payee3, amount: ether('1.40') }, - ); - - expect(await this.token.balanceOf(payee1)).to.be.bignumber.equal(ether('0.40')); - expect(await this.token.balanceOf(payee2)).to.be.bignumber.equal(ether('0.20')); - expect(await this.token.balanceOf(payee3)).to.be.bignumber.equal(ether('1.40')); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/VestingWallet.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/VestingWallet.behavior.js deleted file mode 100644 index d1d2fbf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/VestingWallet.behavior.js +++ /dev/null @@ -1,74 +0,0 @@ -const { time } = require('@nomicfoundation/hardhat-network-helpers'); -const { expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -function releasedEvent (token, amount) { - return token - ? [ 'ERC20Released', { token: token.address, amount } ] - : [ 'EtherReleased', { amount } ]; -} - -function shouldBehaveLikeVesting (beneficiary) { - it('check vesting schedule', async function () { - const [ fnVestedAmount, fnReleasable, ...args ] = this.token - ? [ 'vestedAmount(address,uint64)', 'releasable(address)', this.token.address ] - : [ 'vestedAmount(uint64)', 'releasable()' ]; - - for (const timestamp of this.schedule) { - await time.increaseTo(timestamp); - const vesting = this.vestingFn(timestamp); - - expect(await this.mock.methods[fnVestedAmount](...args, timestamp)) - .to.be.bignumber.equal(vesting); - - expect(await this.mock.methods[fnReleasable](...args)) - .to.be.bignumber.equal(vesting); - } - }); - - it('execute vesting schedule', async function () { - const [ fnRelease, ...args ] = this.token - ? [ 'release(address)', this.token.address ] - : [ 'release()' ]; - - let released = web3.utils.toBN(0); - const before = await this.getBalance(beneficiary); - - { - const receipt = await this.mock.methods[fnRelease](...args); - - await expectEvent.inTransaction( - receipt.tx, - this.mock, - ...releasedEvent(this.token, '0'), - ); - - await this.checkRelease(receipt, beneficiary, '0'); - - expect(await this.getBalance(beneficiary)).to.be.bignumber.equal(before); - } - - for (const timestamp of this.schedule) { - await time.setNextBlockTimestamp(timestamp); - const vested = this.vestingFn(timestamp); - - const receipt = await this.mock.methods[fnRelease](...args); - await expectEvent.inTransaction( - receipt.tx, - this.mock, - ...releasedEvent(this.token, vested.sub(released)), - ); - - await this.checkRelease(receipt, beneficiary, vested.sub(released)); - - expect(await this.getBalance(beneficiary)) - .to.be.bignumber.equal(before.add(vested)); - - released = vested; - } - }); -} - -module.exports = { - shouldBehaveLikeVesting, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/VestingWallet.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/VestingWallet.test.js deleted file mode 100644 index 6aa7378..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/finance/VestingWallet.test.js +++ /dev/null @@ -1,67 +0,0 @@ -const { constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { web3 } = require('@openzeppelin/test-helpers/src/setup'); -const { expect } = require('chai'); - -const ERC20Mock = artifacts.require('ERC20Mock'); -const VestingWallet = artifacts.require('VestingWallet'); - -const { shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); - -const min = (...args) => args.slice(1).reduce((x, y) => x.lt(y) ? x : y, args[0]); - -contract('VestingWallet', function (accounts) { - const [ sender, beneficiary ] = accounts; - - const amount = web3.utils.toBN(web3.utils.toWei('100')); - const duration = web3.utils.toBN(4 * 365 * 86400); // 4 years - - beforeEach(async function () { - this.start = (await time.latest()).addn(3600); // in 1 hour - this.mock = await VestingWallet.new(beneficiary, this.start, duration); - }); - - it('rejects zero address for beneficiary', async function () { - await expectRevert( - VestingWallet.new(constants.ZERO_ADDRESS, this.start, duration), - 'VestingWallet: beneficiary is zero address', - ); - }); - - it('check vesting contract', async function () { - expect(await this.mock.beneficiary()).to.be.equal(beneficiary); - expect(await this.mock.start()).to.be.bignumber.equal(this.start); - expect(await this.mock.duration()).to.be.bignumber.equal(duration); - }); - - describe('vesting schedule', function () { - beforeEach(async function () { - this.schedule = Array(64).fill().map((_, i) => web3.utils.toBN(i).mul(duration).divn(60).add(this.start)); - this.vestingFn = timestamp => min(amount, amount.mul(timestamp.sub(this.start)).div(duration)); - }); - - describe('Eth vesting', function () { - beforeEach(async function () { - await web3.eth.sendTransaction({ from: sender, to: this.mock.address, value: amount }); - this.getBalance = account => web3.eth.getBalance(account).then(web3.utils.toBN); - this.checkRelease = () => {}; - }); - - shouldBehaveLikeVesting(beneficiary); - }); - - describe('ERC20 vesting', function () { - beforeEach(async function () { - this.token = await ERC20Mock.new('Name', 'Symbol', this.mock.address, amount); - this.getBalance = (account) => this.token.balanceOf(account); - this.checkRelease = (receipt, to, value) => expectEvent.inTransaction( - receipt.tx, - this.token, - 'Transfer', - { from: this.mock.address, to, value }, - ); - }); - - shouldBehaveLikeVesting(beneficiary); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/Governor.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/Governor.test.js deleted file mode 100644 index bd10dcd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/Governor.test.js +++ /dev/null @@ -1,632 +0,0 @@ -const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; -const { fromRpcSig } = require('ethereumjs-util'); -const Enums = require('../helpers/enums'); -const { EIP712Domain } = require('../helpers/eip712'); -const { GovernorHelper } = require('../helpers/governance'); - -const { - shouldSupportInterfaces, -} = require('../utils/introspection/SupportsInterface.behavior'); - -const Token = artifacts.require('ERC20VotesMock'); -const Governor = artifacts.require('GovernorMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); -const ERC721Mock = artifacts.require('ERC721Mock'); -const ERC1155Mock = artifacts.require('ERC1155Mock'); - -contract('Governor', function (accounts) { - const [ owner, proposer, voter1, voter2, voter3, voter4 ] = accounts; - const empty = web3.utils.toChecksumAddress(web3.utils.randomHex(20)); - - const name = 'OZ-Governor'; - const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.chainId = await web3.eth.getChainId(); - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address, votingDelay, votingPeriod, 10); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - value, - }, - ], ''); - }); - - shouldSupportInterfaces([ - 'ERC165', - 'ERC1155Receiver', - 'Governor', - 'GovernorWithParams', - ]); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - expect(await this.mock.COUNTING_MODE()).to.be.equal('support=bravo&quorum=for,abstain'); - }); - - it('nominal workflow', async function () { - // Before - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(false); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(value); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal('0'); - - // Run proposal - const txPropose = await this.helper.propose({ from: proposer }); - - expectEvent( - txPropose, - 'ProposalCreated', - { - proposalId: this.proposal.id, - proposer, - targets: this.proposal.targets, - // values: this.proposal.values, - signatures: this.proposal.signatures, - calldatas: this.proposal.data, - startBlock: new BN(txPropose.receipt.blockNumber).add(votingDelay), - endBlock: new BN(txPropose.receipt.blockNumber).add(votingDelay).add(votingPeriod), - description: this.proposal.description, - }, - ); - - await this.helper.waitForSnapshot(); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For, reason: 'This is nice' }, { from: voter1 }), - 'VoteCast', - { - voter: voter1, - support: Enums.VoteType.For, - reason: 'This is nice', - weight: web3.utils.toWei('10'), - }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }), - 'VoteCast', - { - voter: voter2, - support: Enums.VoteType.For, - weight: web3.utils.toWei('7'), - }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }), - 'VoteCast', - { - voter: voter3, - support: Enums.VoteType.Against, - weight: web3.utils.toWei('5'), - }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }), - 'VoteCast', - { - voter: voter4, - support: Enums.VoteType.Abstain, - weight: web3.utils.toWei('2'), - }, - ); - - await this.helper.waitForDeadline(); - - const txExecute = await this.helper.execute(); - - expectEvent( - txExecute, - 'ProposalExecuted', - { proposalId: this.proposal.id }, - ); - - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalled', - ); - - // After - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal(value); - }); - - it('vote with signature', async function () { - const voterBySig = Wallet.generate(); - const voterBySigAddress = web3.utils.toChecksumAddress(voterBySig.getAddressString()); - - const signature = async (message) => { - return fromRpcSig(ethSigUtil.signTypedMessage( - voterBySig.getPrivateKey(), - { - data: { - types: { - EIP712Domain, - Ballot: [ - { name: 'proposalId', type: 'uint256' }, - { name: 'support', type: 'uint8' }, - ], - }, - domain: { name, version, chainId: this.chainId, verifyingContract: this.mock.address }, - primaryType: 'Ballot', - message, - }, - }, - )); - }; - - await this.token.delegate(voterBySigAddress, { from: voter1 }); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For, signature }), - 'VoteCast', - { voter: voterBySigAddress, support: Enums.VoteType.For }, - ); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - // After - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voterBySigAddress)).to.be.equal(true); - }); - - it('send ethers', async function () { - this.proposal = this.helper.setProposal([ - { - target: empty, - value, - }, - ], ''); - - // Before - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(value); - expect(await web3.eth.getBalance(empty)).to.be.bignumber.equal('0'); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - // After - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(empty)).to.be.bignumber.equal(value); - }); - - describe('should revert', function () { - describe('on propose', function () { - it('if proposal already exists', async function () { - await this.helper.propose(); - await expectRevert(this.helper.propose(), 'Governor: proposal already exists'); - }); - }); - - describe('on vote', function () { - it('if proposal does not exist', async function () { - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'Governor: unknown proposal id', - ); - }); - - it('if voting has not started', async function () { - await this.helper.propose(); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'Governor: vote not currently active', - ); - }); - - it('if support value is invalid', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await expectRevert( - this.helper.vote({ support: new BN('255') }), - 'GovernorVotingSimple: invalid value for enum VoteType', - ); - }); - - it('if vote was already casted', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'GovernorVotingSimple: vote already cast', - ); - }); - - it('if voting is over', async function () { - await this.helper.propose(); - await this.helper.waitForDeadline(); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'Governor: vote not currently active', - ); - }); - }); - - describe('on execute', function () { - it('if proposal does not exist', async function () { - await expectRevert(this.helper.execute(), 'Governor: unknown proposal id'); - }); - - it('if quorum is not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter3 }); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('if score not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter1 }); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('if voting is not over', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('if receiver revert without reason', async function () { - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - data: this.receiver.contract.methods.mockFunctionRevertsNoReason().encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await expectRevert(this.helper.execute(), 'Governor: call reverted without message'); - }); - - it('if receiver revert with reason', async function () { - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - data: this.receiver.contract.methods.mockFunctionRevertsReason().encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await expectRevert(this.helper.execute(), 'CallReceiverMock: reverting'); - }); - - it('if proposal was already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - }); - }); - - describe('state', function () { - it('Unset', async function () { - await expectRevert(this.mock.state(this.proposal.id), 'Governor: unknown proposal id'); - }); - - it('Pending & Active', async function () { - await this.helper.propose(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Pending); - await this.helper.waitForSnapshot(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Pending); - await this.helper.waitForSnapshot(+1); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - }); - - it('Defeated', async function () { - await this.helper.propose(); - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - await this.helper.waitForDeadline(+1); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Defeated); - }); - - it('Succeeded', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - await this.helper.waitForDeadline(+1); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Succeeded); - }); - - it('Executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Executed); - }); - }); - - describe('cancel', function () { - it('before proposal', async function () { - await expectRevert(this.helper.cancel(), 'Governor: unknown proposal id'); - }); - - it('after proposal', async function () { - await this.helper.propose(); - - await this.helper.cancel(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - - await this.helper.waitForSnapshot(); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'Governor: vote not currently active', - ); - }); - - it('after vote', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - - await this.helper.cancel(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - - await this.helper.waitForDeadline(); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('after deadline', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - await this.helper.cancel(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('after execution', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - await expectRevert(this.helper.cancel(), 'Governor: proposal not active'); - }); - }); - - describe('proposal length', function () { - it('empty', async function () { - this.helper.setProposal([ ], ''); - await expectRevert(this.helper.propose(), 'Governor: empty proposal'); - }); - - it('missmatch #1', async function () { - this.helper.setProposal({ - targets: [ ], - values: [ web3.utils.toWei('0') ], - data: [ this.receiver.contract.methods.mockFunction().encodeABI() ], - }, ''); - await expectRevert(this.helper.propose(), 'Governor: invalid proposal length'); - }); - - it('missmatch #2', async function () { - this.helper.setProposal({ - targets: [ this.receiver.address ], - values: [ ], - data: [ this.receiver.contract.methods.mockFunction().encodeABI() ], - }, ''); - await expectRevert(this.helper.propose(), 'Governor: invalid proposal length'); - }); - - it('missmatch #3', async function () { - this.helper.setProposal({ - targets: [ this.receiver.address ], - values: [ web3.utils.toWei('0') ], - data: [ ], - }, ''); - await expectRevert(this.helper.propose(), 'Governor: invalid proposal length'); - }); - }); - - describe('onlyGovernance updates', function () { - it('setVotingDelay is protected', async function () { - await expectRevert(this.mock.setVotingDelay('0'), 'Governor: onlyGovernance'); - }); - - it('setVotingPeriod is protected', async function () { - await expectRevert(this.mock.setVotingPeriod('32'), 'Governor: onlyGovernance'); - }); - - it('setProposalThreshold is protected', async function () { - await expectRevert(this.mock.setProposalThreshold('1000000000000000000'), 'Governor: onlyGovernance'); - }); - - it('can setVotingDelay through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setVotingDelay('0').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'VotingDelaySet', - { oldVotingDelay: '4', newVotingDelay: '0' }, - ); - - expect(await this.mock.votingDelay()).to.be.bignumber.equal('0'); - }); - - it('can setVotingPeriod through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setVotingPeriod('32').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'VotingPeriodSet', - { oldVotingPeriod: '16', newVotingPeriod: '32' }, - ); - - expect(await this.mock.votingPeriod()).to.be.bignumber.equal('32'); - }); - - it('cannot setVotingPeriod to 0 through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setVotingPeriod('0').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - await expectRevert(this.helper.execute(), 'GovernorSettings: voting period too low'); - }); - - it('can setProposalThreshold to 0 through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setProposalThreshold('1000000000000000000').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'ProposalThresholdSet', - { oldProposalThreshold: '0', newProposalThreshold: '1000000000000000000' }, - ); - - expect(await this.mock.proposalThreshold()).to.be.bignumber.equal('1000000000000000000'); - }); - }); - - describe('safe receive', function () { - describe('ERC721', function () { - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - const tokenId = new BN(1); - - beforeEach(async function () { - this.token = await ERC721Mock.new(name, symbol); - await this.token.mint(owner, tokenId); - }); - - it('can receive an ERC721 safeTransfer', async function () { - await this.token.safeTransferFrom(owner, this.mock.address, tokenId, { from: owner }); - }); - }); - - describe('ERC1155', function () { - const uri = 'https://token-cdn-domain/{id}.json'; - const tokenIds = { - 1: new BN(1000), - 2: new BN(2000), - 3: new BN(3000), - }; - - beforeEach(async function () { - this.token = await ERC1155Mock.new(uri); - await this.token.mintBatch(owner, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - - it('can receive ERC1155 safeTransfer', async function () { - await this.token.safeTransferFrom( - owner, - this.mock.address, - ...Object.entries(tokenIds)[0], // id + amount - '0x', - { from: owner }, - ); - }); - - it('can receive ERC1155 safeBatchTransfer', async function () { - await this.token.safeBatchTransferFrom( - owner, - this.mock.address, - Object.keys(tokenIds), - Object.values(tokenIds), - '0x', - { from: owner }, - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/TimelockController.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/TimelockController.test.js deleted file mode 100644 index e0a3244..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/TimelockController.test.js +++ /dev/null @@ -1,1134 +0,0 @@ -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const { expect } = require('chai'); - -const { - shouldSupportInterfaces, -} = require('../utils/introspection/SupportsInterface.behavior'); - -const TimelockController = artifacts.require('TimelockController'); -const CallReceiverMock = artifacts.require('CallReceiverMock'); -const Implementation2 = artifacts.require('Implementation2'); -const ERC721Mock = artifacts.require('ERC721Mock'); -const ERC1155Mock = artifacts.require('ERC1155Mock'); - -const MINDELAY = time.duration.days(1); - -const salt = '0x025e7b0be353a74631ad648c667493c0e1cd31caa4cc2d3520fdc171ea0cc726'; // a random value - -function genOperation (target, value, data, predecessor, salt) { - const id = web3.utils.keccak256(web3.eth.abi.encodeParameters([ - 'address', - 'uint256', - 'bytes', - 'uint256', - 'bytes32', - ], [ - target, - value, - data, - predecessor, - salt, - ])); - return { id, target, value, data, predecessor, salt }; -} - -function genOperationBatch (targets, values, payloads, predecessor, salt) { - const id = web3.utils.keccak256(web3.eth.abi.encodeParameters([ - 'address[]', - 'uint256[]', - 'bytes[]', - 'uint256', - 'bytes32', - ], [ - targets, - values, - payloads, - predecessor, - salt, - ])); - return { id, targets, values, payloads, predecessor, salt }; -} - -contract('TimelockController', function (accounts) { - const [ , admin, proposer, canceller, executor, other ] = accounts; - - const TIMELOCK_ADMIN_ROLE = web3.utils.soliditySha3('TIMELOCK_ADMIN_ROLE'); - const PROPOSER_ROLE = web3.utils.soliditySha3('PROPOSER_ROLE'); - const EXECUTOR_ROLE = web3.utils.soliditySha3('EXECUTOR_ROLE'); - const CANCELLER_ROLE = web3.utils.soliditySha3('CANCELLER_ROLE'); - - beforeEach(async function () { - // Deploy new timelock - this.mock = await TimelockController.new( - MINDELAY, - [ proposer ], - [ executor ], - admin, - ); - - expect(await this.mock.hasRole(CANCELLER_ROLE, proposer)).to.be.equal(true); - await this.mock.revokeRole(CANCELLER_ROLE, proposer, { from: admin }); - await this.mock.grantRole(CANCELLER_ROLE, canceller, { from: admin }); - - // Mocks - this.callreceivermock = await CallReceiverMock.new({ from: admin }); - this.implementation2 = await Implementation2.new({ from: admin }); - }); - - shouldSupportInterfaces([ - 'ERC1155Receiver', - ]); - - it('initial state', async function () { - expect(await this.mock.getMinDelay()).to.be.bignumber.equal(MINDELAY); - - expect(await this.mock.TIMELOCK_ADMIN_ROLE()).to.be.equal(TIMELOCK_ADMIN_ROLE); - expect(await this.mock.PROPOSER_ROLE()).to.be.equal(PROPOSER_ROLE); - expect(await this.mock.EXECUTOR_ROLE()).to.be.equal(EXECUTOR_ROLE); - expect(await this.mock.CANCELLER_ROLE()).to.be.equal(CANCELLER_ROLE); - - expect(await Promise.all([ PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE ].map(role => - this.mock.hasRole(role, proposer), - ))).to.be.deep.equal([ true, false, false ]); - - expect(await Promise.all([ PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE ].map(role => - this.mock.hasRole(role, canceller), - ))).to.be.deep.equal([ false, true, false ]); - - expect(await Promise.all([ PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE ].map(role => - this.mock.hasRole(role, executor), - ))).to.be.deep.equal([ false, false, true ]); - }); - - it('optional admin', async function () { - const mock = await TimelockController.new( - MINDELAY, - [ proposer ], - [ executor ], - ZERO_ADDRESS, - { from: other }, - ); - - expect(await mock.hasRole(TIMELOCK_ADMIN_ROLE, admin)).to.be.equal(false); - expect(await mock.hasRole(TIMELOCK_ADMIN_ROLE, other)).to.be.equal(false); - }); - - describe('methods', function () { - describe('operation hashing', function () { - it('hashOperation', async function () { - this.operation = genOperation( - '0x29cebefe301c6ce1bb36b58654fea275e1cacc83', - '0xf94fdd6e21da21d2', - '0xa3bc5104', - '0xba41db3be0a9929145cfe480bd0f1f003689104d275ae912099f925df424ef94', - '0x60d9109846ab510ed75c15f979ae366a8a2ace11d34ba9788c13ac296db50e6e', - ); - expect(await this.mock.hashOperation( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - )).to.be.equal(this.operation.id); - }); - - it('hashOperationBatch', async function () { - this.operation = genOperationBatch( - Array(8).fill('0x2d5f21620e56531c1d59c2df9b8e95d129571f71'), - Array(8).fill('0x2b993cfce932ccee'), - Array(8).fill('0xcf51966b'), - '0xce8f45069cc71d25f71ba05062de1a3974f9849b004de64a70998bca9d29c2e7', - '0x8952d74c110f72bfe5accdf828c74d53a7dfb71235dfa8a1e8c75d8576b372ff', - ); - expect(await this.mock.hashOperationBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - )).to.be.equal(this.operation.id); - }); - }); - describe('simple', function () { - describe('schedule', function () { - beforeEach(async function () { - this.operation = genOperation( - '0x31754f590B97fD975Eb86938f18Cc304E264D2F2', - 0, - '0x3bf92ccc', - ZERO_BYTES32, - salt, - ); - }); - - it('proposer can schedule', async function () { - const receipt = await this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ); - expectEvent(receipt, 'CallScheduled', { - id: this.operation.id, - index: web3.utils.toBN(0), - target: this.operation.target, - value: web3.utils.toBN(this.operation.value), - data: this.operation.data, - predecessor: this.operation.predecessor, - delay: MINDELAY, - }); - - const block = await web3.eth.getBlock(receipt.receipt.blockHash); - - expect(await this.mock.getTimestamp(this.operation.id)) - .to.be.bignumber.equal(web3.utils.toBN(block.timestamp).add(MINDELAY)); - }); - - it('prevent overwriting active operation', async function () { - await this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ); - - await expectRevert( - this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ), - 'TimelockController: operation already scheduled', - ); - }); - - it('prevent non-proposer from committing', async function () { - await expectRevert( - this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: other }, - ), - `AccessControl: account ${other.toLowerCase()} is missing role ${PROPOSER_ROLE}`, - ); - }); - - it('enforce minimum delay', async function () { - await expectRevert( - this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY - 1, - { from: proposer }, - ), - 'TimelockController: insufficient delay', - ); - }); - }); - - describe('execute', function () { - beforeEach(async function () { - this.operation = genOperation( - '0xAe22104DCD970750610E6FE15E623468A98b15f7', - 0, - '0x13e414de', - ZERO_BYTES32, - '0xc1059ed2dc130227aa1d1d539ac94c641306905c020436c636e19e3fab56fc7f', - ); - }); - - it('revert if operation is not scheduled', async function () { - await expectRevert( - this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - describe('with scheduled operation', function () { - beforeEach(async function () { - ({ receipt: this.receipt, logs: this.logs } = await this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - )); - }); - - it('revert if execution comes too early 1/2', async function () { - await expectRevert( - this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - it('revert if execution comes too early 2/2', async function () { - const timestamp = await this.mock.getTimestamp(this.operation.id); - await time.increaseTo(timestamp - 5); // -1 is too tight, test sometime fails - - await expectRevert( - this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - describe('on time', function () { - beforeEach(async function () { - const timestamp = await this.mock.getTimestamp(this.operation.id); - await time.increaseTo(timestamp); - }); - - it('executor can reveal', async function () { - const receipt = await this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ); - expectEvent(receipt, 'CallExecuted', { - id: this.operation.id, - index: web3.utils.toBN(0), - target: this.operation.target, - value: web3.utils.toBN(this.operation.value), - data: this.operation.data, - }); - }); - - it('prevent non-executor from revealing', async function () { - await expectRevert( - this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: other }, - ), - `AccessControl: account ${other.toLowerCase()} is missing role ${EXECUTOR_ROLE}`, - ); - }); - }); - }); - }); - }); - - describe('batch', function () { - describe('schedule', function () { - beforeEach(async function () { - this.operation = genOperationBatch( - Array(8).fill('0xEd912250835c812D4516BBD80BdaEA1bB63a293C'), - Array(8).fill(0), - Array(8).fill('0x2fcb7a88'), - ZERO_BYTES32, - '0x6cf9d042ade5de78bed9ffd075eb4b2a4f6b1736932c2dc8af517d6e066f51f5', - ); - }); - - it('proposer can schedule', async function () { - const receipt = await this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ); - for (const i in this.operation.targets) { - expectEvent(receipt, 'CallScheduled', { - id: this.operation.id, - index: web3.utils.toBN(i), - target: this.operation.targets[i], - value: web3.utils.toBN(this.operation.values[i]), - data: this.operation.payloads[i], - predecessor: this.operation.predecessor, - delay: MINDELAY, - }); - } - - const block = await web3.eth.getBlock(receipt.receipt.blockHash); - - expect(await this.mock.getTimestamp(this.operation.id)) - .to.be.bignumber.equal(web3.utils.toBN(block.timestamp).add(MINDELAY)); - }); - - it('prevent overwriting active operation', async function () { - await this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ); - - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ), - 'TimelockController: operation already scheduled', - ); - }); - - it('length of batch parameter must match #1', async function () { - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - [], - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ), - 'TimelockController: length mismatch', - ); - }); - - it('length of batch parameter must match #1', async function () { - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - [], - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ), - 'TimelockController: length mismatch', - ); - }); - - it('prevent non-proposer from committing', async function () { - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: other }, - ), - `AccessControl: account ${other.toLowerCase()} is missing role ${PROPOSER_ROLE}`, - ); - }); - - it('enforce minimum delay', async function () { - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY - 1, - { from: proposer }, - ), - 'TimelockController: insufficient delay', - ); - }); - }); - - describe('execute', function () { - beforeEach(async function () { - this.operation = genOperationBatch( - Array(8).fill('0x76E53CcEb05131Ef5248553bEBDb8F70536830b1'), - Array(8).fill(0), - Array(8).fill('0x58a60f63'), - ZERO_BYTES32, - '0x9545eeabc7a7586689191f78a5532443698538e54211b5bd4d7dc0fc0102b5c7', - ); - }); - - it('revert if operation is not scheduled', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - describe('with scheduled operation', function () { - beforeEach(async function () { - ({ receipt: this.receipt, logs: this.logs } = await this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - )); - }); - - it('revert if execution comes too early 1/2', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - it('revert if execution comes too early 2/2', async function () { - const timestamp = await this.mock.getTimestamp(this.operation.id); - await time.increaseTo(timestamp - 5); // -1 is to tight, test sometime fails - - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - describe('on time', function () { - beforeEach(async function () { - const timestamp = await this.mock.getTimestamp(this.operation.id); - await time.increaseTo(timestamp); - }); - - it('executor can reveal', async function () { - const receipt = await this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ); - for (const i in this.operation.targets) { - expectEvent(receipt, 'CallExecuted', { - id: this.operation.id, - index: web3.utils.toBN(i), - target: this.operation.targets[i], - value: web3.utils.toBN(this.operation.values[i]), - data: this.operation.payloads[i], - }); - } - }); - - it('prevent non-executor from revealing', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: other }, - ), - `AccessControl: account ${other.toLowerCase()} is missing role ${EXECUTOR_ROLE}`, - ); - }); - - it('length mismatch #1', async function () { - await expectRevert( - this.mock.executeBatch( - [], - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: length mismatch', - ); - }); - - it('length mismatch #2', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - [], - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: length mismatch', - ); - }); - - it('length mismatch #3', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - [], - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: length mismatch', - ); - }); - }); - }); - - it('partial execution', async function () { - const operation = genOperationBatch( - [ - this.callreceivermock.address, - this.callreceivermock.address, - this.callreceivermock.address, - ], - [ - 0, - 0, - 0, - ], - [ - this.callreceivermock.contract.methods.mockFunction().encodeABI(), - this.callreceivermock.contract.methods.mockFunctionThrows().encodeABI(), - this.callreceivermock.contract.methods.mockFunction().encodeABI(), - ], - ZERO_BYTES32, - '0x8ac04aa0d6d66b8812fb41d39638d37af0a9ab11da507afd65c509f8ed079d3e', - ); - - await this.mock.scheduleBatch( - operation.targets, - operation.values, - operation.payloads, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await expectRevert( - this.mock.executeBatch( - operation.targets, - operation.values, - operation.payloads, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - }); - }); - - describe('cancel', function () { - beforeEach(async function () { - this.operation = genOperation( - '0xC6837c44AA376dbe1d2709F13879E040CAb653ca', - 0, - '0x296e58dd', - ZERO_BYTES32, - '0xa2485763600634800df9fc9646fb2c112cf98649c55f63dd1d9c7d13a64399d9', - ); - ({ receipt: this.receipt, logs: this.logs } = await this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - )); - }); - - it('canceller can cancel', async function () { - const receipt = await this.mock.cancel(this.operation.id, { from: canceller }); - expectEvent(receipt, 'Cancelled', { id: this.operation.id }); - }); - - it('cannot cancel invalid operation', async function () { - await expectRevert( - this.mock.cancel(constants.ZERO_BYTES32, { from: canceller }), - 'TimelockController: operation cannot be cancelled', - ); - }); - - it('prevent non-canceller from canceling', async function () { - await expectRevert( - this.mock.cancel(this.operation.id, { from: other }), - `AccessControl: account ${other.toLowerCase()} is missing role ${CANCELLER_ROLE}`, - ); - }); - }); - }); - - describe('maintenance', function () { - it('prevent unauthorized maintenance', async function () { - await expectRevert( - this.mock.updateDelay(0, { from: other }), - 'TimelockController: caller must be timelock', - ); - }); - - it('timelock scheduled maintenance', async function () { - const newDelay = time.duration.hours(6); - const operation = genOperation( - this.mock.address, - 0, - this.mock.contract.methods.updateDelay(newDelay.toString()).encodeABI(), - ZERO_BYTES32, - '0xf8e775b2c5f4d66fb5c7fa800f35ef518c262b6014b3c0aee6ea21bff157f108', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - const receipt = await this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ); - expectEvent(receipt, 'MinDelayChange', { newDuration: newDelay.toString(), oldDuration: MINDELAY }); - - expect(await this.mock.getMinDelay()).to.be.bignumber.equal(newDelay); - }); - }); - - describe('dependency', function () { - beforeEach(async function () { - this.operation1 = genOperation( - '0xdE66bD4c97304200A95aE0AadA32d6d01A867E39', - 0, - '0x01dc731a', - ZERO_BYTES32, - '0x64e932133c7677402ead2926f86205e2ca4686aebecf5a8077627092b9bb2feb', - ); - this.operation2 = genOperation( - '0x3c7944a3F1ee7fc8c5A5134ba7c79D11c3A1FCa3', - 0, - '0x8f531849', - this.operation1.id, - '0x036e1311cac523f9548e6461e29fb1f8f9196b91910a41711ea22f5de48df07d', - ); - await this.mock.schedule( - this.operation1.target, - this.operation1.value, - this.operation1.data, - this.operation1.predecessor, - this.operation1.salt, - MINDELAY, - { from: proposer }, - ); - await this.mock.schedule( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - }); - - it('cannot execute before dependency', async function () { - await expectRevert( - this.mock.execute( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - { from: executor }, - ), - 'TimelockController: missing dependency', - ); - }); - - it('can execute after dependency', async function () { - await this.mock.execute( - this.operation1.target, - this.operation1.value, - this.operation1.data, - this.operation1.predecessor, - this.operation1.salt, - { from: executor }, - ); - await this.mock.execute( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - { from: executor }, - ); - }); - }); - - describe('usage scenario', function () { - this.timeout(10000); - - it('call', async function () { - const operation = genOperation( - this.implementation2.address, - 0, - this.implementation2.contract.methods.setValue(42).encodeABI(), - ZERO_BYTES32, - '0x8043596363daefc89977b25f9d9b4d06c3910959ef0c4d213557a903e1b555e2', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ); - - expect(await this.implementation2.getValue()).to.be.bignumber.equal(web3.utils.toBN(42)); - }); - - it('call reverting', async function () { - const operation = genOperation( - this.callreceivermock.address, - 0, - this.callreceivermock.contract.methods.mockFunctionRevertsNoReason().encodeABI(), - ZERO_BYTES32, - '0xb1b1b276fdf1a28d1e00537ea73b04d56639128b08063c1a2f70a52e38cba693', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - - it('call throw', async function () { - const operation = genOperation( - this.callreceivermock.address, - 0, - this.callreceivermock.contract.methods.mockFunctionThrows().encodeABI(), - ZERO_BYTES32, - '0xe5ca79f295fc8327ee8a765fe19afb58f4a0cbc5053642bfdd7e73bc68e0fc67', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - - it('call out of gas', async function () { - const operation = genOperation( - this.callreceivermock.address, - 0, - this.callreceivermock.contract.methods.mockFunctionOutOfGas().encodeABI(), - ZERO_BYTES32, - '0xf3274ce7c394c5b629d5215723563a744b817e1730cca5587c567099a14578fd', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor, gas: '70000' }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - - it('call payable with eth', async function () { - const operation = genOperation( - this.callreceivermock.address, - 1, - this.callreceivermock.contract.methods.mockFunction().encodeABI(), - ZERO_BYTES32, - '0x5ab73cd33477dcd36c1e05e28362719d0ed59a7b9ff14939de63a43073dc1f44', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - - await this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor, value: 1 }, - ); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(1)); - }); - - it('call nonpayable with eth', async function () { - const operation = genOperation( - this.callreceivermock.address, - 1, - this.callreceivermock.contract.methods.mockFunctionNonPayable().encodeABI(), - ZERO_BYTES32, - '0xb78edbd920c7867f187e5aa6294ae5a656cfbf0dea1ccdca3751b740d0f2bdf8', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - }); - - it('call reverting with eth', async function () { - const operation = genOperation( - this.callreceivermock.address, - 1, - this.callreceivermock.contract.methods.mockFunctionRevertsNoReason().encodeABI(), - ZERO_BYTES32, - '0xdedb4563ef0095db01d81d3f2decf57cf83e4a72aa792af14c43a792b56f4de6', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - }); - }); - - describe('safe receive', function () { - describe('ERC721', function () { - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - const tokenId = new BN(1); - - beforeEach(async function () { - this.token = await ERC721Mock.new(name, symbol); - await this.token.mint(other, tokenId); - }); - - it('can receive an ERC721 safeTransfer', async function () { - await this.token.safeTransferFrom(other, this.mock.address, tokenId, { from: other }); - }); - }); - - describe('ERC1155', function () { - const uri = 'https://token-cdn-domain/{id}.json'; - const tokenIds = { - 1: new BN(1000), - 2: new BN(2000), - 3: new BN(3000), - }; - - beforeEach(async function () { - this.token = await ERC1155Mock.new(uri); - await this.token.mintBatch(other, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - - it('can receive ERC1155 safeTransfer', async function () { - await this.token.safeTransferFrom( - other, - this.mock.address, - ...Object.entries(tokenIds)[0], // id + amount - '0x', - { from: other }, - ); - }); - - it('can receive ERC1155 safeBatchTransfer', async function () { - await this.token.safeBatchTransferFrom( - other, - this.mock.address, - Object.keys(tokenIds), - Object.values(tokenIds), - '0x', - { from: other }, - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/compatibility/GovernorCompatibilityBravo.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/compatibility/GovernorCompatibilityBravo.test.js deleted file mode 100644 index 386a7e8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/compatibility/GovernorCompatibilityBravo.test.js +++ /dev/null @@ -1,280 +0,0 @@ -const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const RLP = require('rlp'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesCompMock'); -const Timelock = artifacts.require('CompTimelock'); -const Governor = artifacts.require('GovernorCompatibilityBravoMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -function makeContractAddress (creator, nonce) { - return web3.utils.toChecksumAddress(web3.utils.sha3(RLP.encode([creator, nonce])).slice(12).substring(14)); -} - -contract('GovernorCompatibilityBravo', function (accounts) { - const [ owner, proposer, voter1, voter2, voter3, voter4, other ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const proposalThreshold = web3.utils.toWei('10'); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - const [ deployer ] = await web3.eth.getAccounts(); - - this.token = await Token.new(tokenName, tokenSymbol); - - // Need to predict governance address to set it as timelock admin with a delayed transfer - const nonce = await web3.eth.getTransactionCount(deployer); - const predictGovernor = makeContractAddress(deployer, nonce + 1); - - this.timelock = await Timelock.new(predictGovernor, 2 * 86400); - this.mock = await Governor.new( - name, - this.token.address, - votingDelay, - votingPeriod, - proposalThreshold, - this.timelock.address, - ); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.timelock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: proposer, value: proposalThreshold }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - signature: 'mockFunction()', - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - expect(await this.mock.quorumVotes()).to.be.bignumber.equal('0'); - expect(await this.mock.COUNTING_MODE()).to.be.equal('support=bravo&quorum=bravo'); - }); - - it('nominal workflow', async function () { - // Before - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(false); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.timelock.address)).to.be.bignumber.equal(value); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal('0'); - - // Run proposal - const txPropose = await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For, reason: 'This is nice' }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - // After - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.timelock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal(value); - - const proposal = await this.mock.proposals(this.proposal.id); - expect(proposal.id).to.be.bignumber.equal(this.proposal.id); - expect(proposal.proposer).to.be.equal(proposer); - expect(proposal.eta).to.be.bignumber.equal(await this.mock.proposalEta(this.proposal.id)); - expect(proposal.startBlock).to.be.bignumber.equal(await this.mock.proposalSnapshot(this.proposal.id)); - expect(proposal.endBlock).to.be.bignumber.equal(await this.mock.proposalDeadline(this.proposal.id)); - expect(proposal.canceled).to.be.equal(false); - expect(proposal.executed).to.be.equal(true); - - const action = await this.mock.getActions(this.proposal.id); - expect(action.targets).to.be.deep.equal(this.proposal.targets); - // expect(action.values).to.be.deep.equal(this.proposal.values); - expect(action.signatures).to.be.deep.equal(this.proposal.signatures); - expect(action.calldatas).to.be.deep.equal(this.proposal.data); - - const voteReceipt1 = await this.mock.getReceipt(this.proposal.id, voter1); - expect(voteReceipt1.hasVoted).to.be.equal(true); - expect(voteReceipt1.support).to.be.bignumber.equal(Enums.VoteType.For); - expect(voteReceipt1.votes).to.be.bignumber.equal(web3.utils.toWei('10')); - - const voteReceipt2 = await this.mock.getReceipt(this.proposal.id, voter2); - expect(voteReceipt2.hasVoted).to.be.equal(true); - expect(voteReceipt2.support).to.be.bignumber.equal(Enums.VoteType.For); - expect(voteReceipt2.votes).to.be.bignumber.equal(web3.utils.toWei('7')); - - const voteReceipt3 = await this.mock.getReceipt(this.proposal.id, voter3); - expect(voteReceipt3.hasVoted).to.be.equal(true); - expect(voteReceipt3.support).to.be.bignumber.equal(Enums.VoteType.Against); - expect(voteReceipt3.votes).to.be.bignumber.equal(web3.utils.toWei('5')); - - const voteReceipt4 = await this.mock.getReceipt(this.proposal.id, voter4); - expect(voteReceipt4.hasVoted).to.be.equal(true); - expect(voteReceipt4.support).to.be.bignumber.equal(Enums.VoteType.Abstain); - expect(voteReceipt4.votes).to.be.bignumber.equal(web3.utils.toWei('2')); - - expectEvent( - txPropose, - 'ProposalCreated', - { - proposalId: this.proposal.id, - proposer, - targets: this.proposal.targets, - // values: this.proposal.values, - signatures: this.proposal.signatures.map(() => ''), // this event doesn't contain the proposal detail - calldatas: this.proposal.fulldata, - startBlock: new BN(txPropose.receipt.blockNumber).add(votingDelay), - endBlock: new BN(txPropose.receipt.blockNumber).add(votingDelay).add(votingPeriod), - description: this.proposal.description, - }, - ); - expectEvent( - txExecute, - 'ProposalExecuted', - { proposalId: this.proposal.id }, - ); - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalled', - ); - }); - - it('double voting is forbiden', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'GovernorCompatibilityBravo: vote already cast', - ); - }); - - it('with function selector and arguments', async function () { - const target = this.receiver.address; - this.helper.setProposal([ - { target, data: this.receiver.contract.methods.mockFunction().encodeABI() }, - { target, data: this.receiver.contract.methods.mockFunctionWithArgs(17, 42).encodeABI() }, - { target, signature: 'mockFunctionNonPayable()' }, - { - target, - signature: 'mockFunctionWithArgs(uint256,uint256)', - data: web3.eth.abi.encodeParameters(['uint256', 'uint256'], [18, 43]), - }, - ], ''); - - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For, reason: 'This is nice' }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalled', - ); - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalled', - ); - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalledWithArgs', - { a: '17', b: '42' }, - ); - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalledWithArgs', - { a: '18', b: '43' }, - ); - }); - - it('with inconsistent array size for selector and arguments', async function () { - const target = this.receiver.address; - this.helper.setProposal( - { - targets: [target, target], - values: [0, 0], - signatures: ['mockFunction()'], // One signature - data: ['0x', this.receiver.contract.methods.mockFunctionWithArgs(17, 42).encodeABI()], // Two data entries - }, - '', - ); - - await expectRevert(this.helper.propose({ from: proposer }), 'GovernorBravo: invalid signatures length'); - }); - - describe('should revert', function () { - describe('on propose', function () { - it('if proposal does not meet proposalThreshold', async function () { - await expectRevert( - this.helper.propose({ from: other }), - 'Governor: proposer votes below proposal threshold', - ); - }); - }); - - describe('on vote', function () { - it('if vote type is invalide', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await expectRevert( - this.helper.vote({ support: 5 }, { from: voter1 }), - 'GovernorCompatibilityBravo: invalid vote type', - ); - }); - }); - }); - - describe('cancel', function () { - it('proposer can cancel', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.cancel({ from: proposer }); - }); - - it('anyone can cancel if proposer drop below threshold', async function () { - await this.helper.propose({ from: proposer }); - await this.token.transfer(voter1, web3.utils.toWei('1'), { from: proposer }); - await this.helper.cancel(); - }); - - it('cannot cancel is proposer is still above threshold', async function () { - await this.helper.propose({ from: proposer }); - await expectRevert(this.helper.cancel(), 'GovernorBravo: proposer above threshold'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorComp.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorComp.test.js deleted file mode 100644 index 06d2d62..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorComp.test.js +++ /dev/null @@ -1,78 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesCompMock'); -const Governor = artifacts.require('GovernorCompMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorComp', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.owner = owner; - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - }); - - it('voting with comp token', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter3)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter4)).to.be.equal(true); - - await this.mock.proposalVotes(this.proposal.id).then(results => { - expect(results.forVotes).to.be.bignumber.equal(web3.utils.toWei('17')); - expect(results.againstVotes).to.be.bignumber.equal(web3.utils.toWei('5')); - expect(results.abstainVotes).to.be.bignumber.equal(web3.utils.toWei('2')); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorERC721.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorERC721.test.js deleted file mode 100644 index 086fca4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorERC721.test.js +++ /dev/null @@ -1,104 +0,0 @@ -const { BN, expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC721VotesMock'); -const Governor = artifacts.require('GovernorVoteMocks'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorERC721Mock', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockNFToken'; - const tokenSymbol = 'MTKN'; - const NFT0 = new BN(0); - const NFT1 = new BN(1); - const NFT2 = new BN(2); - const NFT3 = new BN(3); - const NFT4 = new BN(4); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.owner = owner; - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await Promise.all([ NFT0, NFT1, NFT2, NFT3, NFT4 ].map(tokenId => this.token.mint(owner, tokenId))); - await this.helper.delegate({ token: this.token, to: voter1, tokenId: NFT0 }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, tokenId: NFT1 }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, tokenId: NFT2 }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, tokenId: NFT3 }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, tokenId: NFT4 }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - }); - - it('voting with ERC721 token', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'VoteCast', - { voter: voter1, support: Enums.VoteType.For, weight: '1' }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }), - 'VoteCast', - { voter: voter2, support: Enums.VoteType.For, weight: '2' }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }), - 'VoteCast', - { voter: voter3, support: Enums.VoteType.Against, weight: '1' }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }), - 'VoteCast', - { voter: voter4, support: Enums.VoteType.Abstain, weight: '1' }, - ); - - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter3)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter4)).to.be.equal(true); - - await this.mock.proposalVotes(this.proposal.id).then(results => { - expect(results.forVotes).to.be.bignumber.equal('3'); - expect(results.againstVotes).to.be.bignumber.equal('1'); - expect(results.abstainVotes).to.be.bignumber.equal('1'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorPreventLateQuorum.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorPreventLateQuorum.test.js deleted file mode 100644 index 6a5d644..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorPreventLateQuorum.test.js +++ /dev/null @@ -1,177 +0,0 @@ -const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesCompMock'); -const Governor = artifacts.require('GovernorPreventLateQuorumMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorPreventLateQuorum', function (accounts) { - const [ owner, proposer, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const lateQuorumVoteExtension = new BN(8); - const quorum = web3.utils.toWei('1'); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.owner = owner; - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new( - name, - this.token.address, - votingDelay, - votingPeriod, - quorum, - lateQuorumVoteExtension, - ); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal(quorum); - expect(await this.mock.lateQuorumVoteExtension()).to.be.bignumber.equal(lateQuorumVoteExtension); - }); - - it('nominal workflow unaffected', async function () { - const txPropose = await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter3)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter4)).to.be.equal(true); - - await this.mock.proposalVotes(this.proposal.id).then(results => { - expect(results.forVotes).to.be.bignumber.equal(web3.utils.toWei('17')); - expect(results.againstVotes).to.be.bignumber.equal(web3.utils.toWei('5')); - expect(results.abstainVotes).to.be.bignumber.equal(web3.utils.toWei('2')); - }); - - const startBlock = new BN(txPropose.receipt.blockNumber).add(votingDelay); - const endBlock = new BN(txPropose.receipt.blockNumber).add(votingDelay).add(votingPeriod); - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(endBlock); - - expectEvent( - txPropose, - 'ProposalCreated', - { - proposalId: this.proposal.id, - proposer, - targets: this.proposal.targets, - // values: this.proposal.values.map(value => new BN(value)), - signatures: this.proposal.signatures, - calldatas: this.proposal.data, - startBlock, - endBlock, - description: this.proposal.description, - }, - ); - }); - - it('Delay is extended to prevent last minute take-over', async function () { - const txPropose = await this.helper.propose({ from: proposer }); - - // compute original schedule - const startBlock = new BN(txPropose.receipt.blockNumber).add(votingDelay); - const endBlock = new BN(txPropose.receipt.blockNumber).add(votingDelay).add(votingPeriod); - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(endBlock); - - // wait for the last minute to vote - await this.helper.waitForDeadline(-1); - const txVote = await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - - // cannot execute yet - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - - // compute new extended schedule - const extendedDeadline = new BN(txVote.receipt.blockNumber).add(lateQuorumVoteExtension); - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(extendedDeadline); - - // still possible to vote - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter1 }); - - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - await this.helper.waitForDeadline(+1); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Defeated); - - // check extension event - expectEvent( - txVote, - 'ProposalExtended', - { proposalId: this.proposal.id, extendedDeadline }, - ); - }); - - describe('onlyGovernance updates', function () { - it('setLateQuorumVoteExtension is protected', async function () { - await expectRevert( - this.mock.setLateQuorumVoteExtension(0), - 'Governor: onlyGovernance', - ); - }); - - it('can setLateQuorumVoteExtension through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setLateQuorumVoteExtension('0').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'LateQuorumVoteExtensionSet', - { oldVoteExtension: lateQuorumVoteExtension, newVoteExtension: '0' }, - ); - - expect(await this.mock.lateQuorumVoteExtension()).to.be.bignumber.equal('0'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorTimelockCompound.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorTimelockCompound.test.js deleted file mode 100644 index a31df68..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorTimelockCompound.test.js +++ /dev/null @@ -1,368 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const RLP = require('rlp'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const { - shouldSupportInterfaces, -} = require('../../utils/introspection/SupportsInterface.behavior'); - -const Token = artifacts.require('ERC20VotesMock'); -const Timelock = artifacts.require('CompTimelock'); -const Governor = artifacts.require('GovernorTimelockCompoundMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -function makeContractAddress (creator, nonce) { - return web3.utils.toChecksumAddress(web3.utils.sha3(RLP.encode([creator, nonce])).slice(12).substring(14)); -} - -contract('GovernorTimelockCompound', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4, other ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - const [ deployer ] = await web3.eth.getAccounts(); - - this.token = await Token.new(tokenName, tokenSymbol); - - // Need to predict governance address to set it as timelock admin with a delayed transfer - const nonce = await web3.eth.getTransactionCount(deployer); - const predictGovernor = makeContractAddress(deployer, nonce + 1); - - this.timelock = await Timelock.new(predictGovernor, 2 * 86400); - this.mock = await Governor.new( - name, - this.token.address, - votingDelay, - votingPeriod, - this.timelock.address, - 0, - ); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.timelock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - shouldSupportInterfaces([ - 'ERC165', - 'Governor', - 'GovernorWithParams', - 'GovernorTimelock', - ]); - - it('doesn\'t accept ether transfers', async function () { - await expectRevert.unspecified(web3.eth.sendTransaction({ from: owner, to: this.mock.address, value: 1 })); - }); - - it('post deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - - expect(await this.mock.timelock()).to.be.equal(this.timelock.address); - expect(await this.timelock.admin()).to.be.equal(this.mock.address); - }); - - it('nominal', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - const txQueue = await this.helper.queue(); - const eta = await this.mock.proposalEta(this.proposal.id); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expectEvent(txQueue, 'ProposalQueued', { proposalId: this.proposal.id }); - await expectEvent.inTransaction(txQueue.tx, this.timelock, 'QueueTransaction', { eta }); - - expectEvent(txExecute, 'ProposalExecuted', { proposalId: this.proposal.id }); - await expectEvent.inTransaction(txExecute.tx, this.timelock, 'ExecuteTransaction', { eta }); - await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalled'); - }); - - describe('should revert', function () { - describe('on queue', function () { - it('if already queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await expectRevert(this.helper.queue(), 'Governor: proposal not successful'); - }); - - it('if proposal contains duplicate calls', async function () { - const action = { - target: this.token.address, - data: this.token.contract.methods.approve(this.receiver.address, constants.MAX_UINT256).encodeABI(), - }; - this.helper.setProposal([ action, action ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await expectRevert( - this.helper.queue(), - 'GovernorTimelockCompound: identical proposal action already queued', - ); - await expectRevert( - this.helper.execute(), - 'GovernorTimelockCompound: proposal not yet queued', - ); - }); - }); - - describe('on execute', function () { - it('if not queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(+1); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Succeeded); - - await expectRevert( - this.helper.execute(), - 'GovernorTimelockCompound: proposal not yet queued', - ); - }); - - it('if too early', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Queued); - - await expectRevert( - this.helper.execute(), - 'Timelock::executeTransaction: Transaction hasn\'t surpassed time lock', - ); - }); - - it('if too late', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(+30 * 86400); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Expired); - - await expectRevert( - this.helper.execute(), - 'Governor: proposal not successful', - ); - }); - - it('if already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - await expectRevert( - this.helper.execute(), - 'Governor: proposal not successful', - ); - }); - }); - }); - - describe('cancel', function () { - it('cancel before queue prevents scheduling', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.cancel(), - 'ProposalCanceled', - { proposalId: this.proposal.id }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - await expectRevert(this.helper.queue(), 'Governor: proposal not successful'); - }); - - it('cancel after queue prevents executing', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expectEvent( - await this.helper.cancel(), - 'ProposalCanceled', - { proposalId: this.proposal.id }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - }); - - describe('onlyGovernance', function () { - describe('relay', function () { - beforeEach(async function () { - await this.token.mint(this.mock.address, 1); - }); - - it('is protected', async function () { - await expectRevert( - this.mock.relay( - this.token.address, - 0, - this.token.contract.methods.transfer(other, 1).encodeABI(), - ), - 'Governor: onlyGovernance', - ); - }); - - it('can be executed through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.relay( - this.token.address, - 0, - this.token.contract.methods.transfer(other, 1).encodeABI(), - ).encodeABI(), - }, - ], ''); - - expect(await this.token.balanceOf(this.mock.address), 1); - expect(await this.token.balanceOf(other), 0); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expect(await this.token.balanceOf(this.mock.address), 0); - expect(await this.token.balanceOf(other), 1); - - expectEvent.inTransaction( - txExecute.tx, - this.token, - 'Transfer', - { from: this.mock.address, to: other, value: '1' }, - ); - }); - }); - - describe('updateTimelock', function () { - beforeEach(async function () { - this.newTimelock = await Timelock.new(this.mock.address, 7 * 86400); - }); - - it('is protected', async function () { - await expectRevert( - this.mock.updateTimelock(this.newTimelock.address), - 'Governor: onlyGovernance', - ); - }); - - it('can be executed through governance to', async function () { - this.helper.setProposal([ - { - target: this.timelock.address, - data: this.timelock.contract.methods.setPendingAdmin(owner).encodeABI(), - }, - { - target: this.mock.address, - data: this.mock.contract.methods.updateTimelock(this.newTimelock.address).encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expectEvent( - txExecute, - 'TimelockChange', - { oldTimelock: this.timelock.address, newTimelock: this.newTimelock.address }, - ); - - expect(await this.mock.timelock()).to.be.bignumber.equal(this.newTimelock.address); - }); - }); - - it('can transfer timelock to new governor', async function () { - const newGovernor = await Governor.new(name, this.token.address, 8, 32, this.timelock.address, 0); - - this.helper.setProposal([ - { - target: this.timelock.address, - data: this.timelock.contract.methods.setPendingAdmin(newGovernor.address).encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - await expectEvent.inTransaction( - txExecute.tx, - this.timelock, - 'NewPendingAdmin', - { newPendingAdmin: newGovernor.address }, - ); - - await newGovernor.__acceptAdmin(); - expect(await this.timelock.admin()).to.be.bignumber.equal(newGovernor.address); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorTimelockControl.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorTimelockControl.test.js deleted file mode 100644 index 56d3b22..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorTimelockControl.test.js +++ /dev/null @@ -1,420 +0,0 @@ -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const { - shouldSupportInterfaces, -} = require('../../utils/introspection/SupportsInterface.behavior'); - -const Token = artifacts.require('ERC20VotesMock'); -const Timelock = artifacts.require('TimelockController'); -const Governor = artifacts.require('GovernorTimelockControlMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorTimelockControl', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4, other ] = accounts; - - const TIMELOCK_ADMIN_ROLE = web3.utils.soliditySha3('TIMELOCK_ADMIN_ROLE'); - const PROPOSER_ROLE = web3.utils.soliditySha3('PROPOSER_ROLE'); - const EXECUTOR_ROLE = web3.utils.soliditySha3('EXECUTOR_ROLE'); - const CANCELLER_ROLE = web3.utils.soliditySha3('CANCELLER_ROLE'); - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - const [ deployer ] = await web3.eth.getAccounts(); - - this.token = await Token.new(tokenName, tokenSymbol); - this.timelock = await Timelock.new(3600, [], [], deployer); - this.mock = await Governor.new( - name, - this.token.address, - votingDelay, - votingPeriod, - this.timelock.address, - 0, - ); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - this.TIMELOCK_ADMIN_ROLE = await this.timelock.TIMELOCK_ADMIN_ROLE(); - this.PROPOSER_ROLE = await this.timelock.PROPOSER_ROLE(); - this.EXECUTOR_ROLE = await this.timelock.EXECUTOR_ROLE(); - this.CANCELLER_ROLE = await this.timelock.CANCELLER_ROLE(); - - await web3.eth.sendTransaction({ from: owner, to: this.timelock.address, value }); - - // normal setup: governor is proposer, everyone is executor, timelock is its own admin - await this.timelock.grantRole(PROPOSER_ROLE, this.mock.address); - await this.timelock.grantRole(PROPOSER_ROLE, owner); - await this.timelock.grantRole(CANCELLER_ROLE, this.mock.address); - await this.timelock.grantRole(CANCELLER_ROLE, owner); - await this.timelock.grantRole(EXECUTOR_ROLE, constants.ZERO_ADDRESS); - await this.timelock.revokeRole(TIMELOCK_ADMIN_ROLE, deployer); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - this.proposal.timelockid = await this.timelock.hashOperationBatch( - ...this.proposal.shortProposal.slice(0, 3), - '0x0', - this.proposal.shortProposal[3], - ); - }); - - shouldSupportInterfaces([ - 'ERC165', - 'Governor', - 'GovernorWithParams', - 'GovernorTimelock', - ]); - - it('doesn\'t accept ether transfers', async function () { - await expectRevert.unspecified(web3.eth.sendTransaction({ from: owner, to: this.mock.address, value: 1 })); - }); - - it('post deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - - expect(await this.mock.timelock()).to.be.equal(this.timelock.address); - }); - - it('nominal', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - const txQueue = await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expectEvent(txQueue, 'ProposalQueued', { proposalId: this.proposal.id }); - await expectEvent.inTransaction(txQueue.tx, this.timelock, 'CallScheduled', { id: this.proposal.timelockid }); - - expectEvent(txExecute, 'ProposalExecuted', { proposalId: this.proposal.id }); - await expectEvent.inTransaction(txExecute.tx, this.timelock, 'CallExecuted', { id: this.proposal.timelockid }); - await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalled'); - }); - - describe('should revert', function () { - describe('on queue', function () { - it('if already queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await expectRevert(this.helper.queue(), 'Governor: proposal not successful'); - }); - }); - - describe('on execute', function () { - it('if not queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(+1); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Succeeded); - - await expectRevert(this.helper.execute(), 'TimelockController: operation is not ready'); - }); - - it('if too early', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Queued); - - await expectRevert(this.helper.execute(), 'TimelockController: operation is not ready'); - }); - - it('if already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('if already executed by another proposer', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - await this.timelock.executeBatch( - ...this.proposal.shortProposal.slice(0, 3), - '0x0', - this.proposal.shortProposal[3], - ); - - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - }); - }); - - describe('cancel', function () { - it('cancel before queue prevents scheduling', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.cancel(), - 'ProposalCanceled', - { proposalId: this.proposal.id }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - await expectRevert(this.helper.queue(), 'Governor: proposal not successful'); - }); - - it('cancel after queue prevents executing', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expectEvent( - await this.helper.cancel(), - 'ProposalCanceled', - { proposalId: this.proposal.id }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('cancel on timelock is reflected on governor', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Queued); - - expectEvent( - await this.timelock.cancel(this.proposal.timelockid, { from: owner }), - 'Cancelled', - { id: this.proposal.timelockid }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - }); - }); - - describe('onlyGovernance', function () { - describe('relay', function () { - beforeEach(async function () { - await this.token.mint(this.mock.address, 1); - }); - - it('is protected', async function () { - await expectRevert( - this.mock.relay( - this.token.address, - 0, - this.token.contract.methods.transfer(other, 1).encodeABI(), - ), - 'Governor: onlyGovernance', - ); - }); - - it('can be executed through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.relay( - this.token.address, - 0, - this.token.contract.methods.transfer(other, 1).encodeABI(), - ).encodeABI(), - }, - ], ''); - - expect(await this.token.balanceOf(this.mock.address), 1); - expect(await this.token.balanceOf(other), 0); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expect(await this.token.balanceOf(this.mock.address), 0); - expect(await this.token.balanceOf(other), 1); - - expectEvent.inTransaction( - txExecute.tx, - this.token, - 'Transfer', - { from: this.mock.address, to: other, value: '1' }, - ); - }); - - it('is payable and can transfer eth to EOA', async function () { - const t2g = web3.utils.toBN(128); // timelock to governor - const g2o = web3.utils.toBN(100); // governor to eoa (other) - - this.helper.setProposal([ - { - target: this.mock.address, - value: t2g, - data: this.mock.contract.methods.relay( - other, - g2o, - '0x', - ).encodeABI(), - }, - ], ''); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - const timelockBalance = await web3.eth.getBalance(this.timelock.address).then(web3.utils.toBN); - const otherBalance = await web3.eth.getBalance(other).then(web3.utils.toBN); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - - expect(await web3.eth.getBalance(this.timelock.address)).to.be.bignumber.equal(timelockBalance.sub(t2g)); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(t2g.sub(g2o)); - expect(await web3.eth.getBalance(other)).to.be.bignumber.equal(otherBalance.add(g2o)); - }); - - it('protected against other proposers', async function () { - await this.timelock.schedule( - this.mock.address, - web3.utils.toWei('0'), - this.mock.contract.methods.relay(constants.ZERO_ADDRESS, 0, '0x').encodeABI(), - constants.ZERO_BYTES32, - constants.ZERO_BYTES32, - 3600, - { from: owner }, - ); - - await time.increase(3600); - - await expectRevert( - this.timelock.execute( - this.mock.address, - web3.utils.toWei('0'), - this.mock.contract.methods.relay(constants.ZERO_ADDRESS, 0, '0x').encodeABI(), - constants.ZERO_BYTES32, - constants.ZERO_BYTES32, - { from: owner }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - }); - - describe('updateTimelock', function () { - beforeEach(async function () { - this.newTimelock = await Timelock.new( - 3600, - [ this.mock.address ], - [ this.mock.address ], - constants.ZERO_ADDRESS, - ); - }); - - it('is protected', async function () { - await expectRevert( - this.mock.updateTimelock(this.newTimelock.address), - 'Governor: onlyGovernance', - ); - }); - - it('can be executed through governance to', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.updateTimelock(this.newTimelock.address).encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expectEvent( - txExecute, - 'TimelockChange', - { oldTimelock: this.timelock.address, newTimelock: this.newTimelock.address }, - ); - - expect(await this.mock.timelock()).to.be.bignumber.equal(this.newTimelock.address); - }); - }); - }); - - it('clear queue of pending governor calls', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.nonGovernanceFunction().encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - - // This path clears _governanceCall as part of the afterExecute call, - // but we have not way to check that the cleanup actually happened other - // then coverage reports. - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorVotesQuorumFraction.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorVotesQuorumFraction.test.js deleted file mode 100644 index 9e6b71b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorVotesQuorumFraction.test.js +++ /dev/null @@ -1,137 +0,0 @@ -const { BN, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesMock'); -const Governor = artifacts.require('GovernorMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorVotesQuorumFraction', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = new BN(web3.utils.toWei('100')); - const ratio = new BN(8); // percents - const newRatio = new BN(6); // percents - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.owner = owner; - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address, votingDelay, votingPeriod, ratio); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - expect(await this.mock.quorumNumerator()).to.be.bignumber.equal(ratio); - expect(await this.mock.quorumDenominator()).to.be.bignumber.equal('100'); - expect(await time.latestBlock().then(blockNumber => this.mock.quorum(blockNumber.subn(1)))) - .to.be.bignumber.equal(tokenSupply.mul(ratio).divn(100)); - }); - - it('quroum reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - }); - - it('quroum not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.waitForDeadline(); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - describe('onlyGovernance updates', function () { - it('updateQuorumNumerator is protected', async function () { - await expectRevert( - this.mock.updateQuorumNumerator(newRatio), - 'Governor: onlyGovernance', - ); - }); - - it('can updateQuorumNumerator through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.updateQuorumNumerator(newRatio).encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'QuorumNumeratorUpdated', - { oldQuorumNumerator: ratio, newQuorumNumerator: newRatio }, - ); - - expect(await this.mock.quorumNumerator()).to.be.bignumber.equal(newRatio); - expect(await this.mock.quorumDenominator()).to.be.bignumber.equal('100'); - - // it takes one block for the new quorum to take effect - expect(await time.latestBlock().then(blockNumber => this.mock.quorum(blockNumber.subn(1)))) - .to.be.bignumber.equal(tokenSupply.mul(ratio).divn(100)); - - await time.advanceBlock(); - - expect(await time.latestBlock().then(blockNumber => this.mock.quorum(blockNumber.subn(1)))) - .to.be.bignumber.equal(tokenSupply.mul(newRatio).divn(100)); - }); - - it('cannot updateQuorumNumerator over the maximum', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.updateQuorumNumerator('101').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - await expectRevert( - this.helper.execute(), - 'GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorWithParams.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorWithParams.test.js deleted file mode 100644 index 875b705..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/extensions/GovernorWithParams.test.js +++ /dev/null @@ -1,166 +0,0 @@ -const { BN, expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; -const { fromRpcSig } = require('ethereumjs-util'); -const Enums = require('../../helpers/enums'); -const { EIP712Domain } = require('../../helpers/eip712'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesCompMock'); -const Governor = artifacts.require('GovernorWithParamsMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -const rawParams = { - uintParam: new BN('42'), - strParam: 'These are my params', -}; - -const encodedParams = web3.eth.abi.encodeParameters( - [ 'uint256', 'string' ], - Object.values(rawParams), -); - -contract('GovernorWithParams', function (accounts) { - const [ owner, proposer, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.chainId = await web3.eth.getChainId(); - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - }); - - it('nominal is unaffected', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For, reason: 'This is nice' }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal(value); - }); - - it('Voting with params is properly supported', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - - const weight = new BN(web3.utils.toWei('7')).sub(rawParams.uintParam); - - const tx = await this.helper.vote({ - support: Enums.VoteType.For, - reason: 'no particular reason', - params: encodedParams, - }, { from: voter2 }); - - expectEvent(tx, 'CountParams', { ...rawParams }); - expectEvent(tx, 'VoteCastWithParams', { - voter: voter2, - proposalId: this.proposal.id, - support: Enums.VoteType.For, - weight, - reason: 'no particular reason', - params: encodedParams, - }); - - const votes = await this.mock.proposalVotes(this.proposal.id); - expect(votes.forVotes).to.be.bignumber.equal(weight); - }); - - it('Voting with params by signature is properly supported', async function () { - const voterBySig = Wallet.generate(); - const voterBySigAddress = web3.utils.toChecksumAddress(voterBySig.getAddressString()); - - const signature = async (message) => { - return fromRpcSig(ethSigUtil.signTypedMessage( - voterBySig.getPrivateKey(), - { - data: { - types: { - EIP712Domain, - ExtendedBallot: [ - { name: 'proposalId', type: 'uint256' }, - { name: 'support', type: 'uint8' }, - { name: 'reason', type: 'string' }, - { name: 'params', type: 'bytes' }, - ], - }, - domain: { name, version, chainId: this.chainId, verifyingContract: this.mock.address }, - primaryType: 'ExtendedBallot', - message, - }, - }, - )); - }; - - await this.token.delegate(voterBySigAddress, { from: voter2 }); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - const weight = new BN(web3.utils.toWei('7')).sub(rawParams.uintParam); - - const tx = await this.helper.vote({ - support: Enums.VoteType.For, - reason: 'no particular reason', - params: encodedParams, - signature, - }); - - expectEvent(tx, 'CountParams', { ...rawParams }); - expectEvent(tx, 'VoteCastWithParams', { - voter: voterBySigAddress, - proposalId: this.proposal.id, - support: Enums.VoteType.For, - weight, - reason: 'no particular reason', - params: encodedParams, - }); - - const votes = await this.mock.proposalVotes(this.proposal.id); - expect(votes.forVotes).to.be.bignumber.equal(weight); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/utils/Votes.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/utils/Votes.behavior.js deleted file mode 100644 index aee227b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/utils/Votes.behavior.js +++ /dev/null @@ -1,344 +0,0 @@ -const { constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); - -const { MAX_UINT256, ZERO_ADDRESS } = constants; - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const { EIP712Domain, domainSeparator } = require('../../helpers/eip712'); - -const Delegation = [ - { name: 'delegatee', type: 'address' }, - { name: 'nonce', type: 'uint256' }, - { name: 'expiry', type: 'uint256' }, -]; - -const version = '1'; - -function shouldBehaveLikeVotes () { - describe('run votes workflow', function () { - it('initial nonce is 0', async function () { - expect(await this.votes.nonces(this.account1)).to.be.bignumber.equal('0'); - }); - - it('domain separator', async function () { - expect( - await this.votes.DOMAIN_SEPARATOR(), - ).to.equal( - await domainSeparator(this.name, version, this.chainId, this.votes.address), - ); - }); - - describe('delegation with signature', function () { - const delegator = Wallet.generate(); - const delegatorAddress = web3.utils.toChecksumAddress(delegator.getAddressString()); - const nonce = 0; - - const buildData = (chainId, verifyingContract, name, message) => ({ - data: { - primaryType: 'Delegation', - types: { EIP712Domain, Delegation }, - domain: { name, version, chainId, verifyingContract }, - message, - }, - }); - - beforeEach(async function () { - await this.votes.mint(delegatorAddress, this.NFT0); - }); - - it('accept signed delegation', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - expect(await this.votes.delegates(delegatorAddress)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.votes.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - expectEvent(receipt, 'DelegateChanged', { - delegator: delegatorAddress, - fromDelegate: ZERO_ADDRESS, - toDelegate: delegatorAddress, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: delegatorAddress, - previousBalance: '0', - newBalance: '1', - }); - - expect(await this.votes.delegates(delegatorAddress)).to.be.equal(delegatorAddress); - - expect(await this.votes.getVotes(delegatorAddress)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastVotes(delegatorAddress, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.votes.getPastVotes(delegatorAddress, receipt.blockNumber)).to.be.bignumber.equal('1'); - }); - - it('rejects reused signature', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - await this.votes.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - - await expectRevert( - this.votes.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s), - 'Votes: invalid nonce', - ); - }); - - it('rejects bad delegatee', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - const receipt = await this.votes.delegateBySig(this.account1Delegatee, nonce, MAX_UINT256, v, r, s); - const { args } = receipt.logs.find(({ event }) => event === 'DelegateChanged'); - expect(args.delegator).to.not.be.equal(delegatorAddress); - expect(args.fromDelegate).to.be.equal(ZERO_ADDRESS); - expect(args.toDelegate).to.be.equal(this.account1Delegatee); - }); - - it('rejects bad nonce', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - await expectRevert( - this.votes.delegateBySig(delegatorAddress, nonce + 1, MAX_UINT256, v, r, s), - 'Votes: invalid nonce', - ); - }); - - it('rejects expired permit', async function () { - const expiry = (await time.latest()) - time.duration.weeks(1); - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry, - }), - )); - - await expectRevert( - this.votes.delegateBySig(delegatorAddress, nonce, expiry, v, r, s), - 'Votes: signature expired', - ); - }); - }); - - describe('set delegation', function () { - describe('call', function () { - it('delegation with tokens', async function () { - await this.votes.mint(this.account1, this.NFT0); - expect(await this.votes.delegates(this.account1)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.votes.delegate(this.account1, { from: this.account1 }); - expectEvent(receipt, 'DelegateChanged', { - delegator: this.account1, - fromDelegate: ZERO_ADDRESS, - toDelegate: this.account1, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: this.account1, - previousBalance: '0', - newBalance: '1', - }); - - expect(await this.votes.delegates(this.account1)).to.be.equal(this.account1); - - expect(await this.votes.getVotes(this.account1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastVotes(this.account1, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.votes.getPastVotes(this.account1, receipt.blockNumber)).to.be.bignumber.equal('1'); - }); - - it('delegation without tokens', async function () { - expect(await this.votes.delegates(this.account1)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.votes.delegate(this.account1, { from: this.account1 }); - expectEvent(receipt, 'DelegateChanged', { - delegator: this.account1, - fromDelegate: ZERO_ADDRESS, - toDelegate: this.account1, - }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - expect(await this.votes.delegates(this.account1)).to.be.equal(this.account1); - }); - }); - }); - - describe('change delegation', function () { - beforeEach(async function () { - await this.votes.mint(this.account1, this.NFT0); - await this.votes.delegate(this.account1, { from: this.account1 }); - }); - - it('call', async function () { - expect(await this.votes.delegates(this.account1)).to.be.equal(this.account1); - - const { receipt } = await this.votes.delegate(this.account1Delegatee, { from: this.account1 }); - expectEvent(receipt, 'DelegateChanged', { - delegator: this.account1, - fromDelegate: this.account1, - toDelegate: this.account1Delegatee, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: this.account1, - previousBalance: '1', - newBalance: '0', - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: this.account1Delegatee, - previousBalance: '0', - newBalance: '1', - }); - const prevBlock = receipt.blockNumber - 1; - expect(await this.votes.delegates(this.account1)).to.be.equal(this.account1Delegatee); - - expect(await this.votes.getVotes(this.account1)).to.be.bignumber.equal('0'); - expect(await this.votes.getVotes(this.account1Delegatee)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastVotes(this.account1, receipt.blockNumber - 1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastVotes(this.account1Delegatee, prevBlock)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.votes.getPastVotes(this.account1, receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastVotes(this.account1Delegatee, receipt.blockNumber)).to.be.bignumber.equal('1'); - }); - }); - - describe('getPastTotalSupply', function () { - beforeEach(async function () { - await this.votes.delegate(this.account1, { from: this.account1 }); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.votes.getPastTotalSupply(5e10), - 'block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.votes.getPastTotalSupply(0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const t1 = await this.votes.mint(this.account1, this.NFT0); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t2 = await this.votes.mint(this.account1, this.NFT1); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastTotalSupply(t2.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t2.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.votes.mint(this.account1, this.NFT1); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.votes.burn(this.NFT1); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.votes.mint(this.account1, this.NFT2); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.votes.burn(this.NFT2); - await time.advanceBlock(); - await time.advanceBlock(); - const t5 = await this.votes.mint(this.account1, this.NFT3); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t2.receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t2.receipt.blockNumber + 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t3.receipt.blockNumber)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t3.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t4.receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t4.receipt.blockNumber + 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t5.receipt.blockNumber)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t5.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - }); - }); - - // The following tests are a adaptation of - // https://github.com/compound-finance/compound-protocol/blob/master/tests/Governance/CompTest.js. - describe('Compound test suite', function () { - beforeEach(async function () { - await this.votes.mint(this.account1, this.NFT0); - await this.votes.mint(this.account1, this.NFT1); - await this.votes.mint(this.account1, this.NFT2); - await this.votes.mint(this.account1, this.NFT3); - }); - - describe('getPastVotes', function () { - it('reverts if block number >= current block', async function () { - await expectRevert( - this.votes.getPastVotes(this.account2, 5e10), - 'block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.votes.getPastVotes(this.account2, 0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const t1 = await this.votes.delegate(this.account2, { from: this.account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - const latest = await this.votes.getVotes(this.account2); - const nextBlock = t1.receipt.blockNumber + 1; - expect(await this.votes.getPastVotes(this.account2, t1.receipt.blockNumber)).to.be.bignumber.equal(latest); - expect(await this.votes.getPastVotes(this.account2, nextBlock)).to.be.bignumber.equal(latest); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.votes.delegate(this.account2, { from: this.account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastVotes(this.account2, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - }); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeVotes, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/utils/Votes.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/utils/Votes.test.js deleted file mode 100644 index 32b7d1d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/governance/utils/Votes.test.js +++ /dev/null @@ -1,61 +0,0 @@ -const { expectRevert, BN } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const { - shouldBehaveLikeVotes, -} = require('./Votes.behavior'); - -const Votes = artifacts.require('VotesMock'); - -contract('Votes', function (accounts) { - const [ account1, account2, account3 ] = accounts; - beforeEach(async function () { - this.name = 'My Vote'; - this.votes = await Votes.new(this.name); - }); - - it('starts with zero votes', async function () { - expect(await this.votes.getTotalSupply()).to.be.bignumber.equal('0'); - }); - - describe('performs voting operations', function () { - beforeEach(async function () { - this.tx1 = await this.votes.mint(account1, 1); - this.tx2 = await this.votes.mint(account2, 1); - this.tx3 = await this.votes.mint(account3, 1); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.votes.getPastTotalSupply(this.tx3.receipt.blockNumber + 1), - 'Votes: block not yet mined', - ); - }); - - it('delegates', async function () { - await this.votes.delegate(account3, account2); - - expect(await this.votes.delegates(account3)).to.be.equal(account2); - }); - - it('returns total amount of votes', async function () { - expect(await this.votes.getTotalSupply()).to.be.bignumber.equal('3'); - }); - }); - - describe('performs voting workflow', function () { - beforeEach(async function () { - this.chainId = await this.votes.getChainId(); - this.account1 = account1; - this.account2 = account2; - this.account1Delegatee = account2; - this.NFT0 = new BN('10000000000000000000000000'); - this.NFT1 = new BN('10'); - this.NFT2 = new BN('20'); - this.NFT3 = new BN('30'); - }); - - shouldBehaveLikeVotes(); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/create2.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/create2.js deleted file mode 100644 index 3e57764..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/create2.js +++ /dev/null @@ -1,12 +0,0 @@ -function computeCreate2Address (saltHex, bytecode, deployer) { - return web3.utils.toChecksumAddress(`0x${web3.utils.sha3(`0x${[ - 'ff', - deployer, - saltHex, - web3.utils.soliditySha3(bytecode), - ].map(x => x.replace(/0x/, '')).join('')}`).slice(-40)}`); -} - -module.exports = { - computeCreate2Address, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/crosschain.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/crosschain.js deleted file mode 100644 index d4d25d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/crosschain.js +++ /dev/null @@ -1,63 +0,0 @@ -const { promisify } = require('util'); - -const BridgeAMBMock = artifacts.require('BridgeAMBMock'); -const BridgeArbitrumL1Mock = artifacts.require('BridgeArbitrumL1Mock'); -const BridgeArbitrumL2Mock = artifacts.require('BridgeArbitrumL2Mock'); -const BridgeOptimismMock = artifacts.require('BridgeOptimismMock'); -const BridgePolygonChildMock = artifacts.require('BridgePolygonChildMock'); - -class BridgeHelper { - static async deploy (type) { - return new BridgeHelper(await deployBridge(type)); - } - - constructor (bridge) { - this.bridge = bridge; - this.address = bridge.address; - } - - call (from, target, selector = undefined, args = []) { - return this.bridge.relayAs( - target.address || target, - selector - ? target.contract.methods[selector](...args).encodeABI() - : '0x', - from, - ); - } -} - -async function deployBridge (type = 'Arbitrum-L2') { - switch (type) { - case 'AMB': - return BridgeAMBMock.new(); - - case 'Arbitrum-L1': - return BridgeArbitrumL1Mock.new(); - - case 'Arbitrum-L2': { - const instance = await BridgeArbitrumL2Mock.new(); - const code = await web3.eth.getCode(instance.address); - await promisify(web3.currentProvider.send.bind(web3.currentProvider))({ - jsonrpc: '2.0', - method: 'hardhat_setCode', - params: [ '0x0000000000000000000000000000000000000064', code ], - id: new Date().getTime(), - }); - return BridgeArbitrumL2Mock.at('0x0000000000000000000000000000000000000064'); - } - - case 'Optimism': - return BridgeOptimismMock.new(); - - case 'Polygon-Child': - return BridgePolygonChildMock.new(); - - default: - throw new Error(`CrossChain: ${type} is not supported`); - } -} - -module.exports = { - BridgeHelper, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/customError.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/customError.js deleted file mode 100644 index 8fea434..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/customError.js +++ /dev/null @@ -1,24 +0,0 @@ -const { config } = require('hardhat'); - -const optimizationsEnabled = config.solidity.compilers.some(c => c.settings.optimizer.enabled); - -/** Revert handler that supports custom errors. */ -async function expectRevertCustomError (promise, reason) { - try { - await promise; - expect.fail('Expected promise to throw but it didn\'t'); - } catch (revert) { - if (reason) { - if (optimizationsEnabled) { - // Optimizations currently mess with Hardhat's decoding of custom errors - expect(revert.message).to.include.oneOf([reason, 'unrecognized return data or custom error']); - } else { - expect(revert.message).to.include(reason); - } - } - } -}; - -module.exports = { - expectRevertCustomError, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/eip712.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/eip712.js deleted file mode 100644 index 8a64b8a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/eip712.js +++ /dev/null @@ -1,30 +0,0 @@ -const ethSigUtil = require('eth-sig-util'); - -const EIP712Domain = [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, -]; - -const Permit = [ - { name: 'owner', type: 'address' }, - { name: 'spender', type: 'address' }, - { name: 'value', type: 'uint256' }, - { name: 'nonce', type: 'uint256' }, - { name: 'deadline', type: 'uint256' }, -]; - -async function domainSeparator (name, version, chainId, verifyingContract) { - return '0x' + ethSigUtil.TypedDataUtils.hashStruct( - 'EIP712Domain', - { name, version, chainId, verifyingContract }, - { EIP712Domain }, - ).toString('hex'); -} - -module.exports = { - EIP712Domain, - Permit, - domainSeparator, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/enums.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/enums.js deleted file mode 100644 index 26825de..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/enums.js +++ /dev/null @@ -1,29 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -function Enum (...options) { - return Object.fromEntries(options.map((key, i) => [ key, new BN(i) ])); -} - -module.exports = { - Enum, - ProposalState: Enum( - 'Pending', - 'Active', - 'Canceled', - 'Defeated', - 'Succeeded', - 'Queued', - 'Expired', - 'Executed', - ), - VoteType: Enum( - 'Against', - 'For', - 'Abstain', - ), - Rounding: Enum( - 'Down', - 'Up', - 'Zero', - ), -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/erc1967.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/erc1967.js deleted file mode 100644 index aab0e22..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/erc1967.js +++ /dev/null @@ -1,24 +0,0 @@ -const ImplementationLabel = 'eip1967.proxy.implementation'; -const AdminLabel = 'eip1967.proxy.admin'; -const BeaconLabel = 'eip1967.proxy.beacon'; - -function labelToSlot (label) { - return '0x' + web3.utils.toBN(web3.utils.keccak256(label)).subn(1).toString(16); -} - -function getSlot (address, slot) { - return web3.eth.getStorageAt( - web3.utils.isAddress(address) ? address : address.address, - web3.utils.isHex(slot) ? slot : labelToSlot(slot), - ); -} - -module.exports = { - ImplementationLabel, - AdminLabel, - BeaconLabel, - ImplementationSlot: labelToSlot(ImplementationLabel), - AdminSlot: labelToSlot(AdminLabel), - BeaconSlot: labelToSlot(BeaconLabel), - getSlot, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/governance.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/governance.js deleted file mode 100644 index c56ec4c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/governance.js +++ /dev/null @@ -1,211 +0,0 @@ -const { time } = require('@openzeppelin/test-helpers'); - -function zip (...args) { - return Array(Math.max(...args.map(array => array.length))) - .fill() - .map((_, i) => args.map(array => array[i])); -} - -function concatHex (...args) { - return web3.utils.bytesToHex([].concat(...args.map(h => web3.utils.hexToBytes(h || '0x')))); -} - -function concatOpts (args, opts = null) { - return opts ? args.concat(opts) : args; -} - -class GovernorHelper { - constructor (governor) { - this.governor = governor; - } - - delegate (delegation = {}, opts = null) { - return Promise.all([ - delegation.token.delegate(delegation.to, { from: delegation.to }), - delegation.value && - delegation.token.transfer(...concatOpts([ delegation.to, delegation.value ]), opts), - delegation.tokenId && - delegation.token.ownerOf(delegation.tokenId).then(owner => - delegation.token.transferFrom(...concatOpts([ owner, delegation.to, delegation.tokenId ], opts)), - ), - ]); - } - - propose (opts = null) { - const proposal = this.currentProposal; - - return this.governor.methods[ - proposal.useCompatibilityInterface - ? 'propose(address[],uint256[],string[],bytes[],string)' - : 'propose(address[],uint256[],bytes[],string)' - ](...concatOpts(proposal.fullProposal, opts)); - } - - queue (opts = null) { - const proposal = this.currentProposal; - - return proposal.useCompatibilityInterface - ? this.governor.methods['queue(uint256)'](...concatOpts( - [ proposal.id ], - opts, - )) - : this.governor.methods['queue(address[],uint256[],bytes[],bytes32)'](...concatOpts( - proposal.shortProposal, - opts, - )); - } - - execute (opts = null) { - const proposal = this.currentProposal; - - return proposal.useCompatibilityInterface - ? this.governor.methods['execute(uint256)'](...concatOpts( - [ proposal.id ], - opts, - )) - : this.governor.methods['execute(address[],uint256[],bytes[],bytes32)'](...concatOpts( - proposal.shortProposal, - opts, - )); - } - - cancel (opts = null) { - const proposal = this.currentProposal; - - return proposal.useCompatibilityInterface - ? this.governor.methods['cancel(uint256)'](...concatOpts( - [ proposal.id ], - opts, - )) - : this.governor.methods['cancel(address[],uint256[],bytes[],bytes32)'](...concatOpts( - proposal.shortProposal, - opts, - )); - } - - vote (vote = {}, opts = null) { - const proposal = this.currentProposal; - - return vote.signature - // if signature, and either params or reason → - ? vote.params || vote.reason - ? vote.signature({ - proposalId: proposal.id, - support: vote.support, - reason: vote.reason || '', - params: vote.params || '', - }).then(({ v, r, s }) => this.governor.castVoteWithReasonAndParamsBySig(...concatOpts( - [ proposal.id, vote.support, vote.reason || '', vote.params || '', v, r, s ], - opts, - ))) - : vote.signature({ - proposalId: proposal.id, - support: vote.support, - }).then(({ v, r, s }) => this.governor.castVoteBySig(...concatOpts( - [ proposal.id, vote.support, v, r, s ], - opts, - ))) - : vote.params - // otherwise if params - ? this.governor.castVoteWithReasonAndParams(...concatOpts( - [ proposal.id, vote.support, vote.reason || '', vote.params ], - opts, - )) - : vote.reason - // otherwise if reason - ? this.governor.castVoteWithReason(...concatOpts( - [ proposal.id, vote.support, vote.reason ], - opts, - )) - : this.governor.castVote(...concatOpts( - [ proposal.id, vote.support ], - opts, - )); - } - - waitForSnapshot (offset = 0) { - const proposal = this.currentProposal; - return this.governor.proposalSnapshot(proposal.id) - .then(blockNumber => time.advanceBlockTo(blockNumber.addn(offset))); - } - - waitForDeadline (offset = 0) { - const proposal = this.currentProposal; - return this.governor.proposalDeadline(proposal.id) - .then(blockNumber => time.advanceBlockTo(blockNumber.addn(offset))); - } - - waitForEta (offset = 0) { - const proposal = this.currentProposal; - return this.governor.proposalEta(proposal.id) - .then(timestamp => time.increaseTo(timestamp.addn(offset))); - } - - /** - * Specify a proposal either as - * 1) an array of objects [{ target, value, data, signature? }] - * 2) an object of arrays { targets: [], values: [], data: [], signatures?: [] } - */ - setProposal (actions, description) { - let targets, values, signatures, data, useCompatibilityInterface; - - if (Array.isArray(actions)) { - useCompatibilityInterface = actions.some(a => 'signature' in a); - targets = actions.map(a => a.target); - values = actions.map(a => a.value || '0'); - signatures = actions.map(a => a.signature || ''); - data = actions.map(a => a.data || '0x'); - } else { - useCompatibilityInterface = Array.isArray(actions.signatures); - ({ targets, values, signatures = [], data } = actions); - } - - const fulldata = zip(signatures.map(s => s && web3.eth.abi.encodeFunctionSignature(s)), data) - .map(hexs => concatHex(...hexs)); - - const descriptionHash = web3.utils.keccak256(description); - - // condensed version for queueing end executing - const shortProposal = [ - targets, - values, - fulldata, - descriptionHash, - ]; - - // full version for proposing - const fullProposal = [ - targets, - values, - ...(useCompatibilityInterface ? [ signatures ] : []), - data, - description, - ]; - - // proposal id - const id = web3.utils.toBN(web3.utils.keccak256(web3.eth.abi.encodeParameters( - [ 'address[]', 'uint256[]', 'bytes[]', 'bytes32' ], - shortProposal, - ))); - - this.currentProposal = { - id, - targets, - values, - signatures, - data, - fulldata, - description, - descriptionHash, - shortProposal, - fullProposal, - useCompatibilityInterface, - }; - - return this.currentProposal; - } -} - -module.exports = { - GovernorHelper, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/sign.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/sign.js deleted file mode 100644 index 4c14d1f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/sign.js +++ /dev/null @@ -1,47 +0,0 @@ -function toEthSignedMessageHash (messageHex) { - const messageBuffer = Buffer.from(messageHex.substring(2), 'hex'); - const prefix = Buffer.from(`\u0019Ethereum Signed Message:\n${messageBuffer.length}`); - return web3.utils.sha3(Buffer.concat([prefix, messageBuffer])); -} - -/** - * Create a signer between a contract and a signer for a voucher of method, args, and redeemer - * Note that `method` is the web3 method, not the truffle-contract method - * @param contract TruffleContract - * @param signer address - * @param redeemer address - * @param methodName string - * @param methodArgs any[] - */ -const getSignFor = (contract, signer) => (redeemer, methodName, methodArgs = []) => { - const parts = [ - contract.address, - redeemer, - ]; - - const REAL_SIGNATURE_SIZE = 2 * 65; // 65 bytes in hexadecimal string length - const PADDED_SIGNATURE_SIZE = 2 * 96; // 96 bytes in hexadecimal string length - const DUMMY_SIGNATURE = `0x${web3.utils.padLeft('', REAL_SIGNATURE_SIZE)}`; - - // if we have a method, add it to the parts that we're signing - if (methodName) { - if (methodArgs.length > 0) { - parts.push( - contract.contract.methods[methodName](...methodArgs.concat([DUMMY_SIGNATURE])).encodeABI() - .slice(0, -1 * PADDED_SIGNATURE_SIZE), - ); - } else { - const abi = contract.abi.find(abi => abi.name === methodName); - parts.push(abi.signature); - } - } - - // return the signature of the "Ethereum Signed Message" hash of the hash of `parts` - const messageHex = web3.utils.soliditySha3(...parts); - return web3.eth.sign(messageHex, signer); -}; - -module.exports = { - toEthSignedMessageHash, - getSignFor, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/txpool.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/txpool.js deleted file mode 100644 index 895246b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/helpers/txpool.js +++ /dev/null @@ -1,40 +0,0 @@ -const { network } = require('hardhat'); -const { promisify } = require('util'); - -const queue = promisify(setImmediate); - -async function countPendingTransactions () { - return parseInt( - await network.provider.send('eth_getBlockTransactionCountByNumber', ['pending']), - ); -} - -async function batchInBlock (txs) { - try { - // disable auto-mining - await network.provider.send('evm_setAutomine', [false]); - // send all transactions - const promises = txs.map(fn => fn()); - // wait for node to have all pending transactions - while (txs.length > await countPendingTransactions()) { - await queue(); - } - // mine one block - await network.provider.send('evm_mine'); - // fetch receipts - const receipts = await Promise.all(promises); - // Sanity check, all tx should be in the same block - const minedBlocks = new Set(receipts.map(({ receipt }) => receipt.blockNumber)); - expect(minedBlocks.size).to.equal(1); - - return receipts; - } finally { - // enable auto-mining - await network.provider.send('evm_setAutomine', [true]); - } -} - -module.exports = { - countPendingTransactions, - batchInBlock, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/metatx/ERC2771Context.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/metatx/ERC2771Context.test.js deleted file mode 100644 index 8db92ab..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/metatx/ERC2771Context.test.js +++ /dev/null @@ -1,109 +0,0 @@ -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; -const { EIP712Domain } = require('../helpers/eip712'); - -const { expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const ERC2771ContextMock = artifacts.require('ERC2771ContextMock'); -const MinimalForwarder = artifacts.require('MinimalForwarder'); -const ContextMockCaller = artifacts.require('ContextMockCaller'); - -const { shouldBehaveLikeRegularContext } = require('../utils/Context.behavior'); - -const name = 'MinimalForwarder'; -const version = '0.0.1'; - -contract('ERC2771Context', function (accounts) { - beforeEach(async function () { - this.forwarder = await MinimalForwarder.new(); - this.recipient = await ERC2771ContextMock.new(this.forwarder.address); - - this.domain = { - name, - version, - chainId: await web3.eth.getChainId(), - verifyingContract: this.forwarder.address, - }; - this.types = { - EIP712Domain, - ForwardRequest: [ - { name: 'from', type: 'address' }, - { name: 'to', type: 'address' }, - { name: 'value', type: 'uint256' }, - { name: 'gas', type: 'uint256' }, - { name: 'nonce', type: 'uint256' }, - { name: 'data', type: 'bytes' }, - ], - }; - }); - - it('recognize trusted forwarder', async function () { - expect(await this.recipient.isTrustedForwarder(this.forwarder.address)); - }); - - context('when called directly', function () { - beforeEach(async function () { - this.context = this.recipient; // The Context behavior expects the contract in this.context - this.caller = await ContextMockCaller.new(); - }); - - shouldBehaveLikeRegularContext(...accounts); - }); - - context('when receiving a relayed call', function () { - beforeEach(async function () { - this.wallet = Wallet.generate(); - this.sender = web3.utils.toChecksumAddress(this.wallet.getAddressString()); - this.data = { - types: this.types, - domain: this.domain, - primaryType: 'ForwardRequest', - }; - }); - - describe('msgSender', function () { - it('returns the relayed transaction original sender', async function () { - const data = this.recipient.contract.methods.msgSender().encodeABI(); - - const req = { - from: this.sender, - to: this.recipient.address, - value: '0', - gas: '100000', - nonce: (await this.forwarder.getNonce(this.sender)).toString(), - data, - }; - - const sign = ethSigUtil.signTypedMessage(this.wallet.getPrivateKey(), { data: { ...this.data, message: req } }); - expect(await this.forwarder.verify(req, sign)).to.equal(true); - - const { tx } = await this.forwarder.execute(req, sign); - await expectEvent.inTransaction(tx, ERC2771ContextMock, 'Sender', { sender: this.sender }); - }); - }); - - describe('msgData', function () { - it('returns the relayed transaction original data', async function () { - const integerValue = '42'; - const stringValue = 'OpenZeppelin'; - const data = this.recipient.contract.methods.msgData(integerValue, stringValue).encodeABI(); - - const req = { - from: this.sender, - to: this.recipient.address, - value: '0', - gas: '100000', - nonce: (await this.forwarder.getNonce(this.sender)).toString(), - data, - }; - - const sign = ethSigUtil.signTypedMessage(this.wallet.getPrivateKey(), { data: { ...this.data, message: req } }); - expect(await this.forwarder.verify(req, sign)).to.equal(true); - - const { tx } = await this.forwarder.execute(req, sign); - await expectEvent.inTransaction(tx, ERC2771ContextMock, 'Data', { data, integerValue, stringValue }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/metatx/MinimalForwarder.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/metatx/MinimalForwarder.test.js deleted file mode 100644 index b8984e4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/metatx/MinimalForwarder.test.js +++ /dev/null @@ -1,184 +0,0 @@ -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; -const { EIP712Domain } = require('../helpers/eip712'); - -const { expectRevert, constants } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const MinimalForwarder = artifacts.require('MinimalForwarder'); -const CallReceiverMock = artifacts.require('CallReceiverMock'); - -const name = 'MinimalForwarder'; -const version = '0.0.1'; - -contract('MinimalForwarder', function (accounts) { - beforeEach(async function () { - this.forwarder = await MinimalForwarder.new(); - this.domain = { - name, - version, - chainId: await web3.eth.getChainId(), - verifyingContract: this.forwarder.address, - }; - this.types = { - EIP712Domain, - ForwardRequest: [ - { name: 'from', type: 'address' }, - { name: 'to', type: 'address' }, - { name: 'value', type: 'uint256' }, - { name: 'gas', type: 'uint256' }, - { name: 'nonce', type: 'uint256' }, - { name: 'data', type: 'bytes' }, - ], - }; - }); - - context('with message', function () { - beforeEach(async function () { - this.wallet = Wallet.generate(); - this.sender = web3.utils.toChecksumAddress(this.wallet.getAddressString()); - this.req = { - from: this.sender, - to: constants.ZERO_ADDRESS, - value: '0', - gas: '100000', - nonce: Number(await this.forwarder.getNonce(this.sender)), - data: '0x', - }; - this.sign = () => ethSigUtil.signTypedMessage( - this.wallet.getPrivateKey(), - { - data: { - types: this.types, - domain: this.domain, - primaryType: 'ForwardRequest', - message: this.req, - }, - }, - ); - }); - - context('verify', function () { - context('valid signature', function () { - beforeEach(async function () { - expect(await this.forwarder.getNonce(this.req.from)) - .to.be.bignumber.equal(web3.utils.toBN(this.req.nonce)); - }); - - it('success', async function () { - expect(await this.forwarder.verify(this.req, this.sign())).to.be.equal(true); - }); - - afterEach(async function () { - expect(await this.forwarder.getNonce(this.req.from)) - .to.be.bignumber.equal(web3.utils.toBN(this.req.nonce)); - }); - }); - - context('invalid signature', function () { - it('tampered from', async function () { - expect(await this.forwarder.verify({ ...this.req, from: accounts[0] }, this.sign())) - .to.be.equal(false); - }); - it('tampered to', async function () { - expect(await this.forwarder.verify({ ...this.req, to: accounts[0] }, this.sign())) - .to.be.equal(false); - }); - it('tampered value', async function () { - expect(await this.forwarder.verify({ ...this.req, value: web3.utils.toWei('1') }, this.sign())) - .to.be.equal(false); - }); - it('tampered nonce', async function () { - expect(await this.forwarder.verify({ ...this.req, nonce: this.req.nonce + 1 }, this.sign())) - .to.be.equal(false); - }); - it('tampered data', async function () { - expect(await this.forwarder.verify({ ...this.req, data: '0x1742' }, this.sign())) - .to.be.equal(false); - }); - it('tampered signature', async function () { - const tamperedsign = web3.utils.hexToBytes(this.sign()); - tamperedsign[42] ^= 0xff; - expect(await this.forwarder.verify(this.req, web3.utils.bytesToHex(tamperedsign))) - .to.be.equal(false); - }); - }); - }); - - context('execute', function () { - context('valid signature', function () { - beforeEach(async function () { - expect(await this.forwarder.getNonce(this.req.from)) - .to.be.bignumber.equal(web3.utils.toBN(this.req.nonce)); - }); - - it('success', async function () { - await this.forwarder.execute(this.req, this.sign()); // expect to not revert - }); - - afterEach(async function () { - expect(await this.forwarder.getNonce(this.req.from)) - .to.be.bignumber.equal(web3.utils.toBN(this.req.nonce + 1)); - }); - }); - - context('invalid signature', function () { - it('tampered from', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, from: accounts[0] }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered to', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, to: accounts[0] }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered value', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, value: web3.utils.toWei('1') }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered nonce', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, nonce: this.req.nonce + 1 }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered data', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, data: '0x1742' }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered signature', async function () { - const tamperedsign = web3.utils.hexToBytes(this.sign()); - tamperedsign[42] ^= 0xff; - await expectRevert( - this.forwarder.execute(this.req, web3.utils.bytesToHex(tamperedsign)), - 'MinimalForwarder: signature does not match request', - ); - }); - }); - - it('bubble out of gas', async function () { - const receiver = await CallReceiverMock.new(); - const gasAvailable = 100000; - this.req.to = receiver.address; - this.req.data = receiver.contract.methods.mockFunctionOutOfGas().encodeABI(); - this.req.gas = 1000000; - - await expectRevert.assertion( - this.forwarder.execute(this.req, this.sign(), { gas: gasAvailable }), - ); - - const { transactions } = await web3.eth.getBlock('latest'); - const { gasUsed } = await web3.eth.getTransactionReceipt(transactions[0]); - - expect(gasUsed).to.be.equal(gasAvailable); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/migrate-imports.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/migrate-imports.test.js deleted file mode 100644 index 639767c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/migrate-imports.test.js +++ /dev/null @@ -1,29 +0,0 @@ -const path = require('path'); -const { promises: fs, constants: { F_OK } } = require('fs'); -const { expect } = require('chai'); - -const { pathUpdates, updateImportPaths, getUpgradeablePath } = require('../scripts/migrate-imports.js'); - -describe('migrate-imports.js', function () { - it('every new path exists', async function () { - for (const p of Object.values(pathUpdates)) { - try { - await fs.access(path.join('contracts', p), F_OK); - } catch (e) { - await fs.access(path.join('contracts', getUpgradeablePath(p)), F_OK); - } - } - }); - - it('replaces import paths in a file', async function () { - const source = ` -import '@openzeppelin/contracts/math/Math.sol'; -import '@openzeppelin/contracts-upgradeable/math/MathUpgradeable.sol'; - `; - const expected = ` -import '@openzeppelin/contracts/utils/math/Math.sol'; -import '@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol'; - `; - expect(updateImportPaths(source)).to.equal(expected); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Clones.behaviour.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Clones.behaviour.js deleted file mode 100644 index 81c5ee3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Clones.behaviour.js +++ /dev/null @@ -1,150 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const DummyImplementation = artifacts.require('DummyImplementation'); - -module.exports = function shouldBehaveLikeClone (createClone) { - before('deploy implementation', async function () { - this.implementation = web3.utils.toChecksumAddress((await DummyImplementation.new()).address); - }); - - const assertProxyInitialization = function ({ value, balance }) { - it('initializes the proxy', async function () { - const dummy = new DummyImplementation(this.proxy); - expect(await dummy.value()).to.be.bignumber.equal(value.toString()); - }); - - it('has expected balance', async function () { - expect(await web3.eth.getBalance(this.proxy)).to.be.bignumber.equal(balance.toString()); - }); - }; - - describe('initialization without parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10; - const initializeData = new DummyImplementation('').contract.methods['initializeNonPayable()']().encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expectRevert.unspecified( - createClone(this.implementation, initializeData, { value }), - ); - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 100; - const initializeData = new DummyImplementation('').contract.methods['initializePayable()']().encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData, { value }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); - - describe('initialization with parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10; - const initializeData = new DummyImplementation('').contract - .methods.initializeNonPayableWithValue(expectedInitializedValue).encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expectRevert.unspecified( - createClone(this.implementation, initializeData, { value }), - ); - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 42; - const initializeData = new DummyImplementation('').contract - .methods.initializePayableWithValue(expectedInitializedValue).encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData, { value }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Clones.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Clones.test.js deleted file mode 100644 index 65e5ac1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Clones.test.js +++ /dev/null @@ -1,69 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { computeCreate2Address } = require('../helpers/create2'); -const { expect } = require('chai'); - -const shouldBehaveLikeClone = require('./Clones.behaviour'); - -const ClonesMock = artifacts.require('ClonesMock'); - -contract('Clones', function (accounts) { - describe('clone', function () { - shouldBehaveLikeClone(async (implementation, initData, opts = {}) => { - const factory = await ClonesMock.new(); - const receipt = await factory.clone(implementation, initData, { value: opts.value }); - const address = receipt.logs.find(({ event }) => event === 'NewInstance').args.instance; - return { address }; - }); - }); - - describe('cloneDeterministic', function () { - shouldBehaveLikeClone(async (implementation, initData, opts = {}) => { - const salt = web3.utils.randomHex(32); - const factory = await ClonesMock.new(); - const receipt = await factory.cloneDeterministic(implementation, salt, initData, { value: opts.value }); - const address = receipt.logs.find(({ event }) => event === 'NewInstance').args.instance; - return { address }; - }); - - it('address already used', async function () { - const implementation = web3.utils.randomHex(20); - const salt = web3.utils.randomHex(32); - const factory = await ClonesMock.new(); - // deploy once - expectEvent( - await factory.cloneDeterministic(implementation, salt, '0x'), - 'NewInstance', - ); - // deploy twice - await expectRevert( - factory.cloneDeterministic(implementation, salt, '0x'), - 'ERC1167: create2 failed', - ); - }); - - it('address prediction', async function () { - const implementation = web3.utils.randomHex(20); - const salt = web3.utils.randomHex(32); - const factory = await ClonesMock.new(); - const predicted = await factory.predictDeterministicAddress(implementation, salt); - - const creationCode = [ - '0x3d602d80600a3d3981f3363d3d373d3d3d363d73', - implementation.replace(/0x/, '').toLowerCase(), - '5af43d82803e903d91602b57fd5bf3', - ].join(''); - - expect(computeCreate2Address( - salt, - creationCode, - factory.address, - )).to.be.equal(predicted); - - expectEvent( - await factory.cloneDeterministic(implementation, salt, '0x'), - 'NewInstance', - { instance: predicted }, - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/ERC1967/ERC1967Proxy.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/ERC1967/ERC1967Proxy.test.js deleted file mode 100644 index 22df960..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/ERC1967/ERC1967Proxy.test.js +++ /dev/null @@ -1,13 +0,0 @@ -const shouldBehaveLikeProxy = require('../Proxy.behaviour'); - -const ERC1967Proxy = artifacts.require('ERC1967Proxy'); - -contract('ERC1967Proxy', function (accounts) { - const [proxyAdminOwner] = accounts; - - const createProxy = async function (implementation, _admin, initData, opts) { - return ERC1967Proxy.new(implementation, initData, opts); - }; - - shouldBehaveLikeProxy(createProxy, undefined, proxyAdminOwner); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Proxy.behaviour.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Proxy.behaviour.js deleted file mode 100644 index 435792f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/Proxy.behaviour.js +++ /dev/null @@ -1,224 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { getSlot, ImplementationSlot } = require('../helpers/erc1967'); - -const { expect } = require('chai'); - -const DummyImplementation = artifacts.require('DummyImplementation'); - -module.exports = function shouldBehaveLikeProxy (createProxy, proxyAdminAddress, proxyCreator) { - it('cannot be initialized with a non-contract address', async function () { - const nonContractAddress = proxyCreator; - const initializeData = Buffer.from(''); - await expectRevert.unspecified( - createProxy(nonContractAddress, proxyAdminAddress, initializeData, { - from: proxyCreator, - }), - ); - }); - - before('deploy implementation', async function () { - this.implementation = web3.utils.toChecksumAddress((await DummyImplementation.new()).address); - }); - - const assertProxyInitialization = function ({ value, balance }) { - it('sets the implementation address', async function () { - const implementationSlot = await getSlot(this.proxy, ImplementationSlot); - const implementationAddress = web3.utils.toChecksumAddress(implementationSlot.substr(-40)); - expect(implementationAddress).to.be.equal(this.implementation); - }); - - it('initializes the proxy', async function () { - const dummy = new DummyImplementation(this.proxy); - expect(await dummy.value()).to.be.bignumber.equal(value.toString()); - }); - - it('has expected balance', async function () { - expect(await web3.eth.getBalance(this.proxy)).to.be.bignumber.equal(balance.toString()); - }); - }; - - describe('without initialization', function () { - const initializeData = Buffer.from(''); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ value: 0, balance: 0 }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - value, - }) - ).address; - }); - - assertProxyInitialization({ value: 0, balance: value }); - }); - }); - - describe('initialization without parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10; - const initializeData = new DummyImplementation('').contract.methods['initializeNonPayable()']().encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expectRevert.unspecified( - createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator, value }), - ); - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 100; - const initializeData = new DummyImplementation('').contract.methods['initializePayable()']().encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - value, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); - - describe('initialization with parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10; - const initializeData = new DummyImplementation('').contract - .methods.initializeNonPayableWithValue(expectedInitializedValue).encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expectRevert.unspecified( - createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator, value }), - ); - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 42; - const initializeData = new DummyImplementation('').contract - .methods.initializePayableWithValue(expectedInitializedValue).encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - value, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - - describe('reverting initialization', function () { - const initializeData = new DummyImplementation('').contract - .methods.reverts().encodeABI(); - - it('reverts', async function () { - await expectRevert( - createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator }), - 'DummyImplementation reverted', - ); - }); - }); - }); -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/beacon/BeaconProxy.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/beacon/BeaconProxy.test.js deleted file mode 100644 index 0a4a8d0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/beacon/BeaconProxy.test.js +++ /dev/null @@ -1,156 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { getSlot, BeaconSlot } = require('../../helpers/erc1967'); - -const { expect } = require('chai'); - -const UpgradeableBeacon = artifacts.require('UpgradeableBeacon'); -const BeaconProxy = artifacts.require('BeaconProxy'); -const DummyImplementation = artifacts.require('DummyImplementation'); -const DummyImplementationV2 = artifacts.require('DummyImplementationV2'); -const BadBeaconNoImpl = artifacts.require('BadBeaconNoImpl'); -const BadBeaconNotContract = artifacts.require('BadBeaconNotContract'); - -contract('BeaconProxy', function (accounts) { - const [anotherAccount] = accounts; - - describe('bad beacon is not accepted', async function () { - it('non-contract beacon', async function () { - await expectRevert( - BeaconProxy.new(anotherAccount, '0x'), - 'ERC1967: new beacon is not a contract', - ); - }); - - it('non-compliant beacon', async function () { - const beacon = await BadBeaconNoImpl.new(); - await expectRevert.unspecified( - BeaconProxy.new(beacon.address, '0x'), - ); - }); - - it('non-contract implementation', async function () { - const beacon = await BadBeaconNotContract.new(); - await expectRevert( - BeaconProxy.new(beacon.address, '0x'), - 'ERC1967: beacon implementation is not a contract', - ); - }); - }); - - before('deploy implementation', async function () { - this.implementationV0 = await DummyImplementation.new(); - this.implementationV1 = await DummyImplementationV2.new(); - }); - - describe('initialization', function () { - before(function () { - this.assertInitialized = async ({ value, balance }) => { - const beaconSlot = await getSlot(this.proxy, BeaconSlot); - const beaconAddress = web3.utils.toChecksumAddress(beaconSlot.substr(-40)); - expect(beaconAddress).to.equal(this.beacon.address); - - const dummy = new DummyImplementation(this.proxy.address); - expect(await dummy.value()).to.bignumber.eq(value); - - expect(await web3.eth.getBalance(this.proxy.address)).to.bignumber.eq(balance); - }; - }); - - beforeEach('deploy beacon', async function () { - this.beacon = await UpgradeableBeacon.new(this.implementationV0.address); - }); - - it('no initialization', async function () { - const data = Buffer.from(''); - const balance = '10'; - this.proxy = await BeaconProxy.new(this.beacon.address, data, { value: balance }); - await this.assertInitialized({ value: '0', balance }); - }); - - it('non-payable initialization', async function () { - const value = '55'; - const data = this.implementationV0.contract.methods - .initializeNonPayableWithValue(value) - .encodeABI(); - this.proxy = await BeaconProxy.new(this.beacon.address, data); - await this.assertInitialized({ value, balance: '0' }); - }); - - it('payable initialization', async function () { - const value = '55'; - const data = this.implementationV0.contract.methods - .initializePayableWithValue(value) - .encodeABI(); - const balance = '100'; - this.proxy = await BeaconProxy.new(this.beacon.address, data, { value: balance }); - await this.assertInitialized({ value, balance }); - }); - - it('reverting initialization', async function () { - const data = this.implementationV0.contract.methods.reverts().encodeABI(); - await expectRevert( - BeaconProxy.new(this.beacon.address, data), - 'DummyImplementation reverted', - ); - }); - }); - - it('upgrade a proxy by upgrading its beacon', async function () { - const beacon = await UpgradeableBeacon.new(this.implementationV0.address); - - const value = '10'; - const data = this.implementationV0.contract.methods - .initializeNonPayableWithValue(value) - .encodeABI(); - const proxy = await BeaconProxy.new(beacon.address, data); - - const dummy = new DummyImplementation(proxy.address); - - // test initial values - expect(await dummy.value()).to.bignumber.eq(value); - - // test initial version - expect(await dummy.version()).to.eq('V1'); - - // upgrade beacon - await beacon.upgradeTo(this.implementationV1.address); - - // test upgraded version - expect(await dummy.version()).to.eq('V2'); - }); - - it('upgrade 2 proxies by upgrading shared beacon', async function () { - const value1 = '10'; - const value2 = '42'; - - const beacon = await UpgradeableBeacon.new(this.implementationV0.address); - - const proxy1InitializeData = this.implementationV0.contract.methods - .initializeNonPayableWithValue(value1) - .encodeABI(); - const proxy1 = await BeaconProxy.new(beacon.address, proxy1InitializeData); - - const proxy2InitializeData = this.implementationV0.contract.methods - .initializeNonPayableWithValue(value2) - .encodeABI(); - const proxy2 = await BeaconProxy.new(beacon.address, proxy2InitializeData); - - const dummy1 = new DummyImplementation(proxy1.address); - const dummy2 = new DummyImplementation(proxy2.address); - - // test initial values - expect(await dummy1.value()).to.bignumber.eq(value1); - expect(await dummy2.value()).to.bignumber.eq(value2); - - // test initial version - expect(await dummy1.version()).to.eq('V1'); - expect(await dummy2.version()).to.eq('V1'); - - // upgrade beacon - await beacon.upgradeTo(this.implementationV1.address); - - // test upgraded version - expect(await dummy1.version()).to.eq('V2'); - expect(await dummy2.version()).to.eq('V2'); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/beacon/UpgradeableBeacon.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/beacon/UpgradeableBeacon.test.js deleted file mode 100644 index 0c49906..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/beacon/UpgradeableBeacon.test.js +++ /dev/null @@ -1,50 +0,0 @@ -const { expectRevert, expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const UpgradeableBeacon = artifacts.require('UpgradeableBeacon'); -const Implementation1 = artifacts.require('Implementation1'); -const Implementation2 = artifacts.require('Implementation2'); - -contract('UpgradeableBeacon', function (accounts) { - const [owner, other] = accounts; - - it('cannot be created with non-contract implementation', async function () { - await expectRevert( - UpgradeableBeacon.new(accounts[0]), - 'UpgradeableBeacon: implementation is not a contract', - ); - }); - - context('once deployed', async function () { - beforeEach('deploying beacon', async function () { - this.v1 = await Implementation1.new(); - this.beacon = await UpgradeableBeacon.new(this.v1.address, { from: owner }); - }); - - it('returns implementation', async function () { - expect(await this.beacon.implementation()).to.equal(this.v1.address); - }); - - it('can be upgraded by the owner', async function () { - const v2 = await Implementation2.new(); - const receipt = await this.beacon.upgradeTo(v2.address, { from: owner }); - expectEvent(receipt, 'Upgraded', { implementation: v2.address }); - expect(await this.beacon.implementation()).to.equal(v2.address); - }); - - it('cannot be upgraded to a non-contract', async function () { - await expectRevert( - this.beacon.upgradeTo(other, { from: owner }), - 'UpgradeableBeacon: implementation is not a contract', - ); - }); - - it('cannot be upgraded by other account', async function () { - const v2 = await Implementation2.new(); - await expectRevert( - this.beacon.upgradeTo(v2.address, { from: other }), - 'Ownable: caller is not the owner', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/ProxyAdmin.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/ProxyAdmin.test.js deleted file mode 100644 index 5187fb2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/ProxyAdmin.test.js +++ /dev/null @@ -1,127 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ImplV1 = artifacts.require('DummyImplementation'); -const ImplV2 = artifacts.require('DummyImplementationV2'); -const ProxyAdmin = artifacts.require('ProxyAdmin'); -const TransparentUpgradeableProxy = artifacts.require('TransparentUpgradeableProxy'); -const ITransparentUpgradeableProxy = artifacts.require('ITransparentUpgradeableProxy'); - -contract('ProxyAdmin', function (accounts) { - const [proxyAdminOwner, newAdmin, anotherAccount] = accounts; - - before('set implementations', async function () { - this.implementationV1 = await ImplV1.new(); - this.implementationV2 = await ImplV2.new(); - }); - - beforeEach(async function () { - const initializeData = Buffer.from(''); - this.proxyAdmin = await ProxyAdmin.new({ from: proxyAdminOwner }); - const proxy = await TransparentUpgradeableProxy.new( - this.implementationV1.address, - this.proxyAdmin.address, - initializeData, - { from: proxyAdminOwner }, - ); - this.proxy = await ITransparentUpgradeableProxy.at(proxy.address); - }); - - it('has an owner', async function () { - expect(await this.proxyAdmin.owner()).to.equal(proxyAdminOwner); - }); - - describe('#getProxyAdmin', function () { - it('returns proxyAdmin as admin of the proxy', async function () { - const admin = await this.proxyAdmin.getProxyAdmin(this.proxy.address); - expect(admin).to.be.equal(this.proxyAdmin.address); - }); - - it('call to invalid proxy', async function () { - await expectRevert.unspecified(this.proxyAdmin.getProxyAdmin(this.implementationV1.address)); - }); - }); - - describe('#changeProxyAdmin', function () { - it('fails to change proxy admin if its not the proxy owner', async function () { - await expectRevert( - this.proxyAdmin.changeProxyAdmin(this.proxy.address, newAdmin, { from: anotherAccount }), - 'caller is not the owner', - ); - }); - - it('changes proxy admin', async function () { - await this.proxyAdmin.changeProxyAdmin(this.proxy.address, newAdmin, { from: proxyAdminOwner }); - expect(await this.proxy.admin.call({ from: newAdmin })).to.eq(newAdmin); - }); - }); - - describe('#getProxyImplementation', function () { - it('returns proxy implementation address', async function () { - const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address); - expect(implementationAddress).to.be.equal(this.implementationV1.address); - }); - - it('call to invalid proxy', async function () { - await expectRevert.unspecified(this.proxyAdmin.getProxyImplementation(this.implementationV1.address)); - }); - }); - - describe('#upgrade', function () { - context('with unauthorized account', function () { - it('fails to upgrade', async function () { - await expectRevert( - this.proxyAdmin.upgrade(this.proxy.address, this.implementationV2.address, { from: anotherAccount }), - 'caller is not the owner', - ); - }); - }); - - context('with authorized account', function () { - it('upgrades implementation', async function () { - await this.proxyAdmin.upgrade(this.proxy.address, this.implementationV2.address, { from: proxyAdminOwner }); - const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address); - expect(implementationAddress).to.be.equal(this.implementationV2.address); - }); - }); - }); - - describe('#upgradeAndCall', function () { - context('with unauthorized account', function () { - it('fails to upgrade', async function () { - const callData = new ImplV1('').contract.methods.initializeNonPayableWithValue(1337).encodeABI(); - await expectRevert( - this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData, - { from: anotherAccount }, - ), - 'caller is not the owner', - ); - }); - }); - - context('with authorized account', function () { - context('with invalid callData', function () { - it('fails to upgrade', async function () { - const callData = '0x12345678'; - await expectRevert.unspecified( - this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData, - { from: proxyAdminOwner }, - ), - ); - }); - }); - - context('with valid callData', function () { - it('upgrades implementation', async function () { - const callData = new ImplV1('').contract.methods.initializeNonPayableWithValue(1337).encodeABI(); - await this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData, - { from: proxyAdminOwner }, - ); - const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address); - expect(implementationAddress).to.be.equal(this.implementationV2.address); - }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js deleted file mode 100644 index 114b938..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js +++ /dev/null @@ -1,440 +0,0 @@ -const { BN, expectRevert, expectEvent, constants } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; -const { getSlot, ImplementationSlot, AdminSlot } = require('../../helpers/erc1967'); - -const { expect } = require('chai'); - -const Proxy = artifacts.require('Proxy'); -const Implementation1 = artifacts.require('Implementation1'); -const Implementation2 = artifacts.require('Implementation2'); -const Implementation3 = artifacts.require('Implementation3'); -const Implementation4 = artifacts.require('Implementation4'); -const MigratableMockV1 = artifacts.require('MigratableMockV1'); -const MigratableMockV2 = artifacts.require('MigratableMockV2'); -const MigratableMockV3 = artifacts.require('MigratableMockV3'); -const InitializableMock = artifacts.require('InitializableMock'); -const DummyImplementation = artifacts.require('DummyImplementation'); -const ClashingImplementation = artifacts.require('ClashingImplementation'); - -module.exports = function shouldBehaveLikeTransparentUpgradeableProxy (createProxy, accounts) { - const [proxyAdminAddress, proxyAdminOwner, anotherAccount] = accounts; - - before(async function () { - this.implementationV0 = (await DummyImplementation.new()).address; - this.implementationV1 = (await DummyImplementation.new()).address; - }); - - beforeEach(async function () { - const initializeData = Buffer.from(''); - this.proxy = await createProxy(this.implementationV0, proxyAdminAddress, initializeData, { - from: proxyAdminOwner, - }); - this.proxyAddress = this.proxy.address; - }); - - describe('implementation', function () { - it('returns the current implementation address', async function () { - const implementation = await this.proxy.implementation({ from: proxyAdminAddress }); - - expect(implementation).to.be.equal(this.implementationV0); - }); - - it('delegates to the implementation', async function () { - const dummy = new DummyImplementation(this.proxyAddress); - const value = await dummy.get(); - - expect(value).to.equal(true); - }); - }); - - describe('upgradeTo', function () { - describe('when the sender is the admin', function () { - const from = proxyAdminAddress; - - describe('when the given implementation is different from the current one', function () { - it('upgrades to the requested implementation', async function () { - await this.proxy.upgradeTo(this.implementationV1, { from }); - - const implementation = await this.proxy.implementation({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.implementationV1); - }); - - it('emits an event', async function () { - expectEvent( - await this.proxy.upgradeTo(this.implementationV1, { from }), - 'Upgraded', { - implementation: this.implementationV1, - }, - ); - }); - }); - - describe('when the given implementation is the zero address', function () { - it('reverts', async function () { - await expectRevert( - this.proxy.upgradeTo(ZERO_ADDRESS, { from }), - 'ERC1967: new implementation is not a contract', - ); - }); - }); - }); - - describe('when the sender is not the admin', function () { - const from = anotherAccount; - - it('reverts', async function () { - await expectRevert.unspecified( - this.proxy.upgradeTo(this.implementationV1, { from }), - ); - }); - }); - }); - - describe('upgradeToAndCall', function () { - describe('without migrations', function () { - beforeEach(async function () { - this.behavior = await InitializableMock.new(); - }); - - describe('when the call does not fail', function () { - const initializeData = new InitializableMock('').contract.methods['initializeWithX(uint256)'](42).encodeABI(); - - describe('when the sender is the admin', function () { - const from = proxyAdminAddress; - const value = 1e5; - - beforeEach(async function () { - this.receipt = await this.proxy.upgradeToAndCall(this.behavior.address, initializeData, { from, value }); - }); - - it('upgrades to the requested implementation', async function () { - const implementation = await this.proxy.implementation({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.behavior.address); - }); - - it('emits an event', function () { - expectEvent(this.receipt, 'Upgraded', { implementation: this.behavior.address }); - }); - - it('calls the initializer function', async function () { - const migratable = new InitializableMock(this.proxyAddress); - const x = await migratable.x(); - expect(x).to.be.bignumber.equal('42'); - }); - - it('sends given value to the proxy', async function () { - const balance = await web3.eth.getBalance(this.proxyAddress); - expect(balance.toString()).to.be.bignumber.equal(value.toString()); - }); - - it.skip('uses the storage of the proxy', async function () { - // storage layout should look as follows: - // - 0: Initializable storage - // - 1-50: Initailizable reserved storage (50 slots) - // - 51: initializerRan - // - 52: x - const storedValue = await Proxy.at(this.proxyAddress).getStorageAt(52); - expect(parseInt(storedValue)).to.eq(42); - }); - }); - - describe('when the sender is not the admin', function () { - it('reverts', async function () { - await expectRevert.unspecified( - this.proxy.upgradeToAndCall(this.behavior.address, initializeData, { from: anotherAccount }), - ); - }); - }); - }); - - describe('when the call does fail', function () { - const initializeData = new InitializableMock('').contract.methods.fail().encodeABI(); - - it('reverts', async function () { - await expectRevert.unspecified( - this.proxy.upgradeToAndCall(this.behavior.address, initializeData, { from: proxyAdminAddress }), - ); - }); - }); - }); - - describe('with migrations', function () { - describe('when the sender is the admin', function () { - const from = proxyAdminAddress; - const value = 1e5; - - describe('when upgrading to V1', function () { - const v1MigrationData = new MigratableMockV1('').contract.methods.initialize(42).encodeABI(); - - beforeEach(async function () { - this.behaviorV1 = await MigratableMockV1.new(); - this.balancePreviousV1 = new BN(await web3.eth.getBalance(this.proxyAddress)); - this.receipt = await this.proxy.upgradeToAndCall(this.behaviorV1.address, v1MigrationData, { from, value }); - }); - - it('upgrades to the requested version and emits an event', async function () { - const implementation = await this.proxy.implementation({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.behaviorV1.address); - expectEvent(this.receipt, 'Upgraded', { implementation: this.behaviorV1.address }); - }); - - it('calls the \'initialize\' function and sends given value to the proxy', async function () { - const migratable = new MigratableMockV1(this.proxyAddress); - - const x = await migratable.x(); - expect(x).to.be.bignumber.equal('42'); - - const balance = await web3.eth.getBalance(this.proxyAddress); - expect(new BN(balance)).to.be.bignumber.equal(this.balancePreviousV1.addn(value)); - }); - - describe('when upgrading to V2', function () { - const v2MigrationData = new MigratableMockV2('').contract.methods.migrate(10, 42).encodeABI(); - - beforeEach(async function () { - this.behaviorV2 = await MigratableMockV2.new(); - this.balancePreviousV2 = new BN(await web3.eth.getBalance(this.proxyAddress)); - this.receipt = - await this.proxy.upgradeToAndCall(this.behaviorV2.address, v2MigrationData, { from, value }); - }); - - it('upgrades to the requested version and emits an event', async function () { - const implementation = await this.proxy.implementation({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.behaviorV2.address); - expectEvent(this.receipt, 'Upgraded', { implementation: this.behaviorV2.address }); - }); - - it('calls the \'migrate\' function and sends given value to the proxy', async function () { - const migratable = new MigratableMockV2(this.proxyAddress); - - const x = await migratable.x(); - expect(x).to.be.bignumber.equal('10'); - - const y = await migratable.y(); - expect(y).to.be.bignumber.equal('42'); - - const balance = new BN(await web3.eth.getBalance(this.proxyAddress)); - expect(balance).to.be.bignumber.equal(this.balancePreviousV2.addn(value)); - }); - - describe('when upgrading to V3', function () { - const v3MigrationData = new MigratableMockV3('').contract.methods['migrate()']().encodeABI(); - - beforeEach(async function () { - this.behaviorV3 = await MigratableMockV3.new(); - this.balancePreviousV3 = new BN(await web3.eth.getBalance(this.proxyAddress)); - this.receipt = - await this.proxy.upgradeToAndCall(this.behaviorV3.address, v3MigrationData, { from, value }); - }); - - it('upgrades to the requested version and emits an event', async function () { - const implementation = await this.proxy.implementation({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.behaviorV3.address); - expectEvent(this.receipt, 'Upgraded', { implementation: this.behaviorV3.address }); - }); - - it('calls the \'migrate\' function and sends given value to the proxy', async function () { - const migratable = new MigratableMockV3(this.proxyAddress); - - const x = await migratable.x(); - expect(x).to.be.bignumber.equal('42'); - - const y = await migratable.y(); - expect(y).to.be.bignumber.equal('10'); - - const balance = new BN(await web3.eth.getBalance(this.proxyAddress)); - expect(balance).to.be.bignumber.equal(this.balancePreviousV3.addn(value)); - }); - }); - }); - }); - }); - - describe('when the sender is not the admin', function () { - const from = anotherAccount; - - it('reverts', async function () { - const behaviorV1 = await MigratableMockV1.new(); - const v1MigrationData = new MigratableMockV1('').contract.methods.initialize(42).encodeABI(); - await expectRevert.unspecified( - this.proxy.upgradeToAndCall(behaviorV1.address, v1MigrationData, { from }), - ); - }); - }); - }); - }); - - describe('changeAdmin', function () { - describe('when the new proposed admin is not the zero address', function () { - const newAdmin = anotherAccount; - - describe('when the sender is the admin', function () { - beforeEach('transferring', async function () { - this.receipt = await this.proxy.changeAdmin(newAdmin, { from: proxyAdminAddress }); - }); - - it('assigns new proxy admin', async function () { - const newProxyAdmin = await this.proxy.admin({ from: newAdmin }); - expect(newProxyAdmin).to.be.equal(anotherAccount); - }); - - it('emits an event', function () { - expectEvent(this.receipt, 'AdminChanged', { - previousAdmin: proxyAdminAddress, - newAdmin: newAdmin, - }); - }); - }); - - describe('when the sender is not the admin', function () { - it('reverts', async function () { - await expectRevert.unspecified(this.proxy.changeAdmin(newAdmin, { from: anotherAccount })); - }); - }); - }); - - describe('when the new proposed admin is the zero address', function () { - it('reverts', async function () { - await expectRevert( - this.proxy.changeAdmin(ZERO_ADDRESS, { from: proxyAdminAddress }), - 'ERC1967: new admin is the zero address', - ); - }); - }); - }); - - describe('storage', function () { - it('should store the implementation address in specified location', async function () { - const implementationSlot = await getSlot(this.proxy, ImplementationSlot); - const implementationAddress = web3.utils.toChecksumAddress(implementationSlot.substr(-40)); - expect(implementationAddress).to.be.equal(this.implementationV0); - }); - - it('should store the admin proxy in specified location', async function () { - const proxyAdminSlot = await getSlot(this.proxy, AdminSlot); - const proxyAdminAddress = web3.utils.toChecksumAddress(proxyAdminSlot.substr(-40)); - expect(proxyAdminAddress).to.be.equal(proxyAdminAddress); - }); - }); - - describe('transparent proxy', function () { - beforeEach('creating proxy', async function () { - const initializeData = Buffer.from(''); - this.impl = await ClashingImplementation.new(); - this.proxy = await createProxy(this.impl.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - this.clashing = new ClashingImplementation(this.proxy.address); - }); - - it('proxy admin cannot call delegated functions', async function () { - await expectRevert( - this.clashing.delegatedFunction({ from: proxyAdminAddress }), - 'TransparentUpgradeableProxy: admin cannot fallback to proxy target', - ); - }); - - describe('when function names clash', function () { - it('when sender is proxy admin should run the proxy function', async function () { - const value = await this.proxy.admin({ from: proxyAdminAddress, value: 0 }); - expect(value).to.be.equal(proxyAdminAddress); - }); - - it('when sender is other should delegate to implementation', async function () { - const value = await this.proxy.admin({ from: anotherAccount, value: 0 }); - expect(value).to.be.equal('0x0000000000000000000000000000000011111142'); - }); - - it('when sender is proxy admin value should not be accepted', async function () { - await expectRevert.unspecified(this.proxy.admin({ from: proxyAdminAddress, value: 1 })); - }); - - it('when sender is other value should be accepted', async function () { - const value = await this.proxy.admin({ from: anotherAccount, value: 1 }); - expect(value).to.be.equal('0x0000000000000000000000000000000011111142'); - }); - }); - }); - - describe('regression', () => { - const initializeData = Buffer.from(''); - - it('should add new function', async () => { - const instance1 = await Implementation1.new(); - const proxy = await createProxy(instance1.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const proxyInstance1 = new Implementation1(proxy.address); - await proxyInstance1.setValue(42); - - const instance2 = await Implementation2.new(); - await proxy.upgradeTo(instance2.address, { from: proxyAdminAddress }); - - const proxyInstance2 = new Implementation2(proxy.address); - const res = await proxyInstance2.getValue(); - expect(res.toString()).to.eq('42'); - }); - - it('should remove function', async () => { - const instance2 = await Implementation2.new(); - const proxy = await createProxy(instance2.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const proxyInstance2 = new Implementation2(proxy.address); - await proxyInstance2.setValue(42); - const res = await proxyInstance2.getValue(); - expect(res.toString()).to.eq('42'); - - const instance1 = await Implementation1.new(); - await proxy.upgradeTo(instance1.address, { from: proxyAdminAddress }); - - const proxyInstance1 = new Implementation2(proxy.address); - await expectRevert.unspecified(proxyInstance1.getValue()); - }); - - it('should change function signature', async () => { - const instance1 = await Implementation1.new(); - const proxy = await createProxy(instance1.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const proxyInstance1 = new Implementation1(proxy.address); - await proxyInstance1.setValue(42); - - const instance3 = await Implementation3.new(); - await proxy.upgradeTo(instance3.address, { from: proxyAdminAddress }); - const proxyInstance3 = new Implementation3(proxy.address); - - const res = await proxyInstance3.getValue(8); - expect(res.toString()).to.eq('50'); - }); - - it('should add fallback function', async () => { - const initializeData = Buffer.from(''); - const instance1 = await Implementation1.new(); - const proxy = await createProxy(instance1.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const instance4 = await Implementation4.new(); - await proxy.upgradeTo(instance4.address, { from: proxyAdminAddress }); - const proxyInstance4 = new Implementation4(proxy.address); - - const data = '0x'; - await web3.eth.sendTransaction({ to: proxy.address, from: anotherAccount, data }); - - const res = await proxyInstance4.getValue(); - expect(res.toString()).to.eq('1'); - }); - - it('should remove fallback function', async () => { - const instance4 = await Implementation4.new(); - const proxy = await createProxy(instance4.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const instance2 = await Implementation2.new(); - await proxy.upgradeTo(instance2.address, { from: proxyAdminAddress }); - - const data = '0x'; - await expectRevert.unspecified( - web3.eth.sendTransaction({ to: proxy.address, from: anotherAccount, data }), - ); - - const proxyInstance2 = new Implementation2(proxy.address); - const res = await proxyInstance2.getValue(); - expect(res.toString()).to.eq('0'); - }); - }); -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/TransparentUpgradeableProxy.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/TransparentUpgradeableProxy.test.js deleted file mode 100644 index d60a31a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/transparent/TransparentUpgradeableProxy.test.js +++ /dev/null @@ -1,17 +0,0 @@ -const shouldBehaveLikeProxy = require('../Proxy.behaviour'); -const shouldBehaveLikeTransparentUpgradeableProxy = require('./TransparentUpgradeableProxy.behaviour'); - -const TransparentUpgradeableProxy = artifacts.require('TransparentUpgradeableProxy'); -const ITransparentUpgradeableProxy = artifacts.require('ITransparentUpgradeableProxy'); - -contract('TransparentUpgradeableProxy', function (accounts) { - const [proxyAdminAddress, proxyAdminOwner] = accounts; - - const createProxy = async function (logic, admin, initData, opts) { - const { address } = await TransparentUpgradeableProxy.new(logic, admin, initData, opts); - return ITransparentUpgradeableProxy.at(address); - }; - - shouldBehaveLikeProxy(createProxy, proxyAdminAddress, proxyAdminOwner); - shouldBehaveLikeTransparentUpgradeableProxy(createProxy, accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/utils/Initializable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/utils/Initializable.test.js deleted file mode 100644 index 2c0c147..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/utils/Initializable.test.js +++ /dev/null @@ -1,218 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const InitializableMock = artifacts.require('InitializableMock'); -const ConstructorInitializableMock = artifacts.require('ConstructorInitializableMock'); -const ChildConstructorInitializableMock = artifacts.require('ChildConstructorInitializableMock'); -const ReinitializerMock = artifacts.require('ReinitializerMock'); -const SampleChild = artifacts.require('SampleChild'); -const DisableBad1 = artifacts.require('DisableBad1'); -const DisableBad2 = artifacts.require('DisableBad2'); -const DisableOk = artifacts.require('DisableOk'); - -contract('Initializable', function (accounts) { - describe('basic testing without inheritance', function () { - beforeEach('deploying', async function () { - this.contract = await InitializableMock.new(); - }); - - describe('before initialize', function () { - it('initializer has not run', async function () { - expect(await this.contract.initializerRan()).to.equal(false); - }); - - it('_initializing returns false before initialization', async function () { - expect(await this.contract.isInitializing()).to.equal(false); - }); - }); - - describe('after initialize', function () { - beforeEach('initializing', async function () { - await this.contract.initialize(); - }); - - it('initializer has run', async function () { - expect(await this.contract.initializerRan()).to.equal(true); - }); - - it('_initializing returns false after initialization', async function () { - expect(await this.contract.isInitializing()).to.equal(false); - }); - - it('initializer does not run again', async function () { - await expectRevert(this.contract.initialize(), 'Initializable: contract is already initialized'); - }); - }); - - describe('nested under an initializer', function () { - it('initializer modifier reverts', async function () { - await expectRevert(this.contract.initializerNested(), 'Initializable: contract is already initialized'); - }); - - it('onlyInitializing modifier succeeds', async function () { - await this.contract.onlyInitializingNested(); - expect(await this.contract.onlyInitializingRan()).to.equal(true); - }); - }); - - it('cannot call onlyInitializable function outside the scope of an initializable function', async function () { - await expectRevert(this.contract.initializeOnlyInitializing(), 'Initializable: contract is not initializing'); - }); - }); - - it('nested initializer can run during construction', async function () { - const contract2 = await ConstructorInitializableMock.new(); - expect(await contract2.initializerRan()).to.equal(true); - expect(await contract2.onlyInitializingRan()).to.equal(true); - }); - - it('multiple constructor levels can be initializers', async function () { - const contract2 = await ChildConstructorInitializableMock.new(); - expect(await contract2.initializerRan()).to.equal(true); - expect(await contract2.childInitializerRan()).to.equal(true); - expect(await contract2.onlyInitializingRan()).to.equal(true); - }); - - describe('reinitialization', function () { - beforeEach('deploying', async function () { - this.contract = await ReinitializerMock.new(); - }); - - it('can reinitialize', async function () { - expect(await this.contract.counter()).to.be.bignumber.equal('0'); - await this.contract.initialize(); - expect(await this.contract.counter()).to.be.bignumber.equal('1'); - await this.contract.reinitialize(2); - expect(await this.contract.counter()).to.be.bignumber.equal('2'); - await this.contract.reinitialize(3); - expect(await this.contract.counter()).to.be.bignumber.equal('3'); - }); - - it('can jump multiple steps', async function () { - expect(await this.contract.counter()).to.be.bignumber.equal('0'); - await this.contract.initialize(); - expect(await this.contract.counter()).to.be.bignumber.equal('1'); - await this.contract.reinitialize(128); - expect(await this.contract.counter()).to.be.bignumber.equal('2'); - }); - - it('cannot nest reinitializers', async function () { - expect(await this.contract.counter()).to.be.bignumber.equal('0'); - await expectRevert(this.contract.nestedReinitialize(2, 2), 'Initializable: contract is already initialized'); - await expectRevert(this.contract.nestedReinitialize(2, 3), 'Initializable: contract is already initialized'); - await expectRevert(this.contract.nestedReinitialize(3, 2), 'Initializable: contract is already initialized'); - }); - - it('can chain reinitializers', async function () { - expect(await this.contract.counter()).to.be.bignumber.equal('0'); - await this.contract.chainReinitialize(2, 3); - expect(await this.contract.counter()).to.be.bignumber.equal('2'); - }); - - it('_getInitializedVersion returns right version', async function () { - await this.contract.initialize(); - expect(await this.contract.getInitializedVersion()).to.be.bignumber.equal('1'); - await this.contract.reinitialize(12); - expect(await this.contract.getInitializedVersion()).to.be.bignumber.equal('12'); - }); - - describe('contract locking', function () { - it('prevents initialization', async function () { - await this.contract.disableInitializers(); - await expectRevert(this.contract.initialize(), 'Initializable: contract is already initialized'); - }); - - it('prevents re-initialization', async function () { - await this.contract.disableInitializers(); - await expectRevert(this.contract.reinitialize(255), 'Initializable: contract is already initialized'); - }); - - it('can lock contract after initialization', async function () { - await this.contract.initialize(); - await this.contract.disableInitializers(); - await expectRevert(this.contract.reinitialize(255), 'Initializable: contract is already initialized'); - }); - }); - }); - - describe('events', function () { - it('constructor initialization emits event', async function () { - const contract = await ConstructorInitializableMock.new(); - - await expectEvent.inTransaction(contract.transactionHash, contract, 'Initialized', { version: '1' }); - }); - - it('initialization emits event', async function () { - const contract = await ReinitializerMock.new(); - - const { receipt } = await contract.initialize(); - expect(receipt.logs.filter(({ event }) => event === 'Initialized').length).to.be.equal(1); - expectEvent(receipt, 'Initialized', { version: '1' }); - }); - - it('reinitialization emits event', async function () { - const contract = await ReinitializerMock.new(); - - const { receipt } = await contract.reinitialize(128); - expect(receipt.logs.filter(({ event }) => event === 'Initialized').length).to.be.equal(1); - expectEvent(receipt, 'Initialized', { version: '128' }); - }); - - it('chained reinitialization emits multiple events', async function () { - const contract = await ReinitializerMock.new(); - - const { receipt } = await contract.chainReinitialize(2, 3); - expect(receipt.logs.filter(({ event }) => event === 'Initialized').length).to.be.equal(2); - expectEvent(receipt, 'Initialized', { version: '2' }); - expectEvent(receipt, 'Initialized', { version: '3' }); - }); - }); - - describe('complex testing with inheritance', function () { - const mother = '12'; - const gramps = '56'; - const father = '34'; - const child = '78'; - - beforeEach('deploying', async function () { - this.contract = await SampleChild.new(); - }); - - beforeEach('initializing', async function () { - await this.contract.initialize(mother, gramps, father, child); - }); - - it('initializes human', async function () { - expect(await this.contract.isHuman()).to.be.equal(true); - }); - - it('initializes mother', async function () { - expect(await this.contract.mother()).to.be.bignumber.equal(mother); - }); - - it('initializes gramps', async function () { - expect(await this.contract.gramps()).to.be.bignumber.equal(gramps); - }); - - it('initializes father', async function () { - expect(await this.contract.father()).to.be.bignumber.equal(father); - }); - - it('initializes child', async function () { - expect(await this.contract.child()).to.be.bignumber.equal(child); - }); - }); - - describe('disabling initialization', function () { - it('old and new patterns in bad sequence', async function () { - await expectRevert(DisableBad1.new(), 'Initializable: contract is already initialized'); - await expectRevert(DisableBad2.new(), 'Initializable: contract is initializing'); - }); - - it('old and new patterns in good sequence', async function () { - const ok = await DisableOk.new(); - await expectEvent.inConstruction(ok, 'Initialized', { version: '1' }); - await expectEvent.inConstruction(ok, 'Initialized', { version: '255' }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/utils/UUPSUpgradeable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/utils/UUPSUpgradeable.test.js deleted file mode 100644 index 466081d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/proxy/utils/UUPSUpgradeable.test.js +++ /dev/null @@ -1,85 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { web3 } = require('@openzeppelin/test-helpers/src/setup'); -const { getSlot, ImplementationSlot } = require('../../helpers/erc1967'); - -const ERC1967Proxy = artifacts.require('ERC1967Proxy'); -const UUPSUpgradeableMock = artifacts.require('UUPSUpgradeableMock'); -const UUPSUpgradeableUnsafeMock = artifacts.require('UUPSUpgradeableUnsafeMock'); -const UUPSUpgradeableLegacyMock = artifacts.require('UUPSUpgradeableLegacyMock'); -const CountersImpl = artifacts.require('CountersImpl'); - -contract('UUPSUpgradeable', function (accounts) { - before(async function () { - this.implInitial = await UUPSUpgradeableMock.new(); - this.implUpgradeOk = await UUPSUpgradeableMock.new(); - this.implUpgradeUnsafe = await UUPSUpgradeableUnsafeMock.new(); - this.implUpgradeNonUUPS = await CountersImpl.new(); - }); - - beforeEach(async function () { - const { address } = await ERC1967Proxy.new(this.implInitial.address, '0x'); - this.instance = await UUPSUpgradeableMock.at(address); - }); - - it('upgrade to upgradeable implementation', async function () { - const { receipt } = await this.instance.upgradeTo(this.implUpgradeOk.address); - expect(receipt.logs.filter(({ event }) => event === 'Upgraded').length).to.be.equal(1); - expectEvent(receipt, 'Upgraded', { implementation: this.implUpgradeOk.address }); - }); - - it('upgrade to upgradeable implementation with call', async function () { - expect(await this.instance.current()).to.be.bignumber.equal('0'); - - const { receipt } = await this.instance.upgradeToAndCall( - this.implUpgradeOk.address, - this.implUpgradeOk.contract.methods.increment().encodeABI(), - ); - expect(receipt.logs.filter(({ event }) => event === 'Upgraded').length).to.be.equal(1); - expectEvent(receipt, 'Upgraded', { implementation: this.implUpgradeOk.address }); - - expect(await this.instance.current()).to.be.bignumber.equal('1'); - }); - - it('upgrade to and unsafe upgradeable implementation', async function () { - const { receipt } = await this.instance.upgradeTo(this.implUpgradeUnsafe.address); - expectEvent(receipt, 'Upgraded', { implementation: this.implUpgradeUnsafe.address }); - }); - - // delegate to a non existing upgradeTo function causes a low level revert - it('reject upgrade to non uups implementation', async function () { - await expectRevert( - this.instance.upgradeTo(this.implUpgradeNonUUPS.address), - 'ERC1967Upgrade: new implementation is not UUPS', - ); - }); - - it('reject proxy address as implementation', async function () { - const { address } = await ERC1967Proxy.new(this.implInitial.address, '0x'); - const otherInstance = await UUPSUpgradeableMock.at(address); - - await expectRevert( - this.instance.upgradeTo(otherInstance.address), - 'ERC1967Upgrade: new implementation is not UUPS', - ); - }); - - it('can upgrade from legacy implementations', async function () { - const legacyImpl = await UUPSUpgradeableLegacyMock.new(); - const legacyInstance = await ERC1967Proxy.new(legacyImpl.address, '0x') - .then(({ address }) => UUPSUpgradeableLegacyMock.at(address)); - - const receipt = await legacyInstance.upgradeTo(this.implInitial.address); - - const UpgradedEvents = receipt.logs.filter(({ address, event }) => - address === legacyInstance.address && - event === 'Upgraded', - ); - expect(UpgradedEvents.length).to.be.equal(1); - - expectEvent(receipt, 'Upgraded', { implementation: this.implInitial.address }); - - const implementationSlot = await getSlot(legacyInstance, ImplementationSlot); - const implementationAddress = web3.utils.toChecksumAddress(implementationSlot.substr(-40)); - expect(implementationAddress).to.be.equal(this.implInitial.address); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/Pausable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/Pausable.test.js deleted file mode 100644 index 86701bc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/Pausable.test.js +++ /dev/null @@ -1,89 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const PausableMock = artifacts.require('PausableMock'); - -contract('Pausable', function (accounts) { - const [ pauser ] = accounts; - - beforeEach(async function () { - this.pausable = await PausableMock.new(); - }); - - context('when unpaused', function () { - beforeEach(async function () { - expect(await this.pausable.paused()).to.equal(false); - }); - - it('can perform normal process in non-pause', async function () { - expect(await this.pausable.count()).to.be.bignumber.equal('0'); - - await this.pausable.normalProcess(); - expect(await this.pausable.count()).to.be.bignumber.equal('1'); - }); - - it('cannot take drastic measure in non-pause', async function () { - await expectRevert(this.pausable.drasticMeasure(), - 'Pausable: not paused', - ); - expect(await this.pausable.drasticMeasureTaken()).to.equal(false); - }); - - context('when paused', function () { - beforeEach(async function () { - (this.receipt = await this.pausable.pause({ from: pauser })); - }); - - it('emits a Paused event', function () { - expectEvent(this.receipt, 'Paused', { account: pauser }); - }); - - it('cannot perform normal process in pause', async function () { - await expectRevert(this.pausable.normalProcess(), 'Pausable: paused'); - }); - - it('can take a drastic measure in a pause', async function () { - await this.pausable.drasticMeasure(); - expect(await this.pausable.drasticMeasureTaken()).to.equal(true); - }); - - it('reverts when re-pausing', async function () { - await expectRevert(this.pausable.pause(), 'Pausable: paused'); - }); - - describe('unpausing', function () { - it('is unpausable by the pauser', async function () { - await this.pausable.unpause(); - expect(await this.pausable.paused()).to.equal(false); - }); - - context('when unpaused', function () { - beforeEach(async function () { - (this.receipt = await this.pausable.unpause({ from: pauser })); - }); - - it('emits an Unpaused event', function () { - expectEvent(this.receipt, 'Unpaused', { account: pauser }); - }); - - it('should resume allowing normal process', async function () { - expect(await this.pausable.count()).to.be.bignumber.equal('0'); - await this.pausable.normalProcess(); - expect(await this.pausable.count()).to.be.bignumber.equal('1'); - }); - - it('should prevent drastic measure', async function () { - await expectRevert(this.pausable.drasticMeasure(), - 'Pausable: not paused', - ); - }); - - it('reverts when re-unpausing', async function () { - await expectRevert(this.pausable.unpause(), 'Pausable: not paused'); - }); - }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/PullPayment.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/PullPayment.test.js deleted file mode 100644 index 1552ed9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/PullPayment.test.js +++ /dev/null @@ -1,51 +0,0 @@ -const { balance, ether } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const PullPaymentMock = artifacts.require('PullPaymentMock'); - -contract('PullPayment', function (accounts) { - const [ payer, payee1, payee2 ] = accounts; - - const amount = ether('17'); - - beforeEach(async function () { - this.contract = await PullPaymentMock.new({ value: amount }); - }); - - describe('payments', function () { - it('can record an async payment correctly', async function () { - await this.contract.callTransfer(payee1, 100, { from: payer }); - expect(await this.contract.payments(payee1)).to.be.bignumber.equal('100'); - }); - - it('can add multiple balances on one account', async function () { - await this.contract.callTransfer(payee1, 200, { from: payer }); - await this.contract.callTransfer(payee1, 300, { from: payer }); - expect(await this.contract.payments(payee1)).to.be.bignumber.equal('500'); - }); - - it('can add balances on multiple accounts', async function () { - await this.contract.callTransfer(payee1, 200, { from: payer }); - await this.contract.callTransfer(payee2, 300, { from: payer }); - - expect(await this.contract.payments(payee1)).to.be.bignumber.equal('200'); - - expect(await this.contract.payments(payee2)).to.be.bignumber.equal('300'); - }); - }); - - describe('withdrawPayments', function () { - it('can withdraw payment', async function () { - const balanceTracker = await balance.tracker(payee1); - - await this.contract.callTransfer(payee1, amount, { from: payer }); - expect(await this.contract.payments(payee1)).to.be.bignumber.equal(amount); - - await this.contract.withdrawPayments(payee1); - - expect(await balanceTracker.delta()).to.be.bignumber.equal(amount); - expect(await this.contract.payments(payee1)).to.be.bignumber.equal('0'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/ReentrancyGuard.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/ReentrancyGuard.test.js deleted file mode 100644 index c0116d5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/security/ReentrancyGuard.test.js +++ /dev/null @@ -1,40 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ReentrancyMock = artifacts.require('ReentrancyMock'); -const ReentrancyAttack = artifacts.require('ReentrancyAttack'); - -contract('ReentrancyGuard', function (accounts) { - beforeEach(async function () { - this.reentrancyMock = await ReentrancyMock.new(); - expect(await this.reentrancyMock.counter()).to.be.bignumber.equal('0'); - }); - - it('nonReentrant function can be called', async function () { - expect(await this.reentrancyMock.counter()).to.be.bignumber.equal('0'); - await this.reentrancyMock.callback(); - expect(await this.reentrancyMock.counter()).to.be.bignumber.equal('1'); - }); - - it('does not allow remote callback', async function () { - const attacker = await ReentrancyAttack.new(); - await expectRevert( - this.reentrancyMock.countAndCall(attacker.address), 'ReentrancyAttack: failed call'); - }); - - // The following are more side-effects than intended behavior: - // I put them here as documentation, and to monitor any changes - // in the side-effects. - it('does not allow local recursion', async function () { - await expectRevert( - this.reentrancyMock.countLocalRecursive(10), 'ReentrancyGuard: reentrant call', - ); - }); - - it('does not allow indirect local recursion', async function () { - await expectRevert( - this.reentrancyMock.countThisRecursive(10), 'ReentrancyMock: failed call', - ); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/ERC1155.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/ERC1155.behavior.js deleted file mode 100644 index 62ba666..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/ERC1155.behavior.js +++ /dev/null @@ -1,774 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -const ERC1155ReceiverMock = artifacts.require('ERC1155ReceiverMock'); - -function shouldBehaveLikeERC1155 ([minter, firstTokenHolder, secondTokenHolder, multiTokenHolder, recipient, proxy]) { - const firstTokenId = new BN(1); - const secondTokenId = new BN(2); - const unknownTokenId = new BN(3); - - const firstAmount = new BN(1000); - const secondAmount = new BN(2000); - - const RECEIVER_SINGLE_MAGIC_VALUE = '0xf23a6e61'; - const RECEIVER_BATCH_MAGIC_VALUE = '0xbc197c81'; - - describe('like an ERC1155', function () { - describe('balanceOf', function () { - it('reverts when queried about the zero address', async function () { - await expectRevert( - this.token.balanceOf(ZERO_ADDRESS, firstTokenId), - 'ERC1155: address zero is not a valid owner', - ); - }); - - context('when accounts don\'t own tokens', function () { - it('returns zero for given addresses', async function () { - expect(await this.token.balanceOf( - firstTokenHolder, - firstTokenId, - )).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOf( - secondTokenHolder, - secondTokenId, - )).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOf( - firstTokenHolder, - unknownTokenId, - )).to.be.bignumber.equal('0'); - }); - }); - - context('when accounts own some tokens', function () { - beforeEach(async function () { - await this.token.mint(firstTokenHolder, firstTokenId, firstAmount, '0x', { - from: minter, - }); - await this.token.mint( - secondTokenHolder, - secondTokenId, - secondAmount, - '0x', - { - from: minter, - }, - ); - }); - - it('returns the amount of tokens owned by the given addresses', async function () { - expect(await this.token.balanceOf( - firstTokenHolder, - firstTokenId, - )).to.be.bignumber.equal(firstAmount); - - expect(await this.token.balanceOf( - secondTokenHolder, - secondTokenId, - )).to.be.bignumber.equal(secondAmount); - - expect(await this.token.balanceOf( - firstTokenHolder, - unknownTokenId, - )).to.be.bignumber.equal('0'); - }); - }); - }); - - describe('balanceOfBatch', function () { - it('reverts when input arrays don\'t match up', async function () { - await expectRevert( - this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder, firstTokenHolder, secondTokenHolder], - [firstTokenId, secondTokenId, unknownTokenId], - ), - 'ERC1155: accounts and ids length mismatch', - ); - - await expectRevert( - this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder], - [firstTokenId, secondTokenId, unknownTokenId], - ), - 'ERC1155: accounts and ids length mismatch', - ); - }); - - it('reverts when one of the addresses is the zero address', async function () { - await expectRevert( - this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder, ZERO_ADDRESS], - [firstTokenId, secondTokenId, unknownTokenId], - ), - 'ERC1155: address zero is not a valid owner', - ); - }); - - context('when accounts don\'t own tokens', function () { - it('returns zeros for each account', async function () { - const result = await this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder, firstTokenHolder], - [firstTokenId, secondTokenId, unknownTokenId], - ); - expect(result).to.be.an('array'); - expect(result[0]).to.be.a.bignumber.equal('0'); - expect(result[1]).to.be.a.bignumber.equal('0'); - expect(result[2]).to.be.a.bignumber.equal('0'); - }); - }); - - context('when accounts own some tokens', function () { - beforeEach(async function () { - await this.token.mint(firstTokenHolder, firstTokenId, firstAmount, '0x', { - from: minter, - }); - await this.token.mint( - secondTokenHolder, - secondTokenId, - secondAmount, - '0x', - { - from: minter, - }, - ); - }); - - it('returns amounts owned by each account in order passed', async function () { - const result = await this.token.balanceOfBatch( - [secondTokenHolder, firstTokenHolder, firstTokenHolder], - [secondTokenId, firstTokenId, unknownTokenId], - ); - expect(result).to.be.an('array'); - expect(result[0]).to.be.a.bignumber.equal(secondAmount); - expect(result[1]).to.be.a.bignumber.equal(firstAmount); - expect(result[2]).to.be.a.bignumber.equal('0'); - }); - - it('returns multiple times the balance of the same address when asked', async function () { - const result = await this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder, firstTokenHolder], - [firstTokenId, secondTokenId, firstTokenId], - ); - expect(result).to.be.an('array'); - expect(result[0]).to.be.a.bignumber.equal(result[2]); - expect(result[0]).to.be.a.bignumber.equal(firstAmount); - expect(result[1]).to.be.a.bignumber.equal(secondAmount); - expect(result[2]).to.be.a.bignumber.equal(firstAmount); - }); - }); - }); - - describe('setApprovalForAll', function () { - let receipt; - beforeEach(async function () { - (receipt = await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder })); - }); - - it('sets approval status which can be queried via isApprovedForAll', async function () { - expect(await this.token.isApprovedForAll(multiTokenHolder, proxy)).to.be.equal(true); - }); - - it('emits an ApprovalForAll log', function () { - expectEvent(receipt, 'ApprovalForAll', { account: multiTokenHolder, operator: proxy, approved: true }); - }); - - it('can unset approval for an operator', async function () { - await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder }); - expect(await this.token.isApprovedForAll(multiTokenHolder, proxy)).to.be.equal(false); - }); - - it('reverts if attempting to approve self as an operator', async function () { - await expectRevert( - this.token.setApprovalForAll(multiTokenHolder, true, { from: multiTokenHolder }), - 'ERC1155: setting approval status for self', - ); - }); - }); - - describe('safeTransferFrom', function () { - beforeEach(async function () { - await this.token.mint(multiTokenHolder, firstTokenId, firstAmount, '0x', { - from: minter, - }); - await this.token.mint( - multiTokenHolder, - secondTokenId, - secondAmount, - '0x', - { - from: minter, - }, - ); - }); - - it('reverts when transferring more than balance', async function () { - await expectRevert( - this.token.safeTransferFrom( - multiTokenHolder, - recipient, - firstTokenId, - firstAmount.addn(1), - '0x', - { from: multiTokenHolder }, - ), - 'ERC1155: insufficient balance for transfer', - ); - }); - - it('reverts when transferring to zero address', async function () { - await expectRevert( - this.token.safeTransferFrom( - multiTokenHolder, - ZERO_ADDRESS, - firstTokenId, - firstAmount, - '0x', - { from: multiTokenHolder }, - ), - 'ERC1155: transfer to the zero address', - ); - }); - - function transferWasSuccessful ({ operator, from, id, value }) { - it('debits transferred balance from sender', async function () { - const newBalance = await this.token.balanceOf(from, id); - expect(newBalance).to.be.a.bignumber.equal('0'); - }); - - it('credits transferred balance to receiver', async function () { - const newBalance = await this.token.balanceOf(this.toWhom, id); - expect(newBalance).to.be.a.bignumber.equal(value); - }); - - it('emits a TransferSingle log', function () { - expectEvent(this.transferLogs, 'TransferSingle', { - operator, - from, - to: this.toWhom, - id, - value, - }); - }); - } - - context('when called by the multiTokenHolder', async function () { - beforeEach(async function () { - this.toWhom = recipient; - (this.transferLogs = - await this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', { - from: multiTokenHolder, - })); - }); - - transferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - }); - - it('preserves existing balances which are not transferred by multiTokenHolder', async function () { - const balance1 = await this.token.balanceOf(multiTokenHolder, secondTokenId); - expect(balance1).to.be.a.bignumber.equal(secondAmount); - - const balance2 = await this.token.balanceOf(recipient, secondTokenId); - expect(balance2).to.be.a.bignumber.equal('0'); - }); - }); - - context('when called by an operator on behalf of the multiTokenHolder', function () { - context('when operator is not approved by multiTokenHolder', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder }); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', { - from: proxy, - }), - 'ERC1155: caller is not token owner or approved', - ); - }); - }); - - context('when operator is approved by multiTokenHolder', function () { - beforeEach(async function () { - this.toWhom = recipient; - await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder }); - (this.transferLogs = - await this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', { - from: proxy, - })); - }); - - transferWasSuccessful.call(this, { - operator: proxy, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - }); - - it('preserves operator\'s balances not involved in the transfer', async function () { - const balance1 = await this.token.balanceOf(proxy, firstTokenId); - expect(balance1).to.be.a.bignumber.equal('0'); - - const balance2 = await this.token.balanceOf(proxy, secondTokenId); - expect(balance2).to.be.a.bignumber.equal('0'); - }); - }); - }); - - context('when sending to a valid receiver', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, false, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - }); - - context('without data', function () { - beforeEach(async function () { - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeTransferFrom( - multiTokenHolder, - this.receiver.address, - firstTokenId, - firstAmount, - '0x', - { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - transferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - }); - - it('calls onERC1155Received', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'Received', { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - data: null, - }); - }); - }); - - context('with data', function () { - const data = '0xf00dd00d'; - beforeEach(async function () { - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeTransferFrom( - multiTokenHolder, - this.receiver.address, - firstTokenId, - firstAmount, - data, - { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - transferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - }); - - it('calls onERC1155Received', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'Received', { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - data, - }); - }); - }); - }); - - context('to a receiver contract returning unexpected value', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - '0x00c0ffee', false, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', { - from: multiTokenHolder, - }), - 'ERC1155: ERC1155Receiver rejected tokens', - ); - }); - }); - - context('to a receiver contract that reverts', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, true, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', { - from: multiTokenHolder, - }), - 'ERC1155ReceiverMock: reverting on receive', - ); - }); - }); - - context('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const invalidReceiver = this.token; - await expectRevert.unspecified( - this.token.safeTransferFrom(multiTokenHolder, invalidReceiver.address, firstTokenId, firstAmount, '0x', { - from: multiTokenHolder, - }), - ); - }); - }); - }); - - describe('safeBatchTransferFrom', function () { - beforeEach(async function () { - await this.token.mint(multiTokenHolder, firstTokenId, firstAmount, '0x', { - from: minter, - }); - await this.token.mint( - multiTokenHolder, - secondTokenId, - secondAmount, - '0x', - { - from: minter, - }, - ); - }); - - it('reverts when transferring amount more than any of balances', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount.addn(1)], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: insufficient balance for transfer', - ); - }); - - it('reverts when ids array length doesn\'t match amounts array length', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: ids and amounts length mismatch', - ); - - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: ids and amounts length mismatch', - ); - }); - - it('reverts when transferring to zero address', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, ZERO_ADDRESS, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: transfer to the zero address', - ); - }); - - function batchTransferWasSuccessful ({ operator, from, ids, values }) { - it('debits transferred balances from sender', async function () { - const newBalances = await this.token.balanceOfBatch(new Array(ids.length).fill(from), ids); - for (const newBalance of newBalances) { - expect(newBalance).to.be.a.bignumber.equal('0'); - } - }); - - it('credits transferred balances to receiver', async function () { - const newBalances = await this.token.balanceOfBatch(new Array(ids.length).fill(this.toWhom), ids); - for (let i = 0; i < newBalances.length; i++) { - expect(newBalances[i]).to.be.a.bignumber.equal(values[i]); - } - }); - - it('emits a TransferBatch log', function () { - expectEvent(this.transferLogs, 'TransferBatch', { - operator, - from, - to: this.toWhom, - // ids, - // values, - }); - }); - } - - context('when called by the multiTokenHolder', async function () { - beforeEach(async function () { - this.toWhom = recipient; - (this.transferLogs = - await this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - )); - }); - - batchTransferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - }); - - context('when called by an operator on behalf of the multiTokenHolder', function () { - context('when operator is not approved by multiTokenHolder', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder }); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: proxy }, - ), - 'ERC1155: caller is not token owner or approved', - ); - }); - }); - - context('when operator is approved by multiTokenHolder', function () { - beforeEach(async function () { - this.toWhom = recipient; - await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder }); - (this.transferLogs = - await this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: proxy }, - )); - }); - - batchTransferWasSuccessful.call(this, { - operator: proxy, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - - it('preserves operator\'s balances not involved in the transfer', async function () { - const balance1 = await this.token.balanceOf(proxy, firstTokenId); - expect(balance1).to.be.a.bignumber.equal('0'); - const balance2 = await this.token.balanceOf(proxy, secondTokenId); - expect(balance2).to.be.a.bignumber.equal('0'); - }); - }); - }); - - context('when sending to a valid receiver', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, false, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - }); - - context('without data', function () { - beforeEach(async function () { - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - batchTransferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - - it('calls onERC1155BatchReceived', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', { - operator: multiTokenHolder, - from: multiTokenHolder, - // ids: [firstTokenId, secondTokenId], - // values: [firstAmount, secondAmount], - data: null, - }); - }); - }); - - context('with data', function () { - const data = '0xf00dd00d'; - beforeEach(async function () { - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - data, { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - batchTransferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - - it('calls onERC1155Received', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', { - operator: multiTokenHolder, - from: multiTokenHolder, - // ids: [firstTokenId, secondTokenId], - // values: [firstAmount, secondAmount], - data, - }); - }); - }); - }); - - context('to a receiver contract returning unexpected value', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, false, - RECEIVER_SINGLE_MAGIC_VALUE, false, - ); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: ERC1155Receiver rejected tokens', - ); - }); - }); - - context('to a receiver contract that reverts', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, false, - RECEIVER_BATCH_MAGIC_VALUE, true, - ); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155ReceiverMock: reverting on batch receive', - ); - }); - }); - - context('to a receiver contract that reverts only on single transfers', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, true, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - batchTransferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - - it('calls onERC1155BatchReceived', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', { - operator: multiTokenHolder, - from: multiTokenHolder, - // ids: [firstTokenId, secondTokenId], - // values: [firstAmount, secondAmount], - data: null, - }); - }); - }); - - context('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const invalidReceiver = this.token; - await expectRevert.unspecified( - this.token.safeBatchTransferFrom( - multiTokenHolder, invalidReceiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - ); - }); - }); - }); - - shouldSupportInterfaces(['ERC165', 'ERC1155']); - }); -} - -module.exports = { - shouldBehaveLikeERC1155, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/ERC1155.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/ERC1155.test.js deleted file mode 100644 index a0a8cf3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/ERC1155.test.js +++ /dev/null @@ -1,264 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const { shouldBehaveLikeERC1155 } = require('./ERC1155.behavior'); -const ERC1155Mock = artifacts.require('ERC1155Mock'); - -contract('ERC1155', function (accounts) { - const [operator, tokenHolder, tokenBatchHolder, ...otherAccounts] = accounts; - - const initialURI = 'https://token-cdn-domain/{id}.json'; - - beforeEach(async function () { - this.token = await ERC1155Mock.new(initialURI); - }); - - shouldBehaveLikeERC1155(otherAccounts); - - describe('internal functions', function () { - const tokenId = new BN(1990); - const mintAmount = new BN(9001); - const burnAmount = new BN(3000); - - const tokenBatchIds = [new BN(2000), new BN(2010), new BN(2020)]; - const mintAmounts = [new BN(5000), new BN(10000), new BN(42195)]; - const burnAmounts = [new BN(5000), new BN(9001), new BN(195)]; - - const data = '0x12345678'; - - describe('_mint', function () { - it('reverts with a zero destination address', async function () { - await expectRevert( - this.token.mint(ZERO_ADDRESS, tokenId, mintAmount, data), - 'ERC1155: mint to the zero address', - ); - }); - - context('with minted tokens', function () { - beforeEach(async function () { - (this.receipt = await this.token.mint(tokenHolder, tokenId, mintAmount, data, { from: operator })); - }); - - it('emits a TransferSingle event', function () { - expectEvent(this.receipt, 'TransferSingle', { - operator, - from: ZERO_ADDRESS, - to: tokenHolder, - id: tokenId, - value: mintAmount, - }); - }); - - it('credits the minted amount of tokens', async function () { - expect(await this.token.balanceOf(tokenHolder, tokenId)).to.be.bignumber.equal(mintAmount); - }); - }); - }); - - describe('_mintBatch', function () { - it('reverts with a zero destination address', async function () { - await expectRevert( - this.token.mintBatch(ZERO_ADDRESS, tokenBatchIds, mintAmounts, data), - 'ERC1155: mint to the zero address', - ); - }); - - it('reverts if length of inputs do not match', async function () { - await expectRevert( - this.token.mintBatch(tokenBatchHolder, tokenBatchIds, mintAmounts.slice(1), data), - 'ERC1155: ids and amounts length mismatch', - ); - - await expectRevert( - this.token.mintBatch(tokenBatchHolder, tokenBatchIds.slice(1), mintAmounts, data), - 'ERC1155: ids and amounts length mismatch', - ); - }); - - context('with minted batch of tokens', function () { - beforeEach(async function () { - (this.receipt = await this.token.mintBatch( - tokenBatchHolder, - tokenBatchIds, - mintAmounts, - data, - { from: operator }, - )); - }); - - it('emits a TransferBatch event', function () { - expectEvent(this.receipt, 'TransferBatch', { - operator, - from: ZERO_ADDRESS, - to: tokenBatchHolder, - }); - }); - - it('credits the minted batch of tokens', async function () { - const holderBatchBalances = await this.token.balanceOfBatch( - new Array(tokenBatchIds.length).fill(tokenBatchHolder), - tokenBatchIds, - ); - - for (let i = 0; i < holderBatchBalances.length; i++) { - expect(holderBatchBalances[i]).to.be.bignumber.equal(mintAmounts[i]); - } - }); - }); - }); - - describe('_burn', function () { - it('reverts when burning the zero account\'s tokens', async function () { - await expectRevert( - this.token.burn(ZERO_ADDRESS, tokenId, mintAmount), - 'ERC1155: burn from the zero address', - ); - }); - - it('reverts when burning a non-existent token id', async function () { - await expectRevert( - this.token.burn(tokenHolder, tokenId, mintAmount), - 'ERC1155: burn amount exceeds balance', - ); - }); - - it('reverts when burning more than available tokens', async function () { - await this.token.mint( - tokenHolder, - tokenId, - mintAmount, - data, - { from: operator }, - ); - - await expectRevert( - this.token.burn(tokenHolder, tokenId, mintAmount.addn(1)), - 'ERC1155: burn amount exceeds balance', - ); - }); - - context('with minted-then-burnt tokens', function () { - beforeEach(async function () { - await this.token.mint(tokenHolder, tokenId, mintAmount, data); - (this.receipt = await this.token.burn( - tokenHolder, - tokenId, - burnAmount, - { from: operator }, - )); - }); - - it('emits a TransferSingle event', function () { - expectEvent(this.receipt, 'TransferSingle', { - operator, - from: tokenHolder, - to: ZERO_ADDRESS, - id: tokenId, - value: burnAmount, - }); - }); - - it('accounts for both minting and burning', async function () { - expect(await this.token.balanceOf( - tokenHolder, - tokenId, - )).to.be.bignumber.equal(mintAmount.sub(burnAmount)); - }); - }); - }); - - describe('_burnBatch', function () { - it('reverts when burning the zero account\'s tokens', async function () { - await expectRevert( - this.token.burnBatch(ZERO_ADDRESS, tokenBatchIds, burnAmounts), - 'ERC1155: burn from the zero address', - ); - }); - - it('reverts if length of inputs do not match', async function () { - await expectRevert( - this.token.burnBatch(tokenBatchHolder, tokenBatchIds, burnAmounts.slice(1)), - 'ERC1155: ids and amounts length mismatch', - ); - - await expectRevert( - this.token.burnBatch(tokenBatchHolder, tokenBatchIds.slice(1), burnAmounts), - 'ERC1155: ids and amounts length mismatch', - ); - }); - - it('reverts when burning a non-existent token id', async function () { - await expectRevert( - this.token.burnBatch(tokenBatchHolder, tokenBatchIds, burnAmounts), - 'ERC1155: burn amount exceeds balance', - ); - }); - - context('with minted-then-burnt tokens', function () { - beforeEach(async function () { - await this.token.mintBatch(tokenBatchHolder, tokenBatchIds, mintAmounts, data); - (this.receipt = await this.token.burnBatch( - tokenBatchHolder, - tokenBatchIds, - burnAmounts, - { from: operator }, - )); - }); - - it('emits a TransferBatch event', function () { - expectEvent(this.receipt, 'TransferBatch', { - operator, - from: tokenBatchHolder, - to: ZERO_ADDRESS, - // ids: tokenBatchIds, - // values: burnAmounts, - }); - }); - - it('accounts for both minting and burning', async function () { - const holderBatchBalances = await this.token.balanceOfBatch( - new Array(tokenBatchIds.length).fill(tokenBatchHolder), - tokenBatchIds, - ); - - for (let i = 0; i < holderBatchBalances.length; i++) { - expect(holderBatchBalances[i]).to.be.bignumber.equal(mintAmounts[i].sub(burnAmounts[i])); - } - }); - }); - }); - }); - - describe('ERC1155MetadataURI', function () { - const firstTokenID = new BN('42'); - const secondTokenID = new BN('1337'); - - it('emits no URI event in constructor', async function () { - await expectEvent.notEmitted.inConstruction(this.token, 'URI'); - }); - - it('sets the initial URI for all token types', async function () { - expect(await this.token.uri(firstTokenID)).to.be.equal(initialURI); - expect(await this.token.uri(secondTokenID)).to.be.equal(initialURI); - }); - - describe('_setURI', function () { - const newURI = 'https://token-cdn-domain/{locale}/{id}.json'; - - it('emits no URI event', async function () { - const receipt = await this.token.setURI(newURI); - - expectEvent.notEmitted(receipt, 'URI'); - }); - - it('sets the new URI for all token types', async function () { - await this.token.setURI(newURI); - - expect(await this.token.uri(firstTokenID)).to.be.equal(newURI); - expect(await this.token.uri(secondTokenID)).to.be.equal(newURI); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Burnable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Burnable.test.js deleted file mode 100644 index ff6aee0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Burnable.test.js +++ /dev/null @@ -1,67 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC1155BurnableMock = artifacts.require('ERC1155BurnableMock'); - -contract('ERC1155Burnable', function (accounts) { - const [ holder, operator, other ] = accounts; - - const uri = 'https://token.com'; - - const tokenIds = [new BN('42'), new BN('1137')]; - const amounts = [new BN('3000'), new BN('9902')]; - - beforeEach(async function () { - this.token = await ERC1155BurnableMock.new(uri); - - await this.token.mint(holder, tokenIds[0], amounts[0], '0x'); - await this.token.mint(holder, tokenIds[1], amounts[1], '0x'); - }); - - describe('burn', function () { - it('holder can burn their tokens', async function () { - await this.token.burn(holder, tokenIds[0], amounts[0].subn(1), { from: holder }); - - expect(await this.token.balanceOf(holder, tokenIds[0])).to.be.bignumber.equal('1'); - }); - - it('approved operators can burn the holder\'s tokens', async function () { - await this.token.setApprovalForAll(operator, true, { from: holder }); - await this.token.burn(holder, tokenIds[0], amounts[0].subn(1), { from: operator }); - - expect(await this.token.balanceOf(holder, tokenIds[0])).to.be.bignumber.equal('1'); - }); - - it('unapproved accounts cannot burn the holder\'s tokens', async function () { - await expectRevert( - this.token.burn(holder, tokenIds[0], amounts[0].subn(1), { from: other }), - 'ERC1155: caller is not token owner or approved', - ); - }); - }); - - describe('burnBatch', function () { - it('holder can burn their tokens', async function () { - await this.token.burnBatch(holder, tokenIds, [ amounts[0].subn(1), amounts[1].subn(2) ], { from: holder }); - - expect(await this.token.balanceOf(holder, tokenIds[0])).to.be.bignumber.equal('1'); - expect(await this.token.balanceOf(holder, tokenIds[1])).to.be.bignumber.equal('2'); - }); - - it('approved operators can burn the holder\'s tokens', async function () { - await this.token.setApprovalForAll(operator, true, { from: holder }); - await this.token.burnBatch(holder, tokenIds, [ amounts[0].subn(1), amounts[1].subn(2) ], { from: operator }); - - expect(await this.token.balanceOf(holder, tokenIds[0])).to.be.bignumber.equal('1'); - expect(await this.token.balanceOf(holder, tokenIds[1])).to.be.bignumber.equal('2'); - }); - - it('unapproved accounts cannot burn the holder\'s tokens', async function () { - await expectRevert( - this.token.burnBatch(holder, tokenIds, [ amounts[0].subn(1), amounts[1].subn(2) ], { from: other }), - 'ERC1155: caller is not token owner or approved', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Pausable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Pausable.test.js deleted file mode 100644 index f7c4052..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Pausable.test.js +++ /dev/null @@ -1,108 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC1155PausableMock = artifacts.require('ERC1155PausableMock'); - -contract('ERC1155Pausable', function (accounts) { - const [ holder, operator, receiver, other ] = accounts; - - const uri = 'https://token.com'; - - beforeEach(async function () { - this.token = await ERC1155PausableMock.new(uri); - }); - - context('when token is paused', function () { - const firstTokenId = new BN('37'); - const firstTokenAmount = new BN('42'); - - const secondTokenId = new BN('19842'); - const secondTokenAmount = new BN('23'); - - beforeEach(async function () { - await this.token.setApprovalForAll(operator, true, { from: holder }); - await this.token.mint(holder, firstTokenId, firstTokenAmount, '0x'); - - await this.token.pause(); - }); - - it('reverts when trying to safeTransferFrom from holder', async function () { - await expectRevert( - this.token.safeTransferFrom(holder, receiver, firstTokenId, firstTokenAmount, '0x', { from: holder }), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeTransferFrom from operator', async function () { - await expectRevert( - this.token.safeTransferFrom(holder, receiver, firstTokenId, firstTokenAmount, '0x', { from: operator }), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeBatchTransferFrom from holder', async function () { - await expectRevert( - this.token.safeBatchTransferFrom(holder, receiver, [firstTokenId], [firstTokenAmount], '0x', { from: holder }), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeBatchTransferFrom from operator', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - holder, receiver, [firstTokenId], [firstTokenAmount], '0x', { from: operator }, - ), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to mint', async function () { - await expectRevert( - this.token.mint(holder, secondTokenId, secondTokenAmount, '0x'), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to mintBatch', async function () { - await expectRevert( - this.token.mintBatch(holder, [secondTokenId], [secondTokenAmount], '0x'), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to burn', async function () { - await expectRevert( - this.token.burn(holder, firstTokenId, firstTokenAmount), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to burnBatch', async function () { - await expectRevert( - this.token.burnBatch(holder, [firstTokenId], [firstTokenAmount]), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - describe('setApprovalForAll', function () { - it('approves an operator', async function () { - await this.token.setApprovalForAll(other, true, { from: holder }); - expect(await this.token.isApprovedForAll(holder, other)).to.equal(true); - }); - }); - - describe('balanceOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - const balance = await this.token.balanceOf(holder, firstTokenId); - expect(balance).to.be.bignumber.equal(firstTokenAmount); - }); - }); - - describe('isApprovedForAll', function () { - it('returns the approval of the operator', async function () { - expect(await this.token.isApprovedForAll(holder, operator)).to.equal(true); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Supply.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Supply.test.js deleted file mode 100644 index 1a63260..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155Supply.test.js +++ /dev/null @@ -1,111 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC1155SupplyMock = artifacts.require('ERC1155SupplyMock'); - -contract('ERC1155Supply', function (accounts) { - const [ holder ] = accounts; - - const uri = 'https://token.com'; - - const firstTokenId = new BN('37'); - const firstTokenAmount = new BN('42'); - - const secondTokenId = new BN('19842'); - const secondTokenAmount = new BN('23'); - - beforeEach(async function () { - this.token = await ERC1155SupplyMock.new(uri); - }); - - context('before mint', function () { - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(false); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal('0'); - }); - }); - - context('after mint', function () { - context('single', function () { - beforeEach(async function () { - await this.token.mint(holder, firstTokenId, firstTokenAmount, '0x'); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(true); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal(firstTokenAmount); - }); - }); - - context('batch', function () { - beforeEach(async function () { - await this.token.mintBatch( - holder, - [ firstTokenId, secondTokenId ], - [ firstTokenAmount, secondTokenAmount ], - '0x', - ); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(true); - expect(await this.token.exists(secondTokenId)).to.be.equal(true); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal(firstTokenAmount); - expect(await this.token.totalSupply(secondTokenId)).to.be.bignumber.equal(secondTokenAmount); - }); - }); - }); - - context('after burn', function () { - context('single', function () { - beforeEach(async function () { - await this.token.mint(holder, firstTokenId, firstTokenAmount, '0x'); - await this.token.burn(holder, firstTokenId, firstTokenAmount); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(false); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal('0'); - }); - }); - - context('batch', function () { - beforeEach(async function () { - await this.token.mintBatch( - holder, - [ firstTokenId, secondTokenId ], - [ firstTokenAmount, secondTokenAmount ], - '0x', - ); - await this.token.burnBatch( - holder, - [ firstTokenId, secondTokenId ], - [ firstTokenAmount, secondTokenAmount ], - ); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(false); - expect(await this.token.exists(secondTokenId)).to.be.equal(false); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal('0'); - expect(await this.token.totalSupply(secondTokenId)).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155URIStorage.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155URIStorage.test.js deleted file mode 100644 index 7ba7e56..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/extensions/ERC1155URIStorage.test.js +++ /dev/null @@ -1,66 +0,0 @@ -const { BN, expectEvent } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); -const { artifacts } = require('hardhat'); - -const ERC1155URIStorageMock = artifacts.require('ERC1155URIStorageMock'); - -contract(['ERC1155URIStorage'], function (accounts) { - const [ holder ] = accounts; - - const erc1155Uri = 'https://token.com/nfts/'; - const baseUri = 'https://token.com/'; - - const tokenId = new BN('1'); - const amount = new BN('3000'); - - describe('with base uri set', function () { - beforeEach(async function () { - this.token = await ERC1155URIStorageMock.new(erc1155Uri); - this.token.setBaseURI(baseUri); - - await this.token.mint(holder, tokenId, amount, '0x'); - }); - - it('can request the token uri, returning the erc1155 uri if no token uri was set', async function () { - const receivedTokenUri = await this.token.uri(tokenId); - - expect(receivedTokenUri).to.be.equal(erc1155Uri); - }); - - it('can request the token uri, returning the concatenated uri if a token uri was set', async function () { - const tokenUri = '1234/'; - const receipt = await this.token.setURI(tokenId, tokenUri); - - const receivedTokenUri = await this.token.uri(tokenId); - - const expectedUri = `${baseUri}${tokenUri}`; - expect(receivedTokenUri).to.be.equal(expectedUri); - expectEvent(receipt, 'URI', { value: expectedUri, id: tokenId }); - }); - }); - - describe('with base uri set to the empty string', function () { - beforeEach(async function () { - this.token = await ERC1155URIStorageMock.new(''); - - await this.token.mint(holder, tokenId, amount, '0x'); - }); - - it('can request the token uri, returning an empty string if no token uri was set', async function () { - const receivedTokenUri = await this.token.uri(tokenId); - - expect(receivedTokenUri).to.be.equal(''); - }); - - it('can request the token uri, returning the token uri if a token uri was set', async function () { - const tokenUri = 'ipfs://1234/'; - const receipt = await this.token.setURI(tokenId, tokenUri); - - const receivedTokenUri = await this.token.uri(tokenId); - - expect(receivedTokenUri).to.be.equal(tokenUri); - expectEvent(receipt, 'URI', { value: tokenUri, id: tokenId }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/presets/ERC1155PresetMinterPauser.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/presets/ERC1155PresetMinterPauser.test.js deleted file mode 100644 index a8d83d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/presets/ERC1155PresetMinterPauser.test.js +++ /dev/null @@ -1,146 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); - -const { expect } = require('chai'); - -const ERC1155PresetMinterPauser = artifacts.require('ERC1155PresetMinterPauser'); - -contract('ERC1155PresetMinterPauser', function (accounts) { - const [ deployer, other ] = accounts; - - const firstTokenId = new BN('845'); - const firstTokenIdAmount = new BN('5000'); - - const secondTokenId = new BN('48324'); - const secondTokenIdAmount = new BN('77875'); - - const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const MINTER_ROLE = web3.utils.soliditySha3('MINTER_ROLE'); - const PAUSER_ROLE = web3.utils.soliditySha3('PAUSER_ROLE'); - - const uri = 'https://token.com'; - - beforeEach(async function () { - this.token = await ERC1155PresetMinterPauser.new(uri, { from: deployer }); - }); - - shouldSupportInterfaces(['ERC1155', 'AccessControl', 'AccessControlEnumerable']); - - it('deployer has the default admin role', async function () { - expect(await this.token.getRoleMemberCount(DEFAULT_ADMIN_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(DEFAULT_ADMIN_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the minter role', async function () { - expect(await this.token.getRoleMemberCount(MINTER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(MINTER_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the pauser role', async function () { - expect(await this.token.getRoleMemberCount(PAUSER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(PAUSER_ROLE, 0)).to.equal(deployer); - }); - - it('minter and pauser role admin is the default admin', async function () { - expect(await this.token.getRoleAdmin(MINTER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - expect(await this.token.getRoleAdmin(PAUSER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - describe('minting', function () { - it('deployer can mint tokens', async function () { - const receipt = await this.token.mint(other, firstTokenId, firstTokenIdAmount, '0x', { from: deployer }); - expectEvent(receipt, 'TransferSingle', - { operator: deployer, from: ZERO_ADDRESS, to: other, value: firstTokenIdAmount, id: firstTokenId }, - ); - - expect(await this.token.balanceOf(other, firstTokenId)).to.be.bignumber.equal(firstTokenIdAmount); - }); - - it('other accounts cannot mint tokens', async function () { - await expectRevert( - this.token.mint(other, firstTokenId, firstTokenIdAmount, '0x', { from: other }), - 'ERC1155PresetMinterPauser: must have minter role to mint', - ); - }); - }); - - describe('batched minting', function () { - it('deployer can batch mint tokens', async function () { - const receipt = await this.token.mintBatch( - other, [firstTokenId, secondTokenId], [firstTokenIdAmount, secondTokenIdAmount], '0x', { from: deployer }, - ); - - expectEvent(receipt, 'TransferBatch', - { operator: deployer, from: ZERO_ADDRESS, to: other }, - ); - - expect(await this.token.balanceOf(other, firstTokenId)).to.be.bignumber.equal(firstTokenIdAmount); - }); - - it('other accounts cannot batch mint tokens', async function () { - await expectRevert( - this.token.mintBatch( - other, [firstTokenId, secondTokenId], [firstTokenIdAmount, secondTokenIdAmount], '0x', { from: other }, - ), - 'ERC1155PresetMinterPauser: must have minter role to mint', - ); - }); - }); - - describe('pausing', function () { - it('deployer can pause', async function () { - const receipt = await this.token.pause({ from: deployer }); - expectEvent(receipt, 'Paused', { account: deployer }); - - expect(await this.token.paused()).to.equal(true); - }); - - it('deployer can unpause', async function () { - await this.token.pause({ from: deployer }); - - const receipt = await this.token.unpause({ from: deployer }); - expectEvent(receipt, 'Unpaused', { account: deployer }); - - expect(await this.token.paused()).to.equal(false); - }); - - it('cannot mint while paused', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.mint(other, firstTokenId, firstTokenIdAmount, '0x', { from: deployer }), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('other accounts cannot pause', async function () { - await expectRevert( - this.token.pause({ from: other }), - 'ERC1155PresetMinterPauser: must have pauser role to pause', - ); - }); - - it('other accounts cannot unpause', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.unpause({ from: other }), - 'ERC1155PresetMinterPauser: must have pauser role to unpause', - ); - }); - }); - - describe('burning', function () { - it('holders can burn their tokens', async function () { - await this.token.mint(other, firstTokenId, firstTokenIdAmount, '0x', { from: deployer }); - - const receipt = await this.token.burn(other, firstTokenId, firstTokenIdAmount.subn(1), { from: other }); - expectEvent(receipt, 'TransferSingle', - { operator: other, from: other, to: ZERO_ADDRESS, value: firstTokenIdAmount.subn(1), id: firstTokenId }, - ); - - expect(await this.token.balanceOf(other, firstTokenId)).to.be.bignumber.equal('1'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/utils/ERC1155Holder.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/utils/ERC1155Holder.test.js deleted file mode 100644 index 41225c2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC1155/utils/ERC1155Holder.test.js +++ /dev/null @@ -1,62 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const ERC1155Holder = artifacts.require('ERC1155Holder'); -const ERC1155Mock = artifacts.require('ERC1155Mock'); - -const { expect } = require('chai'); - -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); - -contract('ERC1155Holder', function (accounts) { - const [creator] = accounts; - const uri = 'https://token-cdn-domain/{id}.json'; - const multiTokenIds = [new BN(1), new BN(2), new BN(3)]; - const multiTokenAmounts = [new BN(1000), new BN(2000), new BN(3000)]; - const transferData = '0x12345678'; - - beforeEach(async function () { - this.multiToken = await ERC1155Mock.new(uri, { from: creator }); - this.holder = await ERC1155Holder.new(); - await this.multiToken.mintBatch(creator, multiTokenIds, multiTokenAmounts, '0x', { from: creator }); - }); - - shouldSupportInterfaces(['ERC165', 'ERC1155Receiver']); - - it('receives ERC1155 tokens from a single ID', async function () { - await this.multiToken.safeTransferFrom( - creator, - this.holder.address, - multiTokenIds[0], - multiTokenAmounts[0], - transferData, - { from: creator }, - ); - - expect(await this.multiToken.balanceOf(this.holder.address, multiTokenIds[0])) - .to.be.bignumber.equal(multiTokenAmounts[0]); - - for (let i = 1; i < multiTokenIds.length; i++) { - expect(await this.multiToken.balanceOf(this.holder.address, multiTokenIds[i])).to.be.bignumber.equal(new BN(0)); - } - }); - - it('receives ERC1155 tokens from a multiple IDs', async function () { - for (let i = 0; i < multiTokenIds.length; i++) { - expect(await this.multiToken.balanceOf(this.holder.address, multiTokenIds[i])).to.be.bignumber.equal(new BN(0)); - }; - - await this.multiToken.safeBatchTransferFrom( - creator, - this.holder.address, - multiTokenIds, - multiTokenAmounts, - transferData, - { from: creator }, - ); - - for (let i = 0; i < multiTokenIds.length; i++) { - expect(await this.multiToken.balanceOf(this.holder.address, multiTokenIds[i])) - .to.be.bignumber.equal(multiTokenAmounts[i]); - } - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/ERC20.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/ERC20.behavior.js deleted file mode 100644 index 8bc5476..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/ERC20.behavior.js +++ /dev/null @@ -1,333 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS, MAX_UINT256 } = constants; - -function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recipient, anotherAccount) { - describe('total supply', function () { - it('returns the total amount of tokens', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - }); - }); - - describe('balanceOf', function () { - describe('when the requested account has no tokens', function () { - it('returns zero', async function () { - expect(await this.token.balanceOf(anotherAccount)).to.be.bignumber.equal('0'); - }); - }); - - describe('when the requested account has some tokens', function () { - it('returns the total amount of tokens', async function () { - expect(await this.token.balanceOf(initialHolder)).to.be.bignumber.equal(initialSupply); - }); - }); - }); - - describe('transfer', function () { - shouldBehaveLikeERC20Transfer(errorPrefix, initialHolder, recipient, initialSupply, - function (from, to, value) { - return this.token.transfer(to, value, { from }); - }, - ); - }); - - describe('transfer from', function () { - const spender = recipient; - - describe('when the token owner is not the zero address', function () { - const tokenOwner = initialHolder; - - describe('when the recipient is not the zero address', function () { - const to = anotherAccount; - - describe('when the spender has enough allowance', function () { - beforeEach(async function () { - await this.token.approve(spender, initialSupply, { from: initialHolder }); - }); - - describe('when the token owner has enough balance', function () { - const amount = initialSupply; - - it('transfers the requested amount', async function () { - await this.token.transferFrom(tokenOwner, to, amount, { from: spender }); - - expect(await this.token.balanceOf(tokenOwner)).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOf(to)).to.be.bignumber.equal(amount); - }); - - it('decreases the spender allowance', async function () { - await this.token.transferFrom(tokenOwner, to, amount, { from: spender }); - - expect(await this.token.allowance(tokenOwner, spender)).to.be.bignumber.equal('0'); - }); - - it('emits a transfer event', async function () { - expectEvent( - await this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - 'Transfer', - { from: tokenOwner, to: to, value: amount }, - ); - }); - - it('emits an approval event', async function () { - expectEvent( - await this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - 'Approval', - { owner: tokenOwner, spender: spender, value: await this.token.allowance(tokenOwner, spender) }, - ); - }); - }); - - describe('when the token owner does not have enough balance', function () { - const amount = initialSupply; - - beforeEach('reducing balance', async function () { - await this.token.transfer(to, 1, { from: tokenOwner }); - }); - - it('reverts', async function () { - await expectRevert( - this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - `${errorPrefix}: transfer amount exceeds balance`, - ); - }); - }); - }); - - describe('when the spender does not have enough allowance', function () { - const allowance = initialSupply.subn(1); - - beforeEach(async function () { - await this.token.approve(spender, allowance, { from: tokenOwner }); - }); - - describe('when the token owner has enough balance', function () { - const amount = initialSupply; - - it('reverts', async function () { - await expectRevert( - this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - `${errorPrefix}: insufficient allowance`, - ); - }); - }); - - describe('when the token owner does not have enough balance', function () { - const amount = allowance; - - beforeEach('reducing balance', async function () { - await this.token.transfer(to, 2, { from: tokenOwner }); - }); - - it('reverts', async function () { - await expectRevert( - this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - `${errorPrefix}: transfer amount exceeds balance`, - ); - }); - }); - }); - - describe('when the spender has unlimited allowance', function () { - beforeEach(async function () { - await this.token.approve(spender, MAX_UINT256, { from: initialHolder }); - }); - - it('does not decrease the spender allowance', async function () { - await this.token.transferFrom(tokenOwner, to, 1, { from: spender }); - - expect(await this.token.allowance(tokenOwner, spender)).to.be.bignumber.equal(MAX_UINT256); - }); - - it('does not emit an approval event', async function () { - expectEvent.notEmitted( - await this.token.transferFrom(tokenOwner, to, 1, { from: spender }), - 'Approval', - ); - }); - }); - }); - - describe('when the recipient is the zero address', function () { - const amount = initialSupply; - const to = ZERO_ADDRESS; - - beforeEach(async function () { - await this.token.approve(spender, amount, { from: tokenOwner }); - }); - - it('reverts', async function () { - await expectRevert(this.token.transferFrom( - tokenOwner, to, amount, { from: spender }), `${errorPrefix}: transfer to the zero address`, - ); - }); - }); - }); - - describe('when the token owner is the zero address', function () { - const amount = 0; - const tokenOwner = ZERO_ADDRESS; - const to = recipient; - - it('reverts', async function () { - await expectRevert( - this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - 'from the zero address', - ); - }); - }); - }); - - describe('approve', function () { - shouldBehaveLikeERC20Approve(errorPrefix, initialHolder, recipient, initialSupply, - function (owner, spender, amount) { - return this.token.approve(spender, amount, { from: owner }); - }, - ); - }); -} - -function shouldBehaveLikeERC20Transfer (errorPrefix, from, to, balance, transfer) { - describe('when the recipient is not the zero address', function () { - describe('when the sender does not have enough balance', function () { - const amount = balance.addn(1); - - it('reverts', async function () { - await expectRevert(transfer.call(this, from, to, amount), - `${errorPrefix}: transfer amount exceeds balance`, - ); - }); - }); - - describe('when the sender transfers all balance', function () { - const amount = balance; - - it('transfers the requested amount', async function () { - await transfer.call(this, from, to, amount); - - expect(await this.token.balanceOf(from)).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOf(to)).to.be.bignumber.equal(amount); - }); - - it('emits a transfer event', async function () { - expectEvent( - await transfer.call(this, from, to, amount), - 'Transfer', - { from, to, value: amount }, - ); - }); - }); - - describe('when the sender transfers zero tokens', function () { - const amount = new BN('0'); - - it('transfers the requested amount', async function () { - await transfer.call(this, from, to, amount); - - expect(await this.token.balanceOf(from)).to.be.bignumber.equal(balance); - - expect(await this.token.balanceOf(to)).to.be.bignumber.equal('0'); - }); - - it('emits a transfer event', async function () { - expectEvent( - await transfer.call(this, from, to, amount), - 'Transfer', - { from, to, value: amount }, - ); - }); - }); - }); - - describe('when the recipient is the zero address', function () { - it('reverts', async function () { - await expectRevert(transfer.call(this, from, ZERO_ADDRESS, balance), - `${errorPrefix}: transfer to the zero address`, - ); - }); - }); -} - -function shouldBehaveLikeERC20Approve (errorPrefix, owner, spender, supply, approve) { - describe('when the spender is not the zero address', function () { - describe('when the sender has enough balance', function () { - const amount = supply; - - it('emits an approval event', async function () { - expectEvent( - await approve.call(this, owner, spender, amount), - 'Approval', - { owner: owner, spender: spender, value: amount }, - ); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await approve.call(this, owner, spender, amount); - - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await approve.call(this, owner, spender, new BN(1)); - }); - - it('approves the requested amount and replaces the previous one', async function () { - await approve.call(this, owner, spender, amount); - - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(amount); - }); - }); - }); - - describe('when the sender does not have enough balance', function () { - const amount = supply.addn(1); - - it('emits an approval event', async function () { - expectEvent( - await approve.call(this, owner, spender, amount), - 'Approval', - { owner: owner, spender: spender, value: amount }, - ); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await approve.call(this, owner, spender, amount); - - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await approve.call(this, owner, spender, new BN(1)); - }); - - it('approves the requested amount and replaces the previous one', async function () { - await approve.call(this, owner, spender, amount); - - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(amount); - }); - }); - }); - }); - - describe('when the spender is the zero address', function () { - it('reverts', async function () { - await expectRevert(approve.call(this, owner, ZERO_ADDRESS, supply), - `${errorPrefix}: approve to the zero address`, - ); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/ERC20.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/ERC20.test.js deleted file mode 100644 index 992edf9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/ERC20.test.js +++ /dev/null @@ -1,309 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS } = constants; - -const { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -} = require('./ERC20.behavior'); - -const ERC20Mock = artifacts.require('ERC20Mock'); -const ERC20DecimalsMock = artifacts.require('ERC20DecimalsMock'); - -contract('ERC20', function (accounts) { - const [ initialHolder, recipient, anotherAccount ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - const initialSupply = new BN(100); - - beforeEach(async function () { - this.token = await ERC20Mock.new(name, symbol, initialHolder, initialSupply); - }); - - it('has a name', async function () { - expect(await this.token.name()).to.equal(name); - }); - - it('has a symbol', async function () { - expect(await this.token.symbol()).to.equal(symbol); - }); - - it('has 18 decimals', async function () { - expect(await this.token.decimals()).to.be.bignumber.equal('18'); - }); - - describe('set decimals', function () { - const decimals = new BN(6); - - it('can set decimals during construction', async function () { - const token = await ERC20DecimalsMock.new(name, symbol, decimals); - expect(await token.decimals()).to.be.bignumber.equal(decimals); - }); - }); - - shouldBehaveLikeERC20('ERC20', initialSupply, initialHolder, recipient, anotherAccount); - - describe('decrease allowance', function () { - describe('when the spender is not the zero address', function () { - const spender = recipient; - - function shouldDecreaseApproval (amount) { - describe('when there was no approved amount before', function () { - it('reverts', async function () { - await expectRevert(this.token.decreaseAllowance( - spender, amount, { from: initialHolder }), 'ERC20: decreased allowance below zero', - ); - }); - }); - - describe('when the spender had an approved amount', function () { - const approvedAmount = amount; - - beforeEach(async function () { - await this.token.approve(spender, approvedAmount, { from: initialHolder }); - }); - - it('emits an approval event', async function () { - expectEvent( - await this.token.decreaseAllowance(spender, approvedAmount, { from: initialHolder }), - 'Approval', - { owner: initialHolder, spender: spender, value: new BN(0) }, - ); - }); - - it('decreases the spender allowance subtracting the requested amount', async function () { - await this.token.decreaseAllowance(spender, approvedAmount.subn(1), { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal('1'); - }); - - it('sets the allowance to zero when all allowance is removed', async function () { - await this.token.decreaseAllowance(spender, approvedAmount, { from: initialHolder }); - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal('0'); - }); - - it('reverts when more than the full allowance is removed', async function () { - await expectRevert( - this.token.decreaseAllowance(spender, approvedAmount.addn(1), { from: initialHolder }), - 'ERC20: decreased allowance below zero', - ); - }); - }); - } - - describe('when the sender has enough balance', function () { - const amount = initialSupply; - - shouldDecreaseApproval(amount); - }); - - describe('when the sender does not have enough balance', function () { - const amount = initialSupply.addn(1); - - shouldDecreaseApproval(amount); - }); - }); - - describe('when the spender is the zero address', function () { - const amount = initialSupply; - const spender = ZERO_ADDRESS; - - it('reverts', async function () { - await expectRevert(this.token.decreaseAllowance( - spender, amount, { from: initialHolder }), 'ERC20: decreased allowance below zero', - ); - }); - }); - }); - - describe('increase allowance', function () { - const amount = initialSupply; - - describe('when the spender is not the zero address', function () { - const spender = recipient; - - describe('when the sender has enough balance', function () { - it('emits an approval event', async function () { - expectEvent( - await this.token.increaseAllowance(spender, amount, { from: initialHolder }), - 'Approval', - { owner: initialHolder, spender: spender, value: amount }, - ); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await this.token.increaseAllowance(spender, amount, { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await this.token.approve(spender, new BN(1), { from: initialHolder }); - }); - - it('increases the spender allowance adding the requested amount', async function () { - await this.token.increaseAllowance(spender, amount, { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal(amount.addn(1)); - }); - }); - }); - - describe('when the sender does not have enough balance', function () { - const amount = initialSupply.addn(1); - - it('emits an approval event', async function () { - expectEvent( - await this.token.increaseAllowance(spender, amount, { from: initialHolder }), - 'Approval', - { owner: initialHolder, spender: spender, value: amount }, - ); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await this.token.increaseAllowance(spender, amount, { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await this.token.approve(spender, new BN(1), { from: initialHolder }); - }); - - it('increases the spender allowance adding the requested amount', async function () { - await this.token.increaseAllowance(spender, amount, { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal(amount.addn(1)); - }); - }); - }); - }); - - describe('when the spender is the zero address', function () { - const spender = ZERO_ADDRESS; - - it('reverts', async function () { - await expectRevert( - this.token.increaseAllowance(spender, amount, { from: initialHolder }), 'ERC20: approve to the zero address', - ); - }); - }); - }); - - describe('_mint', function () { - const amount = new BN(50); - it('rejects a null account', async function () { - await expectRevert( - this.token.mint(ZERO_ADDRESS, amount), 'ERC20: mint to the zero address', - ); - }); - - describe('for a non zero account', function () { - beforeEach('minting', async function () { - this.receipt = await this.token.mint(recipient, amount); - }); - - it('increments totalSupply', async function () { - const expectedSupply = initialSupply.add(amount); - expect(await this.token.totalSupply()).to.be.bignumber.equal(expectedSupply); - }); - - it('increments recipient balance', async function () { - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(amount); - }); - - it('emits Transfer event', async function () { - const event = expectEvent( - this.receipt, - 'Transfer', - { from: ZERO_ADDRESS, to: recipient }, - ); - - expect(event.args.value).to.be.bignumber.equal(amount); - }); - }); - }); - - describe('_burn', function () { - it('rejects a null account', async function () { - await expectRevert(this.token.burn(ZERO_ADDRESS, new BN(1)), - 'ERC20: burn from the zero address'); - }); - - describe('for a non zero account', function () { - it('rejects burning more than balance', async function () { - await expectRevert(this.token.burn( - initialHolder, initialSupply.addn(1)), 'ERC20: burn amount exceeds balance', - ); - }); - - const describeBurn = function (description, amount) { - describe(description, function () { - beforeEach('burning', async function () { - this.receipt = await this.token.burn(initialHolder, amount); - }); - - it('decrements totalSupply', async function () { - const expectedSupply = initialSupply.sub(amount); - expect(await this.token.totalSupply()).to.be.bignumber.equal(expectedSupply); - }); - - it('decrements initialHolder balance', async function () { - const expectedBalance = initialSupply.sub(amount); - expect(await this.token.balanceOf(initialHolder)).to.be.bignumber.equal(expectedBalance); - }); - - it('emits Transfer event', async function () { - const event = expectEvent( - this.receipt, - 'Transfer', - { from: initialHolder, to: ZERO_ADDRESS }, - ); - - expect(event.args.value).to.be.bignumber.equal(amount); - }); - }); - }; - - describeBurn('for entire balance', initialSupply); - describeBurn('for less amount than balance', initialSupply.subn(1)); - }); - }); - - describe('_transfer', function () { - shouldBehaveLikeERC20Transfer('ERC20', initialHolder, recipient, initialSupply, function (from, to, amount) { - return this.token.transferInternal(from, to, amount); - }); - - describe('when the sender is the zero address', function () { - it('reverts', async function () { - await expectRevert(this.token.transferInternal(ZERO_ADDRESS, recipient, initialSupply), - 'ERC20: transfer from the zero address', - ); - }); - }); - }); - - describe('_approve', function () { - shouldBehaveLikeERC20Approve('ERC20', initialHolder, recipient, initialSupply, function (owner, spender, amount) { - return this.token.approveInternal(owner, spender, amount); - }); - - describe('when the owner is the zero address', function () { - it('reverts', async function () { - await expectRevert(this.token.approveInternal(ZERO_ADDRESS, recipient, initialSupply), - 'ERC20: approve from the zero address', - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Burnable.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Burnable.behavior.js deleted file mode 100644 index a931bf6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Burnable.behavior.js +++ /dev/null @@ -1,109 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) { - describe('burn', function () { - describe('when the given amount is not greater than balance of the sender', function () { - context('for a zero amount', function () { - shouldBurn(new BN(0)); - }); - - context('for a non-zero amount', function () { - shouldBurn(new BN(100)); - }); - - function shouldBurn (amount) { - beforeEach(async function () { - (this.receipt = await this.token.burn(amount, { from: owner })); - }); - - it('burns the requested amount', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialBalance.sub(amount)); - }); - - it('emits a transfer event', async function () { - expectEvent(this.receipt, 'Transfer', { - from: owner, - to: ZERO_ADDRESS, - value: amount, - }); - }); - } - }); - - describe('when the given amount is greater than the balance of the sender', function () { - const amount = initialBalance.addn(1); - - it('reverts', async function () { - await expectRevert(this.token.burn(amount, { from: owner }), - 'ERC20: burn amount exceeds balance', - ); - }); - }); - }); - - describe('burnFrom', function () { - describe('on success', function () { - context('for a zero amount', function () { - shouldBurnFrom(new BN(0)); - }); - - context('for a non-zero amount', function () { - shouldBurnFrom(new BN(100)); - }); - - function shouldBurnFrom (amount) { - const originalAllowance = amount.muln(3); - - beforeEach(async function () { - await this.token.approve(burner, originalAllowance, { from: owner }); - this.receipt = await this.token.burnFrom(owner, amount, { from: burner }); - }); - - it('burns the requested amount', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialBalance.sub(amount)); - }); - - it('decrements allowance', async function () { - expect(await this.token.allowance(owner, burner)).to.be.bignumber.equal(originalAllowance.sub(amount)); - }); - - it('emits a transfer event', async function () { - expectEvent(this.receipt, 'Transfer', { - from: owner, - to: ZERO_ADDRESS, - value: amount, - }); - }); - } - }); - - describe('when the given amount is greater than the balance of the sender', function () { - const amount = initialBalance.addn(1); - - it('reverts', async function () { - await this.token.approve(burner, amount, { from: owner }); - await expectRevert(this.token.burnFrom(owner, amount, { from: burner }), - 'ERC20: burn amount exceeds balance', - ); - }); - }); - - describe('when the given amount is greater than the allowance', function () { - const allowance = new BN(100); - - it('reverts', async function () { - await this.token.approve(burner, allowance, { from: owner }); - await expectRevert(this.token.burnFrom(owner, allowance.addn(1), { from: burner }), - 'ERC20: insufficient allowance', - ); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC20Burnable, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Burnable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Burnable.test.js deleted file mode 100644 index 8aa4fb6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Burnable.test.js +++ /dev/null @@ -1,19 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const { shouldBehaveLikeERC20Burnable } = require('./ERC20Burnable.behavior'); -const ERC20BurnableMock = artifacts.require('ERC20BurnableMock'); - -contract('ERC20Burnable', function (accounts) { - const [ owner, ...otherAccounts ] = accounts; - - const initialBalance = new BN(1000); - - const name = 'My Token'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.token = await ERC20BurnableMock.new(name, symbol, owner, initialBalance, { from: owner }); - }); - - shouldBehaveLikeERC20Burnable(owner, initialBalance, otherAccounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Capped.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Capped.behavior.js deleted file mode 100644 index 4692f99..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Capped.behavior.js +++ /dev/null @@ -1,32 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -function shouldBehaveLikeERC20Capped (minter, [other], cap) { - describe('capped token', function () { - const from = minter; - - it('starts with the correct cap', async function () { - expect(await this.token.cap()).to.be.bignumber.equal(cap); - }); - - it('mints when amount is less than cap', async function () { - await this.token.mint(other, cap.subn(1), { from }); - expect(await this.token.totalSupply()).to.be.bignumber.equal(cap.subn(1)); - }); - - it('fails to mint if the amount exceeds the cap', async function () { - await this.token.mint(other, cap.subn(1), { from }); - await expectRevert(this.token.mint(other, 2, { from }), 'ERC20Capped: cap exceeded'); - }); - - it('fails to mint after cap is reached', async function () { - await this.token.mint(other, cap, { from }); - await expectRevert(this.token.mint(other, 1, { from }), 'ERC20Capped: cap exceeded'); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC20Capped, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Capped.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Capped.test.js deleted file mode 100644 index 76532ce..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Capped.test.js +++ /dev/null @@ -1,27 +0,0 @@ -const { BN, ether, expectRevert } = require('@openzeppelin/test-helpers'); -const { shouldBehaveLikeERC20Capped } = require('./ERC20Capped.behavior'); - -const ERC20Capped = artifacts.require('ERC20CappedMock'); - -contract('ERC20Capped', function (accounts) { - const [ minter, ...otherAccounts ] = accounts; - - const cap = ether('1000'); - - const name = 'My Token'; - const symbol = 'MTKN'; - - it('requires a non-zero cap', async function () { - await expectRevert( - ERC20Capped.new(name, symbol, new BN(0), { from: minter }), 'ERC20Capped: cap is 0', - ); - }); - - context('once deployed', async function () { - beforeEach(async function () { - this.token = await ERC20Capped.new(name, symbol, cap, { from: minter }); - }); - - shouldBehaveLikeERC20Capped(minter, otherAccounts, cap); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20FlashMint.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20FlashMint.test.js deleted file mode 100644 index d08464d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20FlashMint.test.js +++ /dev/null @@ -1,144 +0,0 @@ -/* eslint-disable */ - -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256, ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const ERC20FlashMintMock = artifacts.require('ERC20FlashMintMock'); -const ERC3156FlashBorrowerMock = artifacts.require('ERC3156FlashBorrowerMock'); - -contract('ERC20FlashMint', function (accounts) { - const [initialHolder, other, anotherAccount] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - const initialSupply = new BN(100); - const loanAmount = new BN(10000000000000); - - beforeEach(async function () { - this.token = await ERC20FlashMintMock.new(name, symbol, initialHolder, initialSupply); - }); - - describe('maxFlashLoan', function () { - it('token match', async function () { - expect(await this.token.maxFlashLoan(this.token.address)).to.be.bignumber.equal(MAX_UINT256.sub(initialSupply)); - }); - - it('token mismatch', async function () { - expect(await this.token.maxFlashLoan(ZERO_ADDRESS)).to.be.bignumber.equal('0'); - }); - }); - - describe('flashFee', function () { - it('token match', async function () { - expect(await this.token.flashFee(this.token.address, loanAmount)).to.be.bignumber.equal('0'); - }); - - it('token mismatch', async function () { - await expectRevert(this.token.flashFee(ZERO_ADDRESS, loanAmount), 'ERC20FlashMint: wrong token'); - }); - }); - - describe('flashFeeReceiver', function () { - it('default receiver', async function () { - expect(await this.token.flashFeeReceiver()).to.be.eq(ZERO_ADDRESS); - }); - }); - - describe('flashLoan', function () { - it('success', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(true, true); - const { tx } = await this.token.flashLoan(receiver.address, this.token.address, loanAmount, '0x'); - - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: ZERO_ADDRESS, to: receiver.address, value: loanAmount }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: receiver.address, to: ZERO_ADDRESS, value: loanAmount }); - await expectEvent.inTransaction(tx, receiver, 'BalanceOf', { token: this.token.address, account: receiver.address, value: loanAmount }); - await expectEvent.inTransaction(tx, receiver, 'TotalSupply', { token: this.token.address, value: initialSupply.add(loanAmount) }); - - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOf(receiver.address)).to.be.bignumber.equal('0'); - expect(await this.token.allowance(receiver.address, this.token.address)).to.be.bignumber.equal('0'); - }); - - it('missing return value', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(false, true); - await expectRevert( - this.token.flashLoan(receiver.address, this.token.address, loanAmount, '0x'), - 'ERC20FlashMint: invalid return value', - ); - }); - - it('missing approval', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(true, false); - await expectRevert( - this.token.flashLoan(receiver.address, this.token.address, loanAmount, '0x'), - 'ERC20: insufficient allowance', - ); - }); - - it('unavailable funds', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(true, true); - const data = this.token.contract.methods.transfer(other, 10).encodeABI(); - await expectRevert( - this.token.flashLoan(receiver.address, this.token.address, loanAmount, data), - 'ERC20: burn amount exceeds balance', - ); - }); - - it('more than maxFlashLoan', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(true, true); - const data = this.token.contract.methods.transfer(other, 10).encodeABI(); - // _mint overflow reverts using a panic code. No reason string. - await expectRevert.unspecified(this.token.flashLoan(receiver.address, this.token.address, MAX_UINT256, data)); - }); - - describe('custom flash fee & custom fee receiver', function () { - const receiverInitialBalance = new BN(200000); - const flashFee = new BN(5000); - - beforeEach('init receiver balance & set flash fee', async function () { - this.receiver = await ERC3156FlashBorrowerMock.new(true, true); - const receipt = await this.token.mint(this.receiver.address, receiverInitialBalance); - await expectEvent(receipt, 'Transfer', { from: ZERO_ADDRESS, to: this.receiver.address, value: receiverInitialBalance }); - expect(await this.token.balanceOf(this.receiver.address)).to.be.bignumber.equal(receiverInitialBalance); - - await this.token.setFlashFee(flashFee); - expect(await this.token.flashFee(this.token.address, loanAmount)).to.be.bignumber.equal(flashFee); - }); - - it('default flash fee receiver', async function () { - const { tx } = await this.token.flashLoan(this.receiver.address, this.token.address, loanAmount, '0x'); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: ZERO_ADDRESS, to: this.receiver.address, value: loanAmount }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: this.receiver.address, to: ZERO_ADDRESS, value: loanAmount.add(flashFee) }); - await expectEvent.inTransaction(tx, this.receiver, 'BalanceOf', { token: this.token.address, account: this.receiver.address, value: receiverInitialBalance.add(loanAmount) }); - await expectEvent.inTransaction(tx, this.receiver, 'TotalSupply', { token: this.token.address, value: initialSupply.add(receiverInitialBalance).add(loanAmount) }); - - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply.add(receiverInitialBalance).sub(flashFee)); - expect(await this.token.balanceOf(this.receiver.address)).to.be.bignumber.equal(receiverInitialBalance.sub(flashFee)); - expect(await this.token.balanceOf(await this.token.flashFeeReceiver())).to.be.bignumber.equal('0'); - expect(await this.token.allowance(this.receiver.address, this.token.address)).to.be.bignumber.equal('0'); - }); - - it('custom flash fee receiver', async function () { - const flashFeeReceiverAddress = anotherAccount; - await this.token.setFlashFeeReceiver(flashFeeReceiverAddress); - expect(await this.token.flashFeeReceiver()).to.be.eq(flashFeeReceiverAddress); - - expect(await this.token.balanceOf(flashFeeReceiverAddress)).to.be.bignumber.equal('0'); - - const { tx } = await this.token.flashLoan(this.receiver.address, this.token.address, loanAmount, '0x'); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: ZERO_ADDRESS, to: this.receiver.address, value: loanAmount }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: this.receiver.address, to: ZERO_ADDRESS, value: loanAmount }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: this.receiver.address, to: flashFeeReceiverAddress, value: flashFee }); - await expectEvent.inTransaction(tx, this.receiver, 'BalanceOf', { token: this.token.address, account: this.receiver.address, value: receiverInitialBalance.add(loanAmount) }); - await expectEvent.inTransaction(tx, this.receiver, 'TotalSupply', { token: this.token.address, value: initialSupply.add(receiverInitialBalance).add(loanAmount) }); - - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply.add(receiverInitialBalance)); - expect(await this.token.balanceOf(this.receiver.address)).to.be.bignumber.equal(receiverInitialBalance.sub(flashFee)); - expect(await this.token.balanceOf(flashFeeReceiverAddress)).to.be.bignumber.equal(flashFee); - expect(await this.token.allowance(this.receiver.address, flashFeeReceiverAddress)).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Pausable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Pausable.test.js deleted file mode 100644 index 8670e2f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Pausable.test.js +++ /dev/null @@ -1,134 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC20PausableMock = artifacts.require('ERC20PausableMock'); - -contract('ERC20Pausable', function (accounts) { - const [ holder, recipient, anotherAccount ] = accounts; - - const initialSupply = new BN(100); - - const name = 'My Token'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.token = await ERC20PausableMock.new(name, symbol, holder, initialSupply); - }); - - describe('pausable token', function () { - describe('transfer', function () { - it('allows to transfer when unpaused', async function () { - await this.token.transfer(recipient, initialSupply, { from: holder }); - - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(initialSupply); - }); - - it('allows to transfer when paused and then unpaused', async function () { - await this.token.pause(); - await this.token.unpause(); - - await this.token.transfer(recipient, initialSupply, { from: holder }); - - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(initialSupply); - }); - - it('reverts when trying to transfer when paused', async function () { - await this.token.pause(); - - await expectRevert(this.token.transfer(recipient, initialSupply, { from: holder }), - 'ERC20Pausable: token transfer while paused', - ); - }); - }); - - describe('transfer from', function () { - const allowance = new BN(40); - - beforeEach(async function () { - await this.token.approve(anotherAccount, allowance, { from: holder }); - }); - - it('allows to transfer from when unpaused', async function () { - await this.token.transferFrom(holder, recipient, allowance, { from: anotherAccount }); - - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(allowance); - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(allowance)); - }); - - it('allows to transfer when paused and then unpaused', async function () { - await this.token.pause(); - await this.token.unpause(); - - await this.token.transferFrom(holder, recipient, allowance, { from: anotherAccount }); - - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(allowance); - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(allowance)); - }); - - it('reverts when trying to transfer from when paused', async function () { - await this.token.pause(); - - await expectRevert(this.token.transferFrom( - holder, recipient, allowance, { from: anotherAccount }), 'ERC20Pausable: token transfer while paused', - ); - }); - }); - - describe('mint', function () { - const amount = new BN('42'); - - it('allows to mint when unpaused', async function () { - await this.token.mint(recipient, amount); - - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(amount); - }); - - it('allows to mint when paused and then unpaused', async function () { - await this.token.pause(); - await this.token.unpause(); - - await this.token.mint(recipient, amount); - - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(amount); - }); - - it('reverts when trying to mint when paused', async function () { - await this.token.pause(); - - await expectRevert(this.token.mint(recipient, amount), - 'ERC20Pausable: token transfer while paused', - ); - }); - }); - - describe('burn', function () { - const amount = new BN('42'); - - it('allows to burn when unpaused', async function () { - await this.token.burn(holder, amount); - - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(amount)); - }); - - it('allows to burn when paused and then unpaused', async function () { - await this.token.pause(); - await this.token.unpause(); - - await this.token.burn(holder, amount); - - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(amount)); - }); - - it('reverts when trying to burn when paused', async function () { - await this.token.pause(); - - await expectRevert(this.token.burn(holder, amount), - 'ERC20Pausable: token transfer while paused', - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Snapshot.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Snapshot.test.js deleted file mode 100644 index 64d9227..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Snapshot.test.js +++ /dev/null @@ -1,204 +0,0 @@ -const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const ERC20SnapshotMock = artifacts.require('ERC20SnapshotMock'); - -const { expect } = require('chai'); - -contract('ERC20Snapshot', function (accounts) { - const [ initialHolder, recipient, other ] = accounts; - - const initialSupply = new BN(100); - - const name = 'My Token'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.token = await ERC20SnapshotMock.new(name, symbol, initialHolder, initialSupply); - }); - - describe('snapshot', function () { - it('emits a snapshot event', async function () { - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot'); - }); - - it('creates increasing snapshots ids, starting from 1', async function () { - for (const id of ['1', '2', '3', '4', '5']) { - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id }); - } - }); - }); - - describe('totalSupplyAt', function () { - it('reverts with a snapshot id of 0', async function () { - await expectRevert(this.token.totalSupplyAt(0), 'ERC20Snapshot: id is 0'); - }); - - it('reverts with a not-yet-created snapshot id', async function () { - await expectRevert(this.token.totalSupplyAt(1), 'ERC20Snapshot: nonexistent id'); - }); - - context('with initial snapshot', function () { - beforeEach(async function () { - this.initialSnapshotId = new BN('1'); - - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id: this.initialSnapshotId }); - }); - - context('with no supply changes after the snapshot', function () { - it('returns the current total supply', async function () { - expect(await this.token.totalSupplyAt(this.initialSnapshotId)).to.be.bignumber.equal(initialSupply); - }); - }); - - context('with supply changes after the snapshot', function () { - beforeEach(async function () { - await this.token.mint(other, new BN('50')); - await this.token.burn(initialHolder, new BN('20')); - }); - - it('returns the total supply before the changes', async function () { - expect(await this.token.totalSupplyAt(this.initialSnapshotId)).to.be.bignumber.equal(initialSupply); - }); - - context('with a second snapshot after supply changes', function () { - beforeEach(async function () { - this.secondSnapshotId = new BN('2'); - - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id: this.secondSnapshotId }); - }); - - it('snapshots return the supply before and after the changes', async function () { - expect(await this.token.totalSupplyAt(this.initialSnapshotId)).to.be.bignumber.equal(initialSupply); - - expect(await this.token.totalSupplyAt(this.secondSnapshotId)).to.be.bignumber.equal( - await this.token.totalSupply(), - ); - }); - }); - - context('with multiple snapshots after supply changes', function () { - beforeEach(async function () { - this.secondSnapshotIds = ['2', '3', '4']; - - for (const id of this.secondSnapshotIds) { - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id }); - } - }); - - it('all posterior snapshots return the supply after the changes', async function () { - expect(await this.token.totalSupplyAt(this.initialSnapshotId)).to.be.bignumber.equal(initialSupply); - - const currentSupply = await this.token.totalSupply(); - - for (const id of this.secondSnapshotIds) { - expect(await this.token.totalSupplyAt(id)).to.be.bignumber.equal(currentSupply); - } - }); - }); - }); - }); - }); - - describe('balanceOfAt', function () { - it('reverts with a snapshot id of 0', async function () { - await expectRevert(this.token.balanceOfAt(other, 0), 'ERC20Snapshot: id is 0'); - }); - - it('reverts with a not-yet-created snapshot id', async function () { - await expectRevert(this.token.balanceOfAt(other, 1), 'ERC20Snapshot: nonexistent id'); - }); - - context('with initial snapshot', function () { - beforeEach(async function () { - this.initialSnapshotId = new BN('1'); - - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id: this.initialSnapshotId }); - }); - - context('with no balance changes after the snapshot', function () { - it('returns the current balance for all accounts', async function () { - expect(await this.token.balanceOfAt(initialHolder, this.initialSnapshotId)) - .to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOfAt(recipient, this.initialSnapshotId)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOfAt(other, this.initialSnapshotId)).to.be.bignumber.equal('0'); - }); - }); - - context('with balance changes after the snapshot', function () { - beforeEach(async function () { - await this.token.transfer(recipient, new BN('10'), { from: initialHolder }); - await this.token.mint(other, new BN('50')); - await this.token.burn(initialHolder, new BN('20')); - }); - - it('returns the balances before the changes', async function () { - expect(await this.token.balanceOfAt(initialHolder, this.initialSnapshotId)) - .to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOfAt(recipient, this.initialSnapshotId)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOfAt(other, this.initialSnapshotId)).to.be.bignumber.equal('0'); - }); - - context('with a second snapshot after supply changes', function () { - beforeEach(async function () { - this.secondSnapshotId = new BN('2'); - - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id: this.secondSnapshotId }); - }); - - it('snapshots return the balances before and after the changes', async function () { - expect(await this.token.balanceOfAt(initialHolder, this.initialSnapshotId)) - .to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOfAt(recipient, this.initialSnapshotId)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOfAt(other, this.initialSnapshotId)).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOfAt(initialHolder, this.secondSnapshotId)).to.be.bignumber.equal( - await this.token.balanceOf(initialHolder), - ); - expect(await this.token.balanceOfAt(recipient, this.secondSnapshotId)).to.be.bignumber.equal( - await this.token.balanceOf(recipient), - ); - expect(await this.token.balanceOfAt(other, this.secondSnapshotId)).to.be.bignumber.equal( - await this.token.balanceOf(other), - ); - }); - }); - - context('with multiple snapshots after supply changes', function () { - beforeEach(async function () { - this.secondSnapshotIds = ['2', '3', '4']; - - for (const id of this.secondSnapshotIds) { - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id }); - } - }); - - it('all posterior snapshots return the supply after the changes', async function () { - expect(await this.token.balanceOfAt(initialHolder, this.initialSnapshotId)) - .to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOfAt(recipient, this.initialSnapshotId)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOfAt(other, this.initialSnapshotId)).to.be.bignumber.equal('0'); - - for (const id of this.secondSnapshotIds) { - expect(await this.token.balanceOfAt(initialHolder, id)).to.be.bignumber.equal( - await this.token.balanceOf(initialHolder), - ); - expect(await this.token.balanceOfAt(recipient, id)).to.be.bignumber.equal( - await this.token.balanceOf(recipient), - ); - expect(await this.token.balanceOfAt(other, id)).to.be.bignumber.equal( - await this.token.balanceOf(other), - ); - } - }); - }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Votes.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Votes.test.js deleted file mode 100644 index 9d3160b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Votes.test.js +++ /dev/null @@ -1,518 +0,0 @@ -/* eslint-disable */ - -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256, ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const ERC20VotesMock = artifacts.require('ERC20VotesMock'); - -const { batchInBlock } = require('../../../helpers/txpool'); -const { EIP712Domain, domainSeparator } = require('../../../helpers/eip712'); - -const Delegation = [ - { name: 'delegatee', type: 'address' }, - { name: 'nonce', type: 'uint256' }, - { name: 'expiry', type: 'uint256' }, -]; - -contract('ERC20Votes', function (accounts) { - const [ holder, recipient, holderDelegatee, recipientDelegatee, other1, other2 ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - const version = '1'; - const supply = new BN('10000000000000000000000000'); - - beforeEach(async function () { - this.token = await ERC20VotesMock.new(name, symbol); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.token.getChainId(); - }); - - it('initial nonce is 0', async function () { - expect(await this.token.nonces(holder)).to.be.bignumber.equal('0'); - }); - - it('domain separator', async function () { - expect( - await this.token.DOMAIN_SEPARATOR(), - ).to.equal( - await domainSeparator(name, version, this.chainId, this.token.address), - ); - }); - - it('minting restriction', async function () { - const amount = new BN('2').pow(new BN('224')); - await expectRevert( - this.token.mint(holder, amount), - 'ERC20Votes: total supply risks overflowing votes', - ); - }); - - it('recent checkpoints', async function () { - await this.token.delegate(holder, { from: holder }); - for (let i = 0; i < 6; i++) { - await this.token.mint(holder, 1); - } - const block = await web3.eth.getBlockNumber(); - expect(await this.token.numCheckpoints(holder)).to.be.bignumber.equal('6'); - // recent - expect(await this.token.getPastVotes(holder, block - 1)).to.be.bignumber.equal('5'); - // non-recent - expect(await this.token.getPastVotes(holder, block - 6)).to.be.bignumber.equal('0'); - }); - - describe('set delegation', function () { - describe('call', function () { - it('delegation with balance', async function () { - await this.token.mint(holder, supply); - expect(await this.token.delegates(holder)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegate(holder, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: ZERO_ADDRESS, - toDelegate: holder, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holder, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(holder)).to.be.equal(holder); - - expect(await this.token.getVotes(holder)).to.be.bignumber.equal(supply); - expect(await this.token.getPastVotes(holder, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPastVotes(holder, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - - it('delegation without balance', async function () { - expect(await this.token.delegates(holder)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegate(holder, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: ZERO_ADDRESS, - toDelegate: holder, - }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - expect(await this.token.delegates(holder)).to.be.equal(holder); - }); - }); - - describe('with signature', function () { - const delegator = Wallet.generate(); - const delegatorAddress = web3.utils.toChecksumAddress(delegator.getAddressString()); - const nonce = 0; - - const buildData = (chainId, verifyingContract, message) => ({ data: { - primaryType: 'Delegation', - types: { EIP712Domain, Delegation }, - domain: { name, version, chainId, verifyingContract }, - message, - }}); - - beforeEach(async function () { - await this.token.mint(delegatorAddress, supply); - }); - - it('accept signed delegation', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - expect(await this.token.delegates(delegatorAddress)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - expectEvent(receipt, 'DelegateChanged', { - delegator: delegatorAddress, - fromDelegate: ZERO_ADDRESS, - toDelegate: delegatorAddress, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: delegatorAddress, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(delegatorAddress)).to.be.equal(delegatorAddress); - - expect(await this.token.getVotes(delegatorAddress)).to.be.bignumber.equal(supply); - expect(await this.token.getPastVotes(delegatorAddress, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPastVotes(delegatorAddress, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - - it('rejects reused signature', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - await this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s), - 'ERC20Votes: invalid nonce', - ); - }); - - it('rejects bad delegatee', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - const receipt = await this.token.delegateBySig(holderDelegatee, nonce, MAX_UINT256, v, r, s); - const { args } = receipt.logs.find(({ event }) => event == 'DelegateChanged'); - expect(args.delegator).to.not.be.equal(delegatorAddress); - expect(args.fromDelegate).to.be.equal(ZERO_ADDRESS); - expect(args.toDelegate).to.be.equal(holderDelegatee); - }); - - it('rejects bad nonce', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce + 1, MAX_UINT256, v, r, s), - 'ERC20Votes: invalid nonce', - ); - }); - - it('rejects expired permit', async function () { - const expiry = (await time.latest()) - time.duration.weeks(1); - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry, - }), - )); - - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce, expiry, v, r, s), - 'ERC20Votes: signature expired', - ); - }); - }); - }); - - describe('change delegation', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - await this.token.delegate(holder, { from: holder }); - }); - - it('call', async function () { - expect(await this.token.delegates(holder)).to.be.equal(holder); - - const { receipt } = await this.token.delegate(holderDelegatee, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: holder, - toDelegate: holderDelegatee, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holder, - previousBalance: supply, - newBalance: '0', - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holderDelegatee, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(holder)).to.be.equal(holderDelegatee); - - expect(await this.token.getVotes(holder)).to.be.bignumber.equal('0'); - expect(await this.token.getVotes(holderDelegatee)).to.be.bignumber.equal(supply); - expect(await this.token.getPastVotes(holder, receipt.blockNumber - 1)).to.be.bignumber.equal(supply); - expect(await this.token.getPastVotes(holderDelegatee, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPastVotes(holder, receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.token.getPastVotes(holderDelegatee, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - }); - - describe('transfers', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - }); - - it('no delegation', async function () { - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - this.holderVotes = '0'; - this.recipientVotes = '0'; - }); - - it('sender delegation', async function () { - await this.token.delegate(holder, { from: holder }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.holderVotes = supply.subn(1); - this.recipientVotes = '0'; - }); - - it('receiver delegation', async function () { - await this.token.delegate(recipient, { from: recipient }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.holderVotes = '0'; - this.recipientVotes = '1'; - }); - - it('full delegation', async function () { - await this.token.delegate(holder, { from: holder }); - await this.token.delegate(recipient, { from: recipient }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.holderVotes = supply.subn(1); - this.recipientVotes = '1'; - }); - - afterEach(async function () { - expect(await this.token.getVotes(holder)).to.be.bignumber.equal(this.holderVotes); - expect(await this.token.getVotes(recipient)).to.be.bignumber.equal(this.recipientVotes); - - // need to advance 2 blocks to see the effect of a transfer on "getPastVotes" - const blockNumber = await time.latestBlock(); - await time.advanceBlock(); - expect(await this.token.getPastVotes(holder, blockNumber)).to.be.bignumber.equal(this.holderVotes); - expect(await this.token.getPastVotes(recipient, blockNumber)).to.be.bignumber.equal(this.recipientVotes); - }); - }); - - // The following tests are a adaptation of https://github.com/compound-finance/compound-protocol/blob/master/tests/Governance/CompTest.js. - describe('Compound test suite', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - }); - - describe('balanceOf', function () { - it('grants to initial account', async function () { - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); - - describe('numCheckpoints', function () { - it('returns the number of checkpoints for a delegate', async function () { - await this.token.transfer(recipient, '100', { from: holder }); //give an account a few tokens for readability - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('0'); - - const t1 = await this.token.delegate(other1, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('1'); - - const t2 = await this.token.transfer(other2, 10, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('2'); - - const t3 = await this.token.transfer(other2, 10, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('3'); - - const t4 = await this.token.transfer(recipient, 20, { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('4'); - - expect(await this.token.checkpoints(other1, 0)).to.be.deep.equal([ t1.receipt.blockNumber.toString(), '100' ]); - expect(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ t2.receipt.blockNumber.toString(), '90' ]); - expect(await this.token.checkpoints(other1, 2)).to.be.deep.equal([ t3.receipt.blockNumber.toString(), '80' ]); - expect(await this.token.checkpoints(other1, 3)).to.be.deep.equal([ t4.receipt.blockNumber.toString(), '100' ]); - - await time.advanceBlock(); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('100'); - expect(await this.token.getPastVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('90'); - expect(await this.token.getPastVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('80'); - expect(await this.token.getPastVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('100'); - }); - - it('does not add more than one checkpoint in a block', async function () { - await this.token.transfer(recipient, '100', { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('0'); - - const [ t1, t2, t3 ] = await batchInBlock([ - () => this.token.delegate(other1, { from: recipient, gas: 100000 }), - () => this.token.transfer(other2, 10, { from: recipient, gas: 100000 }), - () => this.token.transfer(other2, 10, { from: recipient, gas: 100000 }), - ]); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('1'); - expect(await this.token.checkpoints(other1, 0)).to.be.deep.equal([ t1.receipt.blockNumber.toString(), '80' ]); - // expectReve(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ '0', '0' ]); // Reverts due to array overflow check - // expect(await this.token.checkpoints(other1, 2)).to.be.deep.equal([ '0', '0' ]); // Reverts due to array overflow check - - const t4 = await this.token.transfer(recipient, 20, { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('2'); - expect(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ t4.receipt.blockNumber.toString(), '100' ]); - }); - }); - - describe('getPastVotes', function () { - it('reverts if block number >= current block', async function () { - await expectRevert( - this.token.getPastVotes(other1, 5e10), - 'ERC20Votes: block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPastVotes(other1, 0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.token.transfer(other2, 10, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.token.transfer(other2, 10, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.token.transfer(holder, 20, { from: other2 }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastVotes(other1, t2.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastVotes(other1, t3.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastVotes(other1, t4.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); - }); - - describe('getPastTotalSupply', function () { - beforeEach(async function () { - await this.token.delegate(holder, { from: holder }); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.token.getPastTotalSupply(5e10), - 'ERC20Votes: block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPastTotalSupply(0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - t1 = await this.token.mint(holder, supply); - - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal(supply); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal(supply); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.token.mint(holder, supply); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.mint(holder, supply); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.token.burn(holder, 10); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.token.burn(holder, 10); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.token.mint(holder, 20); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t2.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastTotalSupply(t2.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastTotalSupply(t3.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastTotalSupply(t3.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastTotalSupply(t4.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t4.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20VotesComp.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20VotesComp.test.js deleted file mode 100644 index b70c6d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20VotesComp.test.js +++ /dev/null @@ -1,496 +0,0 @@ -/* eslint-disable */ - -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256, ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const ERC20VotesCompMock = artifacts.require('ERC20VotesCompMock'); - -const { batchInBlock } = require('../../../helpers/txpool'); -const { EIP712Domain, domainSeparator } = require('../../../helpers/eip712'); - -const Delegation = [ - { name: 'delegatee', type: 'address' }, - { name: 'nonce', type: 'uint256' }, - { name: 'expiry', type: 'uint256' }, -]; - -contract('ERC20VotesComp', function (accounts) { - const [ holder, recipient, holderDelegatee, recipientDelegatee, other1, other2 ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - const version = '1'; - const supply = new BN('10000000000000000000000000'); - - beforeEach(async function () { - this.token = await ERC20VotesCompMock.new(name, symbol); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.token.getChainId(); - }); - - it('initial nonce is 0', async function () { - expect(await this.token.nonces(holder)).to.be.bignumber.equal('0'); - }); - - it('domain separator', async function () { - expect( - await this.token.DOMAIN_SEPARATOR(), - ).to.equal( - await domainSeparator(name, version, this.chainId, this.token.address), - ); - }); - - it('minting restriction', async function () { - const amount = new BN('2').pow(new BN('96')); - await expectRevert( - this.token.mint(holder, amount), - 'ERC20Votes: total supply risks overflowing votes', - ); - }); - - describe('set delegation', function () { - describe('call', function () { - it('delegation with balance', async function () { - await this.token.mint(holder, supply); - expect(await this.token.delegates(holder)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegate(holder, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: ZERO_ADDRESS, - toDelegate: holder, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holder, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(holder)).to.be.equal(holder); - - expect(await this.token.getCurrentVotes(holder)).to.be.bignumber.equal(supply); - expect(await this.token.getPriorVotes(holder, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPriorVotes(holder, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - - it('delegation without balance', async function () { - expect(await this.token.delegates(holder)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegate(holder, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: ZERO_ADDRESS, - toDelegate: holder, - }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - expect(await this.token.delegates(holder)).to.be.equal(holder); - }); - }); - - describe('with signature', function () { - const delegator = Wallet.generate(); - const delegatorAddress = web3.utils.toChecksumAddress(delegator.getAddressString()); - const nonce = 0; - - const buildData = (chainId, verifyingContract, message) => ({ data: { - primaryType: 'Delegation', - types: { EIP712Domain, Delegation }, - domain: { name, version, chainId, verifyingContract }, - message, - }}); - - beforeEach(async function () { - await this.token.mint(delegatorAddress, supply); - }); - - it('accept signed delegation', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - expect(await this.token.delegates(delegatorAddress)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - expectEvent(receipt, 'DelegateChanged', { - delegator: delegatorAddress, - fromDelegate: ZERO_ADDRESS, - toDelegate: delegatorAddress, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: delegatorAddress, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(delegatorAddress)).to.be.equal(delegatorAddress); - - expect(await this.token.getCurrentVotes(delegatorAddress)).to.be.bignumber.equal(supply); - expect(await this.token.getPriorVotes(delegatorAddress, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPriorVotes(delegatorAddress, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - - it('rejects reused signature', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - await this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s), - 'ERC20Votes: invalid nonce', - ); - }); - - it('rejects bad delegatee', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - const receipt = await this.token.delegateBySig(holderDelegatee, nonce, MAX_UINT256, v, r, s); - const { args } = receipt.logs.find(({ event }) => event == 'DelegateChanged'); - expect(args.delegator).to.not.be.equal(delegatorAddress); - expect(args.fromDelegate).to.be.equal(ZERO_ADDRESS); - expect(args.toDelegate).to.be.equal(holderDelegatee); - }); - - it('rejects bad nonce', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce + 1, MAX_UINT256, v, r, s), - 'ERC20Votes: invalid nonce', - ); - }); - - it('rejects expired permit', async function () { - const expiry = (await time.latest()) - time.duration.weeks(1); - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry, - }), - )); - - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce, expiry, v, r, s), - 'ERC20Votes: signature expired', - ); - }); - }); - }); - - describe('change delegation', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - await this.token.delegate(holder, { from: holder }); - }); - - it('call', async function () { - expect(await this.token.delegates(holder)).to.be.equal(holder); - - const { receipt } = await this.token.delegate(holderDelegatee, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: holder, - toDelegate: holderDelegatee, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holder, - previousBalance: supply, - newBalance: '0', - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holderDelegatee, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(holder)).to.be.equal(holderDelegatee); - - expect(await this.token.getCurrentVotes(holder)).to.be.bignumber.equal('0'); - expect(await this.token.getCurrentVotes(holderDelegatee)).to.be.bignumber.equal(supply); - expect(await this.token.getPriorVotes(holder, receipt.blockNumber - 1)).to.be.bignumber.equal(supply); - expect(await this.token.getPriorVotes(holderDelegatee, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPriorVotes(holder, receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.token.getPriorVotes(holderDelegatee, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - }); - - describe('transfers', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - }); - - it('no delegation', async function () { - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - this.holderVotes = '0'; - this.recipientVotes = '0'; - }); - - it('sender delegation', async function () { - await this.token.delegate(holder, { from: holder }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); - - this.holderVotes = supply.subn(1); - this.recipientVotes = '0'; - }); - - it('receiver delegation', async function () { - await this.token.delegate(recipient, { from: recipient }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); - - this.holderVotes = '0'; - this.recipientVotes = '1'; - }); - - it('full delegation', async function () { - await this.token.delegate(holder, { from: holder }); - await this.token.delegate(recipient, { from: recipient }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); - - this.holderVotes = supply.subn(1); - this.recipientVotes = '1'; - }); - - afterEach(async function () { - expect(await this.token.getCurrentVotes(holder)).to.be.bignumber.equal(this.holderVotes); - expect(await this.token.getCurrentVotes(recipient)).to.be.bignumber.equal(this.recipientVotes); - - // need to advance 2 blocks to see the effect of a transfer on "getPriorVotes" - const blockNumber = await time.latestBlock(); - await time.advanceBlock(); - expect(await this.token.getPriorVotes(holder, blockNumber)).to.be.bignumber.equal(this.holderVotes); - expect(await this.token.getPriorVotes(recipient, blockNumber)).to.be.bignumber.equal(this.recipientVotes); - }); - }); - - // The following tests are a adaptation of https://github.com/compound-finance/compound-protocol/blob/master/tests/Governance/CompTest.js. - describe('Compound test suite', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - }); - - describe('balanceOf', function () { - it('grants to initial account', async function () { - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); - - describe('numCheckpoints', function () { - it('returns the number of checkpoints for a delegate', async function () { - await this.token.transfer(recipient, '100', { from: holder }); //give an account a few tokens for readability - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('0'); - - const t1 = await this.token.delegate(other1, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('1'); - - const t2 = await this.token.transfer(other2, 10, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('2'); - - const t3 = await this.token.transfer(other2, 10, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('3'); - - const t4 = await this.token.transfer(recipient, 20, { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('4'); - - expect(await this.token.checkpoints(other1, 0)).to.be.deep.equal([ t1.receipt.blockNumber.toString(), '100' ]); - expect(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ t2.receipt.blockNumber.toString(), '90' ]); - expect(await this.token.checkpoints(other1, 2)).to.be.deep.equal([ t3.receipt.blockNumber.toString(), '80' ]); - expect(await this.token.checkpoints(other1, 3)).to.be.deep.equal([ t4.receipt.blockNumber.toString(), '100' ]); - - await time.advanceBlock(); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('100'); - expect(await this.token.getPriorVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('90'); - expect(await this.token.getPriorVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('80'); - expect(await this.token.getPriorVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('100'); - }); - - it('does not add more than one checkpoint in a block', async function () { - await this.token.transfer(recipient, '100', { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('0'); - - const [ t1, t2, t3 ] = await batchInBlock([ - () => this.token.delegate(other1, { from: recipient, gas: 100000 }), - () => this.token.transfer(other2, 10, { from: recipient, gas: 100000 }), - () => this.token.transfer(other2, 10, { from: recipient, gas: 100000 }), - ]); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('1'); - expect(await this.token.checkpoints(other1, 0)).to.be.deep.equal([ t1.receipt.blockNumber.toString(), '80' ]); - // expectReve(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ '0', '0' ]); // Reverts due to array overflow check - // expect(await this.token.checkpoints(other1, 2)).to.be.deep.equal([ '0', '0' ]); // Reverts due to array overflow check - - const t4 = await this.token.transfer(recipient, 20, { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('2'); - expect(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ t4.receipt.blockNumber.toString(), '100' ]); - }); - }); - - describe('getPriorVotes', function () { - it('reverts if block number >= current block', async function () { - await expectRevert( - this.token.getPriorVotes(other1, 5e10), - 'ERC20Votes: block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPriorVotes(other1, 0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.token.transfer(other2, 10, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.token.transfer(other2, 10, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.token.transfer(holder, 20, { from: other2 }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPriorVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPriorVotes(other1, t2.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPriorVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPriorVotes(other1, t3.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPriorVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPriorVotes(other1, t4.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); - }); - - describe('getPastTotalSupply', function () { - beforeEach(async function () { - await this.token.delegate(holder, { from: holder }); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.token.getPastTotalSupply(5e10), - 'ERC20Votes: block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPastTotalSupply(0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - t1 = await this.token.mint(holder, supply); - - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal(supply); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal(supply); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.token.mint(holder, supply); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.mint(holder, supply); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.token.burn(holder, 10); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.token.burn(holder, 10); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.token.mint(holder, 20); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t2.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastTotalSupply(t2.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastTotalSupply(t3.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastTotalSupply(t3.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastTotalSupply(t4.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t4.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Wrapper.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Wrapper.test.js deleted file mode 100644 index ceb813e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC20Wrapper.test.js +++ /dev/null @@ -1,190 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS, MAX_UINT256 } = constants; - -const { shouldBehaveLikeERC20 } = require('../ERC20.behavior'); - -const NotAnERC20 = artifacts.require('CallReceiverMock'); -const ERC20Mock = artifacts.require('ERC20DecimalsMock'); -const ERC20WrapperMock = artifacts.require('ERC20WrapperMock'); - -contract('ERC20', function (accounts) { - const [ initialHolder, recipient, anotherAccount ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - const initialSupply = new BN(100); - - beforeEach(async function () { - this.underlying = await ERC20Mock.new(name, symbol, 9); - this.token = await ERC20WrapperMock.new(this.underlying.address, `Wrapped ${name}`, `W${symbol}`); - - await this.underlying.mint(initialHolder, initialSupply); - }); - - afterEach(async function () { - expect(await this.underlying.balanceOf(this.token.address)).to.be.bignumber.equal(await this.token.totalSupply()); - }); - - it('has a name', async function () { - expect(await this.token.name()).to.equal(`Wrapped ${name}`); - }); - - it('has a symbol', async function () { - expect(await this.token.symbol()).to.equal(`W${symbol}`); - }); - - it('has the same decimals as the underlying token', async function () { - expect(await this.token.decimals()).to.be.bignumber.equal('9'); - }); - - it('decimals default back to 18 if token has no metadata', async function () { - const noDecimals = await NotAnERC20.new(); - const otherToken = await ERC20WrapperMock.new(noDecimals.address, `Wrapped ${name}`, `W${symbol}`); - expect(await otherToken.decimals()).to.be.bignumber.equal('18'); - }); - - it('has underlying', async function () { - expect(await this.token.underlying()).to.be.bignumber.equal(this.underlying.address); - }); - - describe('deposit', function () { - it('valid', async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - const { tx } = await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: initialHolder, - to: this.token.address, - value: initialSupply, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: ZERO_ADDRESS, - to: initialHolder, - value: initialSupply, - }); - }); - - it('missing approval', async function () { - await expectRevert( - this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }), - 'ERC20: insufficient allowance', - ); - }); - - it('missing balance', async function () { - await this.underlying.approve(this.token.address, MAX_UINT256, { from: initialHolder }); - await expectRevert( - this.token.depositFor(initialHolder, MAX_UINT256, { from: initialHolder }), - 'ERC20: transfer amount exceeds balance', - ); - }); - - it('to other account', async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - const { tx } = await this.token.depositFor(anotherAccount, initialSupply, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: initialHolder, - to: this.token.address, - value: initialSupply, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: ZERO_ADDRESS, - to: anotherAccount, - value: initialSupply, - }); - }); - }); - - describe('withdraw', function () { - beforeEach(async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }); - }); - - it('missing balance', async function () { - await expectRevert( - this.token.withdrawTo(initialHolder, MAX_UINT256, { from: initialHolder }), - 'ERC20: burn amount exceeds balance', - ); - }); - - it('valid', async function () { - const value = new BN(42); - - const { tx } = await this.token.withdrawTo(initialHolder, value, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: this.token.address, - to: initialHolder, - value: value, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: initialHolder, - to: ZERO_ADDRESS, - value: value, - }); - }); - - it('entire balance', async function () { - const { tx } = await this.token.withdrawTo(initialHolder, initialSupply, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: this.token.address, - to: initialHolder, - value: initialSupply, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: initialHolder, - to: ZERO_ADDRESS, - value: initialSupply, - }); - }); - - it('to other account', async function () { - const { tx } = await this.token.withdrawTo(anotherAccount, initialSupply, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: this.token.address, - to: anotherAccount, - value: initialSupply, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: initialHolder, - to: ZERO_ADDRESS, - value: initialSupply, - }); - }); - }); - - describe('recover', function () { - it('nothing to recover', async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }); - - const { tx } = await this.token.recover(anotherAccount); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: ZERO_ADDRESS, - to: anotherAccount, - value: '0', - }); - }); - - it('something to recover', async function () { - await this.underlying.transfer(this.token.address, initialSupply, { from: initialHolder }); - - const { tx } = await this.token.recover(anotherAccount); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: ZERO_ADDRESS, - to: anotherAccount, - value: initialSupply, - }); - }); - }); - - describe('erc20 behaviour', function () { - beforeEach(async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }); - }); - - shouldBehaveLikeERC20('ERC20', initialSupply, initialHolder, recipient, anotherAccount); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC4626.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC4626.test.js deleted file mode 100644 index 4e6986c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/ERC4626.test.js +++ /dev/null @@ -1,622 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const ERC20DecimalsMock = artifacts.require('ERC20DecimalsMock'); -const ERC4626Mock = artifacts.require('ERC4626Mock'); -const ERC4626DecimalMock = artifacts.require('ERC4626DecimalMock'); - -const parseToken = (token) => (new BN(token)).mul(new BN('1000000000000')); -const parseShare = (share) => (new BN(share)).mul(new BN('1000000000000000000')); - -contract('ERC4626', function (accounts) { - const [ holder, recipient, spender, other, user1, user2 ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.token = await ERC20DecimalsMock.new(name, symbol, 12); - this.vault = await ERC4626DecimalMock.new(this.token.address, name + ' Vault', symbol + 'V', 18); - - await this.token.mint(holder, web3.utils.toWei('100')); - await this.token.approve(this.vault.address, constants.MAX_UINT256, { from: holder }); - await this.vault.approve(spender, constants.MAX_UINT256, { from: holder }); - }); - - it('metadata', async function () { - expect(await this.vault.name()).to.be.equal(name + ' Vault'); - expect(await this.vault.symbol()).to.be.equal(symbol + 'V'); - expect(await this.vault.decimals()).to.be.bignumber.equal('18'); - expect(await this.vault.asset()).to.be.equal(this.token.address); - }); - - it('inherit decimals if from asset', async function () { - for (const decimals of [ 0, 9, 12, 18, 36 ].map(web3.utils.toBN)) { - const token = await ERC20DecimalsMock.new('', '', decimals); - const vault = await ERC4626Mock.new(token.address, '', ''); - expect(await vault.decimals()).to.be.bignumber.equal(decimals); - } - }); - - describe('empty vault: no assets & no shares', function () { - it('status', async function () { - expect(await this.vault.totalAssets()).to.be.bignumber.equal('0'); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewDeposit(parseToken(1))).to.be.bignumber.equal(parseShare(1)); - - const { tx } = await this.vault.deposit(parseToken(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewMint(parseShare(1))).to.be.bignumber.equal(parseToken(1)); - - const { tx } = await this.vault.mint(parseShare(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewWithdraw('0')).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.withdraw('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewRedeem('0')).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.redeem('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - }); - - describe('partially empty vault: assets & no shares', function () { - beforeEach(async function () { - await this.token.mint(this.vault.address, parseToken(1)); // 1 token - }); - - it('status', async function () { - expect(await this.vault.totalAssets()).to.be.bignumber.equal(parseToken(1)); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewDeposit(parseToken(1))).to.be.bignumber.equal(parseShare(1)); - - const { tx } = await this.vault.deposit(parseToken(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewMint(parseShare(1))).to.be.bignumber.equal(parseToken(1)); - - const { tx } = await this.vault.mint(parseShare(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewWithdraw('0')).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.withdraw('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewRedeem('0')).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.redeem('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - }); - - describe('partially empty vault: shares & no assets', function () { - beforeEach(async function () { - await this.vault.mockMint(holder, parseShare(1)); // 1 share - }); - - it('status', async function () { - expect(await this.vault.totalAssets()).to.be.bignumber.equal('0'); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(holder)).to.be.bignumber.equal('0'); - - // Can deposit 0 (max deposit) - const { tx } = await this.vault.deposit(0, recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: 0, - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: 0, - }); - - // Cannot deposit more than 0 - await expectRevert.unspecified(this.vault.previewDeposit(parseToken(1))); - await expectRevert( - this.vault.deposit(parseToken(1), recipient, { from: holder }), - 'ERC4626: deposit more than max', - ); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewMint(parseShare(1))).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.mint(parseShare(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewWithdraw('0')).to.be.bignumber.equal('0'); - await expectRevert.unspecified(this.vault.previewWithdraw('1')); - - const { tx } = await this.vault.withdraw('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(holder)).to.be.bignumber.equal(parseShare(1)); - expect(await this.vault.previewRedeem(parseShare(1))).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.redeem(parseShare(1), recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: parseShare(1), - }); - }); - }); - - describe('full vault: assets & shares', function () { - beforeEach(async function () { - await this.token.mint(this.vault.address, parseToken(1)); // 1 tokens - await this.vault.mockMint(holder, parseShare(100)); // 100 share - }); - - it('status', async function () { - expect(await this.vault.totalAssets()).to.be.bignumber.equal(parseToken(1)); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewDeposit(parseToken(1))).to.be.bignumber.equal(parseShare(100)); - - const { tx } = await this.vault.deposit(parseToken(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(100), - }); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewMint(parseShare(1))).to.be.bignumber.equal(parseToken(1).divn(100)); - - const { tx } = await this.vault.mint(parseShare(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1).divn(100), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(holder)).to.be.bignumber.equal(parseToken(1)); - expect(await this.vault.previewWithdraw(parseToken(1))).to.be.bignumber.equal(parseShare(100)); - - const { tx } = await this.vault.withdraw(parseToken(1), recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: parseShare(100), - }); - }); - - it('withdraw with approval', async function () { - await expectRevert( - this.vault.withdraw(parseToken(1), recipient, holder, { from: other }), - 'ERC20: insufficient allowance', - ); - - await this.vault.withdraw(parseToken(1), recipient, holder, { from: spender }); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(holder)).to.be.bignumber.equal(parseShare(100)); - expect(await this.vault.previewRedeem(parseShare(100))).to.be.bignumber.equal(parseToken(1)); - - const { tx } = await this.vault.redeem(parseShare(100), recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: parseShare(100), - }); - }); - - it('redeem with approval', async function () { - await expectRevert( - this.vault.redeem(parseShare(100), recipient, holder, { from: other }), - 'ERC20: insufficient allowance', - ); - - await this.vault.redeem(parseShare(100), recipient, holder, { from: spender }); - }); - }); - - /// Scenario inspired by solmate ERC4626 tests: - /// https://github.com/transmissions11/solmate/blob/main/src/test/ERC4626.t.sol - it('multiple mint, deposit, redeem & withdrawal', async function () { - // test designed with both asset using similar decimals - this.token = await ERC20DecimalsMock.new(name, symbol, 18); - this.vault = await ERC4626Mock.new(this.token.address, name + ' Vault', symbol + 'V'); - - await this.token.mint(user1, 4000); - await this.token.mint(user2, 7001); - await this.token.approve(this.vault.address, 4000, { from: user1 }); - await this.token.approve(this.vault.address, 7001, { from: user2 }); - - // 1. Alice mints 2000 shares (costs 2000 tokens) - { - const { tx } = await this.vault.mint(2000, user1, { from: user1 }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: user1, - to: this.vault.address, - value: '2000', - }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: user1, - value: '2000', - }); - - expect(await this.vault.previewDeposit(2000)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('0'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('2000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('0'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('2000'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('2000'); - } - - // 2. Bob deposits 4000 tokens (mints 4000 shares) - { - const { tx } = await this.vault.mint(4000, user2, { from: user2 }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: user2, - to: this.vault.address, - value: '4000', - }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: user2, - value: '4000', - }); - - expect(await this.vault.previewDeposit(4000)).to.be.bignumber.equal('4000'); - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('2000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('4000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('6000'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('6000'); - } - - // 3. Vault mutates by +3000 tokens (simulated yield returned from strategy) - await this.token.mint(this.vault.address, 3000); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('3000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('6000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('6000'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('9000'); - - // 4. Alice deposits 2000 tokens (mints 1333 shares) - { - const { tx } = await this.vault.deposit(2000, user1, { from: user1 }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: user1, - to: this.vault.address, - value: '2000', - }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: user1, - value: '1333', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('3333'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('4999'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('6000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('7333'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('11000'); - } - - // 5. Bob mints 2000 shares (costs 3001 assets) - // NOTE: Bob's assets spent got rounded up - // NOTE: Alices's vault assets got rounded up - { - const { tx } = await this.vault.mint(2000, user2, { from: user2 }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: user2, - to: this.vault.address, - value: '3001', - }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: user2, - value: '2000', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('3333'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('6000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('5000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('9000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('9333'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('14001'); - } - - // 6. Vault mutates by +3000 tokens - // NOTE: Vault holds 17001 tokens, but sum of assetsOf() is 17000. - await this.token.mint(this.vault.address, 3000); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('3333'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('6000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('6071'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('10929'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('9333'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('17001'); - - // 7. Alice redeem 1333 shares (2428 assets) - { - const { tx } = await this.vault.redeem(1333, user1, user1, { from: user1 }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: user1, - to: constants.ZERO_ADDRESS, - value: '1333', - }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: user1, - value: '2428', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('6000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('3643'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('10929'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('8000'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('14573'); - } - - // 8. Bob withdraws 2929 assets (1608 shares) - { - const { tx } = await this.vault.withdraw(2929, user2, user2, { from: user2 }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: user2, - to: constants.ZERO_ADDRESS, - value: '1608', - }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: user2, - value: '2929', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4392'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('3643'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('8000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('6392'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('11644'); - } - - // 9. Alice withdraws 3643 assets (2000 shares) - // NOTE: Bob's assets have been rounded back up - { - const { tx } = await this.vault.withdraw(3643, user1, user1, { from: user1 }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: user1, - to: constants.ZERO_ADDRESS, - value: '2000', - }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: user1, - value: '3643', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('0'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4392'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('0'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('8001'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('4392'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('8001'); - } - - // 10. Bob redeem 4392 shares (8001 tokens) - { - const { tx } = await this.vault.redeem(4392, user2, user2, { from: user2 }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: user2, - to: constants.ZERO_ADDRESS, - value: '4392', - }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: user2, - value: '8001', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('0'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('0'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('0'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('0'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('0'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('0'); - } - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/draft-ERC20Permit.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/draft-ERC20Permit.test.js deleted file mode 100644 index fb60a6c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/extensions/draft-ERC20Permit.test.js +++ /dev/null @@ -1,109 +0,0 @@ -/* eslint-disable */ - -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256, ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const ERC20PermitMock = artifacts.require('ERC20PermitMock'); - -const { EIP712Domain, Permit, domainSeparator } = require('../../../helpers/eip712'); - -contract('ERC20Permit', function (accounts) { - const [ initialHolder, spender, recipient, other ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - const version = '1'; - - const initialSupply = new BN(100); - - beforeEach(async function () { - this.token = await ERC20PermitMock.new(name, symbol, initialHolder, initialSupply); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.token.getChainId(); - }); - - it('initial nonce is 0', async function () { - expect(await this.token.nonces(initialHolder)).to.be.bignumber.equal('0'); - }); - - it('domain separator', async function () { - expect( - await this.token.DOMAIN_SEPARATOR(), - ).to.equal( - await domainSeparator(name, version, this.chainId, this.token.address), - ); - }); - - describe('permit', function () { - const wallet = Wallet.generate(); - - const owner = wallet.getAddressString(); - const value = new BN(42); - const nonce = 0; - const maxDeadline = MAX_UINT256; - - const buildData = (chainId, verifyingContract, deadline = maxDeadline) => ({ - primaryType: 'Permit', - types: { EIP712Domain, Permit }, - domain: { name, version, chainId, verifyingContract }, - message: { owner, spender, value, nonce, deadline }, - }); - - it('accepts owner signature', async function () { - const data = buildData(this.chainId, this.token.address); - const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data }); - const { v, r, s } = fromRpcSig(signature); - - const receipt = await this.token.permit(owner, spender, value, maxDeadline, v, r, s); - - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(value); - }); - - it('rejects reused signature', async function () { - const data = buildData(this.chainId, this.token.address); - const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data }); - const { v, r, s } = fromRpcSig(signature); - - await this.token.permit(owner, spender, value, maxDeadline, v, r, s); - - await expectRevert( - this.token.permit(owner, spender, value, maxDeadline, v, r, s), - 'ERC20Permit: invalid signature', - ); - }); - - it('rejects other signature', async function () { - const otherWallet = Wallet.generate(); - const data = buildData(this.chainId, this.token.address); - const signature = ethSigUtil.signTypedMessage(otherWallet.getPrivateKey(), { data }); - const { v, r, s } = fromRpcSig(signature); - - await expectRevert( - this.token.permit(owner, spender, value, maxDeadline, v, r, s), - 'ERC20Permit: invalid signature', - ); - }); - - it('rejects expired permit', async function () { - const deadline = (await time.latest()) - time.duration.weeks(1); - - const data = buildData(this.chainId, this.token.address, deadline); - const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data }); - const { v, r, s } = fromRpcSig(signature); - - await expectRevert( - this.token.permit(owner, spender, value, deadline, v, r, s), - 'ERC20Permit: expired deadline', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/presets/ERC20PresetFixedSupply.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/presets/ERC20PresetFixedSupply.test.js deleted file mode 100644 index f1d0b53..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/presets/ERC20PresetFixedSupply.test.js +++ /dev/null @@ -1,42 +0,0 @@ -const { BN, constants, expectEvent } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC20PresetFixedSupply = artifacts.require('ERC20PresetFixedSupply'); - -contract('ERC20PresetFixedSupply', function (accounts) { - const [deployer, owner] = accounts; - - const name = 'PresetFixedSupply'; - const symbol = 'PFS'; - - const initialSupply = new BN('50000'); - const amount = new BN('10000'); - - before(async function () { - this.token = await ERC20PresetFixedSupply.new(name, symbol, initialSupply, owner, { from: deployer }); - }); - - it('deployer has the balance equal to initial supply', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialSupply); - }); - - it('total supply is equal to initial supply', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - }); - - describe('burning', function () { - it('holders can burn their tokens', async function () { - const remainingBalance = initialSupply.sub(amount); - const receipt = await this.token.burn(amount, { from: owner }); - expectEvent(receipt, 'Transfer', { from: owner, to: ZERO_ADDRESS, value: amount }); - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(remainingBalance); - }); - - it('decrements totalSupply', async function () { - const expectedSupply = initialSupply.sub(amount); - expect(await this.token.totalSupply()).to.be.bignumber.equal(expectedSupply); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/presets/ERC20PresetMinterPauser.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/presets/ERC20PresetMinterPauser.test.js deleted file mode 100644 index c143790..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/presets/ERC20PresetMinterPauser.test.js +++ /dev/null @@ -1,113 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC20PresetMinterPauser = artifacts.require('ERC20PresetMinterPauser'); - -contract('ERC20PresetMinterPauser', function (accounts) { - const [ deployer, other ] = accounts; - - const name = 'MinterPauserToken'; - const symbol = 'DRT'; - - const amount = new BN('5000'); - - const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const MINTER_ROLE = web3.utils.soliditySha3('MINTER_ROLE'); - const PAUSER_ROLE = web3.utils.soliditySha3('PAUSER_ROLE'); - - beforeEach(async function () { - this.token = await ERC20PresetMinterPauser.new(name, symbol, { from: deployer }); - }); - - it('deployer has the default admin role', async function () { - expect(await this.token.getRoleMemberCount(DEFAULT_ADMIN_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(DEFAULT_ADMIN_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the minter role', async function () { - expect(await this.token.getRoleMemberCount(MINTER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(MINTER_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the pauser role', async function () { - expect(await this.token.getRoleMemberCount(PAUSER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(PAUSER_ROLE, 0)).to.equal(deployer); - }); - - it('minter and pauser role admin is the default admin', async function () { - expect(await this.token.getRoleAdmin(MINTER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - expect(await this.token.getRoleAdmin(PAUSER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - describe('minting', function () { - it('deployer can mint tokens', async function () { - const receipt = await this.token.mint(other, amount, { from: deployer }); - expectEvent(receipt, 'Transfer', { from: ZERO_ADDRESS, to: other, value: amount }); - - expect(await this.token.balanceOf(other)).to.be.bignumber.equal(amount); - }); - - it('other accounts cannot mint tokens', async function () { - await expectRevert( - this.token.mint(other, amount, { from: other }), - 'ERC20PresetMinterPauser: must have minter role to mint', - ); - }); - }); - - describe('pausing', function () { - it('deployer can pause', async function () { - const receipt = await this.token.pause({ from: deployer }); - expectEvent(receipt, 'Paused', { account: deployer }); - - expect(await this.token.paused()).to.equal(true); - }); - - it('deployer can unpause', async function () { - await this.token.pause({ from: deployer }); - - const receipt = await this.token.unpause({ from: deployer }); - expectEvent(receipt, 'Unpaused', { account: deployer }); - - expect(await this.token.paused()).to.equal(false); - }); - - it('cannot mint while paused', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.mint(other, amount, { from: deployer }), - 'ERC20Pausable: token transfer while paused', - ); - }); - - it('other accounts cannot pause', async function () { - await expectRevert( - this.token.pause({ from: other }), - 'ERC20PresetMinterPauser: must have pauser role to pause', - ); - }); - - it('other accounts cannot unpause', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.unpause({ from: other }), - 'ERC20PresetMinterPauser: must have pauser role to unpause', - ); - }); - }); - - describe('burning', function () { - it('holders can burn their tokens', async function () { - await this.token.mint(other, amount, { from: deployer }); - - const receipt = await this.token.burn(amount.subn(1), { from: other }); - expectEvent(receipt, 'Transfer', { from: other, to: ZERO_ADDRESS, value: amount.subn(1) }); - - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('1'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/utils/SafeERC20.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/utils/SafeERC20.test.js deleted file mode 100644 index 4c54c58..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/utils/SafeERC20.test.js +++ /dev/null @@ -1,255 +0,0 @@ -const { constants, expectRevert } = require('@openzeppelin/test-helpers'); - -const ERC20ReturnFalseMock = artifacts.require('ERC20ReturnFalseMock'); -const ERC20ReturnTrueMock = artifacts.require('ERC20ReturnTrueMock'); -const ERC20NoReturnMock = artifacts.require('ERC20NoReturnMock'); -const ERC20PermitNoRevertMock = artifacts.require('ERC20PermitNoRevertMock'); -const SafeERC20Wrapper = artifacts.require('SafeERC20Wrapper'); - -const { EIP712Domain, Permit } = require('../../../helpers/eip712'); - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -contract('SafeERC20', function (accounts) { - const [ hasNoCode ] = accounts; - - describe('with address that has no contract code', function () { - beforeEach(async function () { - this.wrapper = await SafeERC20Wrapper.new(hasNoCode); - }); - - shouldRevertOnAllCalls('Address: call to non-contract'); - }); - - describe('with token that returns false on all calls', function () { - beforeEach(async function () { - this.wrapper = await SafeERC20Wrapper.new((await ERC20ReturnFalseMock.new()).address); - }); - - shouldRevertOnAllCalls('SafeERC20: ERC20 operation did not succeed'); - }); - - describe('with token that returns true on all calls', function () { - beforeEach(async function () { - this.wrapper = await SafeERC20Wrapper.new((await ERC20ReturnTrueMock.new()).address); - }); - - shouldOnlyRevertOnErrors(); - }); - - describe('with token that returns no boolean values', function () { - beforeEach(async function () { - this.wrapper = await SafeERC20Wrapper.new((await ERC20NoReturnMock.new()).address); - }); - - shouldOnlyRevertOnErrors(); - }); - - describe('with token that doesn\'t revert on invalid permit', function () { - const wallet = Wallet.generate(); - const owner = wallet.getAddressString(); - const spender = hasNoCode; - - beforeEach(async function () { - this.token = await ERC20PermitNoRevertMock.new(); - this.wrapper = await SafeERC20Wrapper.new(this.token.address); - - const chainId = await this.token.getChainId(); - - this.data = { - primaryType: 'Permit', - types: { EIP712Domain, Permit }, - domain: { name: 'ERC20PermitNoRevertMock', version: '1', chainId, verifyingContract: this.token.address }, - message: { owner, spender, value: '42', nonce: '0', deadline: constants.MAX_UINT256 }, - }; - this.signature = fromRpcSig(ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data: this.data })); - }); - - it('accepts owner signature', async function () { - expect(await this.token.nonces(owner)).to.be.bignumber.equal('0'); - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal('0'); - - await this.wrapper.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - this.signature.v, - this.signature.r, - this.signature.s, - ); - - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(this.data.message.value); - }); - - it('revert on reused signature', async function () { - expect(await this.token.nonces(owner)).to.be.bignumber.equal('0'); - // use valid signature and consume nounce - await this.wrapper.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - this.signature.v, - this.signature.r, - this.signature.s, - ); - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - // invalid call does not revert for this token implementation - await this.token.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - this.signature.v, - this.signature.r, - this.signature.s, - ); - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - // invalid call revert when called through the SafeERC20 library - await expectRevert( - this.wrapper.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - this.signature.v, - this.signature.r, - this.signature.s, - ), - 'SafeERC20: permit did not succeed', - ); - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - }); - - it('revert on invalid signature', async function () { - // signature that is not valid for owner - const invalidSignature = { - v: 27, - r: '0x71753dc5ecb5b4bfc0e3bc530d79ce5988760ed3f3a234c86a5546491f540775', - s: '0x0049cedee5aed990aabed5ad6a9f6e3c565b63379894b5fa8b512eb2b79e485d', - }; - - // invalid call does not revert for this token implementation - await this.token.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - invalidSignature.v, - invalidSignature.r, - invalidSignature.s, - ); - - // invalid call revert when called through the SafeERC20 library - await expectRevert( - this.wrapper.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - invalidSignature.v, - invalidSignature.r, - invalidSignature.s, - ), - 'SafeERC20: permit did not succeed', - ); - }); - }); -}); - -function shouldRevertOnAllCalls (reason) { - it('reverts on transfer', async function () { - await expectRevert(this.wrapper.transfer(), reason); - }); - - it('reverts on transferFrom', async function () { - await expectRevert(this.wrapper.transferFrom(), reason); - }); - - it('reverts on approve', async function () { - await expectRevert(this.wrapper.approve(0), reason); - }); - - it('reverts on increaseAllowance', async function () { - // [TODO] make sure it's reverting for the right reason - await expectRevert.unspecified(this.wrapper.increaseAllowance(0)); - }); - - it('reverts on decreaseAllowance', async function () { - // [TODO] make sure it's reverting for the right reason - await expectRevert.unspecified(this.wrapper.decreaseAllowance(0)); - }); -} - -function shouldOnlyRevertOnErrors () { - it('doesn\'t revert on transfer', async function () { - await this.wrapper.transfer(); - }); - - it('doesn\'t revert on transferFrom', async function () { - await this.wrapper.transferFrom(); - }); - - describe('approvals', function () { - context('with zero allowance', function () { - beforeEach(async function () { - await this.wrapper.setAllowance(0); - }); - - it('doesn\'t revert when approving a non-zero allowance', async function () { - await this.wrapper.approve(100); - }); - - it('doesn\'t revert when approving a zero allowance', async function () { - await this.wrapper.approve(0); - }); - - it('doesn\'t revert when increasing the allowance', async function () { - await this.wrapper.increaseAllowance(10); - }); - - it('reverts when decreasing the allowance', async function () { - await expectRevert( - this.wrapper.decreaseAllowance(10), - 'SafeERC20: decreased allowance below zero', - ); - }); - }); - - context('with non-zero allowance', function () { - beforeEach(async function () { - await this.wrapper.setAllowance(100); - }); - - it('reverts when approving a non-zero allowance', async function () { - await expectRevert( - this.wrapper.approve(20), - 'SafeERC20: approve from non-zero to non-zero allowance', - ); - }); - - it('doesn\'t revert when approving a zero allowance', async function () { - await this.wrapper.approve(0); - }); - - it('doesn\'t revert when increasing the allowance', async function () { - await this.wrapper.increaseAllowance(10); - }); - - it('doesn\'t revert when decreasing the allowance to a positive value', async function () { - await this.wrapper.decreaseAllowance(50); - }); - - it('reverts when decreasing the allowance to a negative value', async function () { - await expectRevert( - this.wrapper.decreaseAllowance(200), - 'SafeERC20: decreased allowance below zero', - ); - }); - }); - }); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/utils/TokenTimelock.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/utils/TokenTimelock.test.js deleted file mode 100644 index e546b34..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC20/utils/TokenTimelock.test.js +++ /dev/null @@ -1,71 +0,0 @@ -const { BN, expectRevert, time } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC20Mock = artifacts.require('ERC20Mock'); -const TokenTimelock = artifacts.require('TokenTimelock'); - -contract('TokenTimelock', function (accounts) { - const [ beneficiary ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - const amount = new BN(100); - - context('with token', function () { - beforeEach(async function () { - this.token = await ERC20Mock.new(name, symbol, beneficiary, 0); // We're not using the preminted tokens - }); - - it('rejects a release time in the past', async function () { - const pastReleaseTime = (await time.latest()).sub(time.duration.years(1)); - await expectRevert( - TokenTimelock.new(this.token.address, beneficiary, pastReleaseTime), - 'TokenTimelock: release time is before current time', - ); - }); - - context('once deployed', function () { - beforeEach(async function () { - this.releaseTime = (await time.latest()).add(time.duration.years(1)); - this.timelock = await TokenTimelock.new(this.token.address, beneficiary, this.releaseTime); - await this.token.mint(this.timelock.address, amount); - }); - - it('can get state', async function () { - expect(await this.timelock.token()).to.equal(this.token.address); - expect(await this.timelock.beneficiary()).to.equal(beneficiary); - expect(await this.timelock.releaseTime()).to.be.bignumber.equal(this.releaseTime); - }); - - it('cannot be released before time limit', async function () { - await expectRevert(this.timelock.release(), 'TokenTimelock: current time is before release time'); - }); - - it('cannot be released just before time limit', async function () { - await time.increaseTo(this.releaseTime.sub(time.duration.seconds(3))); - await expectRevert(this.timelock.release(), 'TokenTimelock: current time is before release time'); - }); - - it('can be released just after limit', async function () { - await time.increaseTo(this.releaseTime.add(time.duration.seconds(1))); - await this.timelock.release(); - expect(await this.token.balanceOf(beneficiary)).to.be.bignumber.equal(amount); - }); - - it('can be released after time limit', async function () { - await time.increaseTo(this.releaseTime.add(time.duration.years(1))); - await this.timelock.release(); - expect(await this.token.balanceOf(beneficiary)).to.be.bignumber.equal(amount); - }); - - it('cannot be released twice', async function () { - await time.increaseTo(this.releaseTime.add(time.duration.years(1))); - await this.timelock.release(); - await expectRevert(this.timelock.release(), 'TokenTimelock: no tokens to release'); - expect(await this.token.balanceOf(beneficiary)).to.be.bignumber.equal(amount); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721.behavior.js deleted file mode 100644 index 0213984..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721.behavior.js +++ /dev/null @@ -1,937 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS } = constants; - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -const ERC721ReceiverMock = artifacts.require('ERC721ReceiverMock'); - -const Error = [ 'None', 'RevertWithMessage', 'RevertWithoutMessage', 'Panic' ] - .reduce((acc, entry, idx) => Object.assign({ [entry]: idx }, acc), {}); - -const firstTokenId = new BN('5042'); -const secondTokenId = new BN('79217'); -const nonExistentTokenId = new BN('13'); -const fourthTokenId = new BN(4); -const baseURI = 'https://api.example.com/v1/'; - -const RECEIVER_MAGIC_VALUE = '0x150b7a02'; - -function shouldBehaveLikeERC721 (errorPrefix, owner, newOwner, approved, anotherApproved, operator, other) { - shouldSupportInterfaces([ - 'ERC165', - 'ERC721', - ]); - - context('with minted tokens', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - this.toWhom = other; // default to other for toWhom in context-dependent tests - }); - - describe('balanceOf', function () { - context('when the given address owns some tokens', function () { - it('returns the amount of tokens owned by the given address', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('2'); - }); - }); - - context('when the given address does not own any tokens', function () { - it('returns 0', async function () { - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('0'); - }); - }); - - context('when querying the zero address', function () { - it('throws', async function () { - await expectRevert( - this.token.balanceOf(ZERO_ADDRESS), 'ERC721: address zero is not a valid owner', - ); - }); - }); - }); - - describe('ownerOf', function () { - context('when the given token ID was tracked by this token', function () { - const tokenId = firstTokenId; - - it('returns the owner of the given token ID', async function () { - expect(await this.token.ownerOf(tokenId)).to.be.equal(owner); - }); - }); - - context('when the given token ID was not tracked by this token', function () { - const tokenId = nonExistentTokenId; - - it('reverts', async function () { - await expectRevert( - this.token.ownerOf(tokenId), 'ERC721: invalid token ID', - ); - }); - }); - }); - - describe('transfers', function () { - const tokenId = firstTokenId; - const data = '0x42'; - - let receipt = null; - - beforeEach(async function () { - await this.token.approve(approved, tokenId, { from: owner }); - await this.token.setApprovalForAll(operator, true, { from: owner }); - }); - - const transferWasSuccessful = function ({ owner, tokenId, approved }) { - it('transfers the ownership of the given token ID to the given address', async function () { - expect(await this.token.ownerOf(tokenId)).to.be.equal(this.toWhom); - }); - - it('emits a Transfer event', async function () { - expectEvent(receipt, 'Transfer', { from: owner, to: this.toWhom, tokenId: tokenId }); - }); - - it('clears the approval for the token ID', async function () { - expect(await this.token.getApproved(tokenId)).to.be.equal(ZERO_ADDRESS); - }); - - it('adjusts owners balances', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1'); - }); - - it('adjusts owners tokens by index', async function () { - if (!this.token.tokenOfOwnerByIndex) return; - - expect(await this.token.tokenOfOwnerByIndex(this.toWhom, 0)).to.be.bignumber.equal(tokenId); - - expect(await this.token.tokenOfOwnerByIndex(owner, 0)).to.be.bignumber.not.equal(tokenId); - }); - }; - - const shouldTransferTokensByUsers = function (transferFunction) { - context('when called by the owner', function () { - beforeEach(async function () { - (receipt = await transferFunction.call(this, owner, this.toWhom, tokenId, { from: owner })); - }); - transferWasSuccessful({ owner, tokenId, approved }); - }); - - context('when called by the approved individual', function () { - beforeEach(async function () { - (receipt = await transferFunction.call(this, owner, this.toWhom, tokenId, { from: approved })); - }); - transferWasSuccessful({ owner, tokenId, approved }); - }); - - context('when called by the operator', function () { - beforeEach(async function () { - (receipt = await transferFunction.call(this, owner, this.toWhom, tokenId, { from: operator })); - }); - transferWasSuccessful({ owner, tokenId, approved }); - }); - - context('when called by the owner without an approved user', function () { - beforeEach(async function () { - await this.token.approve(ZERO_ADDRESS, tokenId, { from: owner }); - (receipt = await transferFunction.call(this, owner, this.toWhom, tokenId, { from: operator })); - }); - transferWasSuccessful({ owner, tokenId, approved: null }); - }); - - context('when sent to the owner', function () { - beforeEach(async function () { - (receipt = await transferFunction.call(this, owner, owner, tokenId, { from: owner })); - }); - - it('keeps ownership of the token', async function () { - expect(await this.token.ownerOf(tokenId)).to.be.equal(owner); - }); - - it('clears the approval for the token ID', async function () { - expect(await this.token.getApproved(tokenId)).to.be.equal(ZERO_ADDRESS); - }); - - it('emits only a transfer event', async function () { - expectEvent(receipt, 'Transfer', { - from: owner, - to: owner, - tokenId: tokenId, - }); - }); - - it('keeps the owner balance', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('2'); - }); - - it('keeps same tokens by index', async function () { - if (!this.token.tokenOfOwnerByIndex) return; - const tokensListed = await Promise.all( - [0, 1].map(i => this.token.tokenOfOwnerByIndex(owner, i)), - ); - expect(tokensListed.map(t => t.toNumber())).to.have.members( - [firstTokenId.toNumber(), secondTokenId.toNumber()], - ); - }); - }); - - context('when the address of the previous owner is incorrect', function () { - it('reverts', async function () { - await expectRevert( - transferFunction.call(this, other, other, tokenId, { from: owner }), - 'ERC721: transfer from incorrect owner', - ); - }); - }); - - context('when the sender is not authorized for the token id', function () { - it('reverts', async function () { - await expectRevert( - transferFunction.call(this, owner, other, tokenId, { from: other }), - 'ERC721: caller is not token owner or approved', - ); - }); - }); - - context('when the given token ID does not exist', function () { - it('reverts', async function () { - await expectRevert( - transferFunction.call(this, owner, other, nonExistentTokenId, { from: owner }), - 'ERC721: invalid token ID', - ); - }); - }); - - context('when the address to transfer the token to is the zero address', function () { - it('reverts', async function () { - await expectRevert( - transferFunction.call(this, owner, ZERO_ADDRESS, tokenId, { from: owner }), - 'ERC721: transfer to the zero address', - ); - }); - }); - }; - - describe('via transferFrom', function () { - shouldTransferTokensByUsers(function (from, to, tokenId, opts) { - return this.token.transferFrom(from, to, tokenId, opts); - }); - }); - - describe('via safeTransferFrom', function () { - const safeTransferFromWithData = function (from, to, tokenId, opts) { - return this.token.methods['safeTransferFrom(address,address,uint256,bytes)'](from, to, tokenId, data, opts); - }; - - const safeTransferFromWithoutData = function (from, to, tokenId, opts) { - return this.token.methods['safeTransferFrom(address,address,uint256)'](from, to, tokenId, opts); - }; - - const shouldTransferSafely = function (transferFun, data) { - describe('to a user account', function () { - shouldTransferTokensByUsers(transferFun); - }); - - describe('to a valid receiver contract', function () { - beforeEach(async function () { - this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None); - this.toWhom = this.receiver.address; - }); - - shouldTransferTokensByUsers(transferFun); - - it('calls onERC721Received', async function () { - const receipt = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: owner }); - - await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { - operator: owner, - from: owner, - tokenId: tokenId, - data: data, - }); - }); - - it('calls onERC721Received from approved', async function () { - const receipt = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: approved }); - - await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { - operator: approved, - from: owner, - tokenId: tokenId, - data: data, - }); - }); - - describe('with an invalid token id', function () { - it('reverts', async function () { - await expectRevert( - transferFun.call( - this, - owner, - this.receiver.address, - nonExistentTokenId, - { from: owner }, - ), - 'ERC721: invalid token ID', - ); - }); - }); - }); - }; - - describe('with data', function () { - shouldTransferSafely(safeTransferFromWithData, data); - }); - - describe('without data', function () { - shouldTransferSafely(safeTransferFromWithoutData, null); - }); - - describe('to a receiver contract returning unexpected value', function () { - it('reverts', async function () { - const invalidReceiver = await ERC721ReceiverMock.new('0x42', Error.None); - await expectRevert( - this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - - describe('to a receiver contract that reverts with message', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithMessage); - await expectRevert( - this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }), - 'ERC721ReceiverMock: reverting', - ); - }); - }); - - describe('to a receiver contract that reverts without message', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithoutMessage); - await expectRevert( - this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - - describe('to a receiver contract that panics', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.Panic); - await expectRevert.unspecified( - this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }), - ); - }); - }); - - describe('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const nonReceiver = this.token; - await expectRevert( - this.token.safeTransferFrom(owner, nonReceiver.address, tokenId, { from: owner }), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - }); - }); - - describe('safe mint', function () { - const tokenId = fourthTokenId; - const data = '0x42'; - - describe('via safeMint', function () { // regular minting is tested in ERC721Mintable.test.js and others - it('calls onERC721Received — with data', async function () { - this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None); - const receipt = await this.token.safeMint(this.receiver.address, tokenId, data); - - await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { - from: ZERO_ADDRESS, - tokenId: tokenId, - data: data, - }); - }); - - it('calls onERC721Received — without data', async function () { - this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None); - const receipt = await this.token.safeMint(this.receiver.address, tokenId); - - await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { - from: ZERO_ADDRESS, - tokenId: tokenId, - }); - }); - - context('to a receiver contract returning unexpected value', function () { - it('reverts', async function () { - const invalidReceiver = await ERC721ReceiverMock.new('0x42', Error.None); - await expectRevert( - this.token.safeMint(invalidReceiver.address, tokenId), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - - context('to a receiver contract that reverts with message', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithMessage); - await expectRevert( - this.token.safeMint(revertingReceiver.address, tokenId), - 'ERC721ReceiverMock: reverting', - ); - }); - }); - - context('to a receiver contract that reverts without message', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithoutMessage); - await expectRevert( - this.token.safeMint(revertingReceiver.address, tokenId), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - - context('to a receiver contract that panics', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.Panic); - await expectRevert.unspecified( - this.token.safeMint(revertingReceiver.address, tokenId), - ); - }); - }); - - context('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const nonReceiver = this.token; - await expectRevert( - this.token.safeMint(nonReceiver.address, tokenId), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - }); - }); - - describe('approve', function () { - const tokenId = firstTokenId; - - let receipt = null; - - const itClearsApproval = function () { - it('clears approval for the token', async function () { - expect(await this.token.getApproved(tokenId)).to.be.equal(ZERO_ADDRESS); - }); - }; - - const itApproves = function (address) { - it('sets the approval for the target address', async function () { - expect(await this.token.getApproved(tokenId)).to.be.equal(address); - }); - }; - - const itEmitsApprovalEvent = function (address) { - it('emits an approval event', async function () { - expectEvent(receipt, 'Approval', { - owner: owner, - approved: address, - tokenId: tokenId, - }); - }); - }; - - context('when clearing approval', function () { - context('when there was no prior approval', function () { - beforeEach(async function () { - (receipt = await this.token.approve(ZERO_ADDRESS, tokenId, { from: owner })); - }); - - itClearsApproval(); - itEmitsApprovalEvent(ZERO_ADDRESS); - }); - - context('when there was a prior approval', function () { - beforeEach(async function () { - await this.token.approve(approved, tokenId, { from: owner }); - (receipt = await this.token.approve(ZERO_ADDRESS, tokenId, { from: owner })); - }); - - itClearsApproval(); - itEmitsApprovalEvent(ZERO_ADDRESS); - }); - }); - - context('when approving a non-zero address', function () { - context('when there was no prior approval', function () { - beforeEach(async function () { - (receipt = await this.token.approve(approved, tokenId, { from: owner })); - }); - - itApproves(approved); - itEmitsApprovalEvent(approved); - }); - - context('when there was a prior approval to the same address', function () { - beforeEach(async function () { - await this.token.approve(approved, tokenId, { from: owner }); - (receipt = await this.token.approve(approved, tokenId, { from: owner })); - }); - - itApproves(approved); - itEmitsApprovalEvent(approved); - }); - - context('when there was a prior approval to a different address', function () { - beforeEach(async function () { - await this.token.approve(anotherApproved, tokenId, { from: owner }); - (receipt = await this.token.approve(anotherApproved, tokenId, { from: owner })); - }); - - itApproves(anotherApproved); - itEmitsApprovalEvent(anotherApproved); - }); - }); - - context('when the address that receives the approval is the owner', function () { - it('reverts', async function () { - await expectRevert( - this.token.approve(owner, tokenId, { from: owner }), 'ERC721: approval to current owner', - ); - }); - }); - - context('when the sender does not own the given token ID', function () { - it('reverts', async function () { - await expectRevert(this.token.approve(approved, tokenId, { from: other }), - 'ERC721: approve caller is not token owner or approved'); - }); - }); - - context('when the sender is approved for the given token ID', function () { - it('reverts', async function () { - await this.token.approve(approved, tokenId, { from: owner }); - await expectRevert(this.token.approve(anotherApproved, tokenId, { from: approved }), - 'ERC721: approve caller is not token owner or approved for all'); - }); - }); - - context('when the sender is an operator', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - (receipt = await this.token.approve(approved, tokenId, { from: operator })); - }); - - itApproves(approved); - itEmitsApprovalEvent(approved); - }); - - context('when the given token ID does not exist', function () { - it('reverts', async function () { - await expectRevert(this.token.approve(approved, nonExistentTokenId, { from: operator }), - 'ERC721: invalid token ID'); - }); - }); - }); - - describe('setApprovalForAll', function () { - context('when the operator willing to approve is not the owner', function () { - context('when there is no operator approval set by the sender', function () { - it('approves the operator', async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(true); - }); - - it('emits an approval event', async function () { - const receipt = await this.token.setApprovalForAll(operator, true, { from: owner }); - - expectEvent(receipt, 'ApprovalForAll', { - owner: owner, - operator: operator, - approved: true, - }); - }); - }); - - context('when the operator was set as not approved', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(operator, false, { from: owner }); - }); - - it('approves the operator', async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(true); - }); - - it('emits an approval event', async function () { - const receipt = await this.token.setApprovalForAll(operator, true, { from: owner }); - - expectEvent(receipt, 'ApprovalForAll', { - owner: owner, - operator: operator, - approved: true, - }); - }); - - it('can unset the operator approval', async function () { - await this.token.setApprovalForAll(operator, false, { from: owner }); - - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(false); - }); - }); - - context('when the operator was already approved', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - }); - - it('keeps the approval to the given address', async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(true); - }); - - it('emits an approval event', async function () { - const receipt = await this.token.setApprovalForAll(operator, true, { from: owner }); - - expectEvent(receipt, 'ApprovalForAll', { - owner: owner, - operator: operator, - approved: true, - }); - }); - }); - }); - - context('when the operator is the owner', function () { - it('reverts', async function () { - await expectRevert(this.token.setApprovalForAll(owner, true, { from: owner }), - 'ERC721: approve to caller'); - }); - }); - }); - - describe('getApproved', async function () { - context('when token is not minted', async function () { - it('reverts', async function () { - await expectRevert( - this.token.getApproved(nonExistentTokenId), - 'ERC721: invalid token ID', - ); - }); - }); - - context('when token has been minted ', async function () { - it('should return the zero address', async function () { - expect(await this.token.getApproved(firstTokenId)).to.be.equal( - ZERO_ADDRESS, - ); - }); - - context('when account has been approved', async function () { - beforeEach(async function () { - await this.token.approve(approved, firstTokenId, { from: owner }); - }); - - it('returns approved account', async function () { - expect(await this.token.getApproved(firstTokenId)).to.be.equal(approved); - }); - }); - }); - }); - }); - - describe('_mint(address, uint256)', function () { - it('reverts with a null destination address', async function () { - await expectRevert( - this.token.mint(ZERO_ADDRESS, firstTokenId), 'ERC721: mint to the zero address', - ); - }); - - context('with minted token', async function () { - beforeEach(async function () { - (this.receipt = await this.token.mint(owner, firstTokenId)); - }); - - it('emits a Transfer event', function () { - expectEvent(this.receipt, 'Transfer', { from: ZERO_ADDRESS, to: owner, tokenId: firstTokenId }); - }); - - it('creates the token', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1'); - expect(await this.token.ownerOf(firstTokenId)).to.equal(owner); - }); - - it('reverts when adding a token id that already exists', async function () { - await expectRevert(this.token.mint(owner, firstTokenId), 'ERC721: token already minted'); - }); - }); - }); - - describe('_burn', function () { - it('reverts when burning a non-existent token id', async function () { - await expectRevert( - this.token.burn(nonExistentTokenId), 'ERC721: invalid token ID', - ); - }); - - context('with minted tokens', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - }); - - context('with burnt token', function () { - beforeEach(async function () { - (this.receipt = await this.token.burn(firstTokenId)); - }); - - it('emits a Transfer event', function () { - expectEvent(this.receipt, 'Transfer', { from: owner, to: ZERO_ADDRESS, tokenId: firstTokenId }); - }); - - it('deletes the token', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1'); - await expectRevert( - this.token.ownerOf(firstTokenId), 'ERC721: invalid token ID', - ); - }); - - it('reverts when burning a token id that has been deleted', async function () { - await expectRevert( - this.token.burn(firstTokenId), 'ERC721: invalid token ID', - ); - }); - }); - }); - }); -} - -function shouldBehaveLikeERC721Enumerable (errorPrefix, owner, newOwner, approved, anotherApproved, operator, other) { - shouldSupportInterfaces([ - 'ERC721Enumerable', - ]); - - context('with minted tokens', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - this.toWhom = other; // default to other for toWhom in context-dependent tests - }); - - describe('totalSupply', function () { - it('returns total token supply', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal('2'); - }); - }); - - describe('tokenOfOwnerByIndex', function () { - describe('when the given index is lower than the amount of tokens owned by the given address', function () { - it('returns the token ID placed at the given index', async function () { - expect(await this.token.tokenOfOwnerByIndex(owner, 0)).to.be.bignumber.equal(firstTokenId); - }); - }); - - describe('when the index is greater than or equal to the total tokens owned by the given address', function () { - it('reverts', async function () { - await expectRevert( - this.token.tokenOfOwnerByIndex(owner, 2), 'ERC721Enumerable: owner index out of bounds', - ); - }); - }); - - describe('when the given address does not own any token', function () { - it('reverts', async function () { - await expectRevert( - this.token.tokenOfOwnerByIndex(other, 0), 'ERC721Enumerable: owner index out of bounds', - ); - }); - }); - - describe('after transferring all tokens to another user', function () { - beforeEach(async function () { - await this.token.transferFrom(owner, other, firstTokenId, { from: owner }); - await this.token.transferFrom(owner, other, secondTokenId, { from: owner }); - }); - - it('returns correct token IDs for target', async function () { - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('2'); - const tokensListed = await Promise.all( - [0, 1].map(i => this.token.tokenOfOwnerByIndex(other, i)), - ); - expect(tokensListed.map(t => t.toNumber())).to.have.members([firstTokenId.toNumber(), - secondTokenId.toNumber()]); - }); - - it('returns empty collection for original owner', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('0'); - await expectRevert( - this.token.tokenOfOwnerByIndex(owner, 0), 'ERC721Enumerable: owner index out of bounds', - ); - }); - }); - }); - - describe('tokenByIndex', function () { - it('returns all tokens', async function () { - const tokensListed = await Promise.all( - [0, 1].map(i => this.token.tokenByIndex(i)), - ); - expect(tokensListed.map(t => t.toNumber())).to.have.members([firstTokenId.toNumber(), - secondTokenId.toNumber()]); - }); - - it('reverts if index is greater than supply', async function () { - await expectRevert( - this.token.tokenByIndex(2), 'ERC721Enumerable: global index out of bounds', - ); - }); - - [firstTokenId, secondTokenId].forEach(function (tokenId) { - it(`returns all tokens after burning token ${tokenId} and minting new tokens`, async function () { - const newTokenId = new BN(300); - const anotherNewTokenId = new BN(400); - - await this.token.burn(tokenId); - await this.token.mint(newOwner, newTokenId); - await this.token.mint(newOwner, anotherNewTokenId); - - expect(await this.token.totalSupply()).to.be.bignumber.equal('3'); - - const tokensListed = await Promise.all( - [0, 1, 2].map(i => this.token.tokenByIndex(i)), - ); - const expectedTokens = [firstTokenId, secondTokenId, newTokenId, anotherNewTokenId].filter( - x => (x !== tokenId), - ); - expect(tokensListed.map(t => t.toNumber())).to.have.members(expectedTokens.map(t => t.toNumber())); - }); - }); - }); - }); - - describe('_mint(address, uint256)', function () { - it('reverts with a null destination address', async function () { - await expectRevert( - this.token.mint(ZERO_ADDRESS, firstTokenId), 'ERC721: mint to the zero address', - ); - }); - - context('with minted token', async function () { - beforeEach(async function () { - (this.receipt = await this.token.mint(owner, firstTokenId)); - }); - - it('adjusts owner tokens by index', async function () { - expect(await this.token.tokenOfOwnerByIndex(owner, 0)).to.be.bignumber.equal(firstTokenId); - }); - - it('adjusts all tokens list', async function () { - expect(await this.token.tokenByIndex(0)).to.be.bignumber.equal(firstTokenId); - }); - }); - }); - - describe('_burn', function () { - it('reverts when burning a non-existent token id', async function () { - await expectRevert( - this.token.burn(firstTokenId), 'ERC721: invalid token ID', - ); - }); - - context('with minted tokens', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - }); - - context('with burnt token', function () { - beforeEach(async function () { - (this.receipt = await this.token.burn(firstTokenId)); - }); - - it('removes that token from the token list of the owner', async function () { - expect(await this.token.tokenOfOwnerByIndex(owner, 0)).to.be.bignumber.equal(secondTokenId); - }); - - it('adjusts all tokens list', async function () { - expect(await this.token.tokenByIndex(0)).to.be.bignumber.equal(secondTokenId); - }); - - it('burns all tokens', async function () { - await this.token.burn(secondTokenId, { from: owner }); - expect(await this.token.totalSupply()).to.be.bignumber.equal('0'); - await expectRevert( - this.token.tokenByIndex(0), 'ERC721Enumerable: global index out of bounds', - ); - }); - }); - }); - }); -} - -function shouldBehaveLikeERC721Metadata (errorPrefix, name, symbol, owner) { - shouldSupportInterfaces([ - 'ERC721Metadata', - ]); - - describe('metadata', function () { - it('has a name', async function () { - expect(await this.token.name()).to.be.equal(name); - }); - - it('has a symbol', async function () { - expect(await this.token.symbol()).to.be.equal(symbol); - }); - - describe('token URI', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - }); - - it('return empty string by default', async function () { - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(''); - }); - - it('reverts when queried for non existent token id', async function () { - await expectRevert( - this.token.tokenURI(nonExistentTokenId), 'ERC721: invalid token ID', - ); - }); - - describe('base URI', function () { - beforeEach(function () { - if (this.token.setBaseURI === undefined) { - this.skip(); - } - }); - - it('base URI can be set', async function () { - await this.token.setBaseURI(baseURI); - expect(await this.token.baseURI()).to.equal(baseURI); - }); - - it('base URI is added as a prefix to the token URI', async function () { - await this.token.setBaseURI(baseURI); - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(baseURI + firstTokenId.toString()); - }); - - it('token URI can be changed by changing the base URI', async function () { - await this.token.setBaseURI(baseURI); - const newBaseURI = 'https://api.example.com/v2/'; - await this.token.setBaseURI(newBaseURI); - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(newBaseURI + firstTokenId.toString()); - }); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Enumerable, - shouldBehaveLikeERC721Metadata, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721.test.js deleted file mode 100644 index 1abbd66..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Metadata, -} = require('./ERC721.behavior'); - -const ERC721Mock = artifacts.require('ERC721Mock'); - -contract('ERC721', function (accounts) { - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - beforeEach(async function () { - this.token = await ERC721Mock.new(name, symbol); - }); - - shouldBehaveLikeERC721('ERC721', ...accounts); - shouldBehaveLikeERC721Metadata('ERC721', name, symbol, ...accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721Enumerable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721Enumerable.test.js deleted file mode 100644 index 2c13621..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/ERC721Enumerable.test.js +++ /dev/null @@ -1,20 +0,0 @@ -const { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Metadata, - shouldBehaveLikeERC721Enumerable, -} = require('./ERC721.behavior'); - -const ERC721Mock = artifacts.require('ERC721EnumerableMock'); - -contract('ERC721Enumerable', function (accounts) { - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - beforeEach(async function () { - this.token = await ERC721Mock.new(name, symbol); - }); - - shouldBehaveLikeERC721('ERC721', ...accounts); - shouldBehaveLikeERC721Metadata('ERC721', name, symbol, ...accounts); - shouldBehaveLikeERC721Enumerable('ERC721', ...accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Burnable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Burnable.test.js deleted file mode 100644 index e8fc334..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Burnable.test.js +++ /dev/null @@ -1,78 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC721BurnableMock = artifacts.require('ERC721BurnableMock'); - -contract('ERC721Burnable', function (accounts) { - const [owner, approved] = accounts; - - const firstTokenId = new BN(1); - const secondTokenId = new BN(2); - const unknownTokenId = new BN(3); - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - beforeEach(async function () { - this.token = await ERC721BurnableMock.new(name, symbol); - }); - - describe('like a burnable ERC721', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - }); - - describe('burn', function () { - const tokenId = firstTokenId; - let receipt = null; - - describe('when successful', function () { - beforeEach(async function () { - receipt = await this.token.burn(tokenId, { from: owner }); - }); - - it('burns the given token ID and adjusts the balance of the owner', async function () { - await expectRevert( - this.token.ownerOf(tokenId), - 'ERC721: invalid token ID', - ); - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1'); - }); - - it('emits a burn event', async function () { - expectEvent(receipt, 'Transfer', { - from: owner, - to: ZERO_ADDRESS, - tokenId: tokenId, - }); - }); - }); - - describe('when there is a previous approval burned', function () { - beforeEach(async function () { - await this.token.approve(approved, tokenId, { from: owner }); - receipt = await this.token.burn(tokenId, { from: owner }); - }); - - context('getApproved', function () { - it('reverts', async function () { - await expectRevert( - this.token.getApproved(tokenId), 'ERC721: invalid token ID', - ); - }); - }); - }); - - describe('when the given token ID was not tracked by this contract', function () { - it('reverts', async function () { - await expectRevert( - this.token.burn(unknownTokenId, { from: owner }), 'ERC721: invalid token ID', - ); - }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Consecutive.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Consecutive.t.sol deleted file mode 100644 index fc6d3c7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Consecutive.t.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../../../../contracts/token/ERC721/extensions/ERC721Consecutive.sol"; -import "forge-std/Test.sol"; - -function toSingleton(address account) pure returns (address[] memory) { - address[] memory accounts = new address[](1); - accounts[0] = account; - return accounts; -} - -contract ERC721ConsecutiveTarget is StdUtils, ERC721Consecutive { - uint256 public totalMinted = 0; - - constructor(address[] memory receivers, uint256[] memory batches) ERC721("", "") { - for (uint256 i = 0; i < batches.length; i++) { - address receiver = receivers[i % receivers.length]; - uint96 batchSize = uint96(bound(batches[i], 0, _maxBatchSize())); - _mintConsecutive(receiver, batchSize); - totalMinted += batchSize; - } - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } -} - -contract ERC721ConsecutiveTest is Test { - function test_balance(address receiver, uint256[] calldata batches) public { - vm.assume(receiver != address(0)); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(toSingleton(receiver), batches); - - assertEq(token.balanceOf(receiver), token.totalMinted()); - } - - function test_ownership(address receiver, uint256[] calldata batches, uint256[2] calldata unboundedTokenId) public { - vm.assume(receiver != address(0)); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(toSingleton(receiver), batches); - - if (token.totalMinted() > 0) { - uint256 validTokenId = bound(unboundedTokenId[0], 0, token.totalMinted() - 1); - assertEq(token.ownerOf(validTokenId), receiver); - } - - uint256 invalidTokenId = bound(unboundedTokenId[1], token.totalMinted(), type(uint256).max); - vm.expectRevert(); - token.ownerOf(invalidTokenId); - } - - function test_burn(address receiver, uint256[] calldata batches, uint256 unboundedTokenId) public { - vm.assume(receiver != address(0)); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(toSingleton(receiver), batches); - - // only test if we minted at least one token - uint256 supply = token.totalMinted(); - vm.assume(supply > 0); - - // burn a token in [0; supply[ - uint256 tokenId = bound(unboundedTokenId, 0, supply - 1); - token.burn(tokenId); - - // balance should have decreased - assertEq(token.balanceOf(receiver), supply - 1); - - // token should be burnt - vm.expectRevert(); - token.ownerOf(tokenId); - } - - function test_transfer( - address[2] calldata accounts, - uint256[2] calldata unboundedBatches, - uint256[2] calldata unboundedTokenId - ) public { - vm.assume(accounts[0] != address(0)); - vm.assume(accounts[1] != address(0)); - vm.assume(accounts[0] != accounts[1]); - - address[] memory receivers = new address[](2); - receivers[0] = accounts[0]; - receivers[1] = accounts[1]; - - // We assume _maxBatchSize is 5000 (the default). This test will break otherwise. - uint256[] memory batches = new uint256[](2); - batches[0] = bound(unboundedBatches[0], 1, 5000); - batches[1] = bound(unboundedBatches[1], 1, 5000); - - ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget(receivers, batches); - - uint256 tokenId0 = bound(unboundedTokenId[0], 0, batches[0] - 1); - uint256 tokenId1 = bound(unboundedTokenId[1], 0, batches[1] - 1) + batches[0]; - - assertEq(token.ownerOf(tokenId0), accounts[0]); - assertEq(token.ownerOf(tokenId1), accounts[1]); - assertEq(token.balanceOf(accounts[0]), batches[0]); - assertEq(token.balanceOf(accounts[1]), batches[1]); - - vm.prank(accounts[0]); - token.transferFrom(accounts[0], accounts[1], tokenId0); - - assertEq(token.ownerOf(tokenId0), accounts[1]); - assertEq(token.ownerOf(tokenId1), accounts[1]); - assertEq(token.balanceOf(accounts[0]), batches[0] - 1); - assertEq(token.balanceOf(accounts[1]), batches[1] + 1); - - vm.prank(accounts[1]); - token.transferFrom(accounts[1], accounts[0], tokenId1); - - assertEq(token.ownerOf(tokenId0), accounts[1]); - assertEq(token.ownerOf(tokenId1), accounts[0]); - assertEq(token.balanceOf(accounts[0]), batches[0]); - assertEq(token.balanceOf(accounts[1]), batches[1]); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Consecutive.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Consecutive.test.js deleted file mode 100644 index 1aad4f4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Consecutive.test.js +++ /dev/null @@ -1,212 +0,0 @@ -const { constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const ERC721ConsecutiveMock = artifacts.require('ERC721ConsecutiveMock'); -const ERC721ConsecutiveNoConstructorMintMock = artifacts.require('ERC721ConsecutiveNoConstructorMintMock'); - -contract('ERC721Consecutive', function (accounts) { - const [ user1, user2, user3, receiver ] = accounts; - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - const batches = [ - { receiver: user1, amount: 0 }, - { receiver: user1, amount: 1 }, - { receiver: user1, amount: 2 }, - { receiver: user2, amount: 5 }, - { receiver: user3, amount: 0 }, - { receiver: user1, amount: 7 }, - ]; - const delegates = [ user1, user3 ]; - - describe('with valid batches', function () { - beforeEach(async function () { - this.token = await ERC721ConsecutiveMock.new( - name, - symbol, - delegates, - batches.map(({ receiver }) => receiver), - batches.map(({ amount }) => amount), - ); - }); - - describe('minting during construction', function () { - it('events are emitted at construction', async function () { - let first = 0; - - for (const batch of batches) { - if (batch.amount > 0) { - await expectEvent.inConstruction(this.token, 'ConsecutiveTransfer', { - fromTokenId: web3.utils.toBN(first), - toTokenId: web3.utils.toBN(first + batch.amount - 1), - fromAddress: constants.ZERO_ADDRESS, - toAddress: batch.receiver, - }); - } else { - // expectEvent.notEmitted.inConstruction only looks at event name, and doesn't check the parameters - } - first += batch.amount; - } - }); - - it('ownership is set', async function () { - const owners = batches.flatMap(({ receiver, amount }) => Array(amount).fill(receiver)); - - for (const tokenId in owners) { - expect(await this.token.ownerOf(tokenId)) - .to.be.equal(owners[tokenId]); - } - }); - - it('balance & voting power are set', async function () { - for (const account of accounts) { - const balance = batches - .filter(({ receiver }) => receiver === account) - .map(({ amount }) => amount) - .reduce((a, b) => a + b, 0); - - expect(await this.token.balanceOf(account)) - .to.be.bignumber.equal(web3.utils.toBN(balance)); - - // If not delegated at construction, check before + do delegation - if (!delegates.includes(account)) { - expect(await this.token.getVotes(account)) - .to.be.bignumber.equal(web3.utils.toBN(0)); - - await this.token.delegate(account, { from: account }); - } - - // At this point all accounts should have delegated - expect(await this.token.getVotes(account)) - .to.be.bignumber.equal(web3.utils.toBN(balance)); - } - }); - }); - - describe('minting after construction', function () { - it('consecutive minting is not possible after construction', async function () { - await expectRevert( - this.token.mintConsecutive(user1, 10), - 'ERC721Consecutive: batch minting restricted to constructor', - ); - }); - - it('simple minting is possible after construction', async function () { - const tokenId = batches.reduce((acc, { amount }) => acc + amount, 0); - - expect(await this.token.exists(tokenId)).to.be.equal(false); - - expectEvent( - await this.token.mint(user1, tokenId), - 'Transfer', - { from: constants.ZERO_ADDRESS, to: user1, tokenId: tokenId.toString() }, - ); - }); - - it('cannot mint a token that has been batched minted', async function () { - const tokenId = batches.reduce((acc, { amount }) => acc + amount, 0) - 1; - - expect(await this.token.exists(tokenId)).to.be.equal(true); - - await expectRevert( - this.token.mint(user1, tokenId), - 'ERC721: token already minted', - ); - }); - }); - - describe('ERC721 behavior', function () { - it('core takes over ownership on transfer', async function () { - await this.token.transferFrom(user1, receiver, 1, { from: user1 }); - - expect(await this.token.ownerOf(1)).to.be.equal(receiver); - }); - - it('tokens can be burned and re-minted #1', async function () { - expectEvent( - await this.token.burn(1, { from: user1 }), - 'Transfer', - { from: user1, to: constants.ZERO_ADDRESS, tokenId: '1' }, - ); - - await expectRevert(this.token.ownerOf(1), 'ERC721: invalid token ID'); - - expectEvent( - await this.token.mint(user2, 1), - 'Transfer', - { from: constants.ZERO_ADDRESS, to: user2, tokenId: '1' }, - ); - - expect(await this.token.ownerOf(1)).to.be.equal(user2); - }); - - it('tokens can be burned and re-minted #2', async function () { - const tokenId = batches.reduce((acc, { amount }) => acc.addn(amount), web3.utils.toBN(0)); - - expect(await this.token.exists(tokenId)).to.be.equal(false); - await expectRevert(this.token.ownerOf(tokenId), 'ERC721: invalid token ID'); - - // mint - await this.token.mint(user1, tokenId); - - expect(await this.token.exists(tokenId)).to.be.equal(true); - expect(await this.token.ownerOf(tokenId), user1); - - // burn - expectEvent( - await this.token.burn(tokenId, { from: user1 }), - 'Transfer', - { from: user1, to: constants.ZERO_ADDRESS, tokenId }, - ); - - expect(await this.token.exists(tokenId)).to.be.equal(false); - await expectRevert(this.token.ownerOf(tokenId), 'ERC721: invalid token ID'); - - // re-mint - expectEvent( - await this.token.mint(user2, tokenId), - 'Transfer', - { from: constants.ZERO_ADDRESS, to: user2, tokenId }, - ); - - expect(await this.token.exists(tokenId)).to.be.equal(true); - expect(await this.token.ownerOf(tokenId), user2); - }); - }); - }); - - describe('invalid use', function () { - it('cannot mint a batch larger than 5000', async function () { - await expectRevert( - ERC721ConsecutiveMock.new( - name, - symbol, - [], - [user1], - ['5001'], - ), - 'ERC721Consecutive: batch too large', - ); - }); - - it('cannot use single minting during construction', async function () { - await expectRevert( - ERC721ConsecutiveNoConstructorMintMock.new( - name, - symbol, - ), - 'ERC721Consecutive: can\'t mint during construction', - ); - }); - - it('cannot use single minting during construction', async function () { - await expectRevert( - ERC721ConsecutiveNoConstructorMintMock.new( - name, - symbol, - ), - 'ERC721Consecutive: can\'t mint during construction', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Pausable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Pausable.test.js deleted file mode 100644 index 16847dc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Pausable.test.js +++ /dev/null @@ -1,98 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC721PausableMock = artifacts.require('ERC721PausableMock'); - -contract('ERC721Pausable', function (accounts) { - const [ owner, receiver, operator ] = accounts; - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - beforeEach(async function () { - this.token = await ERC721PausableMock.new(name, symbol); - }); - - context('when token is paused', function () { - const firstTokenId = new BN(1); - const secondTokenId = new BN(1337); - - const mockData = '0x42'; - - beforeEach(async function () { - await this.token.mint(owner, firstTokenId, { from: owner }); - await this.token.pause(); - }); - - it('reverts when trying to transferFrom', async function () { - await expectRevert( - this.token.transferFrom(owner, receiver, firstTokenId, { from: owner }), - 'ERC721Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeTransferFrom', async function () { - await expectRevert( - this.token.safeTransferFrom(owner, receiver, firstTokenId, { from: owner }), - 'ERC721Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeTransferFrom with data', async function () { - await expectRevert( - this.token.methods['safeTransferFrom(address,address,uint256,bytes)']( - owner, receiver, firstTokenId, mockData, { from: owner }, - ), 'ERC721Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to mint', async function () { - await expectRevert( - this.token.mint(receiver, secondTokenId), - 'ERC721Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to burn', async function () { - await expectRevert( - this.token.burn(firstTokenId), - 'ERC721Pausable: token transfer while paused', - ); - }); - - describe('getApproved', function () { - it('returns approved address', async function () { - const approvedAccount = await this.token.getApproved(firstTokenId); - expect(approvedAccount).to.equal(ZERO_ADDRESS); - }); - }); - - describe('balanceOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - const balance = await this.token.balanceOf(owner); - expect(balance).to.be.bignumber.equal('1'); - }); - }); - - describe('ownerOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - const ownerOfToken = await this.token.ownerOf(firstTokenId); - expect(ownerOfToken).to.equal(owner); - }); - }); - - describe('exists', function () { - it('returns token existence', async function () { - expect(await this.token.exists(firstTokenId)).to.equal(true); - }); - }); - - describe('isApprovedForAll', function () { - it('returns the approval of the operator', async function () { - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(false); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Royalty.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Royalty.test.js deleted file mode 100644 index 29b28dd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Royalty.test.js +++ /dev/null @@ -1,40 +0,0 @@ -const { BN, constants } = require('@openzeppelin/test-helpers'); -const ERC721RoyaltyMock = artifacts.require('ERC721RoyaltyMock'); -const { ZERO_ADDRESS } = constants; - -const { shouldBehaveLikeERC2981 } = require('../../common/ERC2981.behavior'); - -contract('ERC721Royalty', function (accounts) { - const [ account1, account2 ] = accounts; - const tokenId1 = new BN('1'); - const tokenId2 = new BN('2'); - const royalty = new BN('200'); - const salePrice = new BN('1000'); - - beforeEach(async function () { - this.token = await ERC721RoyaltyMock.new('My Token', 'TKN'); - - await this.token.mint(account1, tokenId1); - await this.token.mint(account1, tokenId2); - this.account1 = account1; - this.account2 = account2; - this.tokenId1 = tokenId1; - this.tokenId2 = tokenId2; - this.salePrice = salePrice; - }); - - describe('token specific functions', function () { - beforeEach(async function () { - await this.token.setTokenRoyalty(tokenId1, account1, royalty); - }); - - it('removes royalty information after burn', async function () { - await this.token.burn(tokenId1); - const tokenInfo = await this.token.royaltyInfo(tokenId1, salePrice); - - expect(tokenInfo[0]).to.be.equal(ZERO_ADDRESS); - expect(tokenInfo[1]).to.be.bignumber.equal(new BN('0')); - }); - }); - shouldBehaveLikeERC2981(); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721URIStorage.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721URIStorage.test.js deleted file mode 100644 index eeacf5e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721URIStorage.test.js +++ /dev/null @@ -1,96 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC721URIStorageMock = artifacts.require('ERC721URIStorageMock'); - -contract('ERC721URIStorage', function (accounts) { - const [ owner ] = accounts; - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - const firstTokenId = new BN('5042'); - const nonExistentTokenId = new BN('13'); - - beforeEach(async function () { - this.token = await ERC721URIStorageMock.new(name, symbol); - }); - - describe('token URI', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - }); - - const baseURI = 'https://api.example.com/v1/'; - const sampleUri = 'mock://mytoken'; - - it('it is empty by default', async function () { - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(''); - }); - - it('reverts when queried for non existent token id', async function () { - await expectRevert( - this.token.tokenURI(nonExistentTokenId), 'ERC721: invalid token ID', - ); - }); - - it('can be set for a token id', async function () { - await this.token.setTokenURI(firstTokenId, sampleUri); - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(sampleUri); - }); - - it('reverts when setting for non existent token id', async function () { - await expectRevert( - this.token.setTokenURI(nonExistentTokenId, sampleUri), 'ERC721URIStorage: URI set of nonexistent token', - ); - }); - - it('base URI can be set', async function () { - await this.token.setBaseURI(baseURI); - expect(await this.token.baseURI()).to.equal(baseURI); - }); - - it('base URI is added as a prefix to the token URI', async function () { - await this.token.setBaseURI(baseURI); - await this.token.setTokenURI(firstTokenId, sampleUri); - - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(baseURI + sampleUri); - }); - - it('token URI can be changed by changing the base URI', async function () { - await this.token.setBaseURI(baseURI); - await this.token.setTokenURI(firstTokenId, sampleUri); - - const newBaseURI = 'https://api.example.com/v2/'; - await this.token.setBaseURI(newBaseURI); - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(newBaseURI + sampleUri); - }); - - it('tokenId is appended to base URI for tokens with no URI', async function () { - await this.token.setBaseURI(baseURI); - - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(baseURI + firstTokenId); - }); - - it('tokens without URI can be burnt ', async function () { - await this.token.burn(firstTokenId, { from: owner }); - - expect(await this.token.exists(firstTokenId)).to.equal(false); - await expectRevert( - this.token.tokenURI(firstTokenId), 'ERC721: invalid token ID', - ); - }); - - it('tokens with URI can be burnt ', async function () { - await this.token.setTokenURI(firstTokenId, sampleUri); - - await this.token.burn(firstTokenId, { from: owner }); - - expect(await this.token.exists(firstTokenId)).to.equal(false); - await expectRevert( - this.token.tokenURI(firstTokenId), 'ERC721: invalid token ID', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Votes.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Votes.test.js deleted file mode 100644 index 6f001f2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/extensions/ERC721Votes.test.js +++ /dev/null @@ -1,174 +0,0 @@ -/* eslint-disable */ - -const { BN, expectEvent, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const { promisify } = require('util'); -const queue = promisify(setImmediate); - -const ERC721VotesMock = artifacts.require('ERC721VotesMock'); - -const { shouldBehaveLikeVotes } = require('../../../governance/utils/Votes.behavior'); - -contract('ERC721Votes', function (accounts) { - const [ account1, account2, account1Delegatee, other1, other2 ] = accounts; - this.name = 'My Vote'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.votes = await ERC721VotesMock.new(name, symbol); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.votes.getChainId(); - - this.NFT0 = new BN('10000000000000000000000000'); - this.NFT1 = new BN('10'); - this.NFT2 = new BN('20'); - this.NFT3 = new BN('30'); - }); - - describe('balanceOf', function () { - beforeEach(async function () { - await this.votes.mint(account1, this.NFT0); - await this.votes.mint(account1, this.NFT1); - await this.votes.mint(account1, this.NFT2); - await this.votes.mint(account1, this.NFT3); - }); - - it('grants to initial account', async function () { - expect(await this.votes.balanceOf(account1)).to.be.bignumber.equal('4'); - }); - }); - - describe('transfers', function () { - beforeEach(async function () { - await this.votes.mint(account1, this.NFT0); - }); - - it('no delegation', async function () { - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - expectEvent(receipt, 'Transfer', { from: account1, to: account2, tokenId: this.NFT0 }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - this.account1Votes = '0'; - this.account2Votes = '0'; - }); - - it('sender delegation', async function () { - await this.votes.delegate(account1, { from: account1 }); - - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - expectEvent(receipt, 'Transfer', { from: account1, to: account2, tokenId: this.NFT0 }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: account1, previousBalance: '1', newBalance: '0' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.account1Votes = '0'; - this.account2Votes = '0'; - }); - - it('receiver delegation', async function () { - await this.votes.delegate(account2, { from: account2 }); - - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - expectEvent(receipt, 'Transfer', { from: account1, to: account2, tokenId: this.NFT0 }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: account2, previousBalance: '0', newBalance: '1' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.account1Votes = '0'; - this.account2Votes = '1'; - }); - - it('full delegation', async function () { - await this.votes.delegate(account1, { from: account1 }); - await this.votes.delegate(account2, { from: account2 }); - - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - expectEvent(receipt, 'Transfer', { from: account1, to: account2, tokenId: this.NFT0 }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: account1, previousBalance: '1', newBalance: '0'}); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: account2, previousBalance: '0', newBalance: '1' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.account1Votes = '0'; - this.account2Votes = '1'; - }); - - it('returns the same total supply on transfers', async function () { - await this.votes.delegate(account1, { from: account1 }); - - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastTotalSupply(receipt.blockNumber - 1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - - this.account1Votes = '0'; - this.account2Votes = '0'; - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - await this.votes.mint(account1, this.NFT1); - await this.votes.mint(account1, this.NFT2); - await this.votes.mint(account1, this.NFT3); - - const total = await this.votes.balanceOf(account1); - - const t1 = await this.votes.delegate(other1, { from: account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.votes.transferFrom(account1, other2, this.NFT0, { from: account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.votes.transferFrom(account1, other2, this.NFT2, { from: account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.votes.transferFrom(other2, account1, this.NFT2, { from: other2 }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal(total); - expect(await this.votes.getPastVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal(total); - expect(await this.votes.getPastVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('3'); - expect(await this.votes.getPastVotes(other1, t2.receipt.blockNumber + 1)).to.be.bignumber.equal('3'); - expect(await this.votes.getPastVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('2'); - expect(await this.votes.getPastVotes(other1, t3.receipt.blockNumber + 1)).to.be.bignumber.equal('2'); - expect(await this.votes.getPastVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('3'); - expect(await this.votes.getPastVotes(other1, t4.receipt.blockNumber + 1)).to.be.bignumber.equal('3'); - - this.account1Votes = '0'; - this.account2Votes = '0'; - }); - - afterEach(async function () { - expect(await this.votes.getVotes(account1)).to.be.bignumber.equal(this.account1Votes); - expect(await this.votes.getVotes(account2)).to.be.bignumber.equal(this.account2Votes); - - // need to advance 2 blocks to see the effect of a transfer on "getPastVotes" - const blockNumber = await time.latestBlock(); - await time.advanceBlock(); - expect(await this.votes.getPastVotes(account1, blockNumber)).to.be.bignumber.equal(this.account1Votes); - expect(await this.votes.getPastVotes(account2, blockNumber)).to.be.bignumber.equal(this.account2Votes); - }); - }); - - describe('Voting workflow', function () { - beforeEach(async function () { - this.account1 = account1; - this.account1Delegatee = account1Delegatee; - this.account2 = account2; - this.name = 'My Vote'; - }); - - shouldBehaveLikeVotes(); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/presets/ERC721PresetMinterPauserAutoId.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/presets/ERC721PresetMinterPauserAutoId.test.js deleted file mode 100644 index 4ad7355..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/presets/ERC721PresetMinterPauserAutoId.test.js +++ /dev/null @@ -1,125 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); - -const { expect } = require('chai'); - -const ERC721PresetMinterPauserAutoId = artifacts.require('ERC721PresetMinterPauserAutoId'); - -contract('ERC721PresetMinterPauserAutoId', function (accounts) { - const [ deployer, other ] = accounts; - - const name = 'MinterAutoIDToken'; - const symbol = 'MAIT'; - const baseURI = 'my.app/'; - - const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const MINTER_ROLE = web3.utils.soliditySha3('MINTER_ROLE'); - - beforeEach(async function () { - this.token = await ERC721PresetMinterPauserAutoId.new(name, symbol, baseURI, { from: deployer }); - }); - - shouldSupportInterfaces(['ERC721', 'ERC721Enumerable', 'AccessControl', 'AccessControlEnumerable']); - - it('token has correct name', async function () { - expect(await this.token.name()).to.equal(name); - }); - - it('token has correct symbol', async function () { - expect(await this.token.symbol()).to.equal(symbol); - }); - - it('deployer has the default admin role', async function () { - expect(await this.token.getRoleMemberCount(DEFAULT_ADMIN_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(DEFAULT_ADMIN_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the minter role', async function () { - expect(await this.token.getRoleMemberCount(MINTER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(MINTER_ROLE, 0)).to.equal(deployer); - }); - - it('minter role admin is the default admin', async function () { - expect(await this.token.getRoleAdmin(MINTER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - describe('minting', function () { - it('deployer can mint tokens', async function () { - const tokenId = new BN('0'); - - const receipt = await this.token.mint(other, { from: deployer }); - expectEvent(receipt, 'Transfer', { from: ZERO_ADDRESS, to: other, tokenId }); - - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('1'); - expect(await this.token.ownerOf(tokenId)).to.equal(other); - - expect(await this.token.tokenURI(tokenId)).to.equal(baseURI + tokenId); - }); - - it('other accounts cannot mint tokens', async function () { - await expectRevert( - this.token.mint(other, { from: other }), - 'ERC721PresetMinterPauserAutoId: must have minter role to mint', - ); - }); - }); - - describe('pausing', function () { - it('deployer can pause', async function () { - const receipt = await this.token.pause({ from: deployer }); - expectEvent(receipt, 'Paused', { account: deployer }); - - expect(await this.token.paused()).to.equal(true); - }); - - it('deployer can unpause', async function () { - await this.token.pause({ from: deployer }); - - const receipt = await this.token.unpause({ from: deployer }); - expectEvent(receipt, 'Unpaused', { account: deployer }); - - expect(await this.token.paused()).to.equal(false); - }); - - it('cannot mint while paused', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.mint(other, { from: deployer }), - 'ERC721Pausable: token transfer while paused', - ); - }); - - it('other accounts cannot pause', async function () { - await expectRevert( - this.token.pause({ from: other }), - 'ERC721PresetMinterPauserAutoId: must have pauser role to pause', - ); - }); - - it('other accounts cannot unpause', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.unpause({ from: other }), - 'ERC721PresetMinterPauserAutoId: must have pauser role to unpause', - ); - }); - }); - - describe('burning', function () { - it('holders can burn their tokens', async function () { - const tokenId = new BN('0'); - - await this.token.mint(other, { from: deployer }); - - const receipt = await this.token.burn(tokenId, { from: other }); - - expectEvent(receipt, 'Transfer', { from: other, to: ZERO_ADDRESS, tokenId }); - - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('0'); - expect(await this.token.totalSupply()).to.be.bignumber.equal('0'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/utils/ERC721Holder.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/utils/ERC721Holder.test.js deleted file mode 100644 index 2431e66..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC721/utils/ERC721Holder.test.js +++ /dev/null @@ -1,24 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC721Holder = artifacts.require('ERC721Holder'); -const ERC721Mock = artifacts.require('ERC721Mock'); - -contract('ERC721Holder', function (accounts) { - const [ owner ] = accounts; - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - it('receives an ERC721 token', async function () { - const token = await ERC721Mock.new(name, symbol); - const tokenId = new BN(1); - await token.mint(owner, tokenId); - - const receiver = await ERC721Holder.new(); - await token.safeTransferFrom(owner, receiver.address, tokenId, { from: owner }); - - expect(await token.ownerOf(tokenId)).to.be.equal(receiver.address); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/ERC777.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/ERC777.behavior.js deleted file mode 100644 index f6af942..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/ERC777.behavior.js +++ /dev/null @@ -1,555 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC777SenderRecipientMock = artifacts.require('ERC777SenderRecipientMock'); - -function shouldBehaveLikeERC777DirectSendBurn (holder, recipient, data) { - shouldBehaveLikeERC777DirectSend(holder, recipient, data); - shouldBehaveLikeERC777DirectBurn(holder, data); -} - -function shouldBehaveLikeERC777OperatorSendBurn (holder, recipient, operator, data, operatorData) { - shouldBehaveLikeERC777OperatorSend(holder, recipient, operator, data, operatorData); - shouldBehaveLikeERC777OperatorBurn(holder, operator, data, operatorData); -} - -function shouldBehaveLikeERC777UnauthorizedOperatorSendBurn (holder, recipient, operator, data, operatorData) { - shouldBehaveLikeERC777UnauthorizedOperatorSend(holder, recipient, operator, data, operatorData); - shouldBehaveLikeERC777UnauthorizedOperatorBurn(holder, operator, data, operatorData); -} - -function shouldBehaveLikeERC777DirectSend (holder, recipient, data) { - describe('direct send', function () { - context('when the sender has tokens', function () { - shouldDirectSendTokens(holder, recipient, new BN('0'), data); - shouldDirectSendTokens(holder, recipient, new BN('1'), data); - - it('reverts when sending more than the balance', async function () { - const balance = await this.token.balanceOf(holder); - await expectRevert.unspecified(this.token.send(recipient, balance.addn(1), data, { from: holder })); - }); - - it('reverts when sending to the zero address', async function () { - await expectRevert.unspecified(this.token.send(ZERO_ADDRESS, new BN('1'), data, { from: holder })); - }); - }); - - context('when the sender has no tokens', function () { - removeBalance(holder); - - shouldDirectSendTokens(holder, recipient, new BN('0'), data); - - it('reverts when sending a non-zero amount', async function () { - await expectRevert.unspecified(this.token.send(recipient, new BN('1'), data, { from: holder })); - }); - }); - }); -} - -function shouldBehaveLikeERC777OperatorSend (holder, recipient, operator, data, operatorData) { - describe('operator send', function () { - context('when the sender has tokens', async function () { - shouldOperatorSendTokens(holder, operator, recipient, new BN('0'), data, operatorData); - shouldOperatorSendTokens(holder, operator, recipient, new BN('1'), data, operatorData); - - it('reverts when sending more than the balance', async function () { - const balance = await this.token.balanceOf(holder); - await expectRevert.unspecified( - this.token.operatorSend(holder, recipient, balance.addn(1), data, operatorData, { from: operator }), - ); - }); - - it('reverts when sending to the zero address', async function () { - await expectRevert.unspecified( - this.token.operatorSend( - holder, ZERO_ADDRESS, new BN('1'), data, operatorData, { from: operator }, - ), - ); - }); - }); - - context('when the sender has no tokens', function () { - removeBalance(holder); - - shouldOperatorSendTokens(holder, operator, recipient, new BN('0'), data, operatorData); - - it('reverts when sending a non-zero amount', async function () { - await expectRevert.unspecified( - this.token.operatorSend(holder, recipient, new BN('1'), data, operatorData, { from: operator }), - ); - }); - - it('reverts when sending from the zero address', async function () { - // This is not yet reflected in the spec - await expectRevert.unspecified( - this.token.operatorSend( - ZERO_ADDRESS, recipient, new BN('0'), data, operatorData, { from: operator }, - ), - ); - }); - }); - }); -} - -function shouldBehaveLikeERC777UnauthorizedOperatorSend (holder, recipient, operator, data, operatorData) { - describe('operator send', function () { - it('reverts', async function () { - await expectRevert.unspecified(this.token.operatorSend(holder, recipient, new BN('0'), data, operatorData)); - }); - }); -} - -function shouldBehaveLikeERC777DirectBurn (holder, data) { - describe('direct burn', function () { - context('when the sender has tokens', function () { - shouldDirectBurnTokens(holder, new BN('0'), data); - shouldDirectBurnTokens(holder, new BN('1'), data); - - it('reverts when burning more than the balance', async function () { - const balance = await this.token.balanceOf(holder); - await expectRevert.unspecified(this.token.burn(balance.addn(1), data, { from: holder })); - }); - }); - - context('when the sender has no tokens', function () { - removeBalance(holder); - - shouldDirectBurnTokens(holder, new BN('0'), data); - - it('reverts when burning a non-zero amount', async function () { - await expectRevert.unspecified(this.token.burn(new BN('1'), data, { from: holder })); - }); - }); - }); -} - -function shouldBehaveLikeERC777OperatorBurn (holder, operator, data, operatorData) { - describe('operator burn', function () { - context('when the sender has tokens', async function () { - shouldOperatorBurnTokens(holder, operator, new BN('0'), data, operatorData); - shouldOperatorBurnTokens(holder, operator, new BN('1'), data, operatorData); - - it('reverts when burning more than the balance', async function () { - const balance = await this.token.balanceOf(holder); - await expectRevert.unspecified( - this.token.operatorBurn(holder, balance.addn(1), data, operatorData, { from: operator }), - ); - }); - }); - - context('when the sender has no tokens', function () { - removeBalance(holder); - - shouldOperatorBurnTokens(holder, operator, new BN('0'), data, operatorData); - - it('reverts when burning a non-zero amount', async function () { - await expectRevert.unspecified( - this.token.operatorBurn(holder, new BN('1'), data, operatorData, { from: operator }), - ); - }); - - it('reverts when burning from the zero address', async function () { - // This is not yet reflected in the spec - await expectRevert.unspecified( - this.token.operatorBurn( - ZERO_ADDRESS, new BN('0'), data, operatorData, { from: operator }, - ), - ); - }); - }); - }); -} - -function shouldBehaveLikeERC777UnauthorizedOperatorBurn (holder, operator, data, operatorData) { - describe('operator burn', function () { - it('reverts', async function () { - await expectRevert.unspecified(this.token.operatorBurn(holder, new BN('0'), data, operatorData)); - }); - }); -} - -function shouldDirectSendTokens (from, to, amount, data) { - shouldSendTokens(from, null, to, amount, data, null); -} - -function shouldOperatorSendTokens (from, operator, to, amount, data, operatorData) { - shouldSendTokens(from, operator, to, amount, data, operatorData); -} - -function shouldSendTokens (from, operator, to, amount, data, operatorData) { - const operatorCall = operator !== null; - - it(`${operatorCall ? 'operator ' : ''}can send an amount of ${amount}`, async function () { - const initialTotalSupply = await this.token.totalSupply(); - const initialFromBalance = await this.token.balanceOf(from); - const initialToBalance = await this.token.balanceOf(to); - - let receipt; - if (!operatorCall) { - (receipt = await this.token.send(to, amount, data, { from })); - expectEvent(receipt, 'Sent', { - operator: from, - from, - to, - amount, - data, - operatorData: null, - }); - } else { - (receipt = await this.token.operatorSend(from, to, amount, data, operatorData, { from: operator })); - expectEvent(receipt, 'Sent', { - operator, - from, - to, - amount, - data, - operatorData, - }); - } - - expectEvent(receipt, 'Transfer', { - from, - to, - value: amount, - }); - - const finalTotalSupply = await this.token.totalSupply(); - const finalFromBalance = await this.token.balanceOf(from); - const finalToBalance = await this.token.balanceOf(to); - - expect(finalTotalSupply).to.be.bignumber.equal(initialTotalSupply); - expect(finalToBalance.sub(initialToBalance)).to.be.bignumber.equal(amount); - expect(finalFromBalance.sub(initialFromBalance)).to.be.bignumber.equal(amount.neg()); - }); -} - -function shouldDirectBurnTokens (from, amount, data) { - shouldBurnTokens(from, null, amount, data, null); -} - -function shouldOperatorBurnTokens (from, operator, amount, data, operatorData) { - shouldBurnTokens(from, operator, amount, data, operatorData); -} - -function shouldBurnTokens (from, operator, amount, data, operatorData) { - const operatorCall = operator !== null; - - it(`${operatorCall ? 'operator ' : ''}can burn an amount of ${amount}`, async function () { - const initialTotalSupply = await this.token.totalSupply(); - const initialFromBalance = await this.token.balanceOf(from); - - let receipt; - if (!operatorCall) { - (receipt = await this.token.burn(amount, data, { from })); - expectEvent(receipt, 'Burned', { - operator: from, - from, - amount, - data, - operatorData: null, - }); - } else { - (receipt = await this.token.operatorBurn(from, amount, data, operatorData, { from: operator })); - expectEvent(receipt, 'Burned', { - operator, - from, - amount, - data, - operatorData, - }); - } - - expectEvent(receipt, 'Transfer', { - from, - to: ZERO_ADDRESS, - value: amount, - }); - - const finalTotalSupply = await this.token.totalSupply(); - const finalFromBalance = await this.token.balanceOf(from); - - expect(finalTotalSupply.sub(initialTotalSupply)).to.be.bignumber.equal(amount.neg()); - expect(finalFromBalance.sub(initialFromBalance)).to.be.bignumber.equal(amount.neg()); - }); -} - -function shouldBehaveLikeERC777InternalMint (recipient, operator, amount, data, operatorData) { - shouldInternalMintTokens(operator, recipient, new BN('0'), data, operatorData); - shouldInternalMintTokens(operator, recipient, amount, data, operatorData); - - it('reverts when minting tokens for the zero address', async function () { - await expectRevert.unspecified( - this.token.mintInternal(ZERO_ADDRESS, amount, data, operatorData, { from: operator }), - ); - }); -} - -function shouldInternalMintTokens (operator, to, amount, data, operatorData) { - it(`can (internal) mint an amount of ${amount}`, async function () { - const initialTotalSupply = await this.token.totalSupply(); - const initialToBalance = await this.token.balanceOf(to); - - const receipt = await this.token.mintInternal(to, amount, data, operatorData, { from: operator }); - - expectEvent(receipt, 'Minted', { - operator, - to, - amount, - data, - operatorData, - }); - - expectEvent(receipt, 'Transfer', { - from: ZERO_ADDRESS, - to, - value: amount, - }); - - const finalTotalSupply = await this.token.totalSupply(); - const finalToBalance = await this.token.balanceOf(to); - - expect(finalTotalSupply.sub(initialTotalSupply)).to.be.bignumber.equal(amount); - expect(finalToBalance.sub(initialToBalance)).to.be.bignumber.equal(amount); - }); -} - -function shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook (operator, amount, data, operatorData) { - context('when TokensRecipient reverts', function () { - beforeEach(async function () { - await this.tokensRecipientImplementer.setShouldRevertReceive(true); - }); - - it('send reverts', async function () { - await expectRevert.unspecified(sendFromHolder(this.token, this.sender, this.recipient, amount, data)); - }); - - it('operatorSend reverts', async function () { - await expectRevert.unspecified( - this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }), - ); - }); - - it('mint (internal) reverts', async function () { - await expectRevert.unspecified( - this.token.mintInternal(this.recipient, amount, data, operatorData, { from: operator }), - ); - }); - }); - - context('when TokensRecipient does not revert', function () { - beforeEach(async function () { - await this.tokensRecipientImplementer.setShouldRevertSend(false); - }); - - it('TokensRecipient receives send data and is called after state mutation', async function () { - const { tx } = await sendFromHolder(this.token, this.sender, this.recipient, amount, data); - - const postSenderBalance = await this.token.balanceOf(this.sender); - const postRecipientBalance = await this.token.balanceOf(this.recipient); - - await assertTokensReceivedCalled( - this.token, - tx, - this.sender, - this.sender, - this.recipient, - amount, - data, - null, - postSenderBalance, - postRecipientBalance, - ); - }); - - it('TokensRecipient receives operatorSend data and is called after state mutation', async function () { - const { tx } = await this.token.operatorSend( - this.sender, this.recipient, amount, data, operatorData, - { from: operator }, - ); - - const postSenderBalance = await this.token.balanceOf(this.sender); - const postRecipientBalance = await this.token.balanceOf(this.recipient); - - await assertTokensReceivedCalled( - this.token, - tx, - operator, - this.sender, - this.recipient, - amount, - data, - operatorData, - postSenderBalance, - postRecipientBalance, - ); - }); - - it('TokensRecipient receives mint (internal) data and is called after state mutation', async function () { - const { tx } = await this.token.mintInternal( - this.recipient, amount, data, operatorData, { from: operator }, - ); - - const postRecipientBalance = await this.token.balanceOf(this.recipient); - - await assertTokensReceivedCalled( - this.token, - tx, - operator, - ZERO_ADDRESS, - this.recipient, - amount, - data, - operatorData, - new BN('0'), - postRecipientBalance, - ); - }); - }); -} - -function shouldBehaveLikeERC777SendBurnWithSendHook (operator, amount, data, operatorData) { - context('when TokensSender reverts', function () { - beforeEach(async function () { - await this.tokensSenderImplementer.setShouldRevertSend(true); - }); - - it('send reverts', async function () { - await expectRevert.unspecified(sendFromHolder(this.token, this.sender, this.recipient, amount, data)); - }); - - it('operatorSend reverts', async function () { - await expectRevert.unspecified( - this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }), - ); - }); - - it('burn reverts', async function () { - await expectRevert.unspecified(burnFromHolder(this.token, this.sender, amount, data)); - }); - - it('operatorBurn reverts', async function () { - await expectRevert.unspecified( - this.token.operatorBurn(this.sender, amount, data, operatorData, { from: operator }), - ); - }); - }); - - context('when TokensSender does not revert', function () { - beforeEach(async function () { - await this.tokensSenderImplementer.setShouldRevertSend(false); - }); - - it('TokensSender receives send data and is called before state mutation', async function () { - const preSenderBalance = await this.token.balanceOf(this.sender); - const preRecipientBalance = await this.token.balanceOf(this.recipient); - - const { tx } = await sendFromHolder(this.token, this.sender, this.recipient, amount, data); - - await assertTokensToSendCalled( - this.token, - tx, - this.sender, - this.sender, - this.recipient, - amount, - data, - null, - preSenderBalance, - preRecipientBalance, - ); - }); - - it('TokensSender receives operatorSend data and is called before state mutation', async function () { - const preSenderBalance = await this.token.balanceOf(this.sender); - const preRecipientBalance = await this.token.balanceOf(this.recipient); - - const { tx } = await this.token.operatorSend( - this.sender, this.recipient, amount, data, operatorData, - { from: operator }, - ); - - await assertTokensToSendCalled( - this.token, - tx, - operator, - this.sender, - this.recipient, - amount, - data, - operatorData, - preSenderBalance, - preRecipientBalance, - ); - }); - - it('TokensSender receives burn data and is called before state mutation', async function () { - const preSenderBalance = await this.token.balanceOf(this.sender); - - const { tx } = await burnFromHolder(this.token, this.sender, amount, data, { from: this.sender }); - - await assertTokensToSendCalled( - this.token, tx, this.sender, this.sender, ZERO_ADDRESS, amount, data, null, preSenderBalance, - ); - }); - - it('TokensSender receives operatorBurn data and is called before state mutation', async function () { - const preSenderBalance = await this.token.balanceOf(this.sender); - - const { tx } = await this.token.operatorBurn(this.sender, amount, data, operatorData, { from: operator }); - - await assertTokensToSendCalled( - this.token, tx, operator, this.sender, ZERO_ADDRESS, amount, data, operatorData, preSenderBalance, - ); - }); - }); -} - -function removeBalance (holder) { - beforeEach(async function () { - await this.token.burn(await this.token.balanceOf(holder), '0x', { from: holder }); - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('0'); - }); -} - -async function assertTokensReceivedCalled (token, txHash, operator, from, to, amount, data, operatorData, fromBalance, - toBalance = '0') { - await expectEvent.inTransaction(txHash, ERC777SenderRecipientMock, 'TokensReceivedCalled', { - operator, from, to, amount, data, operatorData, token: token.address, fromBalance, toBalance, - }); -} - -async function assertTokensToSendCalled (token, txHash, operator, from, to, amount, data, operatorData, fromBalance, - toBalance = '0') { - await expectEvent.inTransaction(txHash, ERC777SenderRecipientMock, 'TokensToSendCalled', { - operator, from, to, amount, data, operatorData, token: token.address, fromBalance, toBalance, - }); -} - -async function sendFromHolder (token, holder, to, amount, data) { - if ((await web3.eth.getCode(holder)).length <= '0x'.length) { - return token.send(to, amount, data, { from: holder }); - } else { - // assume holder is ERC777SenderRecipientMock contract - return (await ERC777SenderRecipientMock.at(holder)).send(token.address, to, amount, data); - } -} - -async function burnFromHolder (token, holder, amount, data) { - if ((await web3.eth.getCode(holder)).length <= '0x'.length) { - return token.burn(amount, data, { from: holder }); - } else { - // assume holder is ERC777SenderRecipientMock contract - return (await ERC777SenderRecipientMock.at(holder)).burn(token.address, amount, data); - } -} - -module.exports = { - shouldBehaveLikeERC777DirectSendBurn, - shouldBehaveLikeERC777OperatorSendBurn, - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn, - shouldBehaveLikeERC777InternalMint, - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook, - shouldBehaveLikeERC777SendBurnWithSendHook, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/ERC777.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/ERC777.test.js deleted file mode 100644 index 51da130..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/ERC777.test.js +++ /dev/null @@ -1,610 +0,0 @@ -const { BN, constants, expectEvent, expectRevert, singletons } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const { - shouldBehaveLikeERC777DirectSendBurn, - shouldBehaveLikeERC777OperatorSendBurn, - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn, - shouldBehaveLikeERC777InternalMint, - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook, - shouldBehaveLikeERC777SendBurnWithSendHook, -} = require('./ERC777.behavior'); - -const { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Approve, -} = require('../ERC20/ERC20.behavior'); - -const ERC777 = artifacts.require('ERC777Mock'); -const ERC777SenderRecipientMock = artifacts.require('ERC777SenderRecipientMock'); - -contract('ERC777', function (accounts) { - const [ registryFunder, holder, defaultOperatorA, defaultOperatorB, newOperator, anyone ] = accounts; - - const initialSupply = new BN('10000'); - const name = 'ERC777Test'; - const symbol = '777T'; - const data = web3.utils.sha3('OZ777TestData'); - const operatorData = web3.utils.sha3('OZ777TestOperatorData'); - - const defaultOperators = [defaultOperatorA, defaultOperatorB]; - - beforeEach(async function () { - this.erc1820 = await singletons.ERC1820Registry(registryFunder); - }); - - context('with default operators', function () { - beforeEach(async function () { - this.token = await ERC777.new(holder, initialSupply, name, symbol, defaultOperators); - }); - - describe('as an ERC20 token', function () { - shouldBehaveLikeERC20('ERC777', initialSupply, holder, anyone, defaultOperatorA); - - describe('_approve', function () { - shouldBehaveLikeERC20Approve('ERC777', holder, anyone, initialSupply, function (owner, spender, amount) { - return this.token.approveInternal(owner, spender, amount); - }); - - describe('when the owner is the zero address', function () { - it('reverts', async function () { - await expectRevert(this.token.approveInternal(ZERO_ADDRESS, anyone, initialSupply), - 'ERC777: approve from the zero address', - ); - }); - }); - }); - }); - - it('does not emit AuthorizedOperator events for default operators', async function () { - await expectEvent.notEmitted.inConstruction(this.token, 'AuthorizedOperator'); - }); - - describe('basic information', function () { - it('returns the name', async function () { - expect(await this.token.name()).to.equal(name); - }); - - it('returns the symbol', async function () { - expect(await this.token.symbol()).to.equal(symbol); - }); - - it('returns a granularity of 1', async function () { - expect(await this.token.granularity()).to.be.bignumber.equal('1'); - }); - - it('returns the default operators', async function () { - expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators); - }); - - it('default operators are operators for all accounts', async function () { - for (const operator of defaultOperators) { - expect(await this.token.isOperatorFor(operator, anyone)).to.equal(true); - } - }); - - it('returns the total supply', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - }); - - it('returns 18 when decimals is called', async function () { - expect(await this.token.decimals()).to.be.bignumber.equal('18'); - }); - - it('the ERC777Token interface is registered in the registry', async function () { - expect(await this.erc1820.getInterfaceImplementer(this.token.address, web3.utils.soliditySha3('ERC777Token'))) - .to.equal(this.token.address); - }); - - it('the ERC20Token interface is registered in the registry', async function () { - expect(await this.erc1820.getInterfaceImplementer(this.token.address, web3.utils.soliditySha3('ERC20Token'))) - .to.equal(this.token.address); - }); - }); - - describe('balanceOf', function () { - context('for an account with no tokens', function () { - it('returns zero', async function () { - expect(await this.token.balanceOf(anyone)).to.be.bignumber.equal('0'); - }); - }); - - context('for an account with tokens', function () { - it('returns their balance', async function () { - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply); - }); - }); - }); - - context('with no ERC777TokensSender and no ERC777TokensRecipient implementers', function () { - describe('send/burn', function () { - shouldBehaveLikeERC777DirectSendBurn(holder, anyone, data); - - context('with self operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, holder, data, operatorData); - }); - - context('with first default operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, defaultOperatorA, data, operatorData); - }); - - context('with second default operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, defaultOperatorB, data, operatorData); - }); - - context('before authorizing a new operator', function () { - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn(holder, anyone, newOperator, data, operatorData); - }); - - context('with new authorized operator', function () { - beforeEach(async function () { - await this.token.authorizeOperator(newOperator, { from: holder }); - }); - - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, newOperator, data, operatorData); - - context('with revoked operator', function () { - beforeEach(async function () { - await this.token.revokeOperator(newOperator, { from: holder }); - }); - - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn(holder, anyone, newOperator, data, operatorData); - }); - }); - }); - - describe('mint (internal)', function () { - const to = anyone; - const amount = new BN('5'); - - context('with default operator', function () { - const operator = defaultOperatorA; - - shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData); - }); - - context('with non operator', function () { - const operator = newOperator; - - shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData); - }); - }); - - describe('mint (internal extended)', function () { - const amount = new BN('5'); - - context('to anyone', function () { - beforeEach(async function () { - this.recipient = anyone; - }); - - context('with default operator', function () { - const operator = defaultOperatorA; - - it('without requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - false, - { from: operator }, - ); - }); - - it('with requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - true, - { from: operator }, - ); - }); - }); - - context('with non operator', function () { - const operator = newOperator; - - it('without requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - false, - { from: operator }, - ); - }); - - it('with requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - true, - { from: operator }, - ); - }); - }); - }); - - context('to non ERC777TokensRecipient implementer', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = this.tokensRecipientImplementer.address; - }); - - context('with default operator', function () { - const operator = defaultOperatorA; - - it('without requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - false, - { from: operator }, - ); - }); - - it('with requireReceptionAck', async function () { - await expectRevert( - this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - true, - { from: operator }, - ), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - }); - - context('with non operator', function () { - const operator = newOperator; - - it('without requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - false, - { from: operator }, - ); - }); - - it('with requireReceptionAck', async function () { - await expectRevert( - this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - true, - { from: operator }, - ), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - }); - }); - }); - }); - - describe('operator management', function () { - it('accounts are their own operator', async function () { - expect(await this.token.isOperatorFor(holder, holder)).to.equal(true); - }); - - it('reverts when self-authorizing', async function () { - await expectRevert( - this.token.authorizeOperator(holder, { from: holder }), 'ERC777: authorizing self as operator', - ); - }); - - it('reverts when self-revoking', async function () { - await expectRevert( - this.token.revokeOperator(holder, { from: holder }), 'ERC777: revoking self as operator', - ); - }); - - it('non-operators can be revoked', async function () { - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(false); - - const receipt = await this.token.revokeOperator(newOperator, { from: holder }); - expectEvent(receipt, 'RevokedOperator', { operator: newOperator, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(false); - }); - - it('non-operators can be authorized', async function () { - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(false); - - const receipt = await this.token.authorizeOperator(newOperator, { from: holder }); - expectEvent(receipt, 'AuthorizedOperator', { operator: newOperator, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(true); - }); - - describe('new operators', function () { - beforeEach(async function () { - await this.token.authorizeOperator(newOperator, { from: holder }); - }); - - it('are not added to the default operators list', async function () { - expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators); - }); - - it('can be re-authorized', async function () { - const receipt = await this.token.authorizeOperator(newOperator, { from: holder }); - expectEvent(receipt, 'AuthorizedOperator', { operator: newOperator, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(true); - }); - - it('can be revoked', async function () { - const receipt = await this.token.revokeOperator(newOperator, { from: holder }); - expectEvent(receipt, 'RevokedOperator', { operator: newOperator, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(false); - }); - }); - - describe('default operators', function () { - it('can be re-authorized', async function () { - const receipt = await this.token.authorizeOperator(defaultOperatorA, { from: holder }); - expectEvent(receipt, 'AuthorizedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(defaultOperatorA, holder)).to.equal(true); - }); - - it('can be revoked', async function () { - const receipt = await this.token.revokeOperator(defaultOperatorA, { from: holder }); - expectEvent(receipt, 'RevokedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(defaultOperatorA, holder)).to.equal(false); - }); - - it('cannot be revoked for themselves', async function () { - await expectRevert( - this.token.revokeOperator(defaultOperatorA, { from: defaultOperatorA }), - 'ERC777: revoking self as operator', - ); - }); - - context('with revoked default operator', function () { - beforeEach(async function () { - await this.token.revokeOperator(defaultOperatorA, { from: holder }); - }); - - it('default operator is not revoked for other holders', async function () { - expect(await this.token.isOperatorFor(defaultOperatorA, anyone)).to.equal(true); - }); - - it('other default operators are not revoked', async function () { - expect(await this.token.isOperatorFor(defaultOperatorB, holder)).to.equal(true); - }); - - it('default operators list is not modified', async function () { - expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators); - }); - - it('revoked default operator can be re-authorized', async function () { - const receipt = await this.token.authorizeOperator(defaultOperatorA, { from: holder }); - expectEvent(receipt, 'AuthorizedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(defaultOperatorA, holder)).to.equal(true); - }); - }); - }); - }); - - describe('send and receive hooks', function () { - const amount = new BN('1'); - const operator = defaultOperatorA; - // sender and recipient are stored inside 'this', since in some tests their addresses are determined dynamically - - describe('tokensReceived', function () { - beforeEach(function () { - this.sender = holder; - }); - - context('with no ERC777TokensRecipient implementer', function () { - context('with contract recipient', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = this.tokensRecipientImplementer.address; - - // Note that tokensRecipientImplementer doesn't implement the recipient interface for the recipient - }); - - it('send reverts', async function () { - await expectRevert( - this.token.send(this.recipient, amount, data, { from: holder }), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - - it('operatorSend reverts', async function () { - await expectRevert( - this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - - it('mint (internal) reverts', async function () { - await expectRevert( - this.token.mintInternal(this.recipient, amount, data, operatorData, { from: operator }), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - - it('(ERC20) transfer succeeds', async function () { - await this.token.transfer(this.recipient, amount, { from: holder }); - }); - - it('(ERC20) transferFrom succeeds', async function () { - const approved = anyone; - await this.token.approve(approved, amount, { from: this.sender }); - await this.token.transferFrom(this.sender, this.recipient, amount, { from: approved }); - }); - }); - }); - - context('with ERC777TokensRecipient implementer', function () { - context('with contract as implementer for an externally owned account', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = anyone; - - await this.tokensRecipientImplementer.recipientFor(this.recipient); - - await this.erc1820.setInterfaceImplementer( - this.recipient, - web3.utils.soliditySha3('ERC777TokensRecipient'), this.tokensRecipientImplementer.address, - { from: this.recipient }, - ); - }); - - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); - }); - - context('with contract as implementer for another contract', function () { - beforeEach(async function () { - this.recipientContract = await ERC777SenderRecipientMock.new(); - this.recipient = this.recipientContract.address; - - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - await this.tokensRecipientImplementer.recipientFor(this.recipient); - await this.recipientContract.registerRecipient(this.tokensRecipientImplementer.address); - }); - - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); - }); - - context('with contract as implementer for itself', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = this.tokensRecipientImplementer.address; - - await this.tokensRecipientImplementer.recipientFor(this.recipient); - }); - - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); - }); - }); - }); - - describe('tokensToSend', function () { - beforeEach(function () { - this.recipient = anyone; - }); - - context('with a contract as implementer for an externally owned account', function () { - beforeEach(async function () { - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - this.sender = holder; - - await this.tokensSenderImplementer.senderFor(this.sender); - - await this.erc1820.setInterfaceImplementer( - this.sender, - web3.utils.soliditySha3('ERC777TokensSender'), this.tokensSenderImplementer.address, - { from: this.sender }, - ); - }); - - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); - }); - - context('with contract as implementer for another contract', function () { - beforeEach(async function () { - this.senderContract = await ERC777SenderRecipientMock.new(); - this.sender = this.senderContract.address; - - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - await this.tokensSenderImplementer.senderFor(this.sender); - await this.senderContract.registerSender(this.tokensSenderImplementer.address); - - // For the contract to be able to receive tokens (that it can later send), it must also implement the - // recipient interface. - - await this.senderContract.recipientFor(this.sender); - await this.token.send(this.sender, amount, data, { from: holder }); - }); - - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); - }); - - context('with a contract as implementer for itself', function () { - beforeEach(async function () { - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - this.sender = this.tokensSenderImplementer.address; - - await this.tokensSenderImplementer.senderFor(this.sender); - - // For the contract to be able to receive tokens (that it can later send), it must also implement the - // recipient interface. - - await this.tokensSenderImplementer.recipientFor(this.sender); - await this.token.send(this.sender, amount, data, { from: holder }); - }); - - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); - }); - }); - }); - }); - - context('with no default operators', function () { - beforeEach(async function () { - this.token = await ERC777.new(holder, initialSupply, name, symbol, []); - }); - - it('default operators list is empty', async function () { - expect(await this.token.defaultOperators()).to.deep.equal([]); - }); - }); - - describe('relative order of hooks', function () { - beforeEach(async function () { - await singletons.ERC1820Registry(registryFunder); - this.sender = await ERC777SenderRecipientMock.new(); - await this.sender.registerRecipient(this.sender.address); - await this.sender.registerSender(this.sender.address); - this.token = await ERC777.new(holder, initialSupply, name, symbol, []); - await this.token.send(this.sender.address, 1, '0x', { from: holder }); - }); - - it('send', async function () { - const { receipt } = await this.sender.send(this.token.address, anyone, 1, '0x'); - - const internalBeforeHook = receipt.logs.findIndex(l => l.event === 'BeforeTokenTransfer'); - expect(internalBeforeHook).to.be.gte(0); - const externalSendHook = receipt.logs.findIndex(l => l.event === 'TokensToSendCalled'); - expect(externalSendHook).to.be.gte(0); - - expect(externalSendHook).to.be.lt(internalBeforeHook); - }); - - it('burn', async function () { - const { receipt } = await this.sender.burn(this.token.address, 1, '0x'); - - const internalBeforeHook = receipt.logs.findIndex(l => l.event === 'BeforeTokenTransfer'); - expect(internalBeforeHook).to.be.gte(0); - const externalSendHook = receipt.logs.findIndex(l => l.event === 'TokensToSendCalled'); - expect(externalSendHook).to.be.gte(0); - - expect(externalSendHook).to.be.lt(internalBeforeHook); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/presets/ERC777PresetFixedSupply.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/presets/ERC777PresetFixedSupply.test.js deleted file mode 100644 index e6a842b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/ERC777/presets/ERC777PresetFixedSupply.test.js +++ /dev/null @@ -1,49 +0,0 @@ -const { BN, singletons } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC777PresetFixedSupply = artifacts.require('ERC777PresetFixedSupply'); - -contract('ERC777PresetFixedSupply', function (accounts) { - const [registryFunder, owner, defaultOperatorA, defaultOperatorB, anyone] = accounts; - - const initialSupply = new BN('10000'); - const name = 'ERC777Preset'; - const symbol = '777P'; - - const defaultOperators = [defaultOperatorA, defaultOperatorB]; - - before(async function () { - await singletons.ERC1820Registry(registryFunder); - }); - - beforeEach(async function () { - this.token = await ERC777PresetFixedSupply.new(name, symbol, defaultOperators, initialSupply, owner); - }); - - it('returns the name', async function () { - expect(await this.token.name()).to.equal(name); - }); - - it('returns the symbol', async function () { - expect(await this.token.symbol()).to.equal(symbol); - }); - - it('returns the default operators', async function () { - expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators); - }); - - it('default operators are operators for all accounts', async function () { - for (const operator of defaultOperators) { - expect(await this.token.isOperatorFor(operator, anyone)).to.equal(true); - } - }); - - it('returns the total supply equal to initial supply', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - }); - - it('returns the balance of owner equal to initial supply', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialSupply); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/common/ERC2981.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/common/ERC2981.behavior.js deleted file mode 100644 index 2fd2747..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/token/common/ERC2981.behavior.js +++ /dev/null @@ -1,160 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS } = constants; - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -function shouldBehaveLikeERC2981 () { - const royaltyFraction = new BN('10'); - - shouldSupportInterfaces(['ERC2981']); - - describe('default royalty', function () { - beforeEach(async function () { - await this.token.setDefaultRoyalty(this.account1, royaltyFraction); - }); - - it('checks royalty is set', async function () { - const royalty = new BN((this.salePrice * royaltyFraction) / 10000); - - const initInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - expect(initInfo[0]).to.be.equal(this.account1); - expect(initInfo[1]).to.be.bignumber.equal(royalty); - }); - - it('updates royalty amount', async function () { - const newPercentage = new BN('25'); - - // Updated royalty check - await this.token.setDefaultRoyalty(this.account1, newPercentage); - const royalty = new BN((this.salePrice * newPercentage) / 10000); - const newInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - expect(newInfo[0]).to.be.equal(this.account1); - expect(newInfo[1]).to.be.bignumber.equal(royalty); - }); - - it('holds same royalty value for different tokens', async function () { - const newPercentage = new BN('20'); - await this.token.setDefaultRoyalty(this.account1, newPercentage); - - const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - - expect(token1Info[1]).to.be.bignumber.equal(token2Info[1]); - }); - - it('Remove royalty information', async function () { - const newValue = new BN('0'); - await this.token.deleteDefaultRoyalty(); - - const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - // Test royalty info is still persistent across all tokens - expect(token1Info[0]).to.be.bignumber.equal(token2Info[0]); - expect(token1Info[1]).to.be.bignumber.equal(token2Info[1]); - // Test information was deleted - expect(token1Info[0]).to.be.equal(ZERO_ADDRESS); - expect(token1Info[1]).to.be.bignumber.equal(newValue); - }); - - it('reverts if invalid parameters', async function () { - await expectRevert( - this.token.setDefaultRoyalty(ZERO_ADDRESS, royaltyFraction), - 'ERC2981: invalid receiver', - ); - - await expectRevert( - this.token.setDefaultRoyalty(this.account1, new BN('11000')), - 'ERC2981: royalty fee will exceed salePrice', - ); - }); - }); - - describe('token based royalty', function () { - beforeEach(async function () { - await this.token.setTokenRoyalty(this.tokenId1, this.account1, royaltyFraction); - }); - - it('updates royalty amount', async function () { - const newPercentage = new BN('25'); - let royalty = new BN((this.salePrice * royaltyFraction) / 10000); - // Initial royalty check - const initInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - expect(initInfo[0]).to.be.equal(this.account1); - expect(initInfo[1]).to.be.bignumber.equal(royalty); - - // Updated royalty check - await this.token.setTokenRoyalty(this.tokenId1, this.account1, newPercentage); - royalty = new BN((this.salePrice * newPercentage) / 10000); - const newInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - expect(newInfo[0]).to.be.equal(this.account1); - expect(newInfo[1]).to.be.bignumber.equal(royalty); - }); - - it('holds different values for different tokens', async function () { - const newPercentage = new BN('20'); - await this.token.setTokenRoyalty(this.tokenId2, this.account1, newPercentage); - - const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - - // must be different even at the same this.salePrice - expect(token1Info[1]).to.not.be.equal(token2Info.royaltyFraction); - }); - - it('reverts if invalid parameters', async function () { - await expectRevert( - this.token.setTokenRoyalty(this.tokenId1, ZERO_ADDRESS, royaltyFraction), - 'ERC2981: Invalid parameters', - ); - - await expectRevert( - this.token.setTokenRoyalty(this.tokenId1, this.account1, new BN('11000')), - 'ERC2981: royalty fee will exceed salePrice', - ); - }); - - it('can reset token after setting royalty', async function () { - const newPercentage = new BN('30'); - const royalty = new BN((this.salePrice * newPercentage) / 10000); - await this.token.setTokenRoyalty(this.tokenId1, this.account2, newPercentage); - - const tokenInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - // Tokens must have own information - expect(tokenInfo[1]).to.be.bignumber.equal(royalty); - expect(tokenInfo[0]).to.be.equal(this.account2); - - await this.token.setTokenRoyalty(this.tokenId2, this.account1, new BN('0')); - const result = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - // Token must not share default information - expect(result[0]).to.be.equal(this.account1); - expect(result[1]).to.be.bignumber.equal(new BN('0')); - }); - - it('can hold default and token royalty information', async function () { - const newPercentage = new BN('30'); - const royalty = new BN((this.salePrice * newPercentage) / 10000); - - await this.token.setTokenRoyalty(this.tokenId2, this.account2, newPercentage); - - const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - // Tokens must not have same values - expect(token1Info[1]).to.not.be.bignumber.equal(token2Info[1]); - expect(token1Info[0]).to.not.be.equal(token2Info[0]); - - // Updated token must have new values - expect(token2Info[0]).to.be.equal(this.account2); - expect(token2Info[1]).to.be.bignumber.equal(royalty); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC2981, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Address.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Address.test.js deleted file mode 100644 index 69405f2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Address.test.js +++ /dev/null @@ -1,382 +0,0 @@ -const { balance, ether, expectRevert, send, expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const AddressImpl = artifacts.require('AddressImpl'); -const EtherReceiver = artifacts.require('EtherReceiverMock'); -const CallReceiverMock = artifacts.require('CallReceiverMock'); - -contract('Address', function (accounts) { - const [ recipient, other ] = accounts; - - beforeEach(async function () { - this.mock = await AddressImpl.new(); - }); - - describe('isContract', function () { - it('returns false for account address', async function () { - expect(await this.mock.isContract(other)).to.equal(false); - }); - - it('returns true for contract address', async function () { - const contract = await AddressImpl.new(); - expect(await this.mock.isContract(contract.address)).to.equal(true); - }); - }); - - describe('sendValue', function () { - beforeEach(async function () { - this.recipientTracker = await balance.tracker(recipient); - }); - - context('when sender contract has no funds', function () { - it('sends 0 wei', async function () { - await this.mock.sendValue(other, 0); - - expect(await this.recipientTracker.delta()).to.be.bignumber.equal('0'); - }); - - it('reverts when sending non-zero amounts', async function () { - await expectRevert(this.mock.sendValue(other, 1), 'Address: insufficient balance'); - }); - }); - - context('when sender contract has funds', function () { - const funds = ether('1'); - beforeEach(async function () { - await send.ether(other, this.mock.address, funds); - }); - - it('sends 0 wei', async function () { - await this.mock.sendValue(recipient, 0); - expect(await this.recipientTracker.delta()).to.be.bignumber.equal('0'); - }); - - it('sends non-zero amounts', async function () { - await this.mock.sendValue(recipient, funds.subn(1)); - expect(await this.recipientTracker.delta()).to.be.bignumber.equal(funds.subn(1)); - }); - - it('sends the whole balance', async function () { - await this.mock.sendValue(recipient, funds); - expect(await this.recipientTracker.delta()).to.be.bignumber.equal(funds); - expect(await balance.current(this.mock.address)).to.be.bignumber.equal('0'); - }); - - it('reverts when sending more than the balance', async function () { - await expectRevert(this.mock.sendValue(recipient, funds.addn(1)), 'Address: insufficient balance'); - }); - - context('with contract recipient', function () { - beforeEach(async function () { - this.contractRecipient = await EtherReceiver.new(); - }); - - it('sends funds', async function () { - const tracker = await balance.tracker(this.contractRecipient.address); - - await this.contractRecipient.setAcceptEther(true); - await this.mock.sendValue(this.contractRecipient.address, funds); - expect(await tracker.delta()).to.be.bignumber.equal(funds); - }); - - it('reverts on recipient revert', async function () { - await this.contractRecipient.setAcceptEther(false); - await expectRevert( - this.mock.sendValue(this.contractRecipient.address, funds), - 'Address: unable to send value, recipient may have reverted', - ); - }); - }); - }); - }); - - describe('functionCall', function () { - beforeEach(async function () { - this.contractRecipient = await CallReceiverMock.new(); - }); - - context('with valid contract receiver', function () { - it('calls the requested function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - const receipt = await this.mock.functionCall(this.contractRecipient.address, abiEncodedCall); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); - }); - - it('reverts when the called function reverts with no reason', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionRevertsNoReason', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), - 'Address: low-level call failed', - ); - }); - - it('reverts when the called function reverts, bubbling up the revert reason', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionRevertsReason', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), - 'CallReceiverMock: reverting', - ); - }); - - it('reverts when the called function runs out of gas', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionOutOfGas', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall, { gas: '120000' }), - 'Address: low-level call failed', - ); - }); - - it('reverts when the called function throws', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionThrows', - type: 'function', - inputs: [], - }, []); - - await expectRevert.unspecified( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), - ); - }); - - it('reverts when function does not exist', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionDoesNotExist', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), - 'Address: low-level call failed', - ); - }); - }); - - context('with non-contract receiver', function () { - it('reverts when address is not a contract', async function () { - const [ recipient ] = accounts; - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - await expectRevert(this.mock.functionCall(recipient, abiEncodedCall), 'Address: call to non-contract'); - }); - }); - }); - - describe('functionCallWithValue', function () { - beforeEach(async function () { - this.contractRecipient = await CallReceiverMock.new(); - }); - - context('with zero value', function () { - it('calls the requested function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - const receipt = await this.mock.functionCallWithValue(this.contractRecipient.address, abiEncodedCall, 0); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); - }); - }); - - context('with non-zero value', function () { - const amount = ether('1.2'); - - it('reverts if insufficient sender balance', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCallWithValue(this.contractRecipient.address, abiEncodedCall, amount), - 'Address: insufficient balance for call', - ); - }); - - it('calls the requested function with existing value', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - const tracker = await balance.tracker(this.contractRecipient.address); - - await send.ether(other, this.mock.address, amount); - const receipt = await this.mock.functionCallWithValue(this.contractRecipient.address, abiEncodedCall, amount); - - expect(await tracker.delta()).to.be.bignumber.equal(amount); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); - }); - - it('calls the requested function with transaction funds', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - const tracker = await balance.tracker(this.contractRecipient.address); - - expect(await balance.current(this.mock.address)).to.be.bignumber.equal('0'); - const receipt = await this.mock.functionCallWithValue( - this.contractRecipient.address, abiEncodedCall, amount, { from: other, value: amount }, - ); - - expect(await tracker.delta()).to.be.bignumber.equal(amount); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); - }); - - it('reverts when calling non-payable functions', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionNonPayable', - type: 'function', - inputs: [], - }, []); - - await send.ether(other, this.mock.address, amount); - await expectRevert( - this.mock.functionCallWithValue(this.contractRecipient.address, abiEncodedCall, amount), - 'Address: low-level call with value failed', - ); - }); - }); - }); - - describe('functionStaticCall', function () { - beforeEach(async function () { - this.contractRecipient = await CallReceiverMock.new(); - }); - - it('calls the requested function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockStaticFunction', - type: 'function', - inputs: [], - }, []); - - const receipt = await this.mock.functionStaticCall(this.contractRecipient.address, abiEncodedCall); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - }); - - it('reverts on a non-static function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionStaticCall(this.contractRecipient.address, abiEncodedCall), - 'Address: low-level static call failed', - ); - }); - - it('bubbles up revert reason', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionRevertsReason', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionStaticCall(this.contractRecipient.address, abiEncodedCall), - 'CallReceiverMock: reverting', - ); - }); - - it('reverts when address is not a contract', async function () { - const [ recipient ] = accounts; - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - await expectRevert( - this.mock.functionStaticCall(recipient, abiEncodedCall), - 'Address: call to non-contract', - ); - }); - }); - - describe.skip('functionDelegateCall', function () { - beforeEach(async function () { - this.contractRecipient = await CallReceiverMock.new(); - }); - - it('delegate calls the requested function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionWritesStorage', - type: 'function', - inputs: [], - }, []); - - const receipt = await this.mock.functionDelegateCall(this.contractRecipient.address, abiEncodedCall); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - - expect(await this.mock.sharedAnswer()).to.equal('42'); - }); - - it('bubbles up revert reason', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionRevertsReason', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionDelegateCall(this.contractRecipient.address, abiEncodedCall), - 'CallReceiverMock: reverting', - ); - }); - - it('reverts when address is not a contract', async function () { - const [ recipient ] = accounts; - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - await expectRevert( - this.mock.functionDelegateCall(recipient, abiEncodedCall), - 'Address: call to non-contract', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Arrays.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Arrays.test.js deleted file mode 100644 index 8c287cc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Arrays.test.js +++ /dev/null @@ -1,105 +0,0 @@ -require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const AddressArraysMock = artifacts.require('AddressArraysMock'); -const Bytes32ArraysMock = artifacts.require('Bytes32ArraysMock'); -const Uint256ArraysMock = artifacts.require('Uint256ArraysMock'); - -contract('Arrays', function (accounts) { - describe('findUpperBound', function () { - context('Even number of elements', function () { - const EVEN_ELEMENTS_ARRAY = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; - - beforeEach(async function () { - this.arrays = await Uint256ArraysMock.new(EVEN_ELEMENTS_ARRAY); - }); - - it('returns correct index for the basic case', async function () { - expect(await this.arrays.findUpperBound(16)).to.be.bignumber.equal('5'); - }); - - it('returns 0 for the first element', async function () { - expect(await this.arrays.findUpperBound(11)).to.be.bignumber.equal('0'); - }); - - it('returns index of the last element', async function () { - expect(await this.arrays.findUpperBound(20)).to.be.bignumber.equal('9'); - }); - - it('returns first index after last element if searched value is over the upper boundary', async function () { - expect(await this.arrays.findUpperBound(32)).to.be.bignumber.equal('10'); - }); - - it('returns 0 for the element under the lower boundary', async function () { - expect(await this.arrays.findUpperBound(2)).to.be.bignumber.equal('0'); - }); - }); - - context('Odd number of elements', function () { - const ODD_ELEMENTS_ARRAY = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]; - - beforeEach(async function () { - this.arrays = await Uint256ArraysMock.new(ODD_ELEMENTS_ARRAY); - }); - - it('returns correct index for the basic case', async function () { - expect(await this.arrays.findUpperBound(16)).to.be.bignumber.equal('5'); - }); - - it('returns 0 for the first element', async function () { - expect(await this.arrays.findUpperBound(11)).to.be.bignumber.equal('0'); - }); - - it('returns index of the last element', async function () { - expect(await this.arrays.findUpperBound(21)).to.be.bignumber.equal('10'); - }); - - it('returns first index after last element if searched value is over the upper boundary', async function () { - expect(await this.arrays.findUpperBound(32)).to.be.bignumber.equal('11'); - }); - - it('returns 0 for the element under the lower boundary', async function () { - expect(await this.arrays.findUpperBound(2)).to.be.bignumber.equal('0'); - }); - }); - - context('Array with gap', function () { - const WITH_GAP_ARRAY = [11, 12, 13, 14, 15, 20, 21, 22, 23, 24]; - - beforeEach(async function () { - this.arrays = await Uint256ArraysMock.new(WITH_GAP_ARRAY); - }); - - it('returns index of first element in next filled range', async function () { - expect(await this.arrays.findUpperBound(17)).to.be.bignumber.equal('5'); - }); - }); - - context('Empty array', function () { - beforeEach(async function () { - this.arrays = await Uint256ArraysMock.new([]); - }); - - it('always returns 0 for empty array', async function () { - expect(await this.arrays.findUpperBound(10)).to.be.bignumber.equal('0'); - }); - }); - }); - - describe('unsafeAccess', function () { - for (const { type, artifact, elements } of [ - { type: 'address', artifact: AddressArraysMock, elements: Array(10).fill().map(() => web3.utils.randomHex(20)) }, - { type: 'bytes32', artifact: Bytes32ArraysMock, elements: Array(10).fill().map(() => web3.utils.randomHex(32)) }, - { type: 'uint256', artifact: Uint256ArraysMock, elements: Array(10).fill().map(() => web3.utils.randomHex(32)) }, - ]) { - it(type, async function () { - const contract = await artifact.new(elements); - - for (const i in elements) { - expect(await contract.unsafeAccess(i)).to.be.bignumber.equal(elements[i]); - } - }); - } - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Base64.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Base64.test.js deleted file mode 100644 index b6ee657..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Base64.test.js +++ /dev/null @@ -1,33 +0,0 @@ -const { expect } = require('chai'); - -const Base64Mock = artifacts.require('Base64Mock'); - -contract('Strings', function () { - beforeEach(async function () { - this.base64 = await Base64Mock.new(); - }); - - describe('from bytes - base64', function () { - it('converts to base64 encoded string with double padding', async function () { - const TEST_MESSAGE = 'test'; - const input = web3.utils.asciiToHex(TEST_MESSAGE); - expect(await this.base64.encode(input)).to.equal('dGVzdA=='); - }); - - it('converts to base64 encoded string with single padding', async function () { - const TEST_MESSAGE = 'test1'; - const input = web3.utils.asciiToHex(TEST_MESSAGE); - expect(await this.base64.encode(input)).to.equal('dGVzdDE='); - }); - - it('converts to base64 encoded string without padding', async function () { - const TEST_MESSAGE = 'test12'; - const input = web3.utils.asciiToHex(TEST_MESSAGE); - expect(await this.base64.encode(input)).to.equal('dGVzdDEy'); - }); - - it('empty bytes', async function () { - expect(await this.base64.encode([])).to.equal(''); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Checkpoints.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Checkpoints.test.js deleted file mode 100644 index 9bdb4ae..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Checkpoints.test.js +++ /dev/null @@ -1,189 +0,0 @@ -const { expectRevert, time } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const { batchInBlock } = require('../helpers/txpool'); - -const CheckpointsMock = artifacts.require('CheckpointsMock'); - -const first = (array) => array.length ? array[0] : undefined; -const last = (array) => array.length ? array[array.length - 1] : undefined; - -contract('Checkpoints', function (accounts) { - describe('History checkpoints', function () { - beforeEach(async function () { - this.checkpoint = await CheckpointsMock.new(); - }); - - describe('without checkpoints', function () { - it('returns zero as latest value', async function () { - expect(await this.checkpoint.latest()).to.be.bignumber.equal('0'); - - const ckpt = await this.checkpoint.latestCheckpoint(); - expect(ckpt[0]).to.be.equal(false); - expect(ckpt[1]).to.be.bignumber.equal('0'); - expect(ckpt[2]).to.be.bignumber.equal('0'); - }); - - it('returns zero as past value', async function () { - await time.advanceBlock(); - expect(await this.checkpoint.getAtBlock(await web3.eth.getBlockNumber() - 1)) - .to.be.bignumber.equal('0'); - expect(await this.checkpoint.getAtProbablyRecentBlock(await web3.eth.getBlockNumber() - 1)) - .to.be.bignumber.equal('0'); - }); - }); - - describe('with checkpoints', function () { - beforeEach('pushing checkpoints', async function () { - this.tx1 = await this.checkpoint.push(1); - this.tx2 = await this.checkpoint.push(2); - await time.advanceBlock(); - this.tx3 = await this.checkpoint.push(3); - await time.advanceBlock(); - await time.advanceBlock(); - }); - - it('returns latest value', async function () { - expect(await this.checkpoint.latest()).to.be.bignumber.equal('3'); - - const ckpt = await this.checkpoint.latestCheckpoint(); - expect(ckpt[0]).to.be.equal(true); - expect(ckpt[1]).to.be.bignumber.equal(web3.utils.toBN(this.tx3.receipt.blockNumber)); - expect(ckpt[2]).to.be.bignumber.equal(web3.utils.toBN('3')); - }); - - for (const fn of [ 'getAtBlock(uint256)', 'getAtProbablyRecentBlock(uint256)' ]) { - describe(`lookup: ${fn}`, function () { - it('returns past values', async function () { - expect(await this.checkpoint.methods[fn](this.tx1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.checkpoint.methods[fn](this.tx1.receipt.blockNumber)).to.be.bignumber.equal('1'); - expect(await this.checkpoint.methods[fn](this.tx2.receipt.blockNumber)).to.be.bignumber.equal('2'); - // Block with no new checkpoints - expect(await this.checkpoint.methods[fn](this.tx2.receipt.blockNumber + 1)).to.be.bignumber.equal('2'); - expect(await this.checkpoint.methods[fn](this.tx3.receipt.blockNumber)).to.be.bignumber.equal('3'); - expect(await this.checkpoint.methods[fn](this.tx3.receipt.blockNumber + 1)).to.be.bignumber.equal('3'); - }); - it('reverts if block number >= current block', async function () { - await expectRevert( - this.checkpoint.methods[fn](await web3.eth.getBlockNumber()), - 'Checkpoints: block not yet mined', - ); - - await expectRevert( - this.checkpoint.methods[fn](await web3.eth.getBlockNumber() + 1), - 'Checkpoints: block not yet mined', - ); - }); - }); - } - - it('multiple checkpoints in the same block', async function () { - const lengthBefore = await this.checkpoint.length(); - - await batchInBlock([ - () => this.checkpoint.push(8, { gas: 100000 }), - () => this.checkpoint.push(9, { gas: 100000 }), - () => this.checkpoint.push(10, { gas: 100000 }), - ]); - - expect(await this.checkpoint.length()).to.be.bignumber.equal(lengthBefore.addn(1)); - expect(await this.checkpoint.latest()).to.be.bignumber.equal('10'); - }); - - it('more than 5 checkpoints', async function () { - for (let i = 4; i <= 6; i++) { - await this.checkpoint.push(i); - } - expect(await this.checkpoint.length()).to.be.bignumber.equal('6'); - const block = await web3.eth.getBlockNumber(); - // recent - expect(await this.checkpoint.getAtProbablyRecentBlock(block - 1)).to.be.bignumber.equal('5'); - // non-recent - expect(await this.checkpoint.getAtProbablyRecentBlock(block - 9)).to.be.bignumber.equal('0'); - }); - }); - }); - - for (const length of [160, 224]) { - describe(`Trace${length}`, function () { - beforeEach(async function () { - this.contract = await artifacts.require(`Checkpoints${length}Mock`).new(); - }); - - describe('without checkpoints', function () { - it('returns zero as latest value', async function () { - expect(await this.contract.latest()).to.be.bignumber.equal('0'); - - const ckpt = await this.contract.latestCheckpoint(); - expect(ckpt[0]).to.be.equal(false); - expect(ckpt[1]).to.be.bignumber.equal('0'); - expect(ckpt[2]).to.be.bignumber.equal('0'); - }); - - it('lookup returns 0', async function () { - expect(await this.contract.lowerLookup(0)).to.be.bignumber.equal('0'); - expect(await this.contract.upperLookup(0)).to.be.bignumber.equal('0'); - }); - }); - - describe('with checkpoints', function () { - beforeEach('pushing checkpoints', async function () { - this.checkpoints = [ - { key: '2', value: '17' }, - { key: '3', value: '42' }, - { key: '5', value: '101' }, - { key: '7', value: '23' }, - { key: '11', value: '99' }, - ]; - for (const { key, value } of this.checkpoints) { - await this.contract.push(key, value); - } - }); - - it('returns latest value', async function () { - expect(await this.contract.latest()).to.be.bignumber.equal(last(this.checkpoints).value); - - const ckpt = await this.contract.latestCheckpoint(); - expect(ckpt[0]).to.be.equal(true); - expect(ckpt[1]).to.be.bignumber.equal(last(this.checkpoints).key); - expect(ckpt[2]).to.be.bignumber.equal(last(this.checkpoints).value); - }); - - it('cannot push values in the past', async function () { - await expectRevert(this.contract.push(last(this.checkpoints).key - 1, '0'), 'Checkpoint: invalid key'); - }); - - it('can update last value', async function () { - const newValue = '42'; - - // check length before the update - expect(await this.contract.length()).to.be.bignumber.equal(this.checkpoints.length.toString()); - - // update last key - await this.contract.push(last(this.checkpoints).key, newValue); - expect(await this.contract.latest()).to.be.bignumber.equal(newValue); - - // check that length did not change - expect(await this.contract.length()).to.be.bignumber.equal(this.checkpoints.length.toString()); - }); - - it('lower lookup', async function () { - for (let i = 0; i < 14; ++i) { - const value = first(this.checkpoints.filter(x => i <= x.key))?.value || '0'; - - expect(await this.contract.lowerLookup(i)).to.be.bignumber.equal(value); - } - }); - - it('upper lookup', async function () { - for (let i = 0; i < 14; ++i) { - const value = last(this.checkpoints.filter(x => i >= x.key))?.value || '0'; - - expect(await this.contract.upperLookup(i)).to.be.bignumber.equal(value); - } - }); - }); - }); - } -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Context.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Context.behavior.js deleted file mode 100644 index 8728e10..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Context.behavior.js +++ /dev/null @@ -1,42 +0,0 @@ -const { BN, expectEvent } = require('@openzeppelin/test-helpers'); - -const ContextMock = artifacts.require('ContextMock'); - -function shouldBehaveLikeRegularContext (sender) { - describe('msgSender', function () { - it('returns the transaction sender when called from an EOA', async function () { - const receipt = await this.context.msgSender({ from: sender }); - expectEvent(receipt, 'Sender', { sender }); - }); - - it('returns the transaction sender when from another contract', async function () { - const { tx } = await this.caller.callSender(this.context.address, { from: sender }); - await expectEvent.inTransaction(tx, ContextMock, 'Sender', { sender: this.caller.address }); - }); - }); - - describe('msgData', function () { - const integerValue = new BN('42'); - const stringValue = 'OpenZeppelin'; - - let callData; - - beforeEach(async function () { - callData = this.context.contract.methods.msgData(integerValue.toString(), stringValue).encodeABI(); - }); - - it('returns the transaction data when called from an EOA', async function () { - const receipt = await this.context.msgData(integerValue, stringValue); - expectEvent(receipt, 'Data', { data: callData, integerValue, stringValue }); - }); - - it('returns the transaction sender when from another contract', async function () { - const { tx } = await this.caller.callData(this.context.address, integerValue, stringValue); - await expectEvent.inTransaction(tx, ContextMock, 'Data', { data: callData, integerValue, stringValue }); - }); - }); -} - -module.exports = { - shouldBehaveLikeRegularContext, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Context.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Context.test.js deleted file mode 100644 index 709aa87..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Context.test.js +++ /dev/null @@ -1,17 +0,0 @@ -require('@openzeppelin/test-helpers'); - -const ContextMock = artifacts.require('ContextMock'); -const ContextMockCaller = artifacts.require('ContextMockCaller'); - -const { shouldBehaveLikeRegularContext } = require('./Context.behavior'); - -contract('Context', function (accounts) { - const [ sender ] = accounts; - - beforeEach(async function () { - this.context = await ContextMock.new(); - this.caller = await ContextMockCaller.new(); - }); - - shouldBehaveLikeRegularContext(sender); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Counters.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Counters.test.js deleted file mode 100644 index 04be4c0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Counters.test.js +++ /dev/null @@ -1,84 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const CountersImpl = artifacts.require('CountersImpl'); - -contract('Counters', function (accounts) { - beforeEach(async function () { - this.counter = await CountersImpl.new(); - }); - - it('starts at zero', async function () { - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - - describe('increment', function () { - context('starting from 0', function () { - it('increments the current value by one', async function () { - await this.counter.increment(); - expect(await this.counter.current()).to.be.bignumber.equal('1'); - }); - - it('can be called multiple times', async function () { - await this.counter.increment(); - await this.counter.increment(); - await this.counter.increment(); - - expect(await this.counter.current()).to.be.bignumber.equal('3'); - }); - }); - }); - - describe('decrement', function () { - beforeEach(async function () { - await this.counter.increment(); - expect(await this.counter.current()).to.be.bignumber.equal('1'); - }); - context('starting from 1', function () { - it('decrements the current value by one', async function () { - await this.counter.decrement(); - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - - it('reverts if the current value is 0', async function () { - await this.counter.decrement(); - await expectRevert(this.counter.decrement(), 'Counter: decrement overflow'); - }); - }); - context('after incremented to 3', function () { - it('can be called multiple times', async function () { - await this.counter.increment(); - await this.counter.increment(); - - expect(await this.counter.current()).to.be.bignumber.equal('3'); - - await this.counter.decrement(); - await this.counter.decrement(); - await this.counter.decrement(); - - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - }); - }); - - describe('reset', function () { - context('null counter', function () { - it('does not throw', async function () { - await this.counter.reset(); - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - }); - - context('non null counter', function () { - beforeEach(async function () { - await this.counter.increment(); - expect(await this.counter.current()).to.be.bignumber.equal('1'); - }); - it('reset to 0', async function () { - await this.counter.reset(); - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Create2.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Create2.test.js deleted file mode 100644 index b57e063..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Create2.test.js +++ /dev/null @@ -1,92 +0,0 @@ -const { balance, BN, ether, expectRevert, send } = require('@openzeppelin/test-helpers'); -const { computeCreate2Address } = require('../helpers/create2'); -const { expect } = require('chai'); - -const Create2Impl = artifacts.require('Create2Impl'); -const ERC20Mock = artifacts.require('ERC20Mock'); -const ERC1820Implementer = artifacts.require('ERC1820Implementer'); - -contract('Create2', function (accounts) { - const [deployerAccount] = accounts; - - const salt = 'salt message'; - const saltHex = web3.utils.soliditySha3(salt); - - const encodedParams = web3.eth.abi.encodeParameters( - ['string', 'string', 'address', 'uint256'], - ['MyToken', 'MTKN', deployerAccount, 100], - ).slice(2); - - const constructorByteCode = `${ERC20Mock.bytecode}${encodedParams}`; - - beforeEach(async function () { - this.factory = await Create2Impl.new(); - }); - describe('computeAddress', function () { - it('computes the correct contract address', async function () { - const onChainComputed = await this.factory - .computeAddress(saltHex, web3.utils.keccak256(constructorByteCode)); - const offChainComputed = - computeCreate2Address(saltHex, constructorByteCode, this.factory.address); - expect(onChainComputed).to.equal(offChainComputed); - }); - - it('computes the correct contract address with deployer', async function () { - const onChainComputed = await this.factory - .computeAddressWithDeployer(saltHex, web3.utils.keccak256(constructorByteCode), deployerAccount); - const offChainComputed = - computeCreate2Address(saltHex, constructorByteCode, deployerAccount); - expect(onChainComputed).to.equal(offChainComputed); - }); - }); - - describe('deploy', function () { - it('deploys a ERC1820Implementer from inline assembly code', async function () { - const offChainComputed = - computeCreate2Address(saltHex, ERC1820Implementer.bytecode, this.factory.address); - await this.factory.deployERC1820Implementer(0, saltHex); - expect(ERC1820Implementer.bytecode).to.include((await web3.eth.getCode(offChainComputed)).slice(2)); - }); - - it('deploys a ERC20Mock with correct balances', async function () { - const offChainComputed = computeCreate2Address(saltHex, constructorByteCode, this.factory.address); - - await this.factory.deploy(0, saltHex, constructorByteCode); - - const erc20 = await ERC20Mock.at(offChainComputed); - expect(await erc20.balanceOf(deployerAccount)).to.be.bignumber.equal(new BN(100)); - }); - - it('deploys a contract with funds deposited in the factory', async function () { - const deposit = ether('2'); - await send.ether(deployerAccount, this.factory.address, deposit); - expect(await balance.current(this.factory.address)).to.be.bignumber.equal(deposit); - - const onChainComputed = await this.factory - .computeAddressWithDeployer(saltHex, web3.utils.keccak256(constructorByteCode), this.factory.address); - - await this.factory.deploy(deposit, saltHex, constructorByteCode); - expect(await balance.current(onChainComputed)).to.be.bignumber.equal(deposit); - }); - - it('fails deploying a contract in an existent address', async function () { - await this.factory.deploy(0, saltHex, constructorByteCode, { from: deployerAccount }); - await expectRevert( - this.factory.deploy(0, saltHex, constructorByteCode, { from: deployerAccount }), 'Create2: Failed on deploy', - ); - }); - - it('fails deploying a contract if the bytecode length is zero', async function () { - await expectRevert( - this.factory.deploy(0, saltHex, '0x', { from: deployerAccount }), 'Create2: bytecode length is zero', - ); - }); - - it('fails deploying a contract if factory contract does not have sufficient balance', async function () { - await expectRevert( - this.factory.deploy(1, saltHex, constructorByteCode, { from: deployerAccount }), - 'Create2: insufficient balance', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Multicall.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Multicall.test.js deleted file mode 100644 index 61c2634..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Multicall.test.js +++ /dev/null @@ -1,57 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); -const MulticallTokenMock = artifacts.require('MulticallTokenMock'); - -contract('MulticallToken', function (accounts) { - const [deployer, alice, bob] = accounts; - const amount = 12000; - - beforeEach(async function () { - this.multicallToken = await MulticallTokenMock.new(new BN(amount), { from: deployer }); - }); - - it('batches function calls', async function () { - expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0')); - expect(await this.multicallToken.balanceOf(bob)).to.be.bignumber.equal(new BN('0')); - - await this.multicallToken.multicall([ - this.multicallToken.contract.methods.transfer(alice, amount / 2).encodeABI(), - this.multicallToken.contract.methods.transfer(bob, amount / 3).encodeABI(), - ], { from: deployer }); - - expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN(amount / 2)); - expect(await this.multicallToken.balanceOf(bob)).to.be.bignumber.equal(new BN(amount / 3)); - }); - - it('returns an array with the result of each call', async function () { - const MulticallTest = artifacts.require('MulticallTest'); - const multicallTest = await MulticallTest.new({ from: deployer }); - await this.multicallToken.transfer(multicallTest.address, amount, { from: deployer }); - expect(await this.multicallToken.balanceOf(multicallTest.address)).to.be.bignumber.equal(new BN(amount)); - - const recipients = [alice, bob]; - const amounts = [amount / 2, amount / 3].map(n => new BN(n)); - - await multicallTest.checkReturnValues(this.multicallToken.address, recipients, amounts); - }); - - it('reverts previous calls', async function () { - expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0')); - - const call = this.multicallToken.multicall([ - this.multicallToken.contract.methods.transfer(alice, amount).encodeABI(), - this.multicallToken.contract.methods.transfer(bob, amount).encodeABI(), - ], { from: deployer }); - - await expectRevert(call, 'ERC20: transfer amount exceeds balance'); - expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0')); - }); - - it('bubbles up revert reasons', async function () { - const call = this.multicallToken.multicall([ - this.multicallToken.contract.methods.transfer(alice, amount).encodeABI(), - this.multicallToken.contract.methods.transfer(bob, amount).encodeABI(), - ], { from: deployer }); - - await expectRevert(call, 'ERC20: transfer amount exceeds balance'); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/StorageSlot.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/StorageSlot.test.js deleted file mode 100644 index 9d42887..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/StorageSlot.test.js +++ /dev/null @@ -1,110 +0,0 @@ -const { constants, BN } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const StorageSlotMock = artifacts.require('StorageSlotMock'); - -const slot = web3.utils.keccak256('some.storage.slot'); -const otherSlot = web3.utils.keccak256('some.other.storage.slot'); - -contract('StorageSlot', function (accounts) { - beforeEach(async function () { - this.store = await StorageSlotMock.new(); - }); - - describe('boolean storage slot', function () { - beforeEach(async function () { - this.value = true; - }); - - it('set', async function () { - await this.store.setBoolean(slot, this.value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.store.setBoolean(slot, this.value); - }); - - it('from right slot', async function () { - expect(await this.store.getBoolean(slot)).to.be.equal(this.value); - }); - - it('from other slot', async function () { - expect(await this.store.getBoolean(otherSlot)).to.be.equal(false); - }); - }); - }); - - describe('address storage slot', function () { - beforeEach(async function () { - this.value = accounts[1]; - }); - - it('set', async function () { - await this.store.setAddress(slot, this.value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.store.setAddress(slot, this.value); - }); - - it('from right slot', async function () { - expect(await this.store.getAddress(slot)).to.be.equal(this.value); - }); - - it('from other slot', async function () { - expect(await this.store.getAddress(otherSlot)).to.be.equal(constants.ZERO_ADDRESS); - }); - }); - }); - - describe('bytes32 storage slot', function () { - beforeEach(async function () { - this.value = web3.utils.keccak256('some byte32 value'); - }); - - it('set', async function () { - await this.store.setBytes32(slot, this.value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.store.setBytes32(slot, this.value); - }); - - it('from right slot', async function () { - expect(await this.store.getBytes32(slot)).to.be.equal(this.value); - }); - - it('from other slot', async function () { - expect(await this.store.getBytes32(otherSlot)).to.be.equal(constants.ZERO_BYTES32); - }); - }); - }); - - describe('uint256 storage slot', function () { - beforeEach(async function () { - this.value = new BN(1742); - }); - - it('set', async function () { - await this.store.setUint256(slot, this.value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.store.setUint256(slot, this.value); - }); - - it('from right slot', async function () { - expect(await this.store.getUint256(slot)).to.be.bignumber.equal(this.value); - }); - - it('from other slot', async function () { - expect(await this.store.getUint256(otherSlot)).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Strings.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Strings.test.js deleted file mode 100644 index 7abc859..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/Strings.test.js +++ /dev/null @@ -1,86 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const StringsMock = artifacts.require('StringsMock'); - -contract('Strings', function (accounts) { - before(async function () { - this.strings = await StringsMock.new(); - }); - - describe('toString', function () { - for (const [ key, value ] of Object.entries([ - '0', - '7', - '10', - '99', - '100', - '101', - '123', - '4132', - '12345', - '1234567', - '1234567890', - '123456789012345', - '12345678901234567890', - '123456789012345678901234567890', - '1234567890123456789012345678901234567890', - '12345678901234567890123456789012345678901234567890', - '123456789012345678901234567890123456789012345678901234567890', - '1234567890123456789012345678901234567890123456789012345678901234567890', - ].reduce((acc, value) => Object.assign(acc, { [value]: new BN(value) }), { - MAX_UINT256: constants.MAX_UINT256.toString(), - }))) { - it(`converts ${key}`, async function () { - expect(await this.strings.methods['toString(uint256)'](value)).to.equal(value.toString(10)); - }); - } - }); - - describe('toHexString', function () { - it('converts 0', async function () { - expect(await this.strings.methods['toHexString(uint256)'](0)).to.equal('0x00'); - }); - - it('converts a positive number', async function () { - expect(await this.strings.methods['toHexString(uint256)'](0x4132)).to.equal('0x4132'); - }); - - it('converts MAX_UINT256', async function () { - expect(await this.strings.methods['toHexString(uint256)'](constants.MAX_UINT256)) - .to.equal(web3.utils.toHex(constants.MAX_UINT256)); - }); - }); - - describe('toHexString fixed', function () { - it('converts a positive number (long)', async function () { - expect(await this.strings.methods['toHexString(uint256,uint256)'](0x4132, 32)) - .to.equal('0x0000000000000000000000000000000000000000000000000000000000004132'); - }); - - it('converts a positive number (short)', async function () { - await expectRevert( - this.strings.methods['toHexString(uint256,uint256)'](0x4132, 1), - 'Strings: hex length insufficient', - ); - }); - - it('converts MAX_UINT256', async function () { - expect(await this.strings.methods['toHexString(uint256,uint256)'](constants.MAX_UINT256, 32)) - .to.equal(web3.utils.toHex(constants.MAX_UINT256)); - }); - }); - - describe('toHexString address', function () { - it('converts a random address', async function () { - const addr = '0xa9036907dccae6a1e0033479b12e837e5cf5a02f'; - expect(await this.strings.methods['toHexString(address)'](addr)).to.equal(addr); - }); - - it('converts an address with leading zeros', async function () { - const addr = '0x0000e0ca771e21bd00057f54a68c30d400000000'; - expect(await this.strings.methods['toHexString(address)'](addr)).to.equal(addr); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/TimersBlockNumberImpl.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/TimersBlockNumberImpl.test.js deleted file mode 100644 index d9f83d9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/TimersBlockNumberImpl.test.js +++ /dev/null @@ -1,55 +0,0 @@ -const { BN, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const TimersBlockNumberImpl = artifacts.require('TimersBlockNumberImpl'); - -contract('TimersBlockNumber', function (accounts) { - beforeEach(async function () { - this.instance = await TimersBlockNumberImpl.new(); - this.now = await web3.eth.getBlock('latest').then(({ number }) => number); - }); - - it('unset', async function () { - expect(await this.instance.getDeadline()).to.be.bignumber.equal('0'); - expect(await this.instance.isUnset()).to.be.equal(true); - expect(await this.instance.isStarted()).to.be.equal(false); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('pending', async function () { - await this.instance.setDeadline(this.now + 3); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(this.now + 3)); - expect(await this.instance.isUnset()).to.be.equal(false); - expect(await this.instance.isStarted()).to.be.equal(true); - expect(await this.instance.isPending()).to.be.equal(true); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('expired', async function () { - await this.instance.setDeadline(this.now - 3); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(this.now - 3)); - expect(await this.instance.isUnset()).to.be.equal(false); - expect(await this.instance.isStarted()).to.be.equal(true); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(true); - }); - - it('reset', async function () { - await this.instance.reset(); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(0)); - expect(await this.instance.isUnset()).to.be.equal(true); - expect(await this.instance.isStarted()).to.be.equal(false); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('fast forward', async function () { - await this.instance.setDeadline(this.now + 3); - expect(await this.instance.isPending()).to.be.equal(true); - expect(await this.instance.isExpired()).to.be.equal(false); - await time.advanceBlockTo(this.now + 3); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(true); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/TimersTimestamp.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/TimersTimestamp.test.js deleted file mode 100644 index b08118d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/TimersTimestamp.test.js +++ /dev/null @@ -1,55 +0,0 @@ -const { BN, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const TimersTimestampImpl = artifacts.require('TimersTimestampImpl'); - -contract('TimersTimestamp', function (accounts) { - beforeEach(async function () { - this.instance = await TimersTimestampImpl.new(); - this.now = await web3.eth.getBlock('latest').then(({ timestamp }) => timestamp); - }); - - it('unset', async function () { - expect(await this.instance.getDeadline()).to.be.bignumber.equal('0'); - expect(await this.instance.isUnset()).to.be.equal(true); - expect(await this.instance.isStarted()).to.be.equal(false); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('pending', async function () { - await this.instance.setDeadline(this.now + 100); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(this.now + 100)); - expect(await this.instance.isUnset()).to.be.equal(false); - expect(await this.instance.isStarted()).to.be.equal(true); - expect(await this.instance.isPending()).to.be.equal(true); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('expired', async function () { - await this.instance.setDeadline(this.now - 100); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(this.now - 100)); - expect(await this.instance.isUnset()).to.be.equal(false); - expect(await this.instance.isStarted()).to.be.equal(true); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(true); - }); - - it('reset', async function () { - await this.instance.reset(); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(0)); - expect(await this.instance.isUnset()).to.be.equal(true); - expect(await this.instance.isStarted()).to.be.equal(false); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('fast forward', async function () { - await this.instance.setDeadline(this.now + 100); - expect(await this.instance.isPending()).to.be.equal(true); - expect(await this.instance.isExpired()).to.be.equal(false); - await time.increaseTo(this.now + 100); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(true); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/ECDSA.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/ECDSA.test.js deleted file mode 100644 index 04374c4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/ECDSA.test.js +++ /dev/null @@ -1,204 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { toEthSignedMessageHash } = require('../../helpers/sign'); - -const { expect } = require('chai'); - -const ECDSAMock = artifacts.require('ECDSAMock'); - -const TEST_MESSAGE = web3.utils.sha3('OpenZeppelin'); -const WRONG_MESSAGE = web3.utils.sha3('Nope'); -const NON_HASH_MESSAGE = '0x' + Buffer.from('abcd').toString('hex'); - -function to2098Format (signature) { - const long = web3.utils.hexToBytes(signature); - if (long.length !== 65) { - throw new Error('invalid signature length (expected long format)'); - } - if (long[32] >> 7 === 1) { - throw new Error('invalid signature \'s\' value'); - } - const short = long.slice(0, 64); - short[32] |= (long[64] % 27) << 7; // set the first bit of the 32nd byte to the v parity bit - return web3.utils.bytesToHex(short); -} - -function split (signature) { - const raw = web3.utils.hexToBytes(signature); - switch (raw.length) { - case 64: - return [ - web3.utils.bytesToHex(raw.slice(0, 32)), // r - web3.utils.bytesToHex(raw.slice(32, 64)), // vs - ]; - case 65: - return [ - raw[64], // v - web3.utils.bytesToHex(raw.slice(0, 32)), // r - web3.utils.bytesToHex(raw.slice(32, 64)), // s - ]; - default: - expect.fail('Invalid signature length, cannot split'); - } -} - -contract('ECDSA', function (accounts) { - const [ other ] = accounts; - - beforeEach(async function () { - this.ecdsa = await ECDSAMock.new(); - }); - - context('recover with invalid signature', function () { - it('with short signature', async function () { - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, '0x1234'), 'ECDSA: invalid signature length'); - }); - - it('with long signature', async function () { - await expectRevert( - // eslint-disable-next-line max-len - this.ecdsa.recover(TEST_MESSAGE, '0x01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'), - 'ECDSA: invalid signature length', - ); - }); - }); - - context('recover with valid signature', function () { - context('using web3.eth.sign', function () { - it('returns signer address with correct signature', async function () { - // Create the signature - const signature = await web3.eth.sign(TEST_MESSAGE, other); - - // Recover the signer address from the generated message and signature. - expect(await this.ecdsa.recover( - toEthSignedMessageHash(TEST_MESSAGE), - signature, - )).to.equal(other); - }); - - it('returns signer address with correct signature for arbitrary length message', async function () { - // Create the signature - const signature = await web3.eth.sign(NON_HASH_MESSAGE, other); - - // Recover the signer address from the generated message and signature. - expect(await this.ecdsa.recover( - toEthSignedMessageHash(NON_HASH_MESSAGE), - signature, - )).to.equal(other); - }); - - it('returns a different address', async function () { - const signature = await web3.eth.sign(TEST_MESSAGE, other); - expect(await this.ecdsa.recover(WRONG_MESSAGE, signature)).to.not.equal(other); - }); - - it('reverts with invalid signature', async function () { - // eslint-disable-next-line max-len - const signature = '0x332ce75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c'; - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, signature), 'ECDSA: invalid signature'); - }); - }); - - context('with v=27 signature', function () { - // Signature generated outside ganache with method web3.eth.sign(signer, message) - const signer = '0x2cc1166f6212628A0deEf2B33BEFB2187D35b86c'; - // eslint-disable-next-line max-len - const signatureWithoutV = '0x5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be892'; - - it('works with correct v value', async function () { - const v = '1b'; // 27 = 1b. - const signature = signatureWithoutV + v; - expect(await this.ecdsa.recover(TEST_MESSAGE, signature)).to.equal(signer); - expect(await this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature))).to.equal(signer); - expect(await this.ecdsa.recover_r_vs(TEST_MESSAGE, ...split(to2098Format(signature)))).to.equal(signer); - }); - - it('rejects incorrect v value', async function () { - const v = '1c'; // 28 = 1c. - const signature = signatureWithoutV + v; - expect(await this.ecdsa.recover(TEST_MESSAGE, signature)).to.not.equal(signer); - expect(await this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature))).to.not.equal(signer); - expect(await this.ecdsa.recover_r_vs(TEST_MESSAGE, ...split(to2098Format(signature)))).to.not.equal(signer); - }); - - it('reverts wrong v values', async function () { - for (const v of ['00', '01']) { - const signature = signatureWithoutV + v; - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, signature), 'ECDSA: invalid signature'); - await expectRevert(this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature)), 'ECDSA: invalid signature'); - } - }); - - it('rejects short EIP2098 format', async function () { - const v = '1b'; // 27 = 1b. - const signature = signatureWithoutV + v; - await expectRevert( - this.ecdsa.recover(TEST_MESSAGE, to2098Format(signature)), - 'ECDSA: invalid signature length', - ); - }); - }); - - context('with v=28 signature', function () { - const signer = '0x1E318623aB09Fe6de3C9b8672098464Aeda9100E'; - // eslint-disable-next-line max-len - const signatureWithoutV = '0x331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e0'; - - it('works with correct v value', async function () { - const v = '1c'; // 28 = 1c. - const signature = signatureWithoutV + v; - expect(await this.ecdsa.recover(TEST_MESSAGE, signature)).to.equal(signer); - expect(await this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature))).to.equal(signer); - expect(await this.ecdsa.recover_r_vs(TEST_MESSAGE, ...split(to2098Format(signature)))).to.equal(signer); - }); - - it('rejects incorrect v value', async function () { - const v = '1b'; // 27 = 1b. - const signature = signatureWithoutV + v; - expect(await this.ecdsa.recover(TEST_MESSAGE, signature)).to.not.equal(signer); - expect(await this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature))).to.not.equal(signer); - expect(await this.ecdsa.recover_r_vs(TEST_MESSAGE, ...split(to2098Format(signature)))).to.not.equal(signer); - }); - - it('reverts invalid v values', async function () { - for (const v of ['00', '01']) { - const signature = signatureWithoutV + v; - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, signature), 'ECDSA: invalid signature'); - await expectRevert(this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature)), 'ECDSA: invalid signature'); - } - }); - - it('rejects short EIP2098 format', async function () { - const v = '1c'; // 27 = 1b. - const signature = signatureWithoutV + v; - await expectRevert( - this.ecdsa.recover(TEST_MESSAGE, to2098Format(signature)), - 'ECDSA: invalid signature length', - ); - }); - }); - - it('reverts with high-s value signature', async function () { - const message = '0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'; - // eslint-disable-next-line max-len - const highSSignature = '0xe742ff452d41413616a5bf43fe15dd88294e983d3d36206c2712f39083d638bde0a0fc89be718fbc1033e1d30d78be1c68081562ed2e97af876f286f3453231d1b'; - await expectRevert(this.ecdsa.recover(message, highSSignature), 'ECDSA: invalid signature \'s\' value'); - await expectRevert( - this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(highSSignature)), - 'ECDSA: invalid signature \'s\' value', - ); - expect(() => to2098Format(highSSignature)).to.throw('invalid signature \'s\' value'); - }); - }); - - context('toEthSignedMessageHash', function () { - it('prefixes bytes32 data correctly', async function () { - expect(await this.ecdsa.methods['toEthSignedMessageHash(bytes32)'](TEST_MESSAGE)) - .to.equal(toEthSignedMessageHash(TEST_MESSAGE)); - }); - - it('prefixes dynamic length data correctly', async function () { - expect(await this.ecdsa.methods['toEthSignedMessageHash(bytes)'](NON_HASH_MESSAGE)) - .to.equal(toEthSignedMessageHash(NON_HASH_MESSAGE)); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/EIP712.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/EIP712.test.js deleted file mode 100644 index 9e26a87..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/EIP712.test.js +++ /dev/null @@ -1,57 +0,0 @@ -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const { EIP712Domain, domainSeparator } = require('../../helpers/eip712'); - -const EIP712 = artifacts.require('EIP712External'); - -contract('EIP712', function (accounts) { - const [mailTo] = accounts; - - const name = 'A Name'; - const version = '1'; - - beforeEach('deploying', async function () { - this.eip712 = await EIP712.new(name, version); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.eip712.getChainId(); - }); - - it('domain separator', async function () { - expect( - await this.eip712.domainSeparator(), - ).to.equal( - await domainSeparator(name, version, this.chainId, this.eip712.address), - ); - }); - - it('digest', async function () { - const chainId = this.chainId; - const verifyingContract = this.eip712.address; - const message = { - to: mailTo, - contents: 'very interesting', - }; - - const data = { - types: { - EIP712Domain, - Mail: [ - { name: 'to', type: 'address' }, - { name: 'contents', type: 'string' }, - ], - }, - domain: { name, version, chainId, verifyingContract }, - primaryType: 'Mail', - message, - }; - - const wallet = Wallet.generate(); - const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data }); - - await this.eip712.verify(signature, wallet.getAddressString(), message.to, message.contents); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/MerkleProof.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/MerkleProof.test.js deleted file mode 100644 index 2d4aacd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/MerkleProof.test.js +++ /dev/null @@ -1,179 +0,0 @@ -require('@openzeppelin/test-helpers'); - -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { MerkleTree } = require('merkletreejs'); -const keccak256 = require('keccak256'); - -const { expect } = require('chai'); - -const MerkleProofWrapper = artifacts.require('MerkleProofWrapper'); - -contract('MerkleProof', function (accounts) { - beforeEach(async function () { - this.merkleProof = await MerkleProofWrapper.new(); - }); - - describe('verify', function () { - it('returns true for a valid Merkle proof', async function () { - const elements = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''); - const merkleTree = new MerkleTree(elements, keccak256, { hashLeaves: true, sortPairs: true }); - - const root = merkleTree.getHexRoot(); - - const leaf = keccak256(elements[0]); - - const proof = merkleTree.getHexProof(leaf); - - expect(await this.merkleProof.verify(proof, root, leaf)).to.equal(true); - expect(await this.merkleProof.verifyCalldata(proof, root, leaf)).to.equal(true); - - // For demonstration, it is also possible to create valid proofs for certain 64-byte values *not* in elements: - const noSuchLeaf = keccak256( - Buffer.concat([keccak256(elements[0]), keccak256(elements[1])].sort(Buffer.compare)), - ); - expect(await this.merkleProof.verify(proof.slice(1), root, noSuchLeaf)).to.equal(true); - expect(await this.merkleProof.verifyCalldata(proof.slice(1), root, noSuchLeaf)).to.equal(true); - }); - - it('returns false for an invalid Merkle proof', async function () { - const correctElements = ['a', 'b', 'c']; - const correctMerkleTree = new MerkleTree(correctElements, keccak256, { hashLeaves: true, sortPairs: true }); - - const correctRoot = correctMerkleTree.getHexRoot(); - - const correctLeaf = keccak256(correctElements[0]); - - const badElements = ['d', 'e', 'f']; - const badMerkleTree = new MerkleTree(badElements); - - const badProof = badMerkleTree.getHexProof(badElements[0]); - - expect(await this.merkleProof.verify(badProof, correctRoot, correctLeaf)).to.equal(false); - expect(await this.merkleProof.verifyCalldata(badProof, correctRoot, correctLeaf)).to.equal(false); - }); - - it('returns false for a Merkle proof of invalid length', async function () { - const elements = ['a', 'b', 'c']; - const merkleTree = new MerkleTree(elements, keccak256, { hashLeaves: true, sortPairs: true }); - - const root = merkleTree.getHexRoot(); - - const leaf = keccak256(elements[0]); - - const proof = merkleTree.getHexProof(leaf); - const badProof = proof.slice(0, proof.length - 5); - - expect(await this.merkleProof.verify(badProof, root, leaf)).to.equal(false); - expect(await this.merkleProof.verifyCalldata(badProof, root, leaf)).to.equal(false); - }); - }); - - describe('multiProofVerify', function () { - it('returns true for a valid Merkle multi proof', async function () { - const leaves = ['a', 'b', 'c', 'd', 'e', 'f'].map(keccak256).sort(Buffer.compare); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - const proofLeaves = ['b', 'f', 'd'].map(keccak256).sort(Buffer.compare); - const proof = merkleTree.getMultiProof(proofLeaves); - const proofFlags = merkleTree.getProofFlags(proofLeaves, proof); - - expect(await this.merkleProof.multiProofVerify(proof, proofFlags, root, proofLeaves)).to.equal(true); - expect(await this.merkleProof.multiProofVerifyCalldata(proof, proofFlags, root, proofLeaves)).to.equal(true); - }); - - it('returns false for an invalid Merkle multi proof', async function () { - const leaves = ['a', 'b', 'c', 'd', 'e', 'f'].map(keccak256).sort(Buffer.compare); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - const badProofLeaves = ['g', 'h', 'i'].map(keccak256).sort(Buffer.compare); - const badMerkleTree = new MerkleTree(badProofLeaves); - const badProof = badMerkleTree.getMultiProof(badProofLeaves); - const badProofFlags = badMerkleTree.getProofFlags(badProofLeaves, badProof); - - expect(await this.merkleProof.multiProofVerify(badProof, badProofFlags, root, badProofLeaves)) - .to.equal(false); - expect(await this.merkleProof.multiProofVerifyCalldata(badProof, badProofFlags, root, badProofLeaves)) - .to.equal(false); - }); - - it('revert with invalid multi proof #1', async function () { - const fill = Buffer.alloc(32); // This could be anything, we are reconstructing a fake branch - const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare); - const badLeaf = keccak256('e'); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - - await expectRevert( - this.merkleProof.multiProofVerify( - [ leaves[1], fill, merkleTree.layers[1][1] ], - [ false, false, false ], - root, - [ leaves[0], badLeaf ], // A, E - ), - 'MerkleProof: invalid multiproof', - ); - await expectRevert( - this.merkleProof.multiProofVerifyCalldata( - [ leaves[1], fill, merkleTree.layers[1][1] ], - [ false, false, false ], - root, - [ leaves[0], badLeaf ], // A, E - ), - 'MerkleProof: invalid multiproof', - ); - }); - - it('revert with invalid multi proof #2', async function () { - const fill = Buffer.alloc(32); // This could be anything, we are reconstructing a fake branch - const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare); - const badLeaf = keccak256('e'); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - - await expectRevert( - this.merkleProof.multiProofVerify( - [ leaves[1], fill, merkleTree.layers[1][1] ], - [ false, false, false, false ], - root, - [ badLeaf, leaves[0] ], // A, E - ), - 'reverted with panic code 0x32', - ); - await expectRevert( - this.merkleProof.multiProofVerifyCalldata( - [ leaves[1], fill, merkleTree.layers[1][1] ], - [ false, false, false, false ], - root, - [ badLeaf, leaves[0] ], // A, E - ), - 'reverted with panic code 0x32', - ); - }); - - it('limit case: works for tree containing a single leaf', async function () { - const leaves = ['a'].map(keccak256).sort(Buffer.compare); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - const proofLeaves = ['a'].map(keccak256).sort(Buffer.compare); - const proof = merkleTree.getMultiProof(proofLeaves); - const proofFlags = merkleTree.getProofFlags(proofLeaves, proof); - - expect(await this.merkleProof.multiProofVerify(proof, proofFlags, root, proofLeaves)).to.equal(true); - expect(await this.merkleProof.multiProofVerifyCalldata(proof, proofFlags, root, proofLeaves)).to.equal(true); - }); - - it('limit case: can prove empty leaves', async function () { - const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - expect(await this.merkleProof.multiProofVerify([ root ], [], root, [])).to.equal(true); - expect(await this.merkleProof.multiProofVerifyCalldata([ root ], [], root, [])).to.equal(true); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/SignatureChecker.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/SignatureChecker.test.js deleted file mode 100644 index 801377a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/cryptography/SignatureChecker.test.js +++ /dev/null @@ -1,81 +0,0 @@ -const { toEthSignedMessageHash } = require('../../helpers/sign'); - -const { expect } = require('chai'); - -const SignatureCheckerMock = artifacts.require('SignatureCheckerMock'); -const ERC1271WalletMock = artifacts.require('ERC1271WalletMock'); -const ERC1271MaliciousMock = artifacts.require('ERC1271MaliciousMock'); - -const TEST_MESSAGE = web3.utils.sha3('OpenZeppelin'); -const WRONG_MESSAGE = web3.utils.sha3('Nope'); - -contract('SignatureChecker (ERC1271)', function (accounts) { - const [signer, other] = accounts; - - before('deploying', async function () { - this.signaturechecker = await SignatureCheckerMock.new(); - this.wallet = await ERC1271WalletMock.new(signer); - this.malicious = await ERC1271MaliciousMock.new(); - this.signature = await web3.eth.sign(TEST_MESSAGE, signer); - }); - - context('EOA account', function () { - it('with matching signer and signature', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - signer, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(true); - }); - - it('with invalid signer', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - other, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(false); - }); - - it('with invalid signature', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - signer, - toEthSignedMessageHash(WRONG_MESSAGE), - this.signature, - )).to.equal(false); - }); - }); - - context('ERC1271 wallet', function () { - it('with matching signer and signature', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - this.wallet.address, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(true); - }); - - it('with invalid signer', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - this.signaturechecker.address, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(false); - }); - - it('with invalid signature', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - this.wallet.address, - toEthSignedMessageHash(WRONG_MESSAGE), - this.signature, - )).to.equal(false); - }); - - it('with malicious wallet', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - this.malicious.address, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(false); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/ConditionalEscrow.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/ConditionalEscrow.test.js deleted file mode 100644 index 3386ca5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/ConditionalEscrow.test.js +++ /dev/null @@ -1,36 +0,0 @@ -const { ether, expectRevert } = require('@openzeppelin/test-helpers'); -const { shouldBehaveLikeEscrow } = require('./Escrow.behavior'); - -const ConditionalEscrowMock = artifacts.require('ConditionalEscrowMock'); - -contract('ConditionalEscrow', function (accounts) { - const [ owner, payee, ...otherAccounts ] = accounts; - - beforeEach(async function () { - this.escrow = await ConditionalEscrowMock.new({ from: owner }); - }); - - context('when withdrawal is allowed', function () { - beforeEach(async function () { - await Promise.all(otherAccounts.map(payee => this.escrow.setAllowed(payee, true))); - }); - - shouldBehaveLikeEscrow(owner, otherAccounts); - }); - - context('when withdrawal is disallowed', function () { - const amount = ether('23'); - - beforeEach(async function () { - await this.escrow.setAllowed(payee, false); - }); - - it('reverts on withdrawals', async function () { - await this.escrow.deposit(payee, { from: owner, value: amount }); - - await expectRevert(this.escrow.withdraw(payee, { from: owner }), - 'ConditionalEscrow: payee is not allowed to withdraw', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/Escrow.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/Escrow.behavior.js deleted file mode 100644 index ab59059..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/Escrow.behavior.js +++ /dev/null @@ -1,94 +0,0 @@ -const { balance, ether, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -function shouldBehaveLikeEscrow (owner, [payee1, payee2]) { - const amount = ether('42'); - - describe('as an escrow', function () { - describe('deposits', function () { - it('can accept a single deposit', async function () { - await this.escrow.deposit(payee1, { from: owner, value: amount }); - - expect(await balance.current(this.escrow.address)).to.be.bignumber.equal(amount); - - expect(await this.escrow.depositsOf(payee1)).to.be.bignumber.equal(amount); - }); - - it('can accept an empty deposit', async function () { - await this.escrow.deposit(payee1, { from: owner, value: 0 }); - }); - - it('only the owner can deposit', async function () { - await expectRevert(this.escrow.deposit(payee1, { from: payee2 }), - 'Ownable: caller is not the owner', - ); - }); - - it('emits a deposited event', async function () { - const receipt = await this.escrow.deposit(payee1, { from: owner, value: amount }); - expectEvent(receipt, 'Deposited', { - payee: payee1, - weiAmount: amount, - }); - }); - - it('can add multiple deposits on a single account', async function () { - await this.escrow.deposit(payee1, { from: owner, value: amount }); - await this.escrow.deposit(payee1, { from: owner, value: amount.muln(2) }); - - expect(await balance.current(this.escrow.address)).to.be.bignumber.equal(amount.muln(3)); - - expect(await this.escrow.depositsOf(payee1)).to.be.bignumber.equal(amount.muln(3)); - }); - - it('can track deposits to multiple accounts', async function () { - await this.escrow.deposit(payee1, { from: owner, value: amount }); - await this.escrow.deposit(payee2, { from: owner, value: amount.muln(2) }); - - expect(await balance.current(this.escrow.address)).to.be.bignumber.equal(amount.muln(3)); - - expect(await this.escrow.depositsOf(payee1)).to.be.bignumber.equal(amount); - - expect(await this.escrow.depositsOf(payee2)).to.be.bignumber.equal(amount.muln(2)); - }); - }); - - describe('withdrawals', async function () { - it('can withdraw payments', async function () { - const balanceTracker = await balance.tracker(payee1); - - await this.escrow.deposit(payee1, { from: owner, value: amount }); - await this.escrow.withdraw(payee1, { from: owner }); - - expect(await balanceTracker.delta()).to.be.bignumber.equal(amount); - - expect(await balance.current(this.escrow.address)).to.be.bignumber.equal('0'); - expect(await this.escrow.depositsOf(payee1)).to.be.bignumber.equal('0'); - }); - - it('can do an empty withdrawal', async function () { - await this.escrow.withdraw(payee1, { from: owner }); - }); - - it('only the owner can withdraw', async function () { - await expectRevert(this.escrow.withdraw(payee1, { from: payee1 }), - 'Ownable: caller is not the owner', - ); - }); - - it('emits a withdrawn event', async function () { - await this.escrow.deposit(payee1, { from: owner, value: amount }); - const receipt = await this.escrow.withdraw(payee1, { from: owner }); - expectEvent(receipt, 'Withdrawn', { - payee: payee1, - weiAmount: amount, - }); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeEscrow, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/Escrow.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/Escrow.test.js deleted file mode 100644 index 025a2a9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/Escrow.test.js +++ /dev/null @@ -1,14 +0,0 @@ -require('@openzeppelin/test-helpers'); -const { shouldBehaveLikeEscrow } = require('./Escrow.behavior'); - -const Escrow = artifacts.require('Escrow'); - -contract('Escrow', function (accounts) { - const [ owner, ...otherAccounts ] = accounts; - - beforeEach(async function () { - this.escrow = await Escrow.new({ from: owner }); - }); - - shouldBehaveLikeEscrow(owner, otherAccounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/RefundEscrow.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/RefundEscrow.test.js deleted file mode 100644 index 26c19b3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/escrow/RefundEscrow.test.js +++ /dev/null @@ -1,148 +0,0 @@ -const { balance, constants, ether, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const RefundEscrow = artifacts.require('RefundEscrow'); - -contract('RefundEscrow', function (accounts) { - const [ owner, beneficiary, refundee1, refundee2 ] = accounts; - - const amount = ether('54'); - const refundees = [refundee1, refundee2]; - - it('requires a non-null beneficiary', async function () { - await expectRevert( - RefundEscrow.new(ZERO_ADDRESS, { from: owner }), 'RefundEscrow: beneficiary is the zero address', - ); - }); - - context('once deployed', function () { - beforeEach(async function () { - this.escrow = await RefundEscrow.new(beneficiary, { from: owner }); - }); - - context('active state', function () { - it('has beneficiary and state', async function () { - expect(await this.escrow.beneficiary()).to.equal(beneficiary); - expect(await this.escrow.state()).to.be.bignumber.equal('0'); - }); - - it('accepts deposits', async function () { - await this.escrow.deposit(refundee1, { from: owner, value: amount }); - - expect(await this.escrow.depositsOf(refundee1)).to.be.bignumber.equal(amount); - }); - - it('does not refund refundees', async function () { - await this.escrow.deposit(refundee1, { from: owner, value: amount }); - await expectRevert(this.escrow.withdraw(refundee1), - 'ConditionalEscrow: payee is not allowed to withdraw', - ); - }); - - it('does not allow beneficiary withdrawal', async function () { - await this.escrow.deposit(refundee1, { from: owner, value: amount }); - await expectRevert(this.escrow.beneficiaryWithdraw(), - 'RefundEscrow: beneficiary can only withdraw while closed', - ); - }); - }); - - it('only the owner can enter closed state', async function () { - await expectRevert(this.escrow.close({ from: beneficiary }), - 'Ownable: caller is not the owner', - ); - - const receipt = await this.escrow.close({ from: owner }); - expectEvent(receipt, 'RefundsClosed'); - }); - - context('closed state', function () { - beforeEach(async function () { - await Promise.all(refundees.map(refundee => this.escrow.deposit(refundee, { from: owner, value: amount }))); - - await this.escrow.close({ from: owner }); - }); - - it('rejects deposits', async function () { - await expectRevert(this.escrow.deposit(refundee1, { from: owner, value: amount }), - 'RefundEscrow: can only deposit while active', - ); - }); - - it('does not refund refundees', async function () { - await expectRevert(this.escrow.withdraw(refundee1), - 'ConditionalEscrow: payee is not allowed to withdraw', - ); - }); - - it('allows beneficiary withdrawal', async function () { - const balanceTracker = await balance.tracker(beneficiary); - await this.escrow.beneficiaryWithdraw(); - expect(await balanceTracker.delta()).to.be.bignumber.equal(amount.muln(refundees.length)); - }); - - it('prevents entering the refund state', async function () { - await expectRevert(this.escrow.enableRefunds({ from: owner }), - 'RefundEscrow: can only enable refunds while active', - ); - }); - - it('prevents re-entering the closed state', async function () { - await expectRevert(this.escrow.close({ from: owner }), - 'RefundEscrow: can only close while active', - ); - }); - }); - - it('only the owner can enter refund state', async function () { - await expectRevert(this.escrow.enableRefunds({ from: beneficiary }), - 'Ownable: caller is not the owner', - ); - - const receipt = await this.escrow.enableRefunds({ from: owner }); - expectEvent(receipt, 'RefundsEnabled'); - }); - - context('refund state', function () { - beforeEach(async function () { - await Promise.all(refundees.map(refundee => this.escrow.deposit(refundee, { from: owner, value: amount }))); - - await this.escrow.enableRefunds({ from: owner }); - }); - - it('rejects deposits', async function () { - await expectRevert(this.escrow.deposit(refundee1, { from: owner, value: amount }), - 'RefundEscrow: can only deposit while active', - ); - }); - - it('refunds refundees', async function () { - for (const refundee of [refundee1, refundee2]) { - const balanceTracker = await balance.tracker(refundee); - await this.escrow.withdraw(refundee, { from: owner }); - expect(await balanceTracker.delta()).to.be.bignumber.equal(amount); - } - }); - - it('does not allow beneficiary withdrawal', async function () { - await expectRevert(this.escrow.beneficiaryWithdraw(), - 'RefundEscrow: beneficiary can only withdraw while closed', - ); - }); - - it('prevents entering the closed state', async function () { - await expectRevert(this.escrow.close({ from: owner }), - 'RefundEscrow: can only close while active', - ); - }); - - it('prevents re-entering the refund state', async function () { - await expectRevert(this.escrow.enableRefunds({ from: owner }), - 'RefundEscrow: can only enable refunds while active', - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165.test.js deleted file mode 100644 index c891500..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165.test.js +++ /dev/null @@ -1,13 +0,0 @@ -const { shouldSupportInterfaces } = require('./SupportsInterface.behavior'); - -const ERC165Mock = artifacts.require('ERC165Mock'); - -contract('ERC165', function (accounts) { - beforeEach(async function () { - this.mock = await ERC165Mock.new(); - }); - - shouldSupportInterfaces([ - 'ERC165', - ]); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165Checker.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165Checker.test.js deleted file mode 100644 index 90409a8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165Checker.test.js +++ /dev/null @@ -1,303 +0,0 @@ -require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC165CheckerMock = artifacts.require('ERC165CheckerMock'); -const ERC165MissingData = artifacts.require('ERC165MissingData'); -const ERC165MaliciousData = artifacts.require('ERC165MaliciousData'); -const ERC165NotSupported = artifacts.require('ERC165NotSupported'); -const ERC165InterfacesSupported = artifacts.require('ERC165InterfacesSupported'); -const ERC165ReturnBombMock = artifacts.require('ERC165ReturnBombMock'); - -const DUMMY_ID = '0xdeadbeef'; -const DUMMY_ID_2 = '0xcafebabe'; -const DUMMY_ID_3 = '0xdecafbad'; -const DUMMY_UNSUPPORTED_ID = '0xbaddcafe'; -const DUMMY_UNSUPPORTED_ID_2 = '0xbaadcafe'; -const DUMMY_ACCOUNT = '0x1111111111111111111111111111111111111111'; - -contract('ERC165Checker', function (accounts) { - beforeEach(async function () { - this.mock = await ERC165CheckerMock.new(); - }); - - context('ERC165 missing return data', function () { - beforeEach(async function () { - this.target = await ERC165MissingData.new(); - }); - - it('does not support ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - }); - - context('ERC165 malicious return data', function () { - beforeEach(async function () { - this.target = await ERC165MaliciousData.new(); - }); - - it('does not support ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(true); - }); - }); - - context('ERC165 not supported', function () { - beforeEach(async function () { - this.target = await ERC165NotSupported.new(); - }); - - it('does not support ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - }); - - context('ERC165 supported', function () { - beforeEach(async function () { - this.target = await ERC165InterfacesSupported.new([]); - }); - - it('supports ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(true); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - }); - - context('ERC165 and single interface supported', function () { - beforeEach(async function () { - this.target = await ERC165InterfacesSupported.new([DUMMY_ID]); - }); - - it('supports ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(true); - }); - - it('supports mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(true); - }); - - it('supports mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(true); - }); - - it('supports mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(true); - }); - - it('supports mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(true); - }); - }); - - context('ERC165 and many interfaces supported', function () { - beforeEach(async function () { - this.supportedInterfaces = [DUMMY_ID, DUMMY_ID_2, DUMMY_ID_3]; - this.target = await ERC165InterfacesSupported.new(this.supportedInterfaces); - }); - - it('supports ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(true); - }); - - it('supports each interfaceId via supportsInterface', async function () { - for (const interfaceId of this.supportedInterfaces) { - const supported = await this.mock.supportsInterface(this.target.address, interfaceId); - expect(supported).to.equal(true); - }; - }); - - it('supports all interfaceIds via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, this.supportedInterfaces); - expect(supported).to.equal(true); - }); - - it('supports none of the interfaces queried via supportsAllInterfaces', async function () { - const interfaceIdsToTest = [DUMMY_UNSUPPORTED_ID, DUMMY_UNSUPPORTED_ID_2]; - - const supported = await this.mock.supportsAllInterfaces(this.target.address, interfaceIdsToTest); - expect(supported).to.equal(false); - }); - - it('supports not all of the interfaces queried via supportsAllInterfaces', async function () { - const interfaceIdsToTest = [...this.supportedInterfaces, DUMMY_UNSUPPORTED_ID]; - - const supported = await this.mock.supportsAllInterfaces(this.target.address, interfaceIdsToTest); - expect(supported).to.equal(false); - }); - - it('supports all interfaceIds via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, this.supportedInterfaces); - expect(supported.length).to.equal(3); - expect(supported[0]).to.equal(true); - expect(supported[1]).to.equal(true); - expect(supported[2]).to.equal(true); - }); - - it('supports none of the interfaces queried via getSupportedInterfaces', async function () { - const interfaceIdsToTest = [DUMMY_UNSUPPORTED_ID, DUMMY_UNSUPPORTED_ID_2]; - - const supported = await this.mock.getSupportedInterfaces(this.target.address, interfaceIdsToTest); - expect(supported.length).to.equal(2); - expect(supported[0]).to.equal(false); - expect(supported[1]).to.equal(false); - }); - - it('supports not all of the interfaces queried via getSupportedInterfaces', async function () { - const interfaceIdsToTest = [...this.supportedInterfaces, DUMMY_UNSUPPORTED_ID]; - - const supported = await this.mock.getSupportedInterfaces(this.target.address, interfaceIdsToTest); - expect(supported.length).to.equal(4); - expect(supported[0]).to.equal(true); - expect(supported[1]).to.equal(true); - expect(supported[2]).to.equal(true); - expect(supported[3]).to.equal(false); - }); - - it('supports each interfaceId via supportsERC165InterfaceUnchecked', async function () { - for (const interfaceId of this.supportedInterfaces) { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, interfaceId); - expect(supported).to.equal(true); - }; - }); - }); - - context('account address does not support ERC165', function () { - it('does not support ERC165', async function () { - const supported = await this.mock.supportsERC165(DUMMY_ACCOUNT); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(DUMMY_ACCOUNT, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(DUMMY_ACCOUNT, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(DUMMY_ACCOUNT, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(DUMMY_ACCOUNT, DUMMY_ID); - expect(supported).to.equal(false); - }); - }); - - it('Return bomb resistance', async function () { - this.target = await ERC165ReturnBombMock.new(); - - const tx1 = await this.mock.supportsInterface.sendTransaction(this.target.address, DUMMY_ID); - expect(tx1.receipt.gasUsed).to.be.lessThan(120000); // 3*30k + 21k + some margin - - const tx2 = await this.mock.getSupportedInterfaces.sendTransaction( - this.target.address, - [ - DUMMY_ID, - DUMMY_ID_2, - DUMMY_ID_3, - DUMMY_UNSUPPORTED_ID, - DUMMY_UNSUPPORTED_ID_2, - ], - ); - expect(tx2.receipt.gasUsed).to.be.lessThan(250000); // (2+5)*30k + 21k + some margin - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165Storage.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165Storage.test.js deleted file mode 100644 index 568d645..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC165Storage.test.js +++ /dev/null @@ -1,25 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { shouldSupportInterfaces } = require('./SupportsInterface.behavior'); - -const ERC165Mock = artifacts.require('ERC165StorageMock'); - -contract('ERC165Storage', function (accounts) { - beforeEach(async function () { - this.mock = await ERC165Mock.new(); - }); - - it('register interface', async function () { - expect(await this.mock.supportsInterface('0x00000001')).to.be.equal(false); - await this.mock.registerInterface('0x00000001'); - expect(await this.mock.supportsInterface('0x00000001')).to.be.equal(true); - }); - - it('does not allow 0xffffffff', async function () { - await expectRevert(this.mock.registerInterface('0xffffffff'), 'ERC165: invalid interface id'); - }); - - shouldSupportInterfaces([ - 'ERC165', - ]); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC1820Implementer.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC1820Implementer.test.js deleted file mode 100644 index 8d9fe56..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/ERC1820Implementer.test.js +++ /dev/null @@ -1,66 +0,0 @@ -const { expectRevert, singletons } = require('@openzeppelin/test-helpers'); -const { bufferToHex, keccakFromString } = require('ethereumjs-util'); - -const { expect } = require('chai'); - -const ERC1820ImplementerMock = artifacts.require('ERC1820ImplementerMock'); - -contract('ERC1820Implementer', function (accounts) { - const [ registryFunder, implementee, other ] = accounts; - - const ERC1820_ACCEPT_MAGIC = bufferToHex(keccakFromString('ERC1820_ACCEPT_MAGIC')); - - beforeEach(async function () { - this.implementer = await ERC1820ImplementerMock.new(); - this.registry = await singletons.ERC1820Registry(registryFunder); - - this.interfaceA = bufferToHex(keccakFromString('interfaceA')); - this.interfaceB = bufferToHex(keccakFromString('interfaceB')); - }); - - context('with no registered interfaces', function () { - it('returns false when interface implementation is queried', async function () { - expect(await this.implementer.canImplementInterfaceForAddress(this.interfaceA, implementee)) - .to.not.equal(ERC1820_ACCEPT_MAGIC); - }); - - it('reverts when attempting to set as implementer in the registry', async function () { - await expectRevert( - this.registry.setInterfaceImplementer( - implementee, this.interfaceA, this.implementer.address, { from: implementee }, - ), - 'Does not implement the interface', - ); - }); - }); - - context('with registered interfaces', function () { - beforeEach(async function () { - await this.implementer.registerInterfaceForAddress(this.interfaceA, implementee); - }); - - it('returns true when interface implementation is queried', async function () { - expect(await this.implementer.canImplementInterfaceForAddress(this.interfaceA, implementee)) - .to.equal(ERC1820_ACCEPT_MAGIC); - }); - - it('returns false when interface implementation for non-supported interfaces is queried', async function () { - expect(await this.implementer.canImplementInterfaceForAddress(this.interfaceB, implementee)) - .to.not.equal(ERC1820_ACCEPT_MAGIC); - }); - - it('returns false when interface implementation for non-supported addresses is queried', async function () { - expect(await this.implementer.canImplementInterfaceForAddress(this.interfaceA, other)) - .to.not.equal(ERC1820_ACCEPT_MAGIC); - }); - - it('can be set as an implementer for supported interfaces in the registry', async function () { - await this.registry.setInterfaceImplementer( - implementee, this.interfaceA, this.implementer.address, { from: implementee }, - ); - - expect(await this.registry.getInterfaceImplementer(implementee, this.interfaceA)) - .to.equal(this.implementer.address); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/SupportsInterface.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/SupportsInterface.behavior.js deleted file mode 100644 index 78e3272..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/introspection/SupportsInterface.behavior.js +++ /dev/null @@ -1,147 +0,0 @@ -const { makeInterfaceId } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const INTERFACES = { - ERC165: [ - 'supportsInterface(bytes4)', - ], - ERC721: [ - 'balanceOf(address)', - 'ownerOf(uint256)', - 'approve(address,uint256)', - 'getApproved(uint256)', - 'setApprovalForAll(address,bool)', - 'isApprovedForAll(address,address)', - 'transferFrom(address,address,uint256)', - 'safeTransferFrom(address,address,uint256)', - 'safeTransferFrom(address,address,uint256,bytes)', - ], - ERC721Enumerable: [ - 'totalSupply()', - 'tokenOfOwnerByIndex(address,uint256)', - 'tokenByIndex(uint256)', - ], - ERC721Metadata: [ - 'name()', - 'symbol()', - 'tokenURI(uint256)', - ], - ERC1155: [ - 'balanceOf(address,uint256)', - 'balanceOfBatch(address[],uint256[])', - 'setApprovalForAll(address,bool)', - 'isApprovedForAll(address,address)', - 'safeTransferFrom(address,address,uint256,uint256,bytes)', - 'safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)', - ], - ERC1155Receiver: [ - 'onERC1155Received(address,address,uint256,uint256,bytes)', - 'onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)', - ], - AccessControl: [ - 'hasRole(bytes32,address)', - 'getRoleAdmin(bytes32)', - 'grantRole(bytes32,address)', - 'revokeRole(bytes32,address)', - 'renounceRole(bytes32,address)', - ], - AccessControlEnumerable: [ - 'getRoleMember(bytes32,uint256)', - 'getRoleMemberCount(bytes32)', - ], - Governor: [ - 'name()', - 'version()', - 'COUNTING_MODE()', - 'hashProposal(address[],uint256[],bytes[],bytes32)', - 'state(uint256)', - 'proposalSnapshot(uint256)', - 'proposalDeadline(uint256)', - 'votingDelay()', - 'votingPeriod()', - 'quorum(uint256)', - 'getVotes(address,uint256)', - 'hasVoted(uint256,address)', - 'propose(address[],uint256[],bytes[],string)', - 'execute(address[],uint256[],bytes[],bytes32)', - 'castVote(uint256,uint8)', - 'castVoteWithReason(uint256,uint8,string)', - 'castVoteBySig(uint256,uint8,uint8,bytes32,bytes32)', - ], - GovernorWithParams: [ - 'name()', - 'version()', - 'COUNTING_MODE()', - 'hashProposal(address[],uint256[],bytes[],bytes32)', - 'state(uint256)', - 'proposalSnapshot(uint256)', - 'proposalDeadline(uint256)', - 'votingDelay()', - 'votingPeriod()', - 'quorum(uint256)', - 'getVotes(address,uint256)', - 'getVotesWithParams(address,uint256,bytes)', - 'hasVoted(uint256,address)', - 'propose(address[],uint256[],bytes[],string)', - 'execute(address[],uint256[],bytes[],bytes32)', - 'castVote(uint256,uint8)', - 'castVoteWithReason(uint256,uint8,string)', - 'castVoteWithReasonAndParams(uint256,uint8,string,bytes)', - 'castVoteBySig(uint256,uint8,uint8,bytes32,bytes32)', - 'castVoteWithReasonAndParamsBySig(uint256,uint8,string,bytes,uint8,bytes32,bytes32)', - ], - GovernorTimelock: [ - 'timelock()', - 'proposalEta(uint256)', - 'queue(address[],uint256[],bytes[],bytes32)', - ], - ERC2981: [ - 'royaltyInfo(uint256,uint256)', - ], -}; - -const INTERFACE_IDS = {}; -const FN_SIGNATURES = {}; -for (const k of Object.getOwnPropertyNames(INTERFACES)) { - INTERFACE_IDS[k] = makeInterfaceId.ERC165(INTERFACES[k]); - for (const fnName of INTERFACES[k]) { - // the interface id of a single function is equivalent to its function signature - FN_SIGNATURES[fnName] = makeInterfaceId.ERC165([fnName]); - } -} - -function shouldSupportInterfaces (interfaces = []) { - describe('ERC165', function () { - beforeEach(function () { - this.contractUnderTest = this.mock || this.token || this.holder || this.accessControl; - }); - - it('supportsInterface uses less than 30k gas', async function () { - for (const k of interfaces) { - const interfaceId = INTERFACE_IDS[k]; - expect(await this.contractUnderTest.supportsInterface.estimateGas(interfaceId)).to.be.lte(30000); - } - }); - - it('all interfaces are reported as supported', async function () { - for (const k of interfaces) { - const interfaceId = INTERFACE_IDS[k]; - expect(await this.contractUnderTest.supportsInterface(interfaceId)).to.equal(true); - } - }); - - it('all interface functions are in ABI', async function () { - for (const k of interfaces) { - for (const fnName of INTERFACES[k]) { - const fnSig = FN_SIGNATURES[fnName]; - expect(this.contractUnderTest.abi.filter(fn => fn.signature === fnSig).length).to.equal(1); - } - } - }); - }); -} - -module.exports = { - shouldSupportInterfaces, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/Math.t.sol b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/Math.t.sol deleted file mode 100644 index 2baa3f1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/Math.t.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; - -import "../../../contracts/utils/math/Math.sol"; -import "../../../contracts/utils/math/SafeMath.sol"; - -contract MathTest is Test { - // SQRT - function testSqrt(uint256 input, uint8 r) public { - Math.Rounding rounding = _asRounding(r); - - uint256 result = Math.sqrt(input, rounding); - - // square of result is bigger than input - if (_squareBigger(result, input)) { - assertTrue(rounding == Math.Rounding.Up); - assertTrue(_squareSmaller(result - 1, input)); - } - // square of result is smaller than input - else if (_squareSmaller(result, input)) { - assertFalse(rounding == Math.Rounding.Up); - assertTrue(_squareBigger(result + 1, input)); - } - } - - function _squareBigger(uint256 value, uint256 ref) private pure returns (bool) { - (bool noOverflow, uint256 square) = SafeMath.tryMul(value, value); - return !noOverflow || square > ref; - } - - function _squareSmaller(uint256 value, uint256 ref) private pure returns (bool) { - return value * value < ref; - } - - // LOG2 - function testLog2(uint256 input, uint8 r) public { - Math.Rounding rounding = _asRounding(r); - - uint256 result = Math.log2(input, rounding); - - if (input == 0) { - assertEq(result, 0); - } else if (_powerOf2Bigger(result, input)) { - assertTrue(rounding == Math.Rounding.Up); - assertTrue(_powerOf2Smaller(result - 1, input)); - } else if (_powerOf2Smaller(result, input)) { - assertFalse(rounding == Math.Rounding.Up); - assertTrue(_powerOf2Bigger(result + 1, input)); - } - } - - function _powerOf2Bigger(uint256 value, uint256 ref) private pure returns (bool) { - return value >= 256 || 2**value > ref; // 2**256 overflows uint256 - } - - function _powerOf2Smaller(uint256 value, uint256 ref) private pure returns (bool) { - return 2**value < ref; - } - - // LOG10 - function testLog10(uint256 input, uint8 r) public { - Math.Rounding rounding = _asRounding(r); - - uint256 result = Math.log10(input, rounding); - - if (input == 0) { - assertEq(result, 0); - } else if (_powerOf10Bigger(result, input)) { - assertTrue(rounding == Math.Rounding.Up); - assertTrue(_powerOf10Smaller(result - 1, input)); - } else if (_powerOf10Smaller(result, input)) { - assertFalse(rounding == Math.Rounding.Up); - assertTrue(_powerOf10Bigger(result + 1, input)); - } - } - - function _powerOf10Bigger(uint256 value, uint256 ref) private pure returns (bool) { - return value >= 78 || 10**value > ref; // 10**78 overflows uint256 - } - - function _powerOf10Smaller(uint256 value, uint256 ref) private pure returns (bool) { - return 10**value < ref; - } - - // LOG256 - function testLog256(uint256 input, uint8 r) public { - Math.Rounding rounding = _asRounding(r); - - uint256 result = Math.log256(input, rounding); - - if (input == 0) { - assertEq(result, 0); - } else if (_powerOf256Bigger(result, input)) { - assertTrue(rounding == Math.Rounding.Up); - assertTrue(_powerOf256Smaller(result - 1, input)); - } else if (_powerOf256Smaller(result, input)) { - assertFalse(rounding == Math.Rounding.Up); - assertTrue(_powerOf256Bigger(result + 1, input)); - } - } - - function _powerOf256Bigger(uint256 value, uint256 ref) private pure returns (bool) { - return value >= 32 || 256**value > ref; // 256**32 overflows uint256 - } - - function _powerOf256Smaller(uint256 value, uint256 ref) private pure returns (bool) { - return 256**value < ref; - } - - // Helpers - function _asRounding(uint8 r) private returns (Math.Rounding) { - vm.assume(r < uint8(type(Math.Rounding).max)); - return Math.Rounding(r); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/Math.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/Math.test.js deleted file mode 100644 index 2b5448b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/Math.test.js +++ /dev/null @@ -1,312 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256 } = constants; -const { Rounding } = require('../../helpers/enums.js'); - -const MathMock = artifacts.require('MathMock'); - -contract('Math', function (accounts) { - const min = new BN('1234'); - const max = new BN('5678'); - const MAX_UINT256_SUB1 = MAX_UINT256.sub(new BN('1')); - const MAX_UINT256_SUB2 = MAX_UINT256.sub(new BN('2')); - - beforeEach(async function () { - this.math = await MathMock.new(); - }); - - describe('max', function () { - it('is correctly detected in first argument position', async function () { - expect(await this.math.max(max, min)).to.be.bignumber.equal(max); - }); - - it('is correctly detected in second argument position', async function () { - expect(await this.math.max(min, max)).to.be.bignumber.equal(max); - }); - }); - - describe('min', function () { - it('is correctly detected in first argument position', async function () { - expect(await this.math.min(min, max)).to.be.bignumber.equal(min); - }); - - it('is correctly detected in second argument position', async function () { - expect(await this.math.min(max, min)).to.be.bignumber.equal(min); - }); - }); - - describe('average', function () { - function bnAverage (a, b) { - return a.add(b).divn(2); - } - - it('is correctly calculated with two odd numbers', async function () { - const a = new BN('57417'); - const b = new BN('95431'); - expect(await this.math.average(a, b)).to.be.bignumber.equal(bnAverage(a, b)); - }); - - it('is correctly calculated with two even numbers', async function () { - const a = new BN('42304'); - const b = new BN('84346'); - expect(await this.math.average(a, b)).to.be.bignumber.equal(bnAverage(a, b)); - }); - - it('is correctly calculated with one even and one odd number', async function () { - const a = new BN('57417'); - const b = new BN('84346'); - expect(await this.math.average(a, b)).to.be.bignumber.equal(bnAverage(a, b)); - }); - - it('is correctly calculated with two max uint256 numbers', async function () { - const a = MAX_UINT256; - expect(await this.math.average(a, a)).to.be.bignumber.equal(bnAverage(a, a)); - }); - }); - - describe('ceilDiv', function () { - it('does not round up on exact division', async function () { - const a = new BN('10'); - const b = new BN('5'); - expect(await this.math.ceilDiv(a, b)).to.be.bignumber.equal('2'); - }); - - it('rounds up on division with remainders', async function () { - const a = new BN('42'); - const b = new BN('13'); - expect(await this.math.ceilDiv(a, b)).to.be.bignumber.equal('4'); - }); - - it('does not overflow', async function () { - const b = new BN('2'); - const result = new BN('1').shln(255); - expect(await this.math.ceilDiv(MAX_UINT256, b)).to.be.bignumber.equal(result); - }); - - it('correctly computes max uint256 divided by 1', async function () { - const b = new BN('1'); - expect(await this.math.ceilDiv(MAX_UINT256, b)).to.be.bignumber.equal(MAX_UINT256); - }); - }); - - describe('muldiv', function () { - it('divide by 0', async function () { - await expectRevert.unspecified(this.math.mulDiv(1, 1, 0, Rounding.Down)); - }); - - describe('does round down', async function () { - it('small values', async function () { - expect(await this.math.mulDiv('3', '4', '5', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.mulDiv('3', '5', '5', Rounding.Down)).to.be.bignumber.equal('3'); - }); - - it('large values', async function () { - expect(await this.math.mulDiv( - new BN('42'), - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(new BN('41')); - - expect(await this.math.mulDiv( - new BN('17'), - MAX_UINT256, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(new BN('17')); - - expect(await this.math.mulDiv( - MAX_UINT256_SUB1, - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(MAX_UINT256_SUB2); - - expect(await this.math.mulDiv( - MAX_UINT256, - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(MAX_UINT256_SUB1); - - expect(await this.math.mulDiv( - MAX_UINT256, - MAX_UINT256, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(MAX_UINT256); - }); - }); - - describe('does round up', async function () { - it('small values', async function () { - expect(await this.math.mulDiv('3', '4', '5', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.mulDiv('3', '5', '5', Rounding.Up)).to.be.bignumber.equal('3'); - }); - - it('large values', async function () { - expect(await this.math.mulDiv( - new BN('42'), - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(new BN('42')); - - expect(await this.math.mulDiv( - new BN('17'), - MAX_UINT256, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(new BN('17')); - - expect(await this.math.mulDiv( - MAX_UINT256_SUB1, - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(MAX_UINT256_SUB1); - - expect(await this.math.mulDiv( - MAX_UINT256, - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(MAX_UINT256_SUB1); - - expect(await this.math.mulDiv( - MAX_UINT256, - MAX_UINT256, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(MAX_UINT256); - }); - }); - }); - - describe('sqrt', function () { - it('rounds down', async function () { - expect(await this.math.sqrt('0', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.sqrt('1', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.sqrt('2', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.sqrt('3', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.sqrt('4', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.sqrt('144', Rounding.Down)).to.be.bignumber.equal('12'); - expect(await this.math.sqrt('999999', Rounding.Down)).to.be.bignumber.equal('999'); - expect(await this.math.sqrt('1000000', Rounding.Down)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt('1000001', Rounding.Down)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt('1002000', Rounding.Down)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt('1002001', Rounding.Down)).to.be.bignumber.equal('1001'); - expect(await this.math.sqrt(MAX_UINT256, Rounding.Down)) - .to.be.bignumber.equal('340282366920938463463374607431768211455'); - }); - - it('rounds up', async function () { - expect(await this.math.sqrt('0', Rounding.Up)).to.be.bignumber.equal('0'); - expect(await this.math.sqrt('1', Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.sqrt('2', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.sqrt('3', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.sqrt('4', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.sqrt('144', Rounding.Up)).to.be.bignumber.equal('12'); - expect(await this.math.sqrt('999999', Rounding.Up)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt('1000000', Rounding.Up)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt('1000001', Rounding.Up)).to.be.bignumber.equal('1001'); - expect(await this.math.sqrt('1002000', Rounding.Up)).to.be.bignumber.equal('1001'); - expect(await this.math.sqrt('1002001', Rounding.Up)).to.be.bignumber.equal('1001'); - expect(await this.math.sqrt(MAX_UINT256, Rounding.Up)) - .to.be.bignumber.equal('340282366920938463463374607431768211456'); - }); - }); - - describe('log', function () { - describe('log2', function () { - it('rounds down', async function () { - expect(await this.math.log2('0', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log2('1', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log2('2', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.log2('3', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.log2('4', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log2('5', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log2('6', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log2('7', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log2('8', Rounding.Down)).to.be.bignumber.equal('3'); - expect(await this.math.log2('9', Rounding.Down)).to.be.bignumber.equal('3'); - expect(await this.math.log2(MAX_UINT256, Rounding.Down)).to.be.bignumber.equal('255'); - }); - - it('rounds up', async function () { - expect(await this.math.log2('0', Rounding.Up)).to.be.bignumber.equal('0'); - expect(await this.math.log2('1', Rounding.Up)).to.be.bignumber.equal('0'); - expect(await this.math.log2('2', Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.log2('3', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.log2('4', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.log2('5', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.log2('6', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.log2('7', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.log2('8', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.log2(MAX_UINT256, Rounding.Up)).to.be.bignumber.equal('256'); - }); - }); - - describe('log10', function () { - it('rounds down', async function () { - expect(await this.math.log10('0', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log10('1', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log10('2', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log10('9', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log10('10', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.log10('11', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.log10('99', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.log10('100', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log10('101', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log10('999', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log10('1000', Rounding.Down)).to.be.bignumber.equal('3'); - expect(await this.math.log10('1001', Rounding.Down)).to.be.bignumber.equal('3'); - expect(await this.math.log10(MAX_UINT256, Rounding.Down)).to.be.bignumber.equal('77'); - }); - - it('rounds up', async function () { - expect(await this.math.log10('0', Rounding.Up)).to.be.bignumber.equal('0'); - expect(await this.math.log10('1', Rounding.Up)).to.be.bignumber.equal('0'); - expect(await this.math.log10('2', Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.log10('9', Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.log10('10', Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.log10('11', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.log10('99', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.log10('100', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.log10('101', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.log10('999', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.log10('1000', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.log10('1001', Rounding.Up)).to.be.bignumber.equal('4'); - expect(await this.math.log10(MAX_UINT256, Rounding.Up)).to.be.bignumber.equal('78'); - }); - }); - - describe('log256', function () { - it('rounds down', async function () { - expect(await this.math.log256('0', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log256('1', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log256('2', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log256('255', Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.log256('256', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.log256('257', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.log256('65535', Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.log256('65536', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log256('65537', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.log256(MAX_UINT256, Rounding.Down)).to.be.bignumber.equal('31'); - }); - - it('rounds up', async function () { - expect(await this.math.log256('0', Rounding.Up)).to.be.bignumber.equal('0'); - expect(await this.math.log256('1', Rounding.Up)).to.be.bignumber.equal('0'); - expect(await this.math.log256('2', Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.log256('255', Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.log256('256', Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.log256('257', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.log256('65535', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.log256('65536', Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.log256('65537', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.log256(MAX_UINT256, Rounding.Up)).to.be.bignumber.equal('32'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SafeCast.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SafeCast.test.js deleted file mode 100644 index 97fc22e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SafeCast.test.js +++ /dev/null @@ -1,164 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { range } = require('../../../scripts/helpers'); - -const SafeCastMock = artifacts.require('SafeCastMock'); - -contract('SafeCast', async (accounts) => { - beforeEach(async function () { - this.safeCast = await SafeCastMock.new(); - }); - - function testToUint (bits) { - describe(`toUint${bits}`, () => { - const maxValue = new BN('2').pow(new BN(bits)).subn(1); - - it('downcasts 0', async function () { - expect(await this.safeCast[`toUint${bits}`](0)).to.be.bignumber.equal('0'); - }); - - it('downcasts 1', async function () { - expect(await this.safeCast[`toUint${bits}`](1)).to.be.bignumber.equal('1'); - }); - - it(`downcasts 2^${bits} - 1 (${maxValue})`, async function () { - expect(await this.safeCast[`toUint${bits}`](maxValue)).to.be.bignumber.equal(maxValue); - }); - - it(`reverts when downcasting 2^${bits} (${maxValue.addn(1)})`, async function () { - await expectRevert( - this.safeCast[`toUint${bits}`](maxValue.addn(1)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - - it(`reverts when downcasting 2^${bits} + 1 (${maxValue.addn(2)})`, async function () { - await expectRevert( - this.safeCast[`toUint${bits}`](maxValue.addn(2)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - }); - } - - range(8, 256, 8).forEach(bits => testToUint(bits)); - - describe('toUint256', () => { - const maxInt256 = new BN('2').pow(new BN(255)).subn(1); - const minInt256 = new BN('2').pow(new BN(255)).neg(); - - it('casts 0', async function () { - expect(await this.safeCast.toUint256(0)).to.be.bignumber.equal('0'); - }); - - it('casts 1', async function () { - expect(await this.safeCast.toUint256(1)).to.be.bignumber.equal('1'); - }); - - it(`casts INT256_MAX (${maxInt256})`, async function () { - expect(await this.safeCast.toUint256(maxInt256)).to.be.bignumber.equal(maxInt256); - }); - - it('reverts when casting -1', async function () { - await expectRevert( - this.safeCast.toUint256(-1), - 'SafeCast: value must be positive', - ); - }); - - it(`reverts when casting INT256_MIN (${minInt256})`, async function () { - await expectRevert( - this.safeCast.toUint256(minInt256), - 'SafeCast: value must be positive', - ); - }); - }); - - function testToInt (bits) { - describe(`toInt${bits}`, () => { - const minValue = new BN('-2').pow(new BN(bits - 1)); - const maxValue = new BN('2').pow(new BN(bits - 1)).subn(1); - - it('downcasts 0', async function () { - expect(await this.safeCast[`toInt${bits}`](0)).to.be.bignumber.equal('0'); - }); - - it('downcasts 1', async function () { - expect(await this.safeCast[`toInt${bits}`](1)).to.be.bignumber.equal('1'); - }); - - it('downcasts -1', async function () { - expect(await this.safeCast[`toInt${bits}`](-1)).to.be.bignumber.equal('-1'); - }); - - it(`downcasts -2^${bits - 1} (${minValue})`, async function () { - expect(await this.safeCast[`toInt${bits}`](minValue)).to.be.bignumber.equal(minValue); - }); - - it(`downcasts 2^${bits - 1} - 1 (${maxValue})`, async function () { - expect(await this.safeCast[`toInt${bits}`](maxValue)).to.be.bignumber.equal(maxValue); - }); - - it(`reverts when downcasting -2^${bits - 1} - 1 (${minValue.subn(1)})`, async function () { - await expectRevert( - this.safeCast[`toInt${bits}`](minValue.subn(1)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - - it(`reverts when downcasting -2^${bits - 1} - 2 (${minValue.subn(2)})`, async function () { - await expectRevert( - this.safeCast[`toInt${bits}`](minValue.subn(2)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - - it(`reverts when downcasting 2^${bits - 1} (${maxValue.addn(1)})`, async function () { - await expectRevert( - this.safeCast[`toInt${bits}`](maxValue.addn(1)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - - it(`reverts when downcasting 2^${bits - 1} + 1 (${maxValue.addn(2)})`, async function () { - await expectRevert( - this.safeCast[`toInt${bits}`](maxValue.addn(2)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - }); - } - - range(8, 256, 8).forEach(bits => testToInt(bits)); - - describe('toInt256', () => { - const maxUint256 = new BN('2').pow(new BN(256)).subn(1); - const maxInt256 = new BN('2').pow(new BN(255)).subn(1); - - it('casts 0', async function () { - expect(await this.safeCast.toInt256(0)).to.be.bignumber.equal('0'); - }); - - it('casts 1', async function () { - expect(await this.safeCast.toInt256(1)).to.be.bignumber.equal('1'); - }); - - it(`casts INT256_MAX (${maxInt256})`, async function () { - expect(await this.safeCast.toInt256(maxInt256)).to.be.bignumber.equal(maxInt256); - }); - - it(`reverts when casting INT256_MAX + 1 (${maxInt256.addn(1)})`, async function () { - await expectRevert( - this.safeCast.toInt256(maxInt256.addn(1)), - 'SafeCast: value doesn\'t fit in an int256', - ); - }); - - it(`reverts when casting UINT256_MAX (${maxUint256})`, async function () { - await expectRevert( - this.safeCast.toInt256(maxUint256), - 'SafeCast: value doesn\'t fit in an int256', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SafeMath.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SafeMath.test.js deleted file mode 100644 index 7c9b937..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SafeMath.test.js +++ /dev/null @@ -1,403 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { MAX_UINT256 } = constants; - -const { expect } = require('chai'); - -const SafeMathMock = artifacts.require('SafeMathMock'); - -function expectStruct (value, expected) { - for (const key in expected) { - if (BN.isBN(value[key])) { - expect(value[key]).to.be.bignumber.equal(expected[key]); - } else { - expect(value[key]).to.be.equal(expected[key]); - } - } -} - -contract('SafeMath', function (accounts) { - beforeEach(async function () { - this.safeMath = await SafeMathMock.new(); - }); - - async function testCommutative (fn, lhs, rhs, expected, ...extra) { - expect(await fn(lhs, rhs, ...extra)).to.be.bignumber.equal(expected); - expect(await fn(rhs, lhs, ...extra)).to.be.bignumber.equal(expected); - } - - async function testFailsCommutative (fn, lhs, rhs, reason, ...extra) { - if (reason === undefined) { - await expectRevert.unspecified(fn(lhs, rhs, ...extra)); - await expectRevert.unspecified(fn(rhs, lhs, ...extra)); - } else { - await expectRevert(fn(lhs, rhs, ...extra), reason); - await expectRevert(fn(rhs, lhs, ...extra), reason); - } - } - - async function testCommutativeIterable (fn, lhs, rhs, expected, ...extra) { - expectStruct(await fn(lhs, rhs, ...extra), expected); - expectStruct(await fn(rhs, lhs, ...extra), expected); - } - - describe('with flag', function () { - describe('add', function () { - it('adds correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - testCommutativeIterable(this.safeMath.tryAdd, a, b, { flag: true, value: a.add(b) }); - }); - - it('reverts on addition overflow', async function () { - const a = MAX_UINT256; - const b = new BN('1'); - - testCommutativeIterable(this.safeMath.tryAdd, a, b, { flag: false, value: '0' }); - }); - }); - - describe('sub', function () { - it('subtracts correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - expectStruct(await this.safeMath.trySub(a, b), { flag: true, value: a.sub(b) }); - }); - - it('reverts if subtraction result would be negative', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.trySub(a, b), { flag: false, value: '0' }); - }); - }); - - describe('mul', function () { - it('multiplies correctly', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - testCommutativeIterable(this.safeMath.tryMul, a, b, { flag: true, value: a.mul(b) }); - }); - - it('multiplies by zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - testCommutativeIterable(this.safeMath.tryMul, a, b, { flag: true, value: a.mul(b) }); - }); - - it('reverts on multiplication overflow', async function () { - const a = MAX_UINT256; - const b = new BN('2'); - - testCommutativeIterable(this.safeMath.tryMul, a, b, { flag: false, value: '0' }); - }); - }); - - describe('div', function () { - it('divides correctly', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryDiv(a, b), { flag: true, value: a.div(b) }); - }); - - it('divides zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryDiv(a, b), { flag: true, value: a.div(b) }); - }); - - it('returns complete number result on non-even division', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryDiv(a, b), { flag: true, value: a.div(b) }); - }); - - it('reverts on division by zero', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - expectStruct(await this.safeMath.tryDiv(a, b), { flag: false, value: '0' }); - }); - }); - - describe('mod', function () { - describe('modulos correctly', async function () { - it('when the dividend is smaller than the divisor', async function () { - const a = new BN('284'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: true, value: a.mod(b) }); - }); - - it('when the dividend is equal to the divisor', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: true, value: a.mod(b) }); - }); - - it('when the dividend is larger than the divisor', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: true, value: a.mod(b) }); - }); - - it('when the dividend is a multiple of the divisor', async function () { - const a = new BN('17034'); // 17034 == 5678 * 3 - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: true, value: a.mod(b) }); - }); - }); - - it('reverts with a 0 divisor', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: false, value: '0' }); - }); - }); - }); - - describe('with default revert message', function () { - describe('add', function () { - it('adds correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - await testCommutative(this.safeMath.doAdd, a, b, a.add(b)); - }); - - it('reverts on addition overflow', async function () { - const a = MAX_UINT256; - const b = new BN('1'); - - await testFailsCommutative(this.safeMath.doAdd, a, b, undefined); - }); - }); - - describe('sub', function () { - it('subtracts correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - expect(await this.safeMath.doSub(a, b)).to.be.bignumber.equal(a.sub(b)); - }); - - it('reverts if subtraction result would be negative', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - await expectRevert.unspecified(this.safeMath.doSub(a, b)); - }); - }); - - describe('mul', function () { - it('multiplies correctly', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - await testCommutative(this.safeMath.doMul, a, b, a.mul(b)); - }); - - it('multiplies by zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - await testCommutative(this.safeMath.doMul, a, b, '0'); - }); - - it('reverts on multiplication overflow', async function () { - const a = MAX_UINT256; - const b = new BN('2'); - - await testFailsCommutative(this.safeMath.doMul, a, b, undefined); - }); - }); - - describe('div', function () { - it('divides correctly', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expect(await this.safeMath.doDiv(a, b)).to.be.bignumber.equal(a.div(b)); - }); - - it('divides zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - expect(await this.safeMath.doDiv(a, b)).to.be.bignumber.equal('0'); - }); - - it('returns complete number result on non-even division', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.doDiv(a, b)).to.be.bignumber.equal('1'); - }); - - it('reverts on division by zero', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - await expectRevert.unspecified(this.safeMath.doDiv(a, b)); - }); - }); - - describe('mod', function () { - describe('modulos correctly', async function () { - it('when the dividend is smaller than the divisor', async function () { - const a = new BN('284'); - const b = new BN('5678'); - - expect(await this.safeMath.doMod(a, b)).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is equal to the divisor', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expect(await this.safeMath.doMod(a, b)).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is larger than the divisor', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.doMod(a, b)).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is a multiple of the divisor', async function () { - const a = new BN('17034'); // 17034 == 5678 * 3 - const b = new BN('5678'); - - expect(await this.safeMath.doMod(a, b)).to.be.bignumber.equal(a.mod(b)); - }); - }); - - it('reverts with a 0 divisor', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - await expectRevert.unspecified(this.safeMath.doMod(a, b)); - }); - }); - }); - - describe('with custom revert message', function () { - describe('sub', function () { - it('subtracts correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - expect(await this.safeMath.subWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.sub(b)); - }); - - it('reverts if subtraction result would be negative', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - await expectRevert(this.safeMath.subWithMessage(a, b, 'MyErrorMessage'), 'MyErrorMessage'); - }); - }); - - describe('div', function () { - it('divides correctly', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expect(await this.safeMath.divWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.div(b)); - }); - - it('divides zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - expect(await this.safeMath.divWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal('0'); - }); - - it('returns complete number result on non-even division', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.divWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal('1'); - }); - - it('reverts on division by zero', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - await expectRevert(this.safeMath.divWithMessage(a, b, 'MyErrorMessage'), 'MyErrorMessage'); - }); - }); - - describe('mod', function () { - describe('modulos correctly', async function () { - it('when the dividend is smaller than the divisor', async function () { - const a = new BN('284'); - const b = new BN('5678'); - - expect(await this.safeMath.modWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is equal to the divisor', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expect(await this.safeMath.modWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is larger than the divisor', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.modWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is a multiple of the divisor', async function () { - const a = new BN('17034'); // 17034 == 5678 * 3 - const b = new BN('5678'); - - expect(await this.safeMath.modWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.mod(b)); - }); - }); - - it('reverts with a 0 divisor', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - await expectRevert(this.safeMath.modWithMessage(a, b, 'MyErrorMessage'), 'MyErrorMessage'); - }); - }); - }); - - describe('memory leakage', function () { - it('add', async function () { - expect(await this.safeMath.addMemoryCheck()).to.be.bignumber.equal('0'); - }); - - it('sub', async function () { - expect(await this.safeMath.subMemoryCheck()).to.be.bignumber.equal('0'); - }); - - it('mul', async function () { - expect(await this.safeMath.mulMemoryCheck()).to.be.bignumber.equal('0'); - }); - - it('div', async function () { - expect(await this.safeMath.divMemoryCheck()).to.be.bignumber.equal('0'); - }); - - it('mod', async function () { - expect(await this.safeMath.modMemoryCheck()).to.be.bignumber.equal('0'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SignedMath.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SignedMath.test.js deleted file mode 100644 index 8e9826f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SignedMath.test.js +++ /dev/null @@ -1,93 +0,0 @@ -const { BN, constants } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MIN_INT256, MAX_INT256 } = constants; - -const SignedMathMock = artifacts.require('SignedMathMock'); - -contract('SignedMath', function (accounts) { - const min = new BN('-1234'); - const max = new BN('5678'); - - beforeEach(async function () { - this.math = await SignedMathMock.new(); - }); - - describe('max', function () { - it('is correctly detected in first argument position', async function () { - expect(await this.math.max(max, min)).to.be.bignumber.equal(max); - }); - - it('is correctly detected in second argument position', async function () { - expect(await this.math.max(min, max)).to.be.bignumber.equal(max); - }); - }); - - describe('min', function () { - it('is correctly detected in first argument position', async function () { - expect(await this.math.min(min, max)).to.be.bignumber.equal(min); - }); - - it('is correctly detected in second argument position', async function () { - expect(await this.math.min(max, min)).to.be.bignumber.equal(min); - }); - }); - - describe('average', function () { - function bnAverage (a, b) { - return a.add(b).divn(2); - } - - it('is correctly calculated with various input', async function () { - const valuesX = [ - new BN('0'), - new BN('3'), - new BN('-3'), - new BN('4'), - new BN('-4'), - new BN('57417'), - new BN('-57417'), - new BN('42304'), - new BN('-42304'), - MIN_INT256, - MAX_INT256, - ]; - - const valuesY = [ - new BN('0'), - new BN('5'), - new BN('-5'), - new BN('2'), - new BN('-2'), - new BN('57417'), - new BN('-57417'), - new BN('42304'), - new BN('-42304'), - MIN_INT256, - MAX_INT256, - ]; - - for (const x of valuesX) { - for (const y of valuesY) { - expect(await this.math.average(x, y)) - .to.be.bignumber.equal(bnAverage(x, y), `Bad result for average(${x}, ${y})`); - } - } - }); - }); - - describe('abs', function () { - for (const n of [ - MIN_INT256, - MIN_INT256.addn(1), - new BN('-1'), - new BN('0'), - new BN('1'), - MAX_INT256.subn(1), - MAX_INT256, - ]) { - it(`correctly computes the absolute value of ${n}`, async function () { - expect(await this.math.abs(n)).to.be.bignumber.equal(n.abs()); - }); - } - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SignedSafeMath.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SignedSafeMath.test.js deleted file mode 100644 index c6aa15e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/math/SignedSafeMath.test.js +++ /dev/null @@ -1,152 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { MAX_INT256, MIN_INT256 } = constants; - -const { expect } = require('chai'); - -const SignedSafeMathMock = artifacts.require('SignedSafeMathMock'); - -contract('SignedSafeMath', function (accounts) { - beforeEach(async function () { - this.safeMath = await SignedSafeMathMock.new(); - }); - - async function testCommutative (fn, lhs, rhs, expected) { - expect(await fn(lhs, rhs)).to.be.bignumber.equal(expected); - expect(await fn(rhs, lhs)).to.be.bignumber.equal(expected); - } - - async function testFailsCommutative (fn, lhs, rhs) { - await expectRevert.unspecified(fn(lhs, rhs)); - await expectRevert.unspecified(fn(rhs, lhs)); - } - - describe('add', function () { - it('adds correctly if it does not overflow and the result is positive', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - await testCommutative(this.safeMath.add, a, b, a.add(b)); - }); - - it('adds correctly if it does not overflow and the result is negative', async function () { - const a = MAX_INT256; - const b = MIN_INT256; - - await testCommutative(this.safeMath.add, a, b, a.add(b)); - }); - - it('reverts on positive addition overflow', async function () { - const a = MAX_INT256; - const b = new BN('1'); - - await testFailsCommutative(this.safeMath.add, a, b); - }); - - it('reverts on negative addition overflow', async function () { - const a = MIN_INT256; - const b = new BN('-1'); - - await testFailsCommutative(this.safeMath.add, a, b); - }); - }); - - describe('sub', function () { - it('subtracts correctly if it does not overflow and the result is positive', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - const result = await this.safeMath.sub(a, b); - expect(result).to.be.bignumber.equal(a.sub(b)); - }); - - it('subtracts correctly if it does not overflow and the result is negative', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - const result = await this.safeMath.sub(a, b); - expect(result).to.be.bignumber.equal(a.sub(b)); - }); - - it('reverts on positive subtraction overflow', async function () { - const a = MAX_INT256; - const b = new BN('-1'); - - await expectRevert.unspecified(this.safeMath.sub(a, b)); - }); - - it('reverts on negative subtraction overflow', async function () { - const a = MIN_INT256; - const b = new BN('1'); - - await expectRevert.unspecified(this.safeMath.sub(a, b)); - }); - }); - - describe('mul', function () { - it('multiplies correctly', async function () { - const a = new BN('5678'); - const b = new BN('-1234'); - - await testCommutative(this.safeMath.mul, a, b, a.mul(b)); - }); - - it('multiplies by zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - await testCommutative(this.safeMath.mul, a, b, '0'); - }); - - it('reverts on multiplication overflow, positive operands', async function () { - const a = MAX_INT256; - const b = new BN('2'); - - await testFailsCommutative(this.safeMath.mul, a, b); - }); - - it('reverts when minimum integer is multiplied by -1', async function () { - const a = MIN_INT256; - const b = new BN('-1'); - - await testFailsCommutative(this.safeMath.mul, a, b); - }); - }); - - describe('div', function () { - it('divides correctly', async function () { - const a = new BN('-5678'); - const b = new BN('5678'); - - const result = await this.safeMath.div(a, b); - expect(result).to.be.bignumber.equal(a.div(b)); - }); - - it('divides zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - expect(await this.safeMath.div(a, b)).to.be.bignumber.equal('0'); - }); - - it('returns complete number result on non-even division', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.div(a, b)).to.be.bignumber.equal('1'); - }); - - it('reverts on division by zero', async function () { - const a = new BN('-5678'); - const b = new BN('0'); - - await expectRevert.unspecified(this.safeMath.div(a, b)); - }); - - it('reverts on overflow, negative second', async function () { - const a = new BN(MIN_INT256); - const b = new BN('-1'); - - await expectRevert.unspecified(this.safeMath.div(a, b)); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/BitMap.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/BitMap.test.js deleted file mode 100644 index 58d70ca..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/BitMap.test.js +++ /dev/null @@ -1,145 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const BitMap = artifacts.require('BitMapMock'); - -contract('BitMap', function (accounts) { - const keyA = new BN('7891'); - const keyB = new BN('451'); - const keyC = new BN('9592328'); - - beforeEach(async function () { - this.bitmap = await BitMap.new(); - }); - - it('starts empty', async function () { - expect(await this.bitmap.get(keyA)).to.equal(false); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - describe('setTo', function () { - it('set a key to true', async function () { - await this.bitmap.setTo(keyA, true); - expect(await this.bitmap.get(keyA)).to.equal(true); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('set a key to false', async function () { - await this.bitmap.setTo(keyA, true); - await this.bitmap.setTo(keyA, false); - expect(await this.bitmap.get(keyA)).to.equal(false); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('set several consecutive keys', async function () { - await this.bitmap.setTo(keyA.addn(0), true); - await this.bitmap.setTo(keyA.addn(1), true); - await this.bitmap.setTo(keyA.addn(2), true); - await this.bitmap.setTo(keyA.addn(3), true); - await this.bitmap.setTo(keyA.addn(4), true); - await this.bitmap.setTo(keyA.addn(2), false); - await this.bitmap.setTo(keyA.addn(4), false); - expect(await this.bitmap.get(keyA.addn(0))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(1))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(2))).to.equal(false); - expect(await this.bitmap.get(keyA.addn(3))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(4))).to.equal(false); - }); - }); - - describe('set', function () { - it('adds a key', async function () { - await this.bitmap.set(keyA); - expect(await this.bitmap.get(keyA)).to.equal(true); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('adds several keys', async function () { - await this.bitmap.set(keyA); - await this.bitmap.set(keyB); - expect(await this.bitmap.get(keyA)).to.equal(true); - expect(await this.bitmap.get(keyB)).to.equal(true); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('adds several consecutive keys', async function () { - await this.bitmap.set(keyA.addn(0)); - await this.bitmap.set(keyA.addn(1)); - await this.bitmap.set(keyA.addn(3)); - expect(await this.bitmap.get(keyA.addn(0))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(1))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(2))).to.equal(false); - expect(await this.bitmap.get(keyA.addn(3))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(4))).to.equal(false); - }); - }); - - describe('unset', function () { - it('removes added keys', async function () { - await this.bitmap.set(keyA); - await this.bitmap.set(keyB); - await this.bitmap.unset(keyA); - expect(await this.bitmap.get(keyA)).to.equal(false); - expect(await this.bitmap.get(keyB)).to.equal(true); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('removes consecutive added keys', async function () { - await this.bitmap.set(keyA.addn(0)); - await this.bitmap.set(keyA.addn(1)); - await this.bitmap.set(keyA.addn(3)); - await this.bitmap.unset(keyA.addn(1)); - expect(await this.bitmap.get(keyA.addn(0))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(1))).to.equal(false); - expect(await this.bitmap.get(keyA.addn(2))).to.equal(false); - expect(await this.bitmap.get(keyA.addn(3))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(4))).to.equal(false); - }); - - it('adds and removes multiple keys', async function () { - // [] - - await this.bitmap.set(keyA); - await this.bitmap.set(keyC); - - // [A, C] - - await this.bitmap.unset(keyA); - await this.bitmap.unset(keyB); - - // [C] - - await this.bitmap.set(keyB); - - // [C, B] - - await this.bitmap.set(keyA); - await this.bitmap.unset(keyC); - - // [A, B] - - await this.bitmap.set(keyA); - await this.bitmap.set(keyB); - - // [A, B] - - await this.bitmap.set(keyC); - await this.bitmap.unset(keyA); - - // [B, C] - - await this.bitmap.set(keyA); - await this.bitmap.unset(keyB); - - // [A, C] - - expect(await this.bitmap.get(keyA)).to.equal(true); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(true); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/DoubleEndedQueue.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/DoubleEndedQueue.test.js deleted file mode 100644 index 545c82a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/DoubleEndedQueue.test.js +++ /dev/null @@ -1,96 +0,0 @@ -const { expectEvent } = require('@openzeppelin/test-helpers'); -const { expectRevertCustomError } = require('../../helpers/customError'); - -const Bytes32DequeMock = artifacts.require('Bytes32DequeMock'); - -/** Rebuild the content of the deque as a JS array. */ -async function getContent (deque) { - const length = await deque.length().then(bn => bn.toNumber()); - const values = await Promise.all(Array(length).fill().map((_, i) => deque.at(i))); - return values; -} - -contract('DoubleEndedQueue', function (accounts) { - const bytesA = '0xdeadbeef'.padEnd(66, '0'); - const bytesB = '0x0123456789'.padEnd(66, '0'); - const bytesC = '0x42424242'.padEnd(66, '0'); - const bytesD = '0x171717'.padEnd(66, '0'); - - beforeEach(async function () { - this.deque = await Bytes32DequeMock.new(); - }); - - describe('when empty', function () { - it('getters', async function () { - expect(await this.deque.empty()).to.be.equal(true); - expect(await getContent(this.deque)).to.have.ordered.members([]); - }); - - it('reverts on accesses', async function () { - await expectRevertCustomError(this.deque.popBack(), 'Empty()'); - await expectRevertCustomError(this.deque.popFront(), 'Empty()'); - await expectRevertCustomError(this.deque.back(), 'Empty()'); - await expectRevertCustomError(this.deque.front(), 'Empty()'); - }); - }); - - describe('when not empty', function () { - beforeEach(async function () { - await this.deque.pushBack(bytesB); - await this.deque.pushFront(bytesA); - await this.deque.pushBack(bytesC); - this.content = [ bytesA, bytesB, bytesC ]; - }); - - it('getters', async function () { - expect(await this.deque.empty()).to.be.equal(false); - expect(await this.deque.length()).to.be.bignumber.equal(this.content.length.toString()); - expect(await this.deque.front()).to.be.equal(this.content[0]); - expect(await this.deque.back()).to.be.equal(this.content[this.content.length - 1]); - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - - it('out of bounds access', async function () { - await expectRevertCustomError(this.deque.at(this.content.length), 'OutOfBounds()'); - }); - - describe('push', function () { - it('front', async function () { - await this.deque.pushFront(bytesD); - this.content.unshift(bytesD); // add element at the beginning - - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - - it('back', async function () { - await this.deque.pushBack(bytesD); - this.content.push(bytesD); // add element at the end - - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - }); - - describe('pop', function () { - it('front', async function () { - const value = this.content.shift(); // remove first element - expectEvent(await this.deque.popFront(), 'OperationResult', { value }); - - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - - it('back', async function () { - const value = this.content.pop(); // remove last element - expectEvent(await this.deque.popBack(), 'OperationResult', { value }); - - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - }); - - it('clear', async function () { - await this.deque.clear(); - - expect(await this.deque.empty()).to.be.equal(true); - expect(await getContent(this.deque)).to.have.ordered.members([]); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableMap.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableMap.behavior.js deleted file mode 100644 index b1d0d0d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableMap.behavior.js +++ /dev/null @@ -1,181 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const zip = require('lodash.zip'); - -function shouldBehaveLikeMap (keys, values, zeroValue) { - const [keyA, keyB, keyC] = keys; - const [valueA, valueB, valueC] = values; - - async function expectMembersMatch (map, keys, values) { - expect(keys.length).to.equal(values.length); - - await Promise.all(keys.map(async key => - expect(await map.contains(key)).to.equal(true), - )); - - expect(await map.length()).to.bignumber.equal(keys.length.toString()); - - expect( - (await Promise.all(keys.map(key => map.get(key)))).map(k => k.toString()), - ).to.have.same.members( - values.map(value => value.toString()), - ); - - // To compare key-value pairs, we zip keys and values, and convert BNs to - // strings to workaround Chai limitations when dealing with nested arrays - expect(await Promise.all([...Array(keys.length).keys()].map(async (index) => { - const entry = await map.at(index); - return [entry.key.toString(), entry.value.toString()]; - }))).to.have.same.deep.members( - zip(keys.map(k => k.toString()), values.map(v => v.toString())), - ); - } - - it('starts empty', async function () { - expect(await this.map.contains(keyA)).to.equal(false); - - await expectMembersMatch(this.map, [], []); - }); - - describe('set', function () { - it('adds a key', async function () { - const receipt = await this.map.set(keyA, valueA); - expectEvent(receipt, 'OperationResult', { result: true }); - - await expectMembersMatch(this.map, [keyA], [valueA]); - }); - - it('adds several keys', async function () { - await this.map.set(keyA, valueA); - await this.map.set(keyB, valueB); - - await expectMembersMatch(this.map, [keyA, keyB], [valueA, valueB]); - expect(await this.map.contains(keyC)).to.equal(false); - }); - - it('returns false when adding keys already in the set', async function () { - await this.map.set(keyA, valueA); - - const receipt = (await this.map.set(keyA, valueA)); - expectEvent(receipt, 'OperationResult', { result: false }); - - await expectMembersMatch(this.map, [keyA], [valueA]); - }); - - it('updates values for keys already in the set', async function () { - await this.map.set(keyA, valueA); - - await this.map.set(keyA, valueB); - - await expectMembersMatch(this.map, [keyA], [valueB]); - }); - }); - - describe('remove', function () { - it('removes added keys', async function () { - await this.map.set(keyA, valueA); - - const receipt = await this.map.remove(keyA); - expectEvent(receipt, 'OperationResult', { result: true }); - - expect(await this.map.contains(keyA)).to.equal(false); - await expectMembersMatch(this.map, [], []); - }); - - it('returns false when removing keys not in the set', async function () { - const receipt = await this.map.remove(keyA); - expectEvent(receipt, 'OperationResult', { result: false }); - - expect(await this.map.contains(keyA)).to.equal(false); - }); - - it('adds and removes multiple keys', async function () { - // [] - - await this.map.set(keyA, valueA); - await this.map.set(keyC, valueC); - - // [A, C] - - await this.map.remove(keyA); - await this.map.remove(keyB); - - // [C] - - await this.map.set(keyB, valueB); - - // [C, B] - - await this.map.set(keyA, valueA); - await this.map.remove(keyC); - - // [A, B] - - await this.map.set(keyA, valueA); - await this.map.set(keyB, valueB); - - // [A, B] - - await this.map.set(keyC, valueC); - await this.map.remove(keyA); - - // [B, C] - - await this.map.set(keyA, valueA); - await this.map.remove(keyB); - - // [A, C] - - await expectMembersMatch(this.map, [keyA, keyC], [valueA, valueC]); - - expect(await this.map.contains(keyB)).to.equal(false); - }); - }); - - describe('read', function () { - beforeEach(async function () { - await this.map.set(keyA, valueA); - }); - - describe('get', function () { - it('existing value', async function () { - expect( - (await this.map.get(keyA)).toString(), - ).to.be.equal(valueA.toString()); - }); - it('missing value', async function () { - await expectRevert(this.map.get(keyB), 'EnumerableMap: nonexistent key'); - }); - }); - - describe('get with message', function () { - it('existing value', async function () { - expect( - (await this.map.getWithMessage(keyA, 'custom error string')) - .toString(), - ).to.be.equal(valueA.toString()); - }); - it('missing value', async function () { - await expectRevert(this.map.getWithMessage(keyB, 'custom error string'), 'custom error string'); - }); - }); - - describe('tryGet', function () { - it('existing value', async function () { - const result = await this.map.tryGet(keyA); - expect(result['0']).to.be.equal(true); - expect(result['1'].toString()).to.be.equal(valueA.toString()); - }); - it('missing value', async function () { - const result = await this.map.tryGet(keyB); - expect(result['0']).to.be.equal(false); - expect(result['1'].toString()).to.be.equal(zeroValue.toString()); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeMap, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableMap.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableMap.test.js deleted file mode 100644 index 58f4eb8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableMap.test.js +++ /dev/null @@ -1,86 +0,0 @@ -const { BN, constants } = require('@openzeppelin/test-helpers'); - -const AddressToUintMapMock = artifacts.require('AddressToUintMapMock'); -const UintToAddressMapMock = artifacts.require('UintToAddressMapMock'); -const Bytes32ToBytes32MapMock = artifacts.require('Bytes32ToBytes32MapMock'); -const UintToUintMapMock = artifacts.require('UintToUintMapMock'); -const Bytes32ToUintMapMock = artifacts.require('Bytes32ToUintMapMock'); - -const { shouldBehaveLikeMap } = require('./EnumerableMap.behavior'); - -contract('EnumerableMap', function (accounts) { - const [ accountA, accountB, accountC ] = accounts; - - const keyA = new BN('7891'); - const keyB = new BN('451'); - const keyC = new BN('9592328'); - - const bytesA = '0xdeadbeef'.padEnd(66, '0'); - const bytesB = '0x0123456789'.padEnd(66, '0'); - const bytesC = '0x42424242'.padEnd(66, '0'); - - // AddressToUintMap - describe('AddressToUintMap', function () { - beforeEach(async function () { - this.map = await AddressToUintMapMock.new(); - }); - - shouldBehaveLikeMap( - [ accountA, accountB, accountC ], - [ keyA, keyB, keyC ], - new BN('0'), - ); - }); - - // UintToAddressMap - describe('UintToAddressMap', function () { - beforeEach(async function () { - this.map = await UintToAddressMapMock.new(); - }); - - shouldBehaveLikeMap( - [ keyA, keyB, keyC ], - [ accountA, accountB, accountC ], - constants.ZERO_ADDRESS, - ); - }); - - // Bytes32ToBytes32Map - describe('Bytes32ToBytes32Map', function () { - beforeEach(async function () { - this.map = await Bytes32ToBytes32MapMock.new(); - }); - - shouldBehaveLikeMap( - [ keyA, keyB, keyC ].map(k => '0x' + k.toString(16).padEnd(64, '0')), - [ bytesA, bytesB, bytesC ], - constants.ZERO_BYTES32, - ); - }); - - // UintToUintMap - describe('UintToUintMap', function () { - beforeEach(async function () { - this.map = await UintToUintMapMock.new(); - }); - - shouldBehaveLikeMap( - [ keyA, keyB, keyC ], - [ keyA, keyB, keyC ].map(k => k.add(new BN('1332'))), - new BN('0'), - ); - }); - - // Bytes32ToUintMap - describe('Bytes32ToUintMap', function () { - beforeEach(async function () { - this.map = await Bytes32ToUintMapMock.new(); - }); - - shouldBehaveLikeMap( - [ bytesA, bytesB, bytesC ], - [ keyA, keyB, keyC ], - new BN('0'), - ); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableSet.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableSet.behavior.js deleted file mode 100644 index 17e0866..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableSet.behavior.js +++ /dev/null @@ -1,131 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -function shouldBehaveLikeSet (valueA, valueB, valueC) { - async function expectMembersMatch (set, values) { - const contains = await Promise.all(values.map(value => set.contains(value))); - expect(contains.every(Boolean)).to.be.equal(true); - - const length = await set.length(); - expect(length).to.bignumber.equal(values.length.toString()); - - // To compare values we convert to strings to workaround Chai - // limitations when dealing with nested arrays (required for BNs) - const indexedValues = await Promise.all(Array(values.length).fill().map((_, index) => set.at(index))); - expect( - indexedValues.map(v => v.toString()), - ).to.have.same.members( - values.map(v => v.toString()), - ); - - const returnedValues = await set.values(); - expect( - returnedValues.map(v => v.toString()), - ).to.have.same.members( - values.map(v => v.toString()), - ); - } - - it('starts empty', async function () { - expect(await this.set.contains(valueA)).to.equal(false); - - await expectMembersMatch(this.set, []); - }); - - describe('add', function () { - it('adds a value', async function () { - const receipt = await this.set.add(valueA); - expectEvent(receipt, 'OperationResult', { result: true }); - - await expectMembersMatch(this.set, [valueA]); - }); - - it('adds several values', async function () { - await this.set.add(valueA); - await this.set.add(valueB); - - await expectMembersMatch(this.set, [valueA, valueB]); - expect(await this.set.contains(valueC)).to.equal(false); - }); - - it('returns false when adding values already in the set', async function () { - await this.set.add(valueA); - - const receipt = (await this.set.add(valueA)); - expectEvent(receipt, 'OperationResult', { result: false }); - - await expectMembersMatch(this.set, [valueA]); - }); - }); - - describe('at', function () { - it('reverts when retrieving non-existent elements', async function () { - await expectRevert.unspecified(this.set.at(0)); - }); - }); - - describe('remove', function () { - it('removes added values', async function () { - await this.set.add(valueA); - - const receipt = await this.set.remove(valueA); - expectEvent(receipt, 'OperationResult', { result: true }); - - expect(await this.set.contains(valueA)).to.equal(false); - await expectMembersMatch(this.set, []); - }); - - it('returns false when removing values not in the set', async function () { - const receipt = await this.set.remove(valueA); - expectEvent(receipt, 'OperationResult', { result: false }); - - expect(await this.set.contains(valueA)).to.equal(false); - }); - - it('adds and removes multiple values', async function () { - // [] - - await this.set.add(valueA); - await this.set.add(valueC); - - // [A, C] - - await this.set.remove(valueA); - await this.set.remove(valueB); - - // [C] - - await this.set.add(valueB); - - // [C, B] - - await this.set.add(valueA); - await this.set.remove(valueC); - - // [A, B] - - await this.set.add(valueA); - await this.set.add(valueB); - - // [A, B] - - await this.set.add(valueC); - await this.set.remove(valueA); - - // [B, C] - - await this.set.add(valueA); - await this.set.remove(valueB); - - // [A, C] - - await expectMembersMatch(this.set, [valueA, valueC]); - - expect(await this.set.contains(valueB)).to.equal(false); - }); - }); -} - -module.exports = { - shouldBehaveLikeSet, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableSet.test.js b/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableSet.test.js deleted file mode 100644 index 2b7d0a3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts-upgradeable/test/utils/structs/EnumerableSet.test.js +++ /dev/null @@ -1,46 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const EnumerableBytes32SetMock = artifacts.require('EnumerableBytes32SetMock'); -const EnumerableAddressSetMock = artifacts.require('EnumerableAddressSetMock'); -const EnumerableUintSetMock = artifacts.require('EnumerableUintSetMock'); - -const { shouldBehaveLikeSet } = require('./EnumerableSet.behavior'); - -contract('EnumerableSet', function (accounts) { - // Bytes32Set - describe('EnumerableBytes32Set', function () { - const bytesA = '0xdeadbeef'.padEnd(66, '0'); - const bytesB = '0x0123456789'.padEnd(66, '0'); - const bytesC = '0x42424242'.padEnd(66, '0'); - - beforeEach(async function () { - this.set = await EnumerableBytes32SetMock.new(); - }); - - shouldBehaveLikeSet(bytesA, bytesB, bytesC); - }); - - // AddressSet - describe('EnumerableAddressSet', function () { - const [accountA, accountB, accountC] = accounts; - - beforeEach(async function () { - this.set = await EnumerableAddressSetMock.new(); - }); - - shouldBehaveLikeSet(accountA, accountB, accountC); - }); - - // UintSet - describe('EnumerableUintSet', function () { - const uintA = new BN('1234'); - const uintB = new BN('5678'); - const uintC = new BN('9101112'); - - beforeEach(async function () { - this.set = await EnumerableUintSetMock.new(); - }); - - shouldBehaveLikeSet(uintA, uintB, uintC); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.codecov.yml b/lib/morpho-utils/lib/openzeppelin-contracts/.codecov.yml deleted file mode 100644 index 54616a4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.codecov.yml +++ /dev/null @@ -1,11 +0,0 @@ -comment: off -github_checks: - annotations: false -coverage: - status: - patch: - default: - target: 95% - project: - default: - threshold: 1% diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.editorconfig b/lib/morpho-utils/lib/openzeppelin-contracts/.editorconfig deleted file mode 100644 index f162e8d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.editorconfig +++ /dev/null @@ -1,21 +0,0 @@ -# EditorConfig is awesome: https://EditorConfig.org - -# top-most EditorConfig file -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = false -max_line_length = 120 - -[*.sol] -indent_size = 4 - -[*.js] -indent_size = 2 - -[*.{adoc,md}] -max_line_length = 0 diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.eslintrc b/lib/morpho-utils/lib/openzeppelin-contracts/.eslintrc deleted file mode 100644 index 250e21c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.eslintrc +++ /dev/null @@ -1,62 +0,0 @@ -{ - "extends" : [ - "standard" - ], - "plugins": [ - "mocha" - ], - "env": { - "browser" : true, - "node" : true, - "mocha" : true, - "jest" : true, - }, - "globals" : { - "artifacts": false, - "contract": false, - "assert": false, - "web3": false, - "usePlugin": false, - "extendEnvironment": false, - }, - "rules": { - - // Strict mode - "strict": ["error", "global"], - - // Code style - "array-bracket-spacing": ["off"], - "camelcase": ["error", {"properties": "always"}], - "comma-dangle": ["error", "always-multiline"], - "comma-spacing": ["error", {"before": false, "after": true}], - "dot-notation": ["error", {"allowKeywords": true, "allowPattern": ""}], - "eol-last": ["error", "always"], - "eqeqeq": ["error", "smart"], - "generator-star-spacing": ["error", "before"], - "indent": ["error", 2], - "linebreak-style": ["error", "unix"], - "max-len": ["error", 120, 2], - "no-debugger": "off", - "no-dupe-args": "error", - "no-dupe-keys": "error", - "no-mixed-spaces-and-tabs": ["error", "smart-tabs"], - "no-redeclare": ["error", {"builtinGlobals": true}], - "no-trailing-spaces": ["error", { "skipBlankLines": false }], - "no-undef": "error", - "no-use-before-define": "off", - "no-var": "error", - "object-curly-spacing": ["error", "always"], - "prefer-const": "error", - "quotes": ["error", "single"], - "semi": ["error", "always"], - "space-before-function-paren": ["error", "always"], - - "mocha/no-exclusive-tests": ["error"], - - "promise/always-return": "off", - "promise/avoid-new": "off", - }, - "parserOptions": { - "ecmaVersion": 2018 - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.gitattributes b/lib/morpho-utils/lib/openzeppelin-contracts/.gitattributes deleted file mode 100644 index 52031de..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.sol linguist-language=Solidity diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md b/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 2797a08..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: Bug report -about: Report a bug in OpenZeppelin Contracts - ---- - - - - - -**💻 Environment** - - - -**📝 Details** - - - -**🔢 Code to reproduce bug** - - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml b/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 4018cef..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,4 +0,0 @@ -contact_links: - - name: Questions & Support Requests - url: https://forum.openzeppelin.com/c/support/contracts/18 - about: Ask in the OpenZeppelin Forum diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md b/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index ff596b0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for OpenZeppelin Contracts - ---- - -**🧐 Motivation** - - -**📝 Details** - - - - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md b/lib/morpho-utils/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 469c645..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -Fixes #???? - - - - - -#### PR Checklist - - - - - -- [ ] Tests -- [ ] Documentation -- [ ] Changelog entry diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml b/lib/morpho-utils/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml deleted file mode 100644 index e38c48e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Compare gas costs -inputs: - token: - description: github token - required: true - report: - description: report to read from - required: false - default: gasReporterOutput.json - out_report: - description: report to read - required: false - default: ${{ github.ref_name }}.gasreport.json - ref_report: - description: report to read from - required: false - default: ${{ github.base_ref }}.gasreport.json - -runs: - using: composite - steps: - - name: Download reference report - if: github.event_name == 'pull_request' - run: | - RUN_ID=`gh run list --repo ${{ github.repository }} --branch ${{ github.base_ref }} --workflow ${{ github.workflow }} --limit 100 --json 'conclusion,databaseId,event' --jq 'map(select(.conclusion=="success" and .event!="pull_request"))[0].databaseId'` - gh run download ${RUN_ID} --repo ${{ github.repository }} -n gasreport - env: - GITHUB_TOKEN: ${{ inputs.token }} - shell: bash - continue-on-error: true - id: reference - - name: Compare reports - if: steps.reference.outcome == 'success' && github.event_name == 'pull_request' - run: | - node scripts/checks/compareGasReports.js ${{ inputs.report }} ${{ inputs.ref_report }} >> $GITHUB_STEP_SUMMARY - env: - STYLE: markdown - shell: bash - - name: Rename report for upload - if: github.event_name != 'pull_request' - run: | - mv ${{ inputs.report }} ${{ inputs.out_report }} - shell: bash - - name: Save report - if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v3 - with: - name: gasreport - path: ${{ inputs.out_report }} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/actions/setup/action.yml b/lib/morpho-utils/lib/openzeppelin-contracts/.github/actions/setup/action.yml deleted file mode 100644 index 9e562eb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/actions/setup/action.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Setup - -runs: - using: composite - steps: - - uses: actions/setup-node@v3 - with: - node-version: 14.x - cache: npm - - uses: actions/cache@v3 - id: cache - with: - path: '**/node_modules' - key: npm-v3-${{ hashFiles('**/package-lock.json') }} - - name: Install dependencies - run: npm ci --prefer-offline - shell: bash - if: steps.cache.outputs.cache-hit != 'true' - env: - SKIP_COMPILE: true diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/checks.yml b/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/checks.yml deleted file mode 100644 index 999d588..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/checks.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: checks - -on: - push: - branches: - - master - - release-v* - pull_request: {} - workflow_dispatch: {} - -concurrency: - group: checks-${{ github.ref }} - cancel-in-progress: true - -jobs: - lint: - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - run: npm run lint - - tests: - runs-on: ubuntu-latest - env: - FORCE_COLOR: 1 - GAS: true - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - name: Run tests and generate gas report - run: npm run test - - name: Check linearisation of the inheritance graph - run: npm run test:inheritance - - name: Check proceduraly generated contracts are up-to-date - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - run: npm run test:generation - - name: Compare gas costs - uses: ./.github/actions/gas-compare - with: - token: ${{ github.token }} - - coverage: - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - run: npm run coverage - env: - NODE_OPTIONS: --max_old_space_size=4096 - - uses: codecov/codecov-action@v3 - - slither: - if: github.repository != 'OpenZeppelin/openzeppelin-contracts-upgradeable' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - uses: crytic/slither-action@v0.1.1 diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/docs.yml b/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/docs.yml deleted file mode 100644 index 526fe60..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/docs.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Build Docs - -on: - push: - branches: [release-v*] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up environment - uses: ./.github/actions/setup - - run: bash scripts/git-user-config.sh - - run: node scripts/update-docs-branch.js - - run: git push --all origin diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml b/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml deleted file mode 100644 index a94f78c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Upgradeable Trigger - -on: - push: - branches: - - master - - release-v* - -jobs: - trigger: - runs-on: ubuntu-latest - steps: - - id: app - uses: getsentry/action-github-app-token@v1 - with: - app_id: ${{ secrets.UPGRADEABLE_APP_ID }} - private_key: ${{ secrets.UPGRADEABLE_APP_PK }} - - run: | - curl -X POST \ - https://api.github.com/repos/OpenZeppelin/openzeppelin-contracts-upgradeable/dispatches \ - -H 'Accept: application/vnd.github.v3+json' \ - -H 'Authorization: token ${{ steps.app.outputs.token }}' \ - -d '{ "event_type": "Update", "client_payload": { "ref": "${{ github.ref }}" } }' diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.gitignore b/lib/morpho-utils/lib/openzeppelin-contracts/.gitignore deleted file mode 100644 index c60c5d9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.gitignore +++ /dev/null @@ -1,64 +0,0 @@ -*.swp -*.swo - -# Logs -logs -*.log - -# Runtime data -pids -*.pid -*.seed -allFiredEvents -scTopics - -# Coverage directory used by tools like istanbul -coverage -coverage.json -coverageEnv - -# node-waf configuration -.lock-wscript - -# Dependency directory -node_modules - -# Debug log from npm -npm-debug.log - -# local env variables -.env - -# truffle build directory -build/ - -# macOS -.DS_Store - -# truffle -.node-xmlhttprequest-* - -# IntelliJ IDE -.idea - -# docs artifacts -docs/modules/api - -# only used to package @openzeppelin/contracts -contracts/build/ -contracts/README.md - -# temporary artifact from solidity-coverage -allFiredEvents -.coverage_artifacts -.coverage_cache -.coverage_contracts - -# hardhat -cache -artifacts - -# Certora -.certora* -.last_confs -certora_* diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.mocharc.js b/lib/morpho-utils/lib/openzeppelin-contracts/.mocharc.js deleted file mode 100644 index 920662d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.mocharc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - require: 'hardhat/register', - timeout: 4000, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.prettierrc b/lib/morpho-utils/lib/openzeppelin-contracts/.prettierrc deleted file mode 100644 index f91ad7e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.prettierrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "all", - "overrides": [ - { - "files": "*.sol", - "options": { - "singleQuote": false, - "printWidth": 120, - "explicitTypes": "always" - } - } - ] -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.solcover.js b/lib/morpho-utils/lib/openzeppelin-contracts/.solcover.js deleted file mode 100644 index 6cf991e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.solcover.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - norpc: true, - testCommand: 'npm test', - compileCommand: 'npm run compile', - skipFiles: [ - 'mocks', - ], - providerOptions: { - default_balance_ether: '10000000000000000000000000', - }, - mocha: { - fgrep: '[skip-on-coverage]', - invert: true, - }, -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/.solhint.json b/lib/morpho-utils/lib/openzeppelin-contracts/.solhint.json deleted file mode 100644 index 7729288..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/.solhint.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "rules": { - "no-unused-vars": "error", - "const-name-snakecase": "error", - "contract-name-camelcase": "error", - "event-name-camelcase": "error", - "func-name-mixedcase": "error", - "func-param-name-mixedcase": "error", - "modifier-name-mixedcase": "error", - "private-vars-leading-underscore": "error", - "var-name-mixedcase": "error", - "imports-on-top": "error" - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/CHANGELOG.md b/lib/morpho-utils/lib/openzeppelin-contracts/CHANGELOG.md deleted file mode 100644 index 62fb898..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/CHANGELOG.md +++ /dev/null @@ -1,532 +0,0 @@ -# Changelog - -## Unreleased - - * `ERC165Checker`: add `supportsERC165InterfaceUnchecked` for consulting individual interfaces without the full ERC165 protocol. ([#3339](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3339)) - * `Address`: optimize `functionCall` by calling `functionCallWithValue` directly. ([#3468](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3468)) - * `Address`: optimize `functionCall` functions by checking contract size only if there is no returned data. ([#3469](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3469)) - * `GovernorCompatibilityBravo`: remove unused `using` statements ([#3506](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3506)) - * `ERC20`: optimize `_transfer`, `_mint` and `_burn` by using `unchecked` arithmetic when possible. ([#3513](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3513)) - * `ERC721`: optimize transfers by making approval clearing implicit instead of emitting an event. ([#3481](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3481)) - * `ERC721`: optimize burn by making approval clearing implicit instead of emitting an event. ([#3538](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3538)) - * `ReentrancyGuard`: Reduce code size impact of the modifier by using internal functions. ([#3515](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3515)) - * `SafeCast`: optimize downcasting of signed integers. ([#3565](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3565)) - -### Compatibility Note - -ERC-721 integrators that interpret contract state from events should make sure that they implement the clearing of approval that is implicit in every transfer according to the EIP. Previous versions of OpenZeppellin Contracts emitted an explicit `Approval` event even though it was not required by the specification, and this is no longer the case. - -## 4.7.1 - - * `SignatureChecker`: Fix an issue that causes `isValidSignatureNow` to revert when the target contract returns ill-encoded data. ([#3552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3552)) - * `ERC165Checker`: Fix an issue that causes `supportsInterface` to revert when the target contract returns ill-encoded data. ([#3552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3552)) - -## 4.7.0 (2022-06-29) - - * `TimelockController`: Migrate `_call` to `_execute` and allow inheritance and overriding similar to `Governor`. ([#3317](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3317)) - * `CrossChainEnabledPolygonChild`: replace the `require` statement with the custom error `NotCrossChainCall`. ([#3380](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3380)) - * `ERC20FlashMint`: Add customizable flash fee receiver. ([#3327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3327)) - * `ERC4626`: add an extension of `ERC20` that implements the ERC4626 Tokenized Vault Standard. ([#3171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3171)) - * `SafeERC20`: add `safePermit` as mitigation against phantom permit functions. ([#3280](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3280)) - * `Math`: add a `mulDiv` function that can round the result either up or down. ([#3171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3171)) - * `Math`: Add a `sqrt` function to compute square roots of integers, rounding either up or down. ([#3242](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3242)) - * `Strings`: add a new overloaded function `toHexString` that converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. ([#3403](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3403)) - * `EnumerableMap`: add new `UintToUintMap` map type. ([#3338](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3338)) - * `EnumerableMap`: add new `Bytes32ToUintMap` map type. ([#3416](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3416)) - * `SafeCast`: add support for many more types, using procedural code generation. ([#3245](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3245)) - * `MerkleProof`: add `multiProofVerify` to prove multiple values are part of a Merkle tree. ([#3276](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3276)) - * `MerkleProof`: add calldata versions of the functions to avoid copying input arrays to memory and save gas. ([#3200](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3200)) - * `ERC721`, `ERC1155`: simplified revert reasons. ([#3254](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3254), ([#3438](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3438))) - * `ERC721`: removed redundant require statement. ([#3434](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3434)) - * `PaymentSplitter`: add `releasable` getters. ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) - * `Initializable`: refactored implementation of modifiers for easier understanding. ([#3450](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3450)) - * `Proxies`: remove runtime check of ERC1967 storage slots. ([#3455](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3455)) - -### Breaking changes - - * `Initializable`: functions decorated with the modifier `reinitializer(1)` may no longer invoke each other. - -## 4.6.0 (2022-04-26) - - * `crosschain`: Add a new set of contracts for cross-chain applications. `CrossChainEnabled` is a base contract with instantiations for several chains and bridges, and `AccessControlCrossChain` is an extension of access control that allows cross-chain operation. ([#3183](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3183)) - * `AccessControl`: add a virtual `_checkRole(bytes32)` function that can be overridden to alter the `onlyRole` modifier behavior. ([#3137](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3137)) - * `EnumerableMap`: add new `AddressToUintMap` map type. ([#3150](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3150)) - * `EnumerableMap`: add new `Bytes32ToBytes32Map` map type. ([#3192](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3192)) - * `ERC20FlashMint`: support infinite allowance when paying back a flash loan. ([#3226](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3226)) - * `ERC20Wrapper`: the `decimals()` function now tries to fetch the value from the underlying token instance. If that calls revert, then the default value is used. ([#3259](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3259)) - * `draft-ERC20Permit`: replace `immutable` with `constant` for `_PERMIT_TYPEHASH` since the `keccak256` of string literals is treated specially and the hash is evaluated at compile time. ([#3196](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3196)) - * `ERC1155`: Add a `_afterTokenTransfer` hook for improved extensibility. ([#3166](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3166)) - * `ERC1155URIStorage`: add a new extension that implements a `_setURI` behavior similar to ERC721's `_setTokenURI`. ([#3210](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3210)) - * `DoubleEndedQueue`: a new data structure that supports efficient push and pop to both front and back, useful for FIFO and LIFO queues. ([#3153](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3153)) - * `Governor`: improved security of `onlyGovernance` modifier when using an external executor contract (e.g. a timelock) that can operate without necessarily going through the governance protocol. ([#3147](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3147)) - * `Governor`: Add a way to parameterize votes. This can be used to implement voting systems such as fractionalized voting, ERC721 based voting, or any number of other systems. The `params` argument added to `_countVote` method, and included in the newly added `_getVotes` method, can be used by counting and voting modules respectively for such purposes. ([#3043](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3043)) - * `Governor`: rewording of revert reason for consistency. ([#3275](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3275)) - * `Governor`: fix an inconsistency in data locations that could lead to invalid bytecode being produced. ([#3295](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3295)) - * `Governor`: Implement `IERC721Receiver` and `IERC1155Receiver` to improve token custody by governors. ([#3230](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3230)) - * `TimelockController`: Implement `IERC721Receiver` and `IERC1155Receiver` to improve token custody by timelocks. ([#3230](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3230)) - * `TimelockController`: Add a separate canceller role for the ability to cancel. ([#3165](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3165)) - * `Initializable`: add a reinitializer modifier that enables the initialization of new modules, added to already initialized contracts through upgradeability. ([#3232](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3232)) - * `Initializable`: add an Initialized event that tracks initialized version numbers. ([#3294](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3294)) - * `ERC2981`: make `royaltyInfo` public to allow super call in overrides. ([#3305](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3305)) - -### Upgradeability notice - -* `TimelockController`: **(Action needed)** The upgrade from <4.6 to >=4.6 introduces a new `CANCELLER_ROLE` that requires set up to be assignable. After the upgrade, only addresses with this role will have the ability to cancel. Proposers will no longer be able to cancel. Assigning cancellers can be done by an admin (including the timelock itself) once the role admin is set up. To do this, we recommend upgrading to the `TimelockControllerWith46MigrationUpgradeable` contract and then calling the `migrateTo46` function. - -### Breaking changes - -* `Governor`: Adds internal virtual `_getVotes` method that must be implemented; this is a breaking change for existing concrete extensions to `Governor`. To fix this on an existing voting module extension, rename `getVotes` to `_getVotes` and add a `bytes memory` argument. ([#3043](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3043)) -* `Governor`: Adds `params` parameter to internal virtual `_countVote ` method; this is a breaking change for existing concrete extensions to `Governor`. To fix this on an existing counting module extension, add a `bytes memory` argument to `_countVote`. ([#3043](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3043)) -* `Governor`: Does not emit `VoteCast` event when params data is non-empty; instead emits `VoteCastWithParams` event. To fix this on an integration that consumes the `VoteCast` event, also fetch/monitor `VoteCastWithParams` events. ([#3043](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3043)) -* `Votes`: The internal virtual function `_getVotingUnits` was made `view` (which was accidentally missing). Any overrides should now be updated so they are `view` as well. - -## 4.5.0 (2022-02-09) - - * `ERC2981`: add implementation of the royalty standard, and the respective extensions for `ERC721` and `ERC1155`. ([#3012](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3012)) - * `GovernorTimelockControl`: improve the `state()` function to have it reflect cases where a proposal has been canceled directly on the timelock. ([#2977](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2977)) - * Preset contracts are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com). ([#2986](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2986)) - * `Governor`: add a relay function to help recover assets sent to a governor that is not its own executor (e.g. when using a timelock). ([#2926](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2926)) - * `GovernorPreventLateQuorum`: add new module to ensure a minimum voting duration is available after the quorum is reached. ([#2973](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2973)) - * `ERC721`: improved revert reason when transferring from wrong owner. ([#2975](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2975)) - * `Votes`: Added a base contract for vote tracking with delegation. ([#2944](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2944)) - * `ERC721Votes`: Added an extension of ERC721 enabled with vote tracking and delegation. ([#2944](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2944)) - * `ERC2771Context`: use immutable storage to store the forwarder address, no longer an issue since Solidity >=0.8.8 allows reading immutable variables in the constructor. ([#2917](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2917)) - * `Base64`: add a library to parse bytes into base64 strings using `encode(bytes memory)` function, and provide examples to show how to use to build URL-safe `tokenURIs`. ([#2884](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2884)) - * `ERC20`: reduce allowance before triggering transfer. ([#3056](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3056)) - * `ERC20`: do not update allowance on `transferFrom` when allowance is `type(uint256).max`. ([#3085](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3085)) - * `ERC20`: add a `_spendAllowance` internal function. ([#3170](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3170)) - * `ERC20Burnable`: do not update allowance on `burnFrom` when allowance is `type(uint256).max`. ([#3170](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3170)) - * `ERC777`: do not update allowance on `transferFrom` when allowance is `type(uint256).max`. ([#3085](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3085)) - * `ERC777`: add a `_spendAllowance` internal function. ([#3170](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3170)) - * `SignedMath`: a new signed version of the Math library with `max`, `min`, and `average`. ([#2686](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2686)) - * `SignedMath`: add a `abs(int256)` method that returns the unsigned absolute value of a signed value. ([#2984](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2984)) - * `ERC1967Upgrade`: Refactor the secure upgrade to use `ERC1822` instead of the previous rollback mechanism. This reduces code complexity and attack surface with similar security guarantees. ([#3021](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3021)) - * `UUPSUpgradeable`: Add `ERC1822` compliance to support the updated secure upgrade mechanism. ([#3021](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3021)) - * Some more functions have been made virtual to customize them via overrides. In many cases this will not imply that other functions in the contract will automatically adapt to the overridden definitions. People who wish to override should consult the source code to understand the impact and if they need to override any additional functions to achieve the desired behavior. - -### Breaking changes - -* `ERC1967Upgrade`: The function `_upgradeToAndCallSecure` was renamed to `_upgradeToAndCallUUPS`, along with the change in security mechanism described above. -* `Address`: The Solidity pragma is increased from `^0.8.0` to `^0.8.1`. This is required by the `account.code.length` syntax that replaces inline assembly. This may require users to bump their compiler version from `0.8.0` to `0.8.1` or later. Note that other parts of the code already include stricter requirements. - -## 4.4.2 (2022-01-11) - -### Bugfixes - * `GovernorCompatibilityBravo`: Fix error in the encoding of calldata for proposals submitted through the compatibility interface with explicit signatures. ([#3100](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3100)) - -## 4.4.1 (2021-12-14) - - * `Initializable`: change the existing `initializer` modifier and add a new `onlyInitializing` modifier to prevent reentrancy risk. ([#3006](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3006)) - -### Breaking change - -It is no longer possible to call an `initializer`-protected function from within another `initializer` function outside the context of a constructor. Projects using OpenZeppelin upgradeable proxies should continue to work as is, since in the common case the initializer is invoked in the constructor directly. If this is not the case for you, the suggested change is to use the new `onlyInitializing` modifier in the following way: - -```diff - contract A { -- function initialize() public initializer { ... } -+ function initialize() internal onlyInitializing { ... } - } - contract B is A { - function initialize() public initializer { - A.initialize(); - } - } -``` - -## 4.4.0 (2021-11-25) - - * `Ownable`: add an internal `_transferOwnership(address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568)) - * `AccessControl`: add internal `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568)) - * `AccessControl`: mark `_setupRole(bytes32,address)` as deprecated in favor of `_grantRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2568)) - * `AccessControlEnumerable`: hook into `_grantRole(bytes32,address)` and `_revokeRole(bytes32,address)`. ([#2946](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2946)) - * `EIP712`: cache `address(this)` to immutable storage to avoid potential issues if a vanilla contract is used in a delegatecall context. ([#2852](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2852)) - * Add internal `_setApprovalForAll` to `ERC721` and `ERC1155`. ([#2834](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2834)) - * `Governor`: shift vote start and end by one block to better match Compound's GovernorBravo and prevent voting at the Governor level if the voting snapshot is not ready. ([#2892](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2892)) - * `GovernorCompatibilityBravo`: consider quorum an inclusive rather than exclusive minimum to match Compound's GovernorBravo. ([#2974](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2974)) - * `GovernorSettings`: a new governor module that manages voting settings updatable through governance actions. ([#2904](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2904)) - * `PaymentSplitter`: now supports ERC20 assets in addition to Ether. ([#2858](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2858)) - * `ECDSA`: add a variant of `toEthSignedMessageHash` for arbitrary length message hashing. ([#2865](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2865)) - * `MerkleProof`: add a `processProof` function that returns the rebuilt root hash given a leaf and a proof. ([#2841](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2841)) - * `VestingWallet`: new contract that handles the vesting of Ether and ERC20 tokens following a customizable vesting schedule. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2748)) - * `Governor`: enable receiving Ether when a Timelock contract is not used. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849)) - * `GovernorTimelockCompound`: fix ability to use Ether stored in the Timelock contract. ([#2748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2849)) - -## 4.3.3 - - * `ERC1155Supply`: Handle `totalSupply` changes by hooking into `_beforeTokenTransfer` to ensure consistency of balances and supply during `IERC1155Receiver.onERC1155Received` calls. - -## 4.3.2 (2021-09-14) - - * `UUPSUpgradeable`: Add modifiers to prevent `upgradeTo` and `upgradeToAndCall` being executed on any contract that is not the active ERC1967 proxy. This prevents these functions being called on implementation contracts or minimal ERC1167 clones, in particular. - -## 4.3.1 (2021-08-26) - - * `TimelockController`: Add additional isOperationReady check. - -## 4.3.0 (2021-08-17) - - * `ERC2771Context`: use private variable from storage to store the forwarder address. Fixes issues where `_msgSender()` was not callable from constructors. ([#2754](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2754)) - * `EnumerableSet`: add `values()` functions that returns an array containing all values in a single call. ([#2768](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2768)) - * `Governor`: added a modular system of `Governor` contracts based on `GovernorAlpha` and `GovernorBravo`. ([#2672](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2672)) - * Add an `interfaces` folder containing solidity interfaces to final ERCs. ([#2517](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2517)) - * `ECDSA`: add `tryRecover` functions that will not throw if the signature is invalid, and will return an error flag instead. ([#2661](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2661)) - * `SignatureChecker`: Reduce gas usage of the `isValidSignatureNow` function for the "signature by EOA" case. ([#2661](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2661)) - -## 4.2.0 (2021-06-30) - - * `ERC20Votes`: add a new extension of the `ERC20` token with support for voting snapshots and delegation. ([#2632](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2632)) - * `ERC20VotesComp`: Variant of `ERC20Votes` that is compatible with Compound's `Comp` token interface but restricts supply to `uint96`. ([#2706](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2706)) - * `ERC20Wrapper`: add a new extension of the `ERC20` token which wraps an underlying token. Deposit and withdraw guarantee that the total supply is backed by a corresponding amount of underlying token. ([#2633](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2633)) - * Enumerables: Improve gas cost of removal in `EnumerableSet` and `EnumerableMap`. - * Enumerables: Improve gas cost of lookup in `EnumerableSet` and `EnumerableMap`. - * `Counter`: add a reset method. ([#2678](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2678)) - * Tokens: Wrap definitely safe subtractions in `unchecked` blocks. - * `Math`: Add a `ceilDiv` method for performing ceiling division. - * `ERC1155Supply`: add a new `ERC1155` extension that keeps track of the totalSupply of each tokenId. ([#2593](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2593)) - * `BitMaps`: add a new `BitMaps` library that provides a storage efficient datastructure for `uint256` to `bool` mapping with contiguous keys. ([#2710](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2710)) - -### Breaking Changes - - * `ERC20FlashMint` is no longer a Draft ERC. ([#2673](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2673))) - -**How to update:** Change your import paths by removing the `draft-` prefix from `@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20FlashMint.sol`. - -> See [Releases and Stability: Drafts](https://docs.openzeppelin.com/contracts/4.x/releases-stability#drafts). - -## 4.1.0 (2021-04-29) - - * `IERC20Metadata`: add a new extended interface that includes the optional `name()`, `symbol()` and `decimals()` functions. ([#2561](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2561)) - * `ERC777`: make reception acquirement optional in `_mint`. ([#2552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2552)) - * `ERC20Permit`: add a `_useNonce` to enable further usage of ERC712 signatures. ([#2565](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2565)) - * `ERC20FlashMint`: add an implementation of the ERC3156 extension for flash-minting ERC20 tokens. ([#2543](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2543)) - * `SignatureChecker`: add a signature verification library that supports both EOA and ERC1271 compliant contracts as signers. ([#2532](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2532)) - * `Multicall`: add abstract contract with `multicall(bytes[] calldata data)` function to bundle multiple calls together ([#2608](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2608)) - * `ECDSA`: add support for ERC2098 short-signatures. ([#2582](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2582)) - * `AccessControl`: add a `onlyRole` modifier to restrict specific function to callers bearing a specific role. ([#2609](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2609)) - * `StorageSlot`: add a library for reading and writing primitive types to specific storage slots. ([#2542](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2542)) - * UUPS Proxies: add `UUPSUpgradeable` to implement the UUPS proxy pattern together with `EIP1967Proxy`. ([#2542](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2542)) - -### Breaking changes - -This release includes two small breaking changes in `TimelockController`. - -1. The `onlyRole` modifier in this contract was designed to let anyone through if the role was granted to `address(0)`, - allowing the possibility to to make a role "open", which can be used for `EXECUTOR_ROLE`. This modifier is now - replaced by `AccessControl.onlyRole`, which does not have this ability. The previous behavior was moved to the - modifier `TimelockController.onlyRoleOrOpenRole`. -2. It was possible to make `PROPOSER_ROLE` an open role (as described in the previous item) if it was granted to - `address(0)`. This would affect the `schedule`, `scheduleBatch`, and `cancel` operations in `TimelockController`. - This ability was removed as it does not make sense to open up the `PROPOSER_ROLE` in the same way that it does for - `EXECUTOR_ROLE`. - -## 4.0.0 (2021-03-23) - - * Now targeting the 0.8.x line of Solidity compilers. For 0.6.x (resp 0.7.x) support, use version 3.4.0 (resp 3.4.0-solc-0.7) of OpenZeppelin. - * `Context`: making `_msgData` return `bytes calldata` instead of `bytes memory` ([#2492](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2492)) - * `ERC20`: removed the `_setDecimals` function and the storage slot associated to decimals. ([#2502](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2502)) - * `Strings`: addition of a `toHexString` function. ([#2504](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2504)) - * `EnumerableMap`: change implementation to optimize for `key → value` lookups instead of enumeration. ([#2518](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2518)) - * `GSN`: deprecate GSNv1 support in favor of upcoming support for GSNv2. ([#2521](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2521)) - * `ERC165`: remove uses of storage in the base ERC165 implementation. ERC165 based contracts now use storage-less virtual functions. Old behavior remains available in the `ERC165Storage` extension. ([#2505](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2505)) - * `Initializable`: make initializer check stricter during construction. ([#2531](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2531)) - * `ERC721`: remove enumerability of tokens from the base implementation. This feature is now provided separately through the `ERC721Enumerable` extension. ([#2511](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2511)) - * `AccessControl`: removed enumerability by default for a more lightweight contract. It is now opt-in through `AccessControlEnumerable`. ([#2512](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2512)) - * Meta Transactions: add `ERC2771Context` and a `MinimalForwarder` for meta-transactions. ([#2508](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2508)) - * Overall reorganization of the contract folder to improve clarity and discoverability. ([#2503](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2503)) - * `ERC20Capped`: optimize gas usage by enforcing the check directly in `_mint`. ([#2524](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2524)) - * Rename `UpgradeableProxy` to `ERC1967Proxy`. ([#2547](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2547)) - * `ERC777`: optimize the gas costs of the constructor. ([#2551](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2551)) - * `ERC721URIStorage`: add a new extension that implements the `_setTokenURI` behavior as it was available in 3.4.0. ([#2555](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2555)) - * `AccessControl`: added ERC165 interface detection. ([#2562](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2562)) - * `ERC1155`: make `uri` public so overloading function can call it using super. ([#2576](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2576)) - -### Bug fixes for beta releases - - * `AccessControlEnumerable`: Fixed `renounceRole` not updating enumerable set of addresses for a role. ([#2572](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2572)) - -### How to upgrade from 3.x - -Since this version has moved a few contracts to different directories, users upgrading from a previous version will need to adjust their import statements. To make this easier, the package includes a script that will migrate import statements automatically. After upgrading to the latest version of the package, run: - -``` -npx openzeppelin-contracts-migrate-imports -``` - -Make sure you're using git or another version control system to be able to recover from any potential error in our script. - -### How to upgrade from 4.0-beta.x - -Some further changes have been done between the different beta iterations. Transitions made during this period are configured in the `migrate-imports` script. Consequently, you can upgrade from any previous 4.0-beta.x version using the same script as described in the *How to upgrade from 3.x* section. - -## 3.4.2 - - * `TimelockController`: Add additional isOperationReady check. - -## 3.4.1 (2021-03-03) - - * `ERC721`: made `_approve` an internal function (was private). - -## 3.4.0 (2021-02-02) - - * `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411)) - * `EIP712`: added helpers to verify EIP712 typed data signatures on chain. ([#2418](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2418)) - * `ERC20Permit`: added an implementation of the ERC20 permit extension for gasless token approvals. ([#2237](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237)) - * Presets: added token presets with preminted fixed supply `ERC20PresetFixedSupply` and `ERC777PresetFixedSupply`. ([#2399](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2399)) - * `Address`: added `functionDelegateCall`, similar to the existing `functionCall`. ([#2333](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2333)) - * `Clones`: added a library for deploying EIP 1167 minimal proxies. ([#2449](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2449)) - * `Context`: moved from `contracts/GSN` to `contracts/utils`. ([#2453](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2453)) - * `PaymentSplitter`: replace usage of `.transfer()` with `Address.sendValue` for improved compatibility with smart wallets. ([#2455](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2455)) - * `UpgradeableProxy`: bubble revert reasons from initialization calls. ([#2454](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2454)) - * `SafeMath`: fix a memory allocation issue by adding new `SafeMath.tryOp(uint,uint)→(bool,uint)` functions. `SafeMath.op(uint,uint,string)→uint` are now deprecated. ([#2462](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2462)) - * `EnumerableMap`: fix a memory allocation issue by adding new `EnumerableMap.tryGet(uint)→(bool,address)` functions. `EnumerableMap.get(uint)→string` is now deprecated. ([#2462](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2462)) - * `ERC165Checker`: added batch `getSupportedInterfaces`. ([#2469](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2469)) - * `RefundEscrow`: `beneficiaryWithdraw` will forward all available gas to the beneficiary. ([#2480](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2480)) - * Many view and pure functions have been made virtual to customize them via overrides. In many cases this will not imply that other functions in the contract will automatically adapt to the overridden definitions. People who wish to override should consult the source code to understand the impact and if they need to override any additional functions to achieve the desired behavior. - -### Security Fixes - - * `ERC777`: fix potential reentrancy issues for custom extensions to `ERC777`. ([#2483](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2483)) - -If you're using our implementation of ERC777 from version 3.3.0 or earlier, and you define a custom `_beforeTokenTransfer` function that writes to a storage variable, you may be vulnerable to a reentrancy attack. If you're affected and would like assistance please write to security@openzeppelin.com. [Read more in the pull request.](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2483) - -## 3.3.0 (2020-11-26) - - * Now supports both Solidity 0.6 and 0.7. Compiling with solc 0.7 will result in warnings. Install the `solc-0.7` tag to compile without warnings. - * `Address`: added `functionStaticCall`, similar to the existing `functionCall`. ([#2333](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2333)) - * `TimelockController`: added a contract to augment access control schemes with a delay. ([#2354](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2354)) - * `EnumerableSet`: added `Bytes32Set`, for sets of `bytes32`. ([#2395](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2395)) - -## 3.2.2-solc-0.7 (2020-10-28) - * Resolve warnings introduced by Solidity 0.7.4. ([#2396](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2396)) - -## 3.2.1-solc-0.7 (2020-09-15) - * `ERC777`: Remove a warning about function state visibility in Solidity 0.7. ([#2327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2327)) - -## 3.2.0 (2020-09-10) - -### New features - * Proxies: added the proxy contracts from OpenZeppelin SDK. ([#2335](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2335)) - -#### Proxy changes with respect to OpenZeppelin SDK - -Aside from upgrading them from Solidity 0.5 to 0.6, we've changed a few minor things from the proxy contracts as they were found in OpenZeppelin SDK. - -- `UpgradeabilityProxy` was renamed to `UpgradeableProxy`. -- `AdminUpgradeabilityProxy` was renamed to `TransparentUpgradeableProxy`. -- `Proxy._willFallback` was renamed to `Proxy._beforeFallback`. -- `UpgradeabilityProxy._setImplementation` and `AdminUpgradeabilityProxy._setAdmin` were made private. - -### Improvements - * `Address.isContract`: switched from `extcodehash` to `extcodesize` for less gas usage. ([#2311](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2311)) - -### Breaking changes - * `ERC20Snapshot`: switched to using `_beforeTokenTransfer` hook instead of overriding ERC20 operations. ([#2312](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2312)) - -This small change in the way we implemented `ERC20Snapshot` may affect users who are combining this contract with -other ERC20 flavors, since it no longer overrides `_transfer`, `_mint`, and `_burn`. This can result in having to remove Solidity `override(...)` specifiers in derived contracts for these functions, and to instead have to add it for `_beforeTokenTransfer`. See [Using Hooks](https://docs.openzeppelin.com/contracts/3.x/extending-contracts#using-hooks) in the documentation. - -## 3.1.0 (2020-06-23) - -### New features - * `SafeCast`: added functions to downcast signed integers (e.g. `toInt32`), improving usability of `SignedSafeMath`. ([#2243](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2243)) - * `functionCall`: new helpers that replicate Solidity's function call semantics, reducing the need to rely on `call`. ([#2264](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2264)) - * `ERC1155`: added support for a base implementation, non-standard extensions and a preset contract. ([#2014](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2014), [#2230](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2230)) - -### Improvements - * `ReentrancyGuard`: reduced overhead of using the `nonReentrant` modifier. ([#2171](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2171)) - * `AccessControl`: added a `RoleAdminChanged` event to `_setAdminRole`. ([#2214](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2214)) - * Made all `public` functions in the token preset contracts `virtual`. ([#2257](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2257)) - -### Deprecations - * `SafeERC20`: deprecated `safeApprove`. ([#2268](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2268)) - -## 3.0.2 (2020-06-08) - -### Improvements - * Added SPX license identifier to all contracts. ([#2235](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2235)) - -## 3.0.1 (2020-04-27) - -### Bugfixes - * `ERC777`: fixed the `_approve` internal function not validating some of their arguments for non-zero addresses. ([#2213](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2213)) - -## 3.0.0 (2020-04-20) - -### New features - * `AccessControl`: new contract for managing permissions in a system, replacement for `Ownable` and `Roles`. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112)) - * `SafeCast`: new functions to convert to and from signed and unsigned values: `toUint256` and `toInt256`. ([#2123](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2123)) - * `EnumerableMap`: a new data structure for key-value pairs (like `mapping`) that can be iterated over. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160)) - -### Breaking changes - * `ERC721`: `burn(owner, tokenId)` was removed, use `burn(tokenId)` instead. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125)) - * `ERC721`: `_checkOnERC721Received` was removed. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125)) - * `ERC721`: `_transferFrom` and `_safeTransferFrom` were renamed to `_transfer` and `_safeTransfer`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162)) - * `Ownable`: removed `_transferOwnership`. ([#2162](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2162)) - * `PullPayment`, `Escrow`: `withdrawWithGas` was removed. The old `withdraw` function now forwards all gas. ([#2125](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2125)) - * `Roles` was removed, use `AccessControl` as a replacement. ([#2112](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2112)) - * `ECDSA`: when receiving an invalid signature, `recover` now reverts instead of returning the zero address. ([#2114](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2114)) - * `Create2`: added an `amount` argument to `deploy` for contracts with `payable` constructors. ([#2117](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2117)) - * `Pausable`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `Strings`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `Counters`: moved to the `utils` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `SignedSafeMath`: moved to the `math` directory. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `ERC20Snapshot`: moved to the `token/ERC20` directory. `snapshot` was changed into an `internal` function. ([#2122](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2122)) - * `Ownable`: moved to the `access` directory. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120)) - * `Ownable`: removed `isOwner`. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120)) - * `Secondary`: removed from the library, use `Ownable` instead. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120)) - * `Escrow`, `ConditionalEscrow`, `RefundEscrow`: these now use `Ownable` instead of `Secondary`, their external API changed accordingly. ([#2120](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2120)) - * `ERC20`: removed `_burnFrom`. ([#2119](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2119)) - * `Address`: removed `toPayable`, use `payable(address)` instead. ([#2133](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2133)) - * `ERC777`: `_send`, `_mint` and `_burn` now use the caller as the operator. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134)) - * `ERC777`: removed `_callsTokensToSend` and `_callTokensReceived`. ([#2134](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2134)) - * `EnumerableSet`: renamed `get` to `at`. ([#2151](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2151)) - * `ERC165Checker`: functions no longer have a leading underscore. ([#2150](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2150)) - * `ERC721Metadata`, `ERC721Enumerable`: these contracts were removed, and their functionality merged into `ERC721`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160)) - * `ERC721`: added a constructor for `name` and `symbol`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160)) - * `ERC20Detailed`: this contract was removed and its functionality merged into `ERC20`. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161)) - * `ERC20`: added a constructor for `name` and `symbol`. `decimals` now defaults to 18. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161)) - * `Strings`: renamed `fromUint256` to `toString` ([#2188](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2188)) - -## 2.5.1 (2020-04-24) - -### Bugfixes - * `ERC777`: fixed the `_send` and `_approve` internal functions not validating some of their arguments for non-zero addresses. ([#2212](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2212)) - -## 2.5.0 (2020-02-04) - -### New features - * `SafeCast.toUintXX`: new library for integer downcasting, which allows for safe operation on smaller types (e.g. `uint32`) when combined with `SafeMath`. ([#1926](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1926)) - * `ERC721Metadata`: added `baseURI`, which can be used for dramatic gas savings when all token URIs share a prefix (e.g. `http://api.myapp.com/tokens/`). ([#1970](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1970)) - * `EnumerableSet`: new library for storing enumerable sets of values. Only `AddressSet` is supported in this release. ([#2061](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/2061)) - * `Create2`: simple library to make usage of the `CREATE2` opcode easier. ([#1744](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1744)) - -### Improvements - * `ERC777`: `_burn` is now internal, providing more flexibility and making it easier to create tokens that deflate. ([#1908](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1908)) - * `ReentrancyGuard`: greatly improved gas efficiency by using the net gas metering mechanism introduced in the Istanbul hardfork. ([#1992](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1992), [#1996](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1996)) - * `ERC777`: improve extensibility by making `_send` and related functions `internal`. ([#2027](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2027)) - * `ERC721`: improved revert reason when transferring tokens to a non-recipient contract. ([#2018](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2018)) - -### Breaking changes - * `ERC165Checker` now requires a minimum Solidity compiler version of 0.5.10. ([#1829](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1829)) - -## 2.4.0 (2019-10-29) - -### New features - * `Address.toPayable`: added a helper to convert between address types without having to resort to low-level casting. ([#1773](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1773)) - * Facilities to make metatransaction-enabled contracts through the Gas Station Network. ([#1844](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1844)) - * `Address.sendValue`: added a replacement to Solidity's `transfer`, removing the fixed gas stipend. ([#1962](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1962)) - * Added replacement for functions that don't forward all gas (which have been deprecated): ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976)) - * `PullPayment.withdrawPaymentsWithGas(address payable payee)` - * `Escrow.withdrawWithGas(address payable payee)` - * `SafeMath`: added support for custom error messages to `sub`, `div` and `mod` functions. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828)) - -### Improvements - * `Address.isContract`: switched from `extcodesize` to `extcodehash` for less gas usage. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802)) - * `ERC20` and `ERC777` updated to throw custom errors on subtraction overflows. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828)) - -### Deprecations - * Deprecated functions that don't forward all gas: ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976)) - * `PullPayment.withdrawPayments(address payable payee)` - * `Escrow.withdraw(address payable payee)` - -### Breaking changes - * `Address` now requires a minimum Solidity compiler version of 0.5.5. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802)) - * `SignatureBouncer` has been removed from drafts, both to avoid confusions with the GSN and `GSNRecipientSignature` (previously called `GSNBouncerSignature`) and because the API was not very clear. ([#1879](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1879)) - -### How to upgrade from 2.4.0-beta - -The final 2.4.0 release includes a refactor of the GSN contracts that will be a breaking change for 2.4.0-beta users. - - * The default empty implementations of `_preRelayedCall` and `_postRelayedCall` were removed and must now be explicitly implemented always in custom recipients. If your custom recipient didn't include an implementation, you can provide an empty one. - * `GSNRecipient`, `GSNBouncerBase`, and `GSNContext` were all merged into `GSNRecipient`. - * `GSNBouncerSignature` and `GSNBouncerERC20Fee` were renamed to `GSNRecipientSignature` and `GSNRecipientERC20Fee`. - * It is no longer necessary to inherit from `GSNRecipient` when using `GSNRecipientSignature` and `GSNRecipientERC20Fee`. - -For example, a contract using `GSNBouncerSignature` would have to be changed in the following way. - -```diff --contract MyDapp is GSNRecipient, GSNBouncerSignature { -+contract MyDapp is GSNRecipientSignature { -``` - -Refer to the table below to adjust your inheritance list. - -| 2.4.0-beta | 2.4.0 | -| ---------------------------------- | ---------------------------- | -| `GSNRecipient, GSNBouncerSignature`| `GSNRecipientSignature` | -| `GSNRecipient, GSNBouncerERC20Fee` | `GSNRecipientERC20Fee` | -| `GSNBouncerBase` | `GSNRecipient` | - -## 2.3.0 (2019-05-27) - -### New features - * `ERC1820`: added support for interacting with the [ERC1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract (`IERC1820Registry`), as well as base contracts that can be registered as implementers there. ([#1677](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1677)) - * `ERC777`: support for the [ERC777 token](https://eips.ethereum.org/EIPS/eip-777), which has multiple improvements over `ERC20` (but is backwards compatible with it) such as built-in burning, a more straightforward permission system, and optional sender and receiver hooks on transfer (mandatory for contracts!). ([#1684](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1684)) - * All contracts now have revert reason strings, which give insight into error conditions, and help debug failing transactions. ([#1704](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1704)) - -### Improvements - * Reverted the Solidity version bump done in v2.2.0, setting the minimum compiler version to v0.5.0, to prevent unexpected build breakage. Users are encouraged however to stay on top of new compiler releases, which usually include bugfixes. ([#1729](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1729)) - -### Bugfixes - * `PostDeliveryCrowdsale`: some validations where skipped when paired with other crowdsale flavors, such as `AllowanceCrowdsale`, or `MintableCrowdsale` and `ERC20Capped`, which could cause buyers to not be able to claim their purchased tokens. ([#1721](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1721)) - * `ERC20._transfer`: the `from` argument was allowed to be the zero address, so it was possible to internally trigger a transfer of 0 tokens from the zero address. This address is not a valid destinatary of transfers, nor can it give or receive allowance, so this behavior was inconsistent. It now reverts. ([#1752](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1752)) - -## 2.2.0 (2019-03-14) - -### New features - * `ERC20Snapshot`: create snapshots on demand of the token balances and total supply, to later retrieve and e.g. calculate dividends at a past time. ([#1617](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1617)) - * `SafeERC20`: `ERC20` contracts with no return value (i.e. that revert on failure) are now supported. ([#1655](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1655)) - * `ERC20`: added internal `_approve(address owner, address spender, uint256 value)`, allowing derived contracts to set the allowance of arbitrary accounts. ([#1609](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1609)) - * `ERC20Metadata`: added internal `_setTokenURI(string memory tokenURI)`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618)) - * `TimedCrowdsale`: added internal `_extendTime(uint256 newClosingTime)` as well as `TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime)` event allowing to extend the crowdsale, as long as it hasn't already closed. - -### Improvements - * Upgraded the minimum compiler version to v0.5.2: this removes many Solidity warnings that were false positives. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606)) - * `ECDSA`: `recover` no longer accepts malleable signatures (those using upper-range values for `s`, or 0/1 for `v`). ([#1622](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1622)) - * ``ERC721``'s transfers are now more gas efficient due to removal of unnecessary `SafeMath` calls. ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610)) - * Fixed variable shadowing issues. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606)) - -### Bugfixes - * (minor) `SafeERC20`: `safeApprove` wasn't properly checking for a zero allowance when attempting to set a non-zero allowance. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647)) - -### Breaking changes in drafts - * `TokenMetadata` has been renamed to `ERC20Metadata`. ([#1618](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1618)) - * The library `Counter` has been renamed to `Counters` and its API has been improved. See an example in `ERC721`, lines [17](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L17) and [204](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/3cb4a00fce1da76196ac0ac3a0ae9702b99642b5/contracts/token/ERC721/ERC721.sol#L204). ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610)) - -## 2.1.3 (2019-02-26) - * Backported `SafeERC20.safeApprove` bugfix. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647)) - -## 2.1.2 (2019-01-17) - * Removed most of the test suite from the npm package, except `PublicRole.behavior.js`, which may be useful to users testing their own `Roles`. - -## 2.1.1 (2019-01-04) - * Version bump to avoid conflict in the npm registry. - -## 2.1.0 (2019-01-04) - -### New features - * Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin. - * `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelist admins (`WhitelistAdminRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525), [#1589](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1589)) - * `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543)) - * `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832)) - * `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524)) - * `ERC721`: added `_burn(uint256 tokenId)`, replacing the similar deprecated function (see below). ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550)) - * `ERC721`: added `_tokensOfOwner(address owner)`, allowing to internally retrieve the array of an account's owned tokens. ([#1522](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1522)) - * Crowdsales: all constructors are now `public`, meaning it is not necessary to extend these contracts in order to deploy them. The exception is `FinalizableCrowdsale`, since it is meaningless unless extended. ([#1564](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1564)) - * `SignedSafeMath`: added overflow-safe operations for signed integers (`int256`). ([#1559](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1559), [#1588](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1588)) - -### Improvements - * The compiler version required by `Array` was behind the rest of the library so it was updated to `v0.4.24`. ([#1553](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1553)) - * Now conforming to a 4-space indentation code style. ([1508](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1508)) - * `ERC20`: more gas efficient due to removed redundant `require`s. ([#1409](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1409)) - * `ERC721`: fixed a bug that prevented internal data structures from being properly cleaned, missing potential gas refunds. ([#1539](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1539) and [#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549)) - * `ERC721`: general gas savings on `transferFrom`, `_mint` and `_burn`, due to redudant `require`s and `SSTORE`s. ([#1549](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1549)) - -### Bugfixes - -### Breaking changes - -### Deprecations - * `ERC721._burn(address owner, uint256 tokenId)`: due to the `owner` parameter being unnecessary. ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550)) - * `RefundableCrowdsale`: due to trading abuse potential on crowdsales that miss their goal. ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543)) diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md b/lib/morpho-utils/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md deleted file mode 100644 index 86c0474..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,73 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at maintainers@openzeppelin.org. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/CONTRIBUTING.md b/lib/morpho-utils/lib/openzeppelin-contracts/CONTRIBUTING.md deleted file mode 100644 index 5012847..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/CONTRIBUTING.md +++ /dev/null @@ -1,64 +0,0 @@ -Contributing to OpenZeppelin Contracts -======= - -We really appreciate and value contributions to OpenZeppelin Contracts. Please take 5' to review the items listed below to make sure that your contributions are merged as soon as possible. - -## Contribution guidelines - -Smart contracts manage value and are highly vulnerable to errors and attacks. We have very strict [guidelines], please make sure to review them! - -## Creating Pull Requests (PRs) - -As a contributor, you are expected to fork this repository, work on your own fork and then submit pull requests. The pull requests will be reviewed and eventually merged into the main repo. See ["Fork-a-Repo"](https://help.github.com/articles/fork-a-repo/) for how this works. - -## A typical workflow - -1) Make sure your fork is up to date with the main repository: - -``` -cd openzeppelin-contracts -git remote add upstream https://github.com/OpenZeppelin/openzeppelin-contracts.git -git fetch upstream -git pull --rebase upstream master -``` -NOTE: The directory `openzeppelin-contracts` represents your fork's local copy. - -2) Branch out from `master` into `fix/some-bug-#123`: -(Postfixing #123 will associate your PR with the issue #123 and make everyone's life easier =D) -``` -git checkout -b fix/some-bug-#123 -``` - -3) Make your changes, add your files, commit, and push to your fork. - -``` -git add SomeFile.js -git commit "Fix some bug #123" -git push origin fix/some-bug-#123 -``` - -4) Run tests, linter, etc. This can be done by running local continuous integration and make sure it passes. - -```bash -npm test -npm run lint -``` - -5) Go to [github.com/OpenZeppelin/openzeppelin-contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) in your web browser and issue a new pull request. - -*IMPORTANT* Read the PR template very carefully and make sure to follow all the instructions. These instructions -refer to some very important conditions that your PR must meet in order to be accepted, such as making sure that all tests pass, JS linting tests pass, Solidity linting tests pass, etc. - -6) Maintainers will review your code and possibly ask for changes before your code is pulled in to the main repository. We'll check that all tests pass, review the coding style, and check for general code correctness. If everything is OK, we'll merge your pull request and your code will be part of OpenZeppelin Contracts. - -*IMPORTANT* Please pay attention to the maintainer's feedback, since it's a necessary step to keep up with the standards OpenZeppelin Contracts attains to. - -## All set! - -If you have any questions, feel free to post them to github.com/OpenZeppelin/openzeppelin-contracts/issues. - -Finally, if you're looking to collaborate and want to find easy tasks to start, look at the issues we marked as ["Good first issue"](https://github.com/OpenZeppelin/openzeppelin-contracts/labels/good%20first%20issue). - -Thanks for your time and code! - -[guidelines]: GUIDELINES.md diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/DOCUMENTATION.md b/lib/morpho-utils/lib/openzeppelin-contracts/DOCUMENTATION.md deleted file mode 100644 index ca39e51..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/DOCUMENTATION.md +++ /dev/null @@ -1,16 +0,0 @@ -Documentation is hosted at https://docs.openzeppelin.com/contracts. - -All of the content for the site is in this repository. The guides are in the -[docs](/docs) directory, and the API Reference is extracted from comments in -the source code. If you want to help improve the content, this is the -repository you should be contributing to. - -[`solidity-docgen`](https://github.com/OpenZeppelin/solidity-docgen) is the -program that extracts the API Reference from source code. - -The [`docs.openzeppelin.com`](https://github.com/OpenZeppelin/docs.openzeppelin.com) -repository hosts the configuration for the entire site, which includes -documentation for all of the OpenZeppelin projects. - -To run the docs locally you should run `npm run docs:watch` on this -repository. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/GUIDELINES.md b/lib/morpho-utils/lib/openzeppelin-contracts/GUIDELINES.md deleted file mode 100644 index 9706750..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/GUIDELINES.md +++ /dev/null @@ -1,105 +0,0 @@ -Design Guidelines -======= - -These are some global design goals in OpenZeppelin Contracts. - -#### D0 - Security in Depth -We strive to provide secure, tested, audited code. To achieve this, we need to match intention with function. Thus, documentation, code clarity, community review and security discussions are fundamental. - -#### D1 - Simple and Modular -Simpler code means easier audits, and better understanding of what each component does. We look for small files, small contracts, and small functions. If you can separate a contract into two independent functionalities you should probably do it. - -#### D2 - Naming Matters - -We take our time with picking names. Code is going to be written once, and read hundreds of times. Renaming for clarity is encouraged. - -#### D3 - Tests - -Write tests for all your code. We encourage Test Driven Development so we know when our code is right. Even though not all code in the repository is tested at the moment, we aim to test every line of code in the future. - -#### D4 - Check preconditions and post-conditions - -A very important way to prevent vulnerabilities is to catch a contract’s inconsistent state as early as possible. This is why we want functions to check pre- and post-conditions for executing its logic. When writing code, ask yourself what you are expecting to be true before and after the function runs, and express it in code. - -#### D5 - Code Consistency - -Consistency on the way classes are used is paramount to an easier understanding of the library. The codebase should be as unified as possible. Read existing code and get inspired before you write your own. Follow the style guidelines. Don’t hesitate to ask for help on how to best write a specific piece of code. - -#### D6 - Regular Audits -Following good programming practices is a way to reduce the risk of vulnerabilities, but professional code audits are still needed. We will perform regular code audits on major releases, and hire security professionals to provide independent review. - -# Style Guidelines - -The design guidelines have quite a high abstraction level. These style guidelines are more concrete and easier to apply, and also more opinionated. We value clean code and consistency, and those are prerequisites for us to include new code in the repository. Before proposing a change, please read these guidelines and take some time to familiarize yourself with the style of the existing codebase. - -## Solidity code - -In order to be consistent with all the other Solidity projects, we follow the -[official recommendations documented in the Solidity style guide](http://solidity.readthedocs.io/en/latest/style-guide.html). - -Any exception or additions specific to our project are documented below. - -* Try to avoid acronyms and abbreviations. - -* All state variables should be private. - -* Private state variables should have an underscore prefix. - - ``` - contract TestContract { - uint256 private _privateVar; - uint256 internal _internalVar; - } - ``` - -* Parameters must not be prefixed with an underscore. - - ``` - function test(uint256 testParameter1, uint256 testParameter2) { - ... - } - ``` - -* Internal and private functions should have an underscore prefix. - - ``` - function _testInternal() internal { - ... - } - ``` - - ``` - function _testPrivate() private { - ... - } - ``` - -* Events should be emitted immediately after the state change that they - represent, and consequently they should be named in past tense. - - ``` - function _burn(address who, uint256 value) internal { - super._burn(who, value); - emit TokensBurned(who, value); - } - ``` - - Some standards (e.g. ERC20) use present tense, and in those cases the - standard specification prevails. - -* Interface names should have a capital I prefix. - - ``` - interface IERC777 { - ``` - - -## Tests - -* Tests Must be Written Elegantly - - Tests are a good way to show how to use the library, and maintaining them is extremely necessary. Don't write long tests, write helper functions to make them be as short and concise as possible (they should take just a few lines each), and use good variable names. - -* Tests Must not be Random - - Inputs for tests should not be generated randomly. Accounts used to create test contracts are an exception, those can be random. Also, the type and structure of outputs should be checked. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/LICENSE b/lib/morpho-utils/lib/openzeppelin-contracts/LICENSE deleted file mode 100644 index 4f51be0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016-2022 zOS Global Limited and contributors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/README.md b/lib/morpho-utils/lib/openzeppelin-contracts/README.md deleted file mode 100644 index f8679f5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# OpenZeppelin - -[![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.openzeppelin.com/contracts) -[![NPM Package](https://img.shields.io/npm/v/@openzeppelin/contracts.svg)](https://www.npmjs.org/package/@openzeppelin/contracts) -[![Coverage Status](https://codecov.io/gh/OpenZeppelin/openzeppelin-contracts/graph/badge.svg)](https://codecov.io/gh/OpenZeppelin/openzeppelin-contracts) -[![gitpoap badge](https://public-api.gitpoap.io/v1/repo/OpenZeppelin/openzeppelin-contracts/badge)](https://www.gitpoap.io/gh/OpenZeppelin/openzeppelin-contracts) - -**A library for secure smart contract development.** Build on a solid foundation of community-vetted code. - - * Implementations of standards like [ERC20](https://docs.openzeppelin.com/contracts/erc20) and [ERC721](https://docs.openzeppelin.com/contracts/erc721). - * Flexible [role-based permissioning](https://docs.openzeppelin.com/contracts/access-control) scheme. - * Reusable [Solidity components](https://docs.openzeppelin.com/contracts/utilities) to build custom contracts and complex decentralized systems. - -:mage: **Not sure how to get started?** Check out [Contracts Wizard](https://wizard.openzeppelin.com/) — an interactive smart contract generator. - -:building_construction: **Want to scale your decentralized application?** Check out [OpenZeppelin Defender](https://openzeppelin.com/defender) — a secure platform for automating and monitoring your operations. - -## Overview - -### Installation - -```console -$ npm install @openzeppelin/contracts -``` - -OpenZeppelin Contracts features a [stable API](https://docs.openzeppelin.com/contracts/releases-stability#api-stability), which means your contracts won't break unexpectedly when upgrading to a newer minor version. - -An alternative to npm is to use the GitHub repository `openzeppelin/openzeppelin-contracts` to retrieve the contracts. When doing this, make sure to specify the tag for a release such as `v4.5.0`, instead of using the `master` branch. - -### Usage - -Once installed, you can use the contracts in the library by importing them: - -```solidity -pragma solidity ^0.8.0; - -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; - -contract MyCollectible is ERC721 { - constructor() ERC721("MyCollectible", "MCO") { - } -} -``` - -_If you're new to smart contract development, head to [Developing Smart Contracts](https://docs.openzeppelin.com/learn/developing-smart-contracts) to learn about creating a new project and compiling your contracts._ - -To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself. The library is designed so that only the contracts and functions you use are deployed, so you don't need to worry about it needlessly increasing gas costs. - -## Learn More - -The guides in the [docs site](https://docs.openzeppelin.com/contracts) will teach about different concepts, and how to use the related contracts that OpenZeppelin Contracts provides: - -* [Access Control](https://docs.openzeppelin.com/contracts/access-control): decide who can perform each of the actions on your system. -* [Tokens](https://docs.openzeppelin.com/contracts/tokens): create tradeable assets or collectives, and distribute them via [Crowdsales](https://docs.openzeppelin.com/contracts/crowdsales). -* [Gas Station Network](https://docs.openzeppelin.com/contracts/gsn): let your users interact with your contracts without having to pay for gas themselves. -* [Utilities](https://docs.openzeppelin.com/contracts/utilities): generic useful tools, including non-overflowing math, signature verification, and trustless paying systems. - -The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts's development in the [community forum](https://forum.openzeppelin.com). - -Finally, you may want to take a look at the [guides on our blog](https://blog.openzeppelin.com/guides), which cover several common use cases and good practices.. The following articles provide great background reading, though please note, some of the referenced tools have changed as the tooling in the ecosystem continues to rapidly evolve. - -* [The Hitchhiker’s Guide to Smart Contracts in Ethereum](https://blog.openzeppelin.com/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05) will help you get an overview of the various tools available for smart contract development, and help you set up your environment. -* [A Gentle Introduction to Ethereum Programming, Part 1](https://blog.openzeppelin.com/a-gentle-introduction-to-ethereum-programming-part-1-783cc7796094) provides very useful information on an introductory level, including many basic concepts from the Ethereum platform. -* For a more in-depth dive, you may read the guide [Designing the Architecture for Your Ethereum Application](https://blog.openzeppelin.com/designing-the-architecture-for-your-ethereum-application-9cec086f8317), which discusses how to better structure your application and its relationship to the real world. - -## Security - -This project is maintained by [OpenZeppelin](https://openzeppelin.com), and developed following our high standards for code quality and security. OpenZeppelin Contracts is meant to provide tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problems you might experience. - -The core development principles and strategies that OpenZeppelin Contracts is based on include: security in depth, simple and modular code, clarity-driven naming conventions, comprehensive unit testing, pre-and-post-condition sanity checks, code consistency, and regular audits. - -The latest audit was done on October 2018 on version 2.0.0. - -We have a [**bug bounty program** on Immunefi](https://www.immunefi.com/bounty/openzeppelin). Please report any security issues you find through the Immunefi dashboard, or reach out to security@openzeppelin.com. - -Critical bug fixes will be backported to past major releases. - -## Contribute - -OpenZeppelin Contracts exists thanks to its contributors. There are many ways you can participate and help build high quality software. Check out the [contribution guide](CONTRIBUTING.md)! - -## License - -OpenZeppelin Contracts is released under the [MIT License](LICENSE). diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/RELEASING.md b/lib/morpho-utils/lib/openzeppelin-contracts/RELEASING.md deleted file mode 100644 index f356ab2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/RELEASING.md +++ /dev/null @@ -1,36 +0,0 @@ -# Releasing - -> Visit the documentation for [details about release schedule]. - -Start on an up-to-date `master` branch. - -Create the release branch with `npm run release start minor`. - -Publish a release candidate with `npm run release rc`. - -Publish the final release with `npm run release final`. - -Follow the general [OpenZeppelin Contracts release checklist]. - -[details about release schedule]: https://docs.openzeppelin.com/contracts/releases-stability -[OpenZeppelin Contracts release checklist]: https://github.com/OpenZeppelin/code-style/blob/master/RELEASE_CHECKLIST.md - - -## Merging the release branch - -After the final release, the release branch should be merged back into `master`. This merge must not be squashed because it would lose the tagged release commit. Since the GitHub repo is set up to only allow squashed merges, the merge should be done locally and pushed. - -Make sure to have the latest changes from `upstream` in your local release branch. - -``` -git checkout release-vX.Y.Z -git pull upstream -``` - -``` -git checkout master -git merge --no-ff release-vX.Y.Z -git push upstream master -``` - -The release branch can then be deleted on GitHub. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/SECURITY.md b/lib/morpho-utils/lib/openzeppelin-contracts/SECURITY.md deleted file mode 100644 index 98701be..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/SECURITY.md +++ /dev/null @@ -1,20 +0,0 @@ -# Security Policy - -## Bug Bounty - -We have a [**bug bounty program** on Immunefi](https://www.immunefi.com/bounty/openzeppelin). Please report any security issues you find through the Immunefi dashboard, or reach out to security@openzeppelin.com. - -Critical bug fixes will be backported to past major releases. - -## Supported Versions - -The recommendation is to use the latest version available. - -| Version | Supported | -| ------- | ------------------------------------ | -| 4.x | :white_check_mark::white_check_mark: | -| 3.4 | :white_check_mark: | -| 2.5 | :white_check_mark: | -| < 2.0 | :x: | - -Note that the Solidity language itself only guarantees security updates for the latest release. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/audit/2017-03.md b/lib/morpho-utils/lib/openzeppelin-contracts/audit/2017-03.md deleted file mode 100644 index 5ca874b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/audit/2017-03.md +++ /dev/null @@ -1,292 +0,0 @@ -# OpenZeppelin Audit - -NOTE ON 2021-07-19: This report makes reference to Zeppelin, OpenZeppelin, OpenZeppelin [C]ontracts, the OpenZeppelin team, and OpenZeppelin library. Many of these things have since been renamed and know that this audit applies to what is currently called the OpenZeppelin Contracts which are maintained by the OpenZeppelin Conracts Community. - -March, 2017 -Authored by Dennis Peterson and Peter Vessenes - -# Introduction - -Zeppelin requested that New Alchemy perform an audit of the contracts in their OpenZeppelin library. The OpenZeppelin contracts are a set of contracts intended to be a safe building block for a variety of uses by parties that may not be as sophisticated as the OpenZeppelin team. It is a design goal that the contracts be deployable safely and "as-is". - -The contracts are hosted at: - -https://github.com/OpenZeppelin/zeppelin-solidity - -All the contracts in the "contracts" folder are in scope. - -The git commit hash we evaluated is: -9c5975a706b076b7000e8179f8101e0c61024c87 - -# Disclaimer - -The audit makes no statements or warrantees about utility of the code, safety of the code, suitability of the business model, regulatory regime for the business model, or any other statements about fitness of the contracts to purpose, or their bugfree status. The audit documentation is for discussion purposes only. - -# Executive Summary - -Overall the OpenZeppelin codebase is of reasonably high quality -- it is clean, modular and follows best practices throughout. - -It is still in flux as a codebase, and needs better documentation per file as to expected behavior and future plans. It probably needs more comprehensive and aggressive tests written by people less nice than the current OpenZeppelin team. - -We identified two critical errors and one moderate issue, and would not recommend this commit hash for public use until these bugs are remedied. - -The repository includes a set of Truffle unit tests, a requirement and best practice for smart contracts like these; we recommend these be bulked up. - -# Discussion - -## Big Picture: Is This A Worthwhile Project? - -As soon as a developer touches OpenZeppelin contracts, they will modify something, leaving them in an un-audited state. We do not recommend developers deploy any unaudited code to the Blockchain if it will handle money, information or other things of value. - -> "In accordance with Unix philosophy, Perl gives you enough rope to hang yourself" -> --Larry Wall - -We think this is an incredibly worthwhile project -- aided by the high code quality. Creating a framework that can be easily extended helps increase the average code quality on the Blockchain by charting a course for developers and encouraging containment of modifications to certain sections. - -> "Rust: The language that makes you take the safety off before shooting yourself in the foot" -> -- (@mbrubeck) - -We think much more could be done here, and recommend the OpenZeppelin team keep at this and keep focusing on the design goal of removing rope and adding safety. - -## Solidity Version Updates Recommended - -Most of the code uses Solidity 0.4.11, but some files under `Ownership` are marked 0.4.0. These should be updated. - -Solidity 0.4.10 will add several features which could be useful in these contracts: - -- `assert(condition)`, which throws if the condition is false - -- `revert()`, which rolls back without consuming all remaining gas. - -- `address.transfer(value)`, which is like `send` but automatically propagates exceptions, and supports `.gas()`. See https://github.com/ethereum/solidity/issues/610 for more on this. - -## Error Handling: Throw vs Return False -Solidity standards allow two ways to handle an error -- either calling `throw` or returning `false`. Both have benefits. In particular, a `throw` guarantees a complete wipe of the call stack (up to the preceding external call), whereas `false` allows a function to continue. - -In general we prefer `throw` in our code audits, because it is simpler -- it's less for an engineer to keep track of. Returning `false` and using logic to check results can quickly become a poorly-tracked state machine, and this sort of complexity can cause errors. - -In the OpenZeppelin contracts, both styles are used in different parts of the codebase. `SimpleToken` transfers throw upon failure, while the full ERC20 token returns `false`. Some modifiers `throw`, others just wrap the function body in a conditional, effectively allowing the function to return false if the condition is not met. - -We don't love this, and would usually recommend you stick with one style or the other throughout the codebase. - -In at least one case, these different techniques are combined cleverly (see the Multisig comments, line 65). As a set of contracts intended for general use, we recommend you either strive for more consistency or document explicit design criteria that govern which techniques are used where. - -Note that it may be impossible to use either one in all situations. For example, SafeMath functions pretty much have to throw upon failure, but ERC20 specifies returning booleans. Therefore we make no particular recommendations, but simply point out inconsistencies to consider. - -# Critical Issues - -## Stuck Ether in Crowdsale contract -CrowdsaleToken.sol has no provision for withdrawing the raised ether. We *strongly* recommend a standard `withdraw` function be added. There is no scenario in which someone should deploy this contract as is, whether for testing or live. - -## Recursive Call in MultisigWallet -Line 45 of `MultisigWallet.sol` checks if the amount being sent by `execute` is under a daily limit. - -This function can only be called by the "Owner". As a first angle of attack, it's worth asking what will happen if the multisig wallet owners reset the daily limit by approving a call to `resetSpentToday`. - -If a chain of calls can be constructed in which the owner confirms the `resetSpentToday` function and then withdraws through `execute` in a recursive call, the contract can be drained. In fact, this could be done without a recursive call, just through repeated `execute` calls alternating with the `confirm` calls. - -We are still working through the confirmation protocol in `Shareable.sol`, but we are not convinced that this is impossible, in fact it looks possible. The flexibility any shared owner has in being able to revoke confirmation later is another worrisome angle of approach even if some simple patches are included. - -This bug has a number of causes that need to be addressed: - -1. `resetSpentToday` and `confirm` together do not limit the days on which the function can be called or (it appears) the number of times it can be called. -1. Once a call has been confirmed and `execute`d it appears that it can be re-executed. This is not good. -3. `confirmandCheck` doesn't seem to have logic about whether or not the function in question has been called. -4. Even if it did, `revoke` would need updates and logic to deal with revocation requests after a function call had been completed. - -We do not recommend using the MultisigWallet until these issues are fixed. - -# Moderate to Minor Issues - -## PullPayment -PullPayment.sol needs some work. It has no explicit provision for cancelling a payment. This would be desirable in a number of scenarios; consider a payee losing their wallet, or giving a griefing address, or just an address that requires more than the default gas offered by `send`. - -`asyncSend` has no overflow checking. This is a bad plan. We recommend overflow and underflow checking at the layer closest to the data manipulation. - -`asyncSend` allows more balance to be queued up for sending than the contract holds. This is probably a bad idea, or at the very least should be called something different. If the intent is to allow this, it should have provisions for dealing with race conditions between competing `withdrawPayments` calls. - -It would be nice to see how many payments are pending. This would imply a bit of a rewrite; we recommend this contract get some design time, and that developers don't rely on it in its current state. - -## Shareable Contract - -We do not believe the `Shareable.sol` contract is ready for primetime. It is missing functions, and as written may be vulnerable to a reordering attack -- an attack in which a miner or other party "racing" with a smart contract participant inserts their own information into a list or mapping. - -The confirmation and revocation code needs to be looked over with a very careful eye imagining extraordinarily bad behavior by shared owners before this contract can be called safe. - -No sanity checks on the initial constructor's `required` argument are worrisome as well. - -# Line by Line Comments - -## Lifecycle - -### Killable - -Very simple, allows owner to call selfdestruct, sending funds to owner. No issues. However, note that `selfdestruct` should typically not be used; it is common that a developer may want to access data in a former contract, and they may not understand that `selfdestruct` limits access to the contract. We recommend better documentation about this dynamic, and an alternate function name for `kill` like `completelyDestroy` while `kill` would perhaps merely send funds to the owner. - -Also note that a killable function allows the owner to take funds regardless of other logic. This may be desirable or undesirable depending on the circumstances. Perhaps `Killable` should have a different name as well. - -### Migrations - -I presume that the goal of this contract is to allow and annotate a migration to a new smart contract address. We are not clear here how this would be accomplished by the code; we'd like to review with the OpenZeppelin team. - -### Pausable - -We like these pauses! Note that these allow significant griefing potential by owners, and that this might not be obvious to participants in smart contracts using the OpenZeppelin framework. We would recommend that additional sample logic be added to for instance the TokenContract showing safer use of the pause and resume functions. In particular, we would recommend a timelock after which anyone could unpause the contract. - -The modifiers use the pattern `if(bool){_;}`. This is fine for functions that return false upon failure, but could be problematic for functions expected to throw upon failure. See our comments above on standardizing on `throw` or `return(false)`. - -## Ownership - -### Ownable - -Line 19: Modifier throws if doesn't meet condition, in contrast to some other inheritable modifiers (e.g. in Pausable) that use `if(bool){_;}`. - -### Claimable - -Inherits from Ownable but the existing owner sets a pendingOwner who has to claim ownership. - -Line 17: Another modifier that throws. - -### DelayedClaimable - -Is there any reason to descend from Ownable directly, instead of just Claimable, which descends from Ownable? If not, descending from both just adds confusion. - -### Contactable - -Allows owner to set a public string of contract information. No issues. - -### Shareable - -This needs some work. Doesn't check if `_required <= len(_owners)` for instance, that would be a bummer. What if _required were like `MAX - 1`? - -I have a general concern about the difference between `owners`, `_owners`, and `owner` in `Ownable.sol`. I recommend "Owners" be renamed. In general we do not recomment single character differences in variable names, although a preceding underscore is not uncommon in Solidity code. - -Line 34: "this contract only has six types of events"...actually only two. - -Line 61: Why is `ownerIndex` keyed by addresses hashed to `uint`s? Why not use the addresses directly, so `ownerIndex` is less obscure, and so there's stronger typing? - -Line 62: Do not love `++i) ... owners[2+ i]`. Makes me do math, which is not what I want to do. I want to not have to do math. - -There should probably be a function for adding a new operation, so the developer doesn't have to work directly with the internal data. (This would make the multisig contract even shorter.) - -There's a `revoke` function but not a `propose` function that we can see. - -Beware reordering. If `propose` allows the user to choose a bytes string for their proposal, bad things(TM) will happen as currently written. - - -### Multisig - -Just an interface. Note it allows changing an owner address, but not changing the number of owners. This is somewhat limiting but also simplifies implementation. - -## Payment - -### PullPayment - -Safe from reentrance attack since ether send is at the end, plus it uses `.send()` rather than `.call.value()`. - -There's an argument to be made that `.call.value()` is a better option *if* you're sure that it will be done after all state updates, since `.send` will fail if the recipient has an expensive fallback function. However, in the context of a function meant to be embedded in other contracts, it's probably better to use `.send`. One possible compromise is to add a function which allows only the owner to send ether via `.call.value`. - -If you don't use `call.value` you should implement a `cancel` function in case some value is pending here. - -Line 14: -Doesn't use safeAdd. Although it appears that payout amounts can only be increased, in fact the payer could lower the payout as much as desired via overflow. Also, the payer could add a large non-overflowing amount, causing the payment to exceed the contract balance and therefore fail when withdraw is attempted. - -Recommendation: track the sum of non-withdrawn asyncSends, and don't allow a new one which exceeds the leftover balance. If it's ever desirable to make payments revocable, it should be done explicitly. - -## Tokens - -### ERC20 - -Standard ERC20 interface only. - -There's a security hole in the standard, reported at Edcon: `approve` does not protect against race conditions and simply replaces the current value. An approved spender could wait for the owner to call `approve` again, then attempt to spend the old limit before the new limit is applied. If successful, this attacker could successfully spend the sum of both limits. - -This could be fixed by either (1) including the old limit as a parameter, so the update will fail if some gets spent, or (2) using the value parameter as a delta instead of replacement value. - -This is not fixable while adhering to the current full ERC20 standard, though it would be possible to add a "secureApprove" function. The impact isn't extreme since at least you can only be attacked by addresses you approved. Also, users could mitigate this by always setting spending limits to zero and checking for spends, before setting the new limit. - -Edcon slides: -https://drive.google.com/file/d/0ByMtMw2hul0EN3NCaVFHSFdxRzA/view - -### ERC20Basic - -Simpler interface skipping the Approve function. Note this departs from ERC20 in another way: transfer throws instead of returning false. - -### BasicToken - -Uses `SafeSub` and `SafeMath`, so transfer `throw`s instead of returning false. This complies with ERC20Basic but not the actual ERC20 standard. - -### StandardToken - -Implementation of full ERC20 token. - -Transfer() and transferFrom() use SafeMath functions, which will cause them to throw instead of returning false. Not a security issue but departs from standard. - -### SimpleToken - -Sample instantiation of StandardToken. Note that in this sample, decimals is 18 and supply only 10,000, so the supply is a small fraction of a single nominal token. - -### CrowdsaleToken - -StandardToken which mints tokens at a fixed price when sent ether. - -There's no provision for owner withdrawing the ether. As a sample for crowdsales it should be Ownable and allow the owner to withdraw ether, rather than stranding the ether in the contract. - -Note: an alternative pattern is a mint() function which is only callable from a separate crowdsale contract, so any sort of rules can be added without modifying the token itself. - -### VestedToken - -Lines 23, 27: -Functions `transfer()` and `transferFrom()` have a modifier canTransfer which throws if not enough tokens are available. However, transfer() returns a boolean success. Inconsistent treatment of failure conditions may cause problems for other contracts using the token. (Note that transferableTokens() relies on safeSub(), so will also throw if there's insufficient balance.) - -Line 64: -Delete not actually necessary since the value is overwritten in the next line anyway. - -## Root level - -### Bounty - -Avoids potential race condition by having each researcher deploy a separate contract for attack; if a research manages to break his associated contract, other researchers can't immediately claim the reward, they have to reproduce the attack in their own contracts. - -A developer could subvert this intent by implementing `deployContract()` to always return the same address. However, this would break the `researchers` mapping, updating the researcher address associated with the contract. This could be prevented by blocking rewrites in `researchers`. - -### DayLimit - -The modifier `limitedDaily` calls `underLimit`, which both checks that the spend is below the daily limit, and adds the input value to the daily spend. This is fine if all functions throw upon failure. However, not all OpenZeppelin functions do this; there are functions that returns false, and modifiers that wrap the function body in `if (bool) {_;}`. In these cases, `_value` will be added to `spentToday`, but ether may not actually be sent because other preconditions were not met. (However in the OpenZeppelin multisig this is not a problem.) - -Lines 4, 11: -Comment claims that `DayLimit` is multiowned, and Shareable is imported, but DayLimit does not actually inherit from Shareable. The intent may be for child contracts to inherit from Shareable (as Multisig does); in this case the import should be removed and the comment altered. - -Line 46: -Manual overflow check instead of using safeAdd. Since this is called from a function that throws upon failure anyway, there's no real downside to using safeAdd. - -### LimitBalance - -No issues. - -### MultisigWallet - -Lines 28, 76, 80: -`kill`, `setDailyLimit`, and `resetSpentToday` only happen with multisig approval, and hashes for these actions are logged by Shareable. However, they should probably post their own events for easy reading. - -Line 45: -This call to underLimit will reduce the daily limit, and then either throw or return 0. So in this case there's no danger that the limit will be reduced without the operation going through. - -Line 65: -Shareable's onlyManyOwners will take the user's confirmation, and execute the function body if and only if enough users have confirmed. Whole thing throws if the send fails, which will roll back the confirmation. Confirm returns false if not enough have confirmed yet, true if the whole thing succeeds, and throws only in the exceptional circumstance that the designated transaction unexpectedly fails. Elegant design. - -Line 68: -Throw here is good but note this function can fail either by returning false or by throwing. - -Line 92: -A bit odd to split `clearPending()` between this contract and Shareable. However this does allow contracts inheriting from Shareable to use custom structs for pending transactions. - - -### SafeMath - -Another interesting comment from the same Edcon presentation was that the overflow behavior of Solidity is undocumented, so in theory, source code that relies on it could break with a future revision. - -However, compiled code should be fine, and in the unlikely event that the compiler is revised in this way, there should be plenty of warning. (But this is an argument for keeping overflow checks isolated in SafeMath.) - -Aside from that small caveat, these are fine. - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/audit/2018-10.pdf b/lib/morpho-utils/lib/openzeppelin-contracts/audit/2018-10.pdf deleted file mode 100644 index d5bf12741c8a6d44ed597de7204fde72d91dec35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1000527 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%0AXGSxD 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%0Ds@WxhHVsCq?&%C$272odl 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

    %X-{jq)zF)pGEGKPHkt7x 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

    @!c9KnY4NvNgEvnPA? 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

    QsKH{N_IQtXo9hrt1|lnPuADU$b1Mf#WXL540@w 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%0DQ_tNgAAku*dN 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

    fwy2<7q zDUf=Nh}CM0fE@!qOXtsLFjQ>$FZ2yw)|OeY5B{dg9ZVSOX9Cpw#z`7!j7aa6(6{a$4FhsBu72G5Gt3ar2e+Aijb6l&EFnK zgbkye>R;w7rO=AxuAv~#+b(Q)j+Y#7Nn#15O)!WjhFJ*}vDBRwPW>2EYH(nfeo!Zs zP>e)wKb@f2;oB4uV%v|fqUSmpTAMbtW&7L?cX91cn|dOtrX8qUXNP$Ynz=hWo;#yF zeTFVdpOqs}-XfM|7RKBO^#dvUB!<69j0Pv*DFGL^*?2Xg4WcIZ81Ze(rMDXv=B5gr z<9w|<*ww7#S7KM{6vkIj!s}wu^RAU+} z_+K98!d36qresKVe%TT&ENQq3Sg+fC`0q?GZUKkR?AYGfa}DTY*=Qf_l#vck<3kiw z)H!4f1H7PuBOsy~O!MjSBzK9$Qk%vRJ3`)gI9gz7WnCOjxn86hH5G zgD2-V=1O-9F}V6$>;W)YiiN_{+hFUvN-Wr1Z;}-~3CYu48b8G4sV%T5_<6e;?41i< zjxjYG61gXMT!-zH)h1a@ zzc@*6>iAi^b8nC5UC}~_MsyT}^^(~wsL=@x7|M-zzxr9lm%+QP@EdH+{C$fX`+;Q( z6QV%O;N3e8@LmWGzhK^LA0Q5QC4-Bno^1V-xPGwh2!?h-RL=3UU`*a$N(Myz9YXbe zGV-Jy;QRF*wM$$KEGL|k|4~5yvx}Jma+ZO|rC!)gkGV|_;9cFr$DKk)>BWN~(;Eu9o zomyAR7ZTY?Mw9i78#mq71J%i>vEvcO@L4c;SS7$}G0MR95G$TbzhB=wK7TeZ^v?q7 ziLHMk4zvAQPw@rFW*L67mPFv?af}v=)9%L|y^|wk-!-aR|Llg~K39@`R9^xSxPBM= z%b2T` zPo$0~?@P|iQG+?;Gs3Zeo zXbX#;hntIv%fKX0ES1%mVtNWu);V)bS{0CYn#r{ph#h?w# z6aK&5lWm|BG){A;kL3ay6mvhXy9Cy3k{vbYCUbt;C6TYg5`sON*TKz6$DWUL*^*E{x;lj@bJ z`4&lWklridPA3CY5l%c%$^n1Pm&%PAQplvCa{3Hib?3gz27P1s91=R+^1+6H6s zX}R-IsHye2ggRzPgJVhe%bq-+OzFo;e9%7PGPj1Aleg=h9i%k;OnTRh-aB0J;p<7I zw8+$Jd~qD@_#kGO7hC21FO8qv#;DYxlStWbP@_fqy&$j#>utVouc?l14i?Wu0^zp8s}gvot|7hnFNC zNiTi`YloFI@S9Z0z=e9|Zi9c5kfAEH;n^;ShS75#=|_e?dpF__yh8mH z@lHAhs3jbuCqTWS2G)ou-vDLCDK&o^B(jY&xUPFgnaQZU-r>t&d!_}x_}*z9Py%dJ zo~*7^s3fb$Hh);$S4u^*)^*L&3AJx#kqJWrpA%fu8vwaoV>(@ZVbbi9->7^y3+t`j zOdyK|8R>PHS>NTy{V24#@~TB{Ai*l~%)=y%p0F5LwJi!m{hd_H>zP%|P&@OPnn{(p z)I&0*F`{<3ibJlFcSRyTh*HXKypRwbS9wdOry13AL+CQ-QzNa5dJR*(3EzXU-09Q2 z$F+?M%r#y(sagSlaDIZ#Eb7m`f~_?_>%~Z)9B&#@`Qs7Z=aw|SF4b$MV9zTjxm^UQ&3@=GE<<&7(JLN9}mZ)$p_t0B4G1_N`E7X0ysF_!kS!O6?rx z)DQcdDb-YS_Km5JRCsx{yrWTQgN%2B{gCK!8Y`28OY9u+Ko1@@IW}nN?#MruYBeF; vmz$7%8{kQOm<9x(L!%4$|Fbnt&IXRo?v5s=upAsL9Bk~cBqSnoqOku9foUHh diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/Makefile b/lib/morpho-utils/lib/openzeppelin-contracts/certora/Makefile deleted file mode 100644 index bbbddbc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -default: help - -PATCH = applyHarness.patch -CONTRACTS_DIR = ../contracts -MUNGED_DIR = munged - -help: - @echo "usage:" - @echo " make clean: remove all generated files (those ignored by git)" - @echo " make $(MUNGED_DIR): create $(MUNGED_DIR) directory by applying the patch file to $(CONTRACTS_DIR)" - @echo " make record: record a new patch file capturing the differences between $(CONTRACTS_DIR) and $(MUNGED_DIR)" - -munged: $(wildcard $(CONTRACTS_DIR)/*.sol) $(PATCH) - rm -rf $@ - cp -r $(CONTRACTS_DIR) $@ - patch -p0 -d $@ < $(PATCH) - -record: - diff -ruN $(CONTRACTS_DIR) $(MUNGED_DIR) | sed 's+../contracts/++g' | sed 's+munged/++g' > $(PATCH) - -clean: - git clean -fdX - touch $(PATCH) - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/README.md b/lib/morpho-utils/lib/openzeppelin-contracts/certora/README.md deleted file mode 100644 index 55f84d4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Running the certora verification tool - -These instructions detail the process for running CVT on the OpenZeppelin (Wizard/Governor) contracts. - -Documentation for CVT and the specification language are available -[here](https://certora.atlassian.net/wiki/spaces/CPD/overview) - -## Running the verification - -The scripts in the `certora/scripts` directory are used to submit verification -jobs to the Certora verification service. After the job is complete, the results will be available on -[the Certora portal](https://vaas-stg.certora.com/). - -These scripts should be run from the root directory; for example by running - -``` -sh certora/scripts/verifyAll.sh -``` - -The most important of these is `verifyAll.sh`, which checks -all of the harnessed contracts (`certora/harness/Wizard*.sol`) against all of -the specifications (`certora/spec/*.spec`). - -The other scripts run a subset of the specifications or the contracts. You can -verify different contracts or specifications by changing the `--verify` option, -and you can run a single rule or method with the `--rule` or `--method` option. - -For example, to verify the `WizardFirstPriority` contract against the -`GovernorCountingSimple` specification, you could change the `--verify` line of -the `WizardControlFirstPriortity.sh` script to: - -``` ---verify WizardFirstPriority:certora/specs/GovernorCountingSimple.spec \ -``` - -## Adapting to changes in the contracts - -Some of our rules require the code to be simplified in various ways. Our -primary tool for performing these simplifications is to run verification on a -contract that extends the original contracts and overrides some of the methods. -These "harness" contracts can be found in the `certora/harness` directory. - -This pattern does require some modifications to the original code: some methods -need to be made virtual or public, for example. These changes are handled by -applying a patch to the code before verification. - -When one of the `verify` scripts is executed, it first applies the patch file -`certora/applyHarness.patch` to the `contracts` directory, placing the output -in the `certora/munged` directory. We then verify the contracts in the -`certora/munged` directory. - -If the original contracts change, it is possible to create a conflict with the -patch. In this case, the verify scripts will report an error message and output -rejected changes in the `munged` directory. After merging the changes, run -`make record` in the `certora` directory; this will regenerate the patch file, -which can then be checked into git. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/applyHarness.patch b/lib/morpho-utils/lib/openzeppelin-contracts/certora/applyHarness.patch deleted file mode 100644 index 0fbe9ac..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/applyHarness.patch +++ /dev/null @@ -1,101 +0,0 @@ -diff -ruN .gitignore .gitignore ---- .gitignore 1969-12-31 19:00:00.000000000 -0500 -+++ .gitignore 2021-12-09 14:46:33.923637220 -0500 -@@ -0,0 +1,2 @@ -+* -+!.gitignore -diff -ruN governance/compatibility/GovernorCompatibilityBravo.sol governance/compatibility/GovernorCompatibilityBravo.sol ---- governance/compatibility/GovernorCompatibilityBravo.sol 2021-12-03 15:24:56.523654357 -0500 -+++ governance/compatibility/GovernorCompatibilityBravo.sol 2021-12-09 14:46:33.923637220 -0500 -@@ -245,7 +245,7 @@ - /** - * @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum. - */ -- function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { -+ function _quorumReached(uint256 proposalId) public view virtual override returns (bool) { // HARNESS: changed to public from internal - ProposalDetails storage details = _proposalDetails[proposalId]; - return quorum(proposalSnapshot(proposalId)) <= details.forVotes; - } -@@ -253,7 +253,7 @@ - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be scritly over the againstVotes. - */ -- function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { -+ function _voteSucceeded(uint256 proposalId) public view virtual override returns (bool) { // HARNESS: changed to public from internal - ProposalDetails storage details = _proposalDetails[proposalId]; - return details.forVotes > details.againstVotes; - } -diff -ruN governance/extensions/GovernorCountingSimple.sol governance/extensions/GovernorCountingSimple.sol ---- governance/extensions/GovernorCountingSimple.sol 2021-12-03 15:24:56.523654357 -0500 -+++ governance/extensions/GovernorCountingSimple.sol 2021-12-09 14:46:33.923637220 -0500 -@@ -64,7 +64,7 @@ - /** - * @dev See {Governor-_quorumReached}. - */ -- function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { -+ function _quorumReached(uint256 proposalId) public view virtual override returns (bool) { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - return quorum(proposalSnapshot(proposalId)) <= proposalvote.forVotes + proposalvote.abstainVotes; -@@ -73,7 +73,7 @@ - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. - */ -- function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { -+ function _voteSucceeded(uint256 proposalId) public view virtual override returns (bool) { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - return proposalvote.forVotes > proposalvote.againstVotes; -diff -ruN governance/extensions/GovernorTimelockControl.sol governance/extensions/GovernorTimelockControl.sol ---- governance/extensions/GovernorTimelockControl.sol 2021-12-03 15:24:56.523654357 -0500 -+++ governance/extensions/GovernorTimelockControl.sol 2021-12-09 14:46:33.923637220 -0500 -@@ -111,7 +111,7 @@ - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override { -- _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash); -+ _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash); - } - - /** -diff -ruN governance/Governor.sol governance/Governor.sol ---- governance/Governor.sol 2021-12-03 15:24:56.523654357 -0500 -+++ governance/Governor.sol 2021-12-09 14:46:56.411503587 -0500 -@@ -38,8 +38,8 @@ - - string private _name; - -- mapping(uint256 => ProposalCore) private _proposals; -- -+ mapping(uint256 => ProposalCore) public _proposals; -+ - /** - * @dev Restrict access to governor executing address. Some module might override the _executor function to make - * sure this modifier is consistent with the execution model. -@@ -167,12 +167,12 @@ - /** - * @dev Amount of votes already cast passes the threshold limit. - */ -- function _quorumReached(uint256 proposalId) internal view virtual returns (bool); -+ function _quorumReached(uint256 proposalId) public view virtual returns (bool); // HARNESS: changed to public from internal - - /** - * @dev Is the proposal successful or not. - */ -- function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); -+ function _voteSucceeded(uint256 proposalId) public view virtual returns (bool); // HARNESS: changed to public from internal - - /** - * @dev Register a vote with a given support and voting weight. -diff -ruN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Votes.sol ---- token/ERC20/extensions/ERC20Votes.sol 2021-12-03 15:24:56.527654330 -0500 -+++ token/ERC20/extensions/ERC20Votes.sol 2021-12-09 14:46:33.927637196 -0500 -@@ -84,7 +84,7 @@ - * - * - `blockNumber` must have been already mined - */ -- function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) { -+ function getPastVotes(address account, uint256 blockNumber) public view virtual returns (uint256) { - require(blockNumber < block.number, "ERC20Votes: block not yet mined"); - return _checkpointsLookup(_checkpoints[account], blockNumber); - } diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/ERC20VotesHarness.sol b/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/ERC20VotesHarness.sol deleted file mode 100644 index 5067ecf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/ERC20VotesHarness.sol +++ /dev/null @@ -1,28 +0,0 @@ -import "../munged/token/ERC20/extensions/ERC20Votes.sol"; - -contract ERC20VotesHarness is ERC20Votes { - constructor(string memory name, string memory symbol) ERC20Permit(name) ERC20(name, symbol) {} - - mapping(address => mapping(uint256 => uint256)) public _getPastVotes; - - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - super._afterTokenTransfer(from, to, amount); - _getPastVotes[from][block.number] -= amount; - _getPastVotes[to][block.number] += amount; - } - - /** - * @dev Change delegation for `delegator` to `delegatee`. - * - * Emits events {DelegateChanged} and {DelegateVotesChanged}. - */ - function _delegate(address delegator, address delegatee) internal virtual override{ - super._delegate(delegator, delegatee); - _getPastVotes[delegator][block.number] -= balanceOf(delegator); - _getPastVotes[delegatee][block.number] += balanceOf(delegator); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/WizardControlFirstPriority.sol b/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/WizardControlFirstPriority.sol deleted file mode 100644 index 5ae7fe0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/WizardControlFirstPriority.sol +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../munged/governance/Governor.sol"; -import "../munged/governance/extensions/GovernorCountingSimple.sol"; -import "../munged/governance/extensions/GovernorVotes.sol"; -import "../munged/governance/extensions/GovernorVotesQuorumFraction.sol"; -import "../munged/governance/extensions/GovernorTimelockControl.sol"; -import "../munged/governance/extensions/GovernorProposalThreshold.sol"; - -/* -Wizard options: -ProposalThreshhold = 10 -ERC20Votes -TimelockController -*/ - -contract WizardControlFirstPriority is Governor, GovernorProposalThreshold, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl { - constructor(ERC20Votes _token, TimelockController _timelock, string memory name, uint256 quorumFraction) - Governor(name) - GovernorVotes(_token) - GovernorVotesQuorumFraction(quorumFraction) - GovernorTimelockControl(_timelock) - {} - - //HARNESS - - function isExecuted(uint256 proposalId) public view returns (bool) { - return _proposals[proposalId].executed; - } - - function isCanceled(uint256 proposalId) public view returns (bool) { - return _proposals[proposalId].canceled; - } - - uint256 _votingDelay; - - uint256 _votingPeriod; - - uint256 _proposalThreshold; - - mapping(uint256 => uint256) public ghost_sum_vote_power_by_id; - - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason - ) internal override virtual returns (uint256) { - - uint256 deltaWeight = super._castVote(proposalId, account, support, reason); //HARNESS - ghost_sum_vote_power_by_id[proposalId] += deltaWeight; - - return deltaWeight; - } - - function snapshot(uint256 proposalId) public view returns (uint64) { - return _proposals[proposalId].voteStart._deadline; - } - - - function getExecutor() public view returns (address){ - return _executor(); - } - - // original code, harnessed - - function votingDelay() public view override returns (uint256) { // HARNESS: pure -> view - return _votingDelay; // HARNESS: parametric - } - - function votingPeriod() public view override returns (uint256) { // HARNESS: pure -> view - return _votingPeriod; // HARNESS: parametric - } - - function proposalThreshold() public view override returns (uint256) { // HARNESS: pure -> view - return _proposalThreshold; // HARNESS: parametric - } - - // original code, not harnessed - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function getVotes(address account, uint256 blockNumber) - public - view - override(IGovernor, GovernorVotes) - returns (uint256) - { - return super.getVotes(account, blockNumber); - } - - function state(uint256 proposalId) - public - view - override(Governor, GovernorTimelockControl) - returns (ProposalState) - { - return super.state(proposalId); - } - - function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) - public - override(Governor, GovernorProposalThreshold, IGovernor) - returns (uint256) - { - return super.propose(targets, values, calldatas, description); - } - - function _execute(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) - internal - override(Governor, GovernorTimelockControl) - { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) - internal - override(Governor, GovernorTimelockControl) - returns (uint256) - { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() - internal - view - override(Governor, GovernorTimelockControl) - returns (address) - { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(Governor, GovernorTimelockControl) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/WizardFirstTry.sol b/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/WizardFirstTry.sol deleted file mode 100644 index 83fece0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/harnesses/WizardFirstTry.sol +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../munged/governance/Governor.sol"; -import "../munged/governance/extensions/GovernorCountingSimple.sol"; -import "../munged/governance/extensions/GovernorVotes.sol"; -import "../munged/governance/extensions/GovernorVotesQuorumFraction.sol"; -import "../munged/governance/extensions/GovernorTimelockCompound.sol"; - -/* -Wizard options: -ERC20Votes -TimelockCompound -*/ - -contract WizardFirstTry is Governor, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockCompound { - constructor(ERC20Votes _token, ICompoundTimelock _timelock, string memory name, uint256 quorumFraction) - Governor(name) - GovernorVotes(_token) - GovernorVotesQuorumFraction(quorumFraction) - GovernorTimelockCompound(_timelock) - {} - - //HARNESS - - function isExecuted(uint256 proposalId) public view returns (bool) { - return _proposals[proposalId].executed; - } - - function isCanceled(uint256 proposalId) public view returns (bool) { - return _proposals[proposalId].canceled; - } - - function snapshot(uint256 proposalId) public view returns (uint64) { - return _proposals[proposalId].voteStart._deadline; - } - - function getExecutor() public view returns (address){ - return _executor(); - } - - uint256 _votingDelay; - - uint256 _votingPeriod; - - mapping(uint256 => uint256) public ghost_sum_vote_power_by_id; - - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason - ) internal override virtual returns (uint256) { - - uint256 deltaWeight = super._castVote(proposalId, account, support, reason); //HARNESS - ghost_sum_vote_power_by_id[proposalId] += deltaWeight; - - return deltaWeight; - } - - // original code, harnessed - - function votingDelay() public view override virtual returns (uint256) { // HARNESS: pure -> view - return _votingDelay; // HARNESS: parametric - } - - function votingPeriod() public view override virtual returns (uint256) { // HARNESS: pure -> view - return _votingPeriod; // HARNESS: parametric - } - - // original code, not harnessed - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function getVotes(address account, uint256 blockNumber) - public - view - override(IGovernor, GovernorVotes) - returns (uint256) - { - return super.getVotes(account, blockNumber); - } - - function state(uint256 proposalId) - public - view - override(Governor, GovernorTimelockCompound) - returns (ProposalState) - { - return super.state(proposalId); - } - - function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) - public - override(Governor, IGovernor) - returns (uint256) - { - return super.propose(targets, values, calldatas, description); - } - - function _execute(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) - internal - override(Governor, GovernorTimelockCompound) - { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) - internal - override(Governor, GovernorTimelockCompound) - returns (uint256) - { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() - internal - view - override(Governor, GovernorTimelockCompound) - returns (address) - { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(Governor, GovernorTimelockCompound) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/munged/.gitignore b/lib/morpho-utils/lib/openzeppelin-contracts/certora/munged/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/munged/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/Governor.sh b/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/Governor.sh deleted file mode 100755 index 53ade50..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/Governor.sh +++ /dev/null @@ -1,10 +0,0 @@ -make -C certora munged - -certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/GovernorHarness.sol \ - --verify GovernorHarness:certora/specs/GovernorBase.spec \ - --solc solc8.0 \ - --staging shelly/forSasha \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --rule voteStartBeforeVoteEnd \ - --msg "$1" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/GovernorCountingSimple-counting.sh b/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/GovernorCountingSimple-counting.sh deleted file mode 100644 index 9ed8fe3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/GovernorCountingSimple-counting.sh +++ /dev/null @@ -1,10 +0,0 @@ -make -C certora munged - -certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/GovernorBasicHarness.sol \ - --verify GovernorBasicHarness:certora/specs/GovernorCountingSimple.spec \ - --solc solc8.2 \ - --staging shelly/forSasha \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --rule hasVotedCorrelation \ - --msg "$1" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/WizardControlFirstPriority.sh b/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/WizardControlFirstPriority.sh deleted file mode 100644 index b815986..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/WizardControlFirstPriority.sh +++ /dev/null @@ -1,12 +0,0 @@ -make -C certora munged - -certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/WizardControlFirstPriority.sol \ - --link WizardControlFirstPriority:token=ERC20VotesHarness \ - --verify WizardControlFirstPriority:certora/specs/GovernorBase.spec \ - --solc solc8.2 \ - --disableLocalTypeChecking \ - --staging shelly/forSasha \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --rule canVoteDuringVotingPeriod \ - --msg "$1" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/WizardFirstTry.sh b/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/WizardFirstTry.sh deleted file mode 100644 index fd5a32a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/WizardFirstTry.sh +++ /dev/null @@ -1,10 +0,0 @@ -make -C certora munged - -certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/WizardFirstTry.sol \ - --verify WizardFirstTry:certora/specs/GovernorBase.spec \ - --solc solc8.2 \ - --staging shelly/forSasha \ - --optimistic_loop \ - --disableLocalTypeChecking \ - --settings -copyLoopUnroll=4 \ - --msg "$1" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/sanity.sh b/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/sanity.sh deleted file mode 100644 index b6cdb4e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/sanity.sh +++ /dev/null @@ -1,14 +0,0 @@ -make -C certora munged - -for f in certora/harnesses/Wizard*.sol -do - echo "Processing $f" - file=$(basename $f) - echo ${file%.*} - certoraRun certora/harnesses/$file \ - --verify ${file%.*}:certora/specs/sanity.spec "$@" \ - --solc solc8.2 --staging shelly/forSasha \ - --optimistic_loop \ - --msg "checking sanity on ${file%.*}" - --settings -copyLoopUnroll=4 -done diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/verifyAll.sh b/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/verifyAll.sh deleted file mode 100644 index 90d7691..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/scripts/verifyAll.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -make -C certora munged - -for contract in certora/harnesses/Wizard*.sol; -do - for spec in certora/specs/*.spec; - do - contractFile=$(basename $contract) - specFile=$(basename $spec) - if [[ "${specFile%.*}" != "RulesInProgress" ]]; - then - echo "Processing ${contractFile%.*} with $specFile" - if [[ "${contractFile%.*}" = *"WizardControl"* ]]; - then - certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/$contractFile \ - --link ${contractFile%.*}:token=ERC20VotesHarness \ - --verify ${contractFile%.*}:certora/specs/$specFile "$@" \ - --solc solc8.2 \ - --staging shelly/forSasha \ - --disableLocalTypeChecking \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --send_only \ - --msg "checking $specFile on ${contractFile%.*}" - else - certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/$contractFile \ - --verify ${contractFile%.*}:certora/specs/$specFile "$@" \ - --solc solc8.2 \ - --staging shelly/forSasha \ - --disableLocalTypeChecking \ - --optimistic_loop \ - --settings -copyLoopUnroll=4 \ - --send_only \ - --msg "checking $specFile on ${contractFile%.*}" - fi - fi - done -done diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/GovernorBase.spec b/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/GovernorBase.spec deleted file mode 100644 index 3dfc180..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/GovernorBase.spec +++ /dev/null @@ -1,334 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -///////////////////// Governor.sol base definitions ////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -using ERC20VotesHarness as erc20votes - -methods { - proposalSnapshot(uint256) returns uint256 envfree // matches proposalVoteStart - proposalDeadline(uint256) returns uint256 envfree // matches proposalVoteEnd - hashProposal(address[],uint256[],bytes[],bytes32) returns uint256 envfree - isExecuted(uint256) returns bool envfree - isCanceled(uint256) returns bool envfree - execute(address[], uint256[], bytes[], bytes32) returns uint256 - hasVoted(uint256, address) returns bool - castVote(uint256, uint8) returns uint256 - updateQuorumNumerator(uint256) - queue(address[], uint256[], bytes[], bytes32) returns uint256 - - // internal functions made public in harness: - _quorumReached(uint256) returns bool - _voteSucceeded(uint256) returns bool envfree - - // function summarization - proposalThreshold() returns uint256 envfree - - getVotes(address, uint256) returns uint256 => DISPATCHER(true) - - getPastTotalSupply(uint256 t) returns uint256 => PER_CALLEE_CONSTANT - getPastVotes(address a, uint256 t) returns uint256 => PER_CALLEE_CONSTANT - - //scheduleBatch(address[],uint256[],bytes[],bytes32,bytes32,uint256) => DISPATCHER(true) - //executeBatch(address[], uint256[], bytes[], bytes32, bytes32) => DISPATCHER(true) -} - -////////////////////////////////////////////////////////////////////////////// -//////////////////////////////// Definitions ///////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -// proposal was created - relation proved in noStartBeforeCreation -definition proposalCreated(uint256 pId) returns bool = proposalSnapshot(pId) > 0; - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////// Helper Functions /////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -function helperFunctionsWithRevert(uint256 proposalId, method f, env e) { - address[] targets; uint256[] values; bytes[] calldatas; string reason; bytes32 descriptionHash; - uint8 support; uint8 v; bytes32 r; bytes32 s; - if (f.selector == propose(address[], uint256[], bytes[], string).selector) { - uint256 result = propose@withrevert(e, targets, values, calldatas, reason); - require(result == proposalId); - } else if (f.selector == execute(address[], uint256[], bytes[], bytes32).selector) { - uint256 result = execute@withrevert(e, targets, values, calldatas, descriptionHash); - require(result == proposalId); - } else if (f.selector == castVote(uint256, uint8).selector) { - castVote@withrevert(e, proposalId, support); - } else if (f.selector == castVoteWithReason(uint256, uint8, string).selector) { - castVoteWithReason@withrevert(e, proposalId, support, reason); - } else if (f.selector == castVoteBySig(uint256, uint8,uint8, bytes32, bytes32).selector) { - castVoteBySig@withrevert(e, proposalId, support, v, r, s); - } else if (f.selector == queue(address[], uint256[], bytes[], bytes32).selector) { - queue@withrevert(e, targets, values, calldatas, descriptionHash); - } else { - calldataarg args; - f@withrevert(e, args); - } -} - -/* - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////// State Diagram ////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // // - // castVote(s)() // - // ------------- propose() ---------------------- time pass --------------- time passes ----------- // - // | No Proposal | --------> | Before Start (Delay) | --------> | Voting Period | ----------------------> | execute() | // - // ------------- ---------------------- --------------- -> Executed/Canceled ----------- // - // ------------------------------------------------------------|---------------|-------------------------|--------------> // - // t start end timelock // - // // - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -*/ - - -/////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// Global Valid States ///////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// - - -/* - * Start and end date are either initialized (non zero) or uninitialized (zero) simultaneously - * This invariant assumes that the block number cannot be 0 at any stage of the contract cycle - * This is very safe assumption as usually the 0 block is genesis block which is uploaded with data - * by the developers and will not be valid to raise proposals (at the current way that block chain is functioning) - */ - // To use env with general preserved block disable type checking [--disableLocalTypeChecking] -invariant startAndEndDatesNonZero(uint256 pId) - proposalSnapshot(pId) != 0 <=> proposalDeadline(pId) != 0 - { preserved with (env e){ - require e.block.number > 0; - }} - - -/* - * If a proposal is canceled it must have a start and an end date - */ - // To use env with general preserved block disable type checking [--disableLocalTypeChecking] -invariant canceledImplyStartAndEndDateNonZero(uint pId) - isCanceled(pId) => proposalSnapshot(pId) != 0 - {preserved with (env e){ - require e.block.number > 0; - }} - - -/* - * If a proposal is executed it must have a start and an end date - */ - // To use env with general preserved block disable type checking [--disableLocalTypeChecking] -invariant executedImplyStartAndEndDateNonZero(uint pId) - isExecuted(pId) => proposalSnapshot(pId) != 0 - { preserved with (env e){ - requireInvariant startAndEndDatesNonZero(pId); - require e.block.number > 0; - }} - - -/* - * A proposal starting block number must be less or equal than the proposal end date - */ -invariant voteStartBeforeVoteEnd(uint256 pId) - // from < to <= because snapshot and deadline can be the same block number if delays are set to 0 - // This is possible before the integration of GovernorSettings.sol to the system. - // After integration of GovernorSettings.sol the invariant expression should be changed from <= to < - (proposalSnapshot(pId) > 0 => proposalSnapshot(pId) <= proposalDeadline(pId)) - // (proposalSnapshot(pId) > 0 => proposalSnapshot(pId) <= proposalDeadline(pId)) - { preserved { - requireInvariant startAndEndDatesNonZero(pId); - }} - - -/* - * A proposal cannot be both executed and canceled simultaneously. - */ -invariant noBothExecutedAndCanceled(uint256 pId) - !isExecuted(pId) || !isCanceled(pId) - - -/* - * A proposal could be executed only if quorum was reached and vote succeeded - */ -rule executionOnlyIfQuoromReachedAndVoteSucceeded(uint256 pId, env e, method f){ - bool isExecutedBefore = isExecuted(pId); - bool quorumReachedBefore = _quorumReached(e, pId); - bool voteSucceededBefore = _voteSucceeded(pId); - - calldataarg args; - f(e, args); - - bool isExecutedAfter = isExecuted(pId); - assert (!isExecutedBefore && isExecutedAfter) => (quorumReachedBefore && voteSucceededBefore), "quorum was changed"; -} - -/////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////// In-State Rules ///////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// - -//========================================== -//------------- Voting Period -------------- -//========================================== - -/* - * A user cannot vote twice - */ - // Checked for castVote only. all 3 castVote functions call _castVote, so the completeness of the verification is counted on - // the fact that the 3 functions themselves makes no changes, but rather call an internal function to execute. - // That means that we do not check those 3 functions directly, however for castVote & castVoteWithReason it is quite trivial - // to understand why this is ok. For castVoteBySig we basically assume that the signature referendum is correct without checking it. - // We could check each function separately and pass the rule, but that would have uglyfied the code with no concrete - // benefit, as it is evident that nothing is happening in the first 2 functions (calling a view function), and we do not desire to check the signature verification. -rule doubleVoting(uint256 pId, uint8 sup, method f) { - env e; - address user = e.msg.sender; - bool votedCheck = hasVoted(e, pId, user); - - castVote@withrevert(e, pId, sup); - - assert votedCheck => lastReverted, "double voting accured"; -} - - -/////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////// State Transitions Rules ////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// - -//=========================================== -//-------- Propose() --> End of Time -------- -//=========================================== - - -/* - * Once a proposal is created, voteStart and voteEnd are immutable - */ -rule immutableFieldsAfterProposalCreation(uint256 pId, method f) { - uint256 _voteStart = proposalSnapshot(pId); - uint256 _voteEnd = proposalDeadline(pId); - - require proposalCreated(pId); // startDate > 0 - - env e; calldataarg arg; - f(e, arg); - - uint256 voteStart_ = proposalSnapshot(pId); - uint256 voteEnd_ = proposalDeadline(pId); - assert _voteStart == voteStart_, "Start date was changed"; - assert _voteEnd == voteEnd_, "End date was changed"; -} - - -/* - * Voting cannot start at a block number prior to proposal’s creation block number - */ -rule noStartBeforeCreation(uint256 pId) { - uint256 previousStart = proposalSnapshot(pId); - // This line makes sure that we see only cases where start date is changed from 0, i.e. creation of proposal - // We proved in immutableFieldsAfterProposalCreation that once dates set for proposal, it cannot be changed - require !proposalCreated(pId); // previousStart == 0; - - env e; calldataarg args; - propose(e, args); - - uint256 newStart = proposalSnapshot(pId); - // if created, start is after current block number (creation block) - assert(newStart != previousStart => newStart >= e.block.number); -} - - -//============================================ -//--- End of Voting Period --> End of Time --- -//============================================ - - -/* - * A proposal can neither be executed nor canceled before it ends - */ - // By induction it cannot be executed nor canceled before it starts, due to voteStartBeforeVoteEnd -rule noExecuteOrCancelBeforeDeadline(uint256 pId, method f){ - require !isExecuted(pId) && !isCanceled(pId); - - env e; calldataarg args; - f(e, args); - - assert e.block.number < proposalDeadline(pId) => (!isExecuted(pId) && !isCanceled(pId)), "executed/cancelled before deadline"; -} - -//////////////////////////////////////////////////////////////////////////////// -////////////////////// Integrity Of Functions (Unit Tests) ///////////////////// -//////////////////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////////////////// -////////////////////////////// High Level Rules //////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////////////////// -///////////////////////////// Not Categorized Yet ////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - - -/* - * All proposal specific (non-view) functions should revert if proposal is executed - */ - // In this rule we show that if a function is executed, i.e. execute() was called on the proposal ID, - // non of the proposal specific functions can make changes again. In executedOnlyAfterExecuteFunc - // we connected the executed attribute to the execute() function, showing that only execute() can - // change it, and that it will always change it. -rule allFunctionsRevertIfExecuted(method f) filtered { f -> - !f.isView && !f.isFallback - && f.selector != updateTimelock(address).selector - && f.selector != updateQuorumNumerator(uint256).selector - && f.selector != queue(address[],uint256[],bytes[],bytes32).selector - && f.selector != relay(address,uint256,bytes).selector - && f.selector != 0xb9a61961 // __acceptAdmin() -} { - env e; calldataarg args; - uint256 pId; - require(isExecuted(pId)); - requireInvariant noBothExecutedAndCanceled(pId); - requireInvariant executedImplyStartAndEndDateNonZero(pId); - - helperFunctionsWithRevert(pId, f, e); - - assert(lastReverted, "Function was not reverted"); -} - -/* - * All proposal specific (non-view) functions should revert if proposal is canceled - */ -rule allFunctionsRevertIfCanceled(method f) filtered { - f -> !f.isView && !f.isFallback - && f.selector != updateTimelock(address).selector - && f.selector != updateQuorumNumerator(uint256).selector - && f.selector != queue(address[],uint256[],bytes[],bytes32).selector - && f.selector != relay(address,uint256,bytes).selector - && f.selector != 0xb9a61961 // __acceptAdmin() -} { - env e; calldataarg args; - uint256 pId; - require(isCanceled(pId)); - requireInvariant noBothExecutedAndCanceled(pId); - requireInvariant canceledImplyStartAndEndDateNonZero(pId); - - helperFunctionsWithRevert(pId, f, e); - - assert(lastReverted, "Function was not reverted"); -} - -/* - * Proposal can be switched to executed only via execute() function - */ -rule executedOnlyAfterExecuteFunc(address[] targets, uint256[] values, bytes[] calldatas, bytes32 descriptionHash, method f) { - env e; calldataarg args; - uint256 pId; - bool executedBefore = isExecuted(pId); - require(!executedBefore); - - helperFunctionsWithRevert(pId, f, e); - - bool executedAfter = isExecuted(pId); - assert(executedAfter != executedBefore => f.selector == execute(address[], uint256[], bytes[], bytes32).selector, "isExecuted only changes in the execute method"); -} - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/GovernorCountingSimple.spec b/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/GovernorCountingSimple.spec deleted file mode 100644 index 7af73be..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/GovernorCountingSimple.spec +++ /dev/null @@ -1,221 +0,0 @@ -import "GovernorBase.spec" - -using ERC20VotesHarness as erc20votes - -methods { - ghost_sum_vote_power_by_id(uint256) returns uint256 envfree - - quorum(uint256) returns uint256 - proposalVotes(uint256) returns (uint256, uint256, uint256) envfree - - quorumNumerator() returns uint256 - _executor() returns address - - erc20votes._getPastVotes(address, uint256) returns uint256 - - getExecutor() returns address - - timelock() returns address -} - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// GHOSTS ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -//////////// ghosts to keep track of votes counting //////////// - -/* - * the sum of voting power of those who voted - */ -ghost sum_all_votes_power() returns uint256 { - init_state axiom sum_all_votes_power() == 0; -} - -hook Sstore ghost_sum_vote_power_by_id [KEY uint256 pId] uint256 current_power(uint256 old_power) STORAGE { - havoc sum_all_votes_power assuming sum_all_votes_power@new() == sum_all_votes_power@old() - old_power + current_power; -} - -/* - * sum of all votes casted per proposal - */ -ghost tracked_weight(uint256) returns uint256 { - init_state axiom forall uint256 p. tracked_weight(p) == 0; -} - -/* - * sum of all votes casted - */ -ghost sum_tracked_weight() returns uint256 { - init_state axiom sum_tracked_weight() == 0; -} - -/* - * getter for _proposalVotes.againstVotes - */ -ghost votesAgainst() returns uint256 { - init_state axiom votesAgainst() == 0; -} - -/* - * getter for _proposalVotes.forVotes - */ -ghost votesFor() returns uint256 { - init_state axiom votesFor() == 0; -} - -/* - * getter for _proposalVotes.abstainVotes - */ -ghost votesAbstain() returns uint256 { - init_state axiom votesAbstain() == 0; -} - -hook Sstore _proposalVotes [KEY uint256 pId].againstVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesAgainst assuming votesAgainst@new() == votesAgainst@old() - old_votes + votes; -} - -hook Sstore _proposalVotes [KEY uint256 pId].forVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesFor assuming votesFor@new() == votesFor@old() - old_votes + votes; -} - -hook Sstore _proposalVotes [KEY uint256 pId].abstainVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesAbstain assuming votesAbstain@new() == votesAbstain@old() - old_votes + votes; -} - - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////// INVARIANTS //////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -/* - * sum of all votes casted is equal to the sum of voting power of those who voted, per each proposal - */ -invariant SumOfVotesCastEqualSumOfPowerOfVotedPerProposal(uint256 pId) - tracked_weight(pId) == ghost_sum_vote_power_by_id(pId) - - -/* - * sum of all votes casted is equal to the sum of voting power of those who voted - */ -invariant SumOfVotesCastEqualSumOfPowerOfVoted() - sum_tracked_weight() == sum_all_votes_power() - - -/* -* sum of all votes casted is greater or equal to the sum of voting power of those who voted at a specific proposal -*/ -invariant OneIsNotMoreThanAll(uint256 pId) - sum_all_votes_power() >= tracked_weight(pId) - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// RULES ////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -/* - * Only sender's voting status can be changed by execution of any cast vote function - */ -// Checked for castVote only. all 3 castVote functions call _castVote, so the completeness of the verification is counted on - // the fact that the 3 functions themselves makes no changes, but rather call an internal function to execute. - // That means that we do not check those 3 functions directly, however for castVote & castVoteWithReason it is quite trivial - // to understand why this is ok. For castVoteBySig we basically assume that the signature referendum is correct without checking it. - // We could check each function separately and pass the rule, but that would have uglyfied the code with no concrete - // benefit, as it is evident that nothing is happening in the first 2 functions (calling a view function), and we do not desire to check the signature verification. -rule noVoteForSomeoneElse(uint256 pId, uint8 sup, method f) { - env e; calldataarg args; - - address voter = e.msg.sender; - address user; - - bool hasVotedBefore_User = hasVoted(e, pId, user); - - castVote@withrevert(e, pId, sup); - require(!lastReverted); - - bool hasVotedAfter_User = hasVoted(e, pId, user); - - assert user != voter => hasVotedBefore_User == hasVotedAfter_User; -} - - -/* -* Total voting tally is monotonically non-decreasing in every operation -*/ -rule votingWeightMonotonicity(method f){ - uint256 votingWeightBefore = sum_tracked_weight(); - - env e; - calldataarg args; - f(e, args); - - uint256 votingWeightAfter = sum_tracked_weight(); - - assert votingWeightBefore <= votingWeightAfter, "Voting weight was decreased somehow"; -} - - -/* -* A change in hasVoted must be correlated with an non-decreasing of the vote supports (nondecrease because user can vote with weight 0) -*/ -rule hasVotedCorrelation(uint256 pId, method f, env e, uint256 bn) { - address acc = e.msg.sender; - - uint256 againstBefore = votesAgainst(); - uint256 forBefore = votesFor(); - uint256 abstainBefore = votesAbstain(); - - bool hasVotedBefore = hasVoted(e, pId, acc); - - helperFunctionsWithRevert(pId, f, e); - require(!lastReverted); - - uint256 againstAfter = votesAgainst(); - uint256 forAfter = votesFor(); - uint256 abstainAfter = votesAbstain(); - - bool hasVotedAfter = hasVoted(e, pId, acc); - - assert (!hasVotedBefore && hasVotedAfter) => againstBefore <= againstAfter || forBefore <= forAfter || abstainBefore <= abstainAfter, "no correlation"; -} - - -/* -* Only privileged users can execute privileged operations, e.g. change _quorumNumerator or _timelock -*/ -rule privilegedOnlyNumerator(method f, uint256 newQuorumNumerator){ - env e; - calldataarg arg; - uint256 quorumNumBefore = quorumNumerator(e); - - f(e, arg); - - uint256 quorumNumAfter = quorumNumerator(e); - address executorCheck = getExecutor(e); - - assert quorumNumBefore != quorumNumAfter => e.msg.sender == executorCheck, "non privileged user changed quorum numerator"; -} - -rule privilegedOnlyTimelock(method f, uint256 newQuorumNumerator){ - env e; - calldataarg arg; - uint256 timelockBefore = timelock(e); - - f(e, arg); - - uint256 timelockAfter = timelock(e); - - assert timelockBefore != timelockAfter => e.msg.sender == timelockBefore, "non privileged user changed timelock"; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/RulesInProgress.spec b/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/RulesInProgress.spec deleted file mode 100644 index cbad333..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/RulesInProgress.spec +++ /dev/null @@ -1,139 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -////////////// THIS SPEC IS A RESERVE FOR NOT IN PROGRESS ////////////// -////////////////////////////////////////////////////////////////////////////// - -import "GovernorBase.spec" - -using ERC20VotesHarness as erc20votes - -methods { - ghost_sum_vote_power_by_id(uint256) returns uint256 envfree - - quorum(uint256) returns uint256 - proposalVotes(uint256) returns (uint256, uint256, uint256) envfree - - quorumNumerator() returns uint256 - _executor() returns address - - erc20votes._getPastVotes(address, uint256) returns uint256 - - getExecutor() returns address - - timelock() returns address -} - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// GHOSTS ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -//////////// ghosts to keep track of votes counting //////////// - -/* - * the sum of voting power of those who voted - */ -ghost sum_all_votes_power() returns uint256 { - init_state axiom sum_all_votes_power() == 0; -} - -hook Sstore ghost_sum_vote_power_by_id [KEY uint256 pId] uint256 current_power(uint256 old_power) STORAGE { - havoc sum_all_votes_power assuming sum_all_votes_power@new() == sum_all_votes_power@old() - old_power + current_power; -} - -/* - * sum of all votes casted per proposal - */ -ghost tracked_weight(uint256) returns uint256 { - init_state axiom forall uint256 p. tracked_weight(p) == 0; -} - -/* - * sum of all votes casted - */ -ghost sum_tracked_weight() returns uint256 { - init_state axiom sum_tracked_weight() == 0; -} - -/* - * getter for _proposalVotes.againstVotes - */ -ghost votesAgainst() returns uint256 { - init_state axiom votesAgainst() == 0; -} - -/* - * getter for _proposalVotes.forVotes - */ -ghost votesFor() returns uint256 { - init_state axiom votesFor() == 0; -} - -/* - * getter for _proposalVotes.abstainVotes - */ -ghost votesAbstain() returns uint256 { - init_state axiom votesAbstain() == 0; -} - -hook Sstore _proposalVotes [KEY uint256 pId].againstVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesAgainst assuming votesAgainst@new() == votesAgainst@old() - old_votes + votes; -} - -hook Sstore _proposalVotes [KEY uint256 pId].forVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesFor assuming votesFor@new() == votesFor@old() - old_votes + votes; -} - -hook Sstore _proposalVotes [KEY uint256 pId].abstainVotes uint256 votes(uint256 old_votes) STORAGE { - havoc tracked_weight assuming forall uint256 p.(p == pId => tracked_weight@new(p) == tracked_weight@old(p) - old_votes + votes) && - (p != pId => tracked_weight@new(p) == tracked_weight@old(p)); - havoc sum_tracked_weight assuming sum_tracked_weight@new() == sum_tracked_weight@old() - old_votes + votes; - havoc votesAbstain assuming votesAbstain@new() == votesAbstain@old() - old_votes + votes; -} - - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////// INVARIANTS //////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - - -////////////////////////////////////////////////////////////////////////////// -///////////////////////////////// RULES ////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -//NOT FINISHED -/* -* the sum of voting power of those who voted is less or equal to the maximum possible votes, per each proposal -*/ -rule possibleTotalVotes(uint256 pId, uint8 sup, env e, method f) { - - // add requireinvariant for all i, j. i = i - 1 && i < j => checkpointlookup[i] < checkpointlookup[j]; - require tracked_weight(pId) <= erc20votes.getPastTotalSupply(e, proposalSnapshot(pId)); - - uint256 againstB; - uint256 forB; - uint256 absatinB; - againstB, forB, absatinB = proposalVotes(pId); - - calldataarg args; - //f(e, args); - - castVote(e, pId, sup); - - uint256 against; - uint256 for; - uint256 absatin; - against, for, absatin = proposalVotes(pId); - - uint256 ps = proposalSnapshot(pId); - - assert tracked_weight(pId) <= erc20votes.getPastTotalSupply(e, proposalSnapshot(pId)), "bla bla bla"; -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/sanity.spec b/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/sanity.spec deleted file mode 100644 index e08f688..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/certora/specs/sanity.spec +++ /dev/null @@ -1,14 +0,0 @@ -/* -This rule looks for a non-reverting execution path to each method, including those overridden in the harness. -A method has such an execution path if it violates this rule. -How it works: - - If there is a non-reverting execution path, we reach the false assertion, and the sanity fails. - - If all execution paths are reverting, we never call the assertion, and the method will pass this rule vacuously. -*/ - -rule sanity(method f) { - env e; - calldataarg arg; - f(e, arg); - assert false; -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControl.sol deleted file mode 100644 index 93fd028..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControl.sol +++ /dev/null @@ -1,247 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) - -pragma solidity ^0.8.0; - -import "./IAccessControl.sol"; -import "../utils/Context.sol"; -import "../utils/Strings.sol"; -import "../utils/introspection/ERC165.sol"; - -/** - * @dev Contract module that allows children to implement role-based access - * control mechanisms. This is a lightweight version that doesn't allow enumerating role - * members except through off-chain means by accessing the contract event logs. Some - * applications may benefit from on-chain enumerability, for those cases see - * {AccessControlEnumerable}. - * - * Roles are referred to by their `bytes32` identifier. These should be exposed - * in the external API and be unique. The best way to achieve this is by - * using `public constant` hash digests: - * - * ``` - * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); - * ``` - * - * Roles can be used to represent a set of permissions. To restrict access to a - * function call, use {hasRole}: - * - * ``` - * function foo() public { - * require(hasRole(MY_ROLE, msg.sender)); - * ... - * } - * ``` - * - * Roles can be granted and revoked dynamically via the {grantRole} and - * {revokeRole} functions. Each role has an associated admin role, and only - * accounts that have a role's admin role can call {grantRole} and {revokeRole}. - * - * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means - * that only accounts with this role will be able to grant or revoke other - * roles. More complex role relationships can be created by using - * {_setRoleAdmin}. - * - * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to - * grant and revoke this role. Extra precautions should be taken to secure - * accounts that have been granted it. - */ -abstract contract AccessControl is Context, IAccessControl, ERC165 { - struct RoleData { - mapping(address => bool) members; - bytes32 adminRole; - } - - mapping(bytes32 => RoleData) private _roles; - - bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; - - /** - * @dev Modifier that checks that an account has a specific role. Reverts - * with a standardized message including the required role. - * - * The format of the revert reason is given by the following regular expression: - * - * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ - * - * _Available since v4.1._ - */ - modifier onlyRole(bytes32 role) { - _checkRole(role); - _; - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Returns `true` if `account` has been granted `role`. - */ - function hasRole(bytes32 role, address account) public view virtual override returns (bool) { - return _roles[role].members[account]; - } - - /** - * @dev Revert with a standard message if `_msgSender()` is missing `role`. - * Overriding this function changes the behavior of the {onlyRole} modifier. - * - * Format of the revert message is described in {_checkRole}. - * - * _Available since v4.6._ - */ - function _checkRole(bytes32 role) internal view virtual { - _checkRole(role, _msgSender()); - } - - /** - * @dev Revert with a standard message if `account` is missing `role`. - * - * The format of the revert reason is given by the following regular expression: - * - * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ - */ - function _checkRole(bytes32 role, address account) internal view virtual { - if (!hasRole(role, account)) { - revert( - string( - abi.encodePacked( - "AccessControl: account ", - Strings.toHexString(account), - " is missing role ", - Strings.toHexString(uint256(role), 32) - ) - ) - ); - } - } - - /** - * @dev Returns the admin role that controls `role`. See {grantRole} and - * {revokeRole}. - * - * To change a role's admin, use {_setRoleAdmin}. - */ - function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { - return _roles[role].adminRole; - } - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - * - * May emit a {RoleGranted} event. - */ - function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { - _grantRole(role, account); - } - - /** - * @dev Revokes `role` from `account`. - * - * If `account` had been granted `role`, emits a {RoleRevoked} event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - * - * May emit a {RoleRevoked} event. - */ - function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { - _revokeRole(role, account); - } - - /** - * @dev Revokes `role` from the calling account. - * - * Roles are often managed via {grantRole} and {revokeRole}: this function's - * purpose is to provide a mechanism for accounts to lose their privileges - * if they are compromised (such as when a trusted device is misplaced). - * - * If the calling account had been revoked `role`, emits a {RoleRevoked} - * event. - * - * Requirements: - * - * - the caller must be `account`. - * - * May emit a {RoleRevoked} event. - */ - function renounceRole(bytes32 role, address account) public virtual override { - require(account == _msgSender(), "AccessControl: can only renounce roles for self"); - - _revokeRole(role, account); - } - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. Note that unlike {grantRole}, this function doesn't perform any - * checks on the calling account. - * - * May emit a {RoleGranted} event. - * - * [WARNING] - * ==== - * This function should only be called from the constructor when setting - * up the initial roles for the system. - * - * Using this function in any other way is effectively circumventing the admin - * system imposed by {AccessControl}. - * ==== - * - * NOTE: This function is deprecated in favor of {_grantRole}. - */ - function _setupRole(bytes32 role, address account) internal virtual { - _grantRole(role, account); - } - - /** - * @dev Sets `adminRole` as ``role``'s admin role. - * - * Emits a {RoleAdminChanged} event. - */ - function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { - bytes32 previousAdminRole = getRoleAdmin(role); - _roles[role].adminRole = adminRole; - emit RoleAdminChanged(role, previousAdminRole, adminRole); - } - - /** - * @dev Grants `role` to `account`. - * - * Internal function without access restriction. - * - * May emit a {RoleGranted} event. - */ - function _grantRole(bytes32 role, address account) internal virtual { - if (!hasRole(role, account)) { - _roles[role].members[account] = true; - emit RoleGranted(role, account, _msgSender()); - } - } - - /** - * @dev Revokes `role` from `account`. - * - * Internal function without access restriction. - * - * May emit a {RoleRevoked} event. - */ - function _revokeRole(bytes32 role, address account) internal virtual { - if (hasRole(role, account)) { - _roles[role].members[account] = false; - emit RoleRevoked(role, account, _msgSender()); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControlCrossChain.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControlCrossChain.sol deleted file mode 100644 index 95be509..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControlCrossChain.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControlCrossChain.sol) - -pragma solidity ^0.8.4; - -import "./AccessControl.sol"; -import "../crosschain/CrossChainEnabled.sol"; - -/** - * @dev An extension to {AccessControl} with support for cross-chain access management. - * For each role, is extension implements an equivalent "aliased" role that is used for - * restricting calls originating from other chains. - * - * For example, if a function `myFunction` is protected by `onlyRole(SOME_ROLE)`, and - * if an address `x` has role `SOME_ROLE`, it would be able to call `myFunction` directly. - * A wallet or contract at the same address on another chain would however not be able - * to call this function. In order to do so, it would require to have the role - * `_crossChainRoleAlias(SOME_ROLE)`. - * - * This aliasing is required to protect against multiple contracts living at the same - * address on different chains but controlled by conflicting entities. - * - * _Available since v4.6._ - */ -abstract contract AccessControlCrossChain is AccessControl, CrossChainEnabled { - bytes32 public constant CROSSCHAIN_ALIAS = keccak256("CROSSCHAIN_ALIAS"); - - /** - * @dev See {AccessControl-_checkRole}. - */ - function _checkRole(bytes32 role) internal view virtual override { - if (_isCrossChain()) { - _checkRole(_crossChainRoleAlias(role), _crossChainSender()); - } else { - super._checkRole(role); - } - } - - /** - * @dev Returns the aliased role corresponding to `role`. - */ - function _crossChainRoleAlias(bytes32 role) internal pure virtual returns (bytes32) { - return role ^ CROSSCHAIN_ALIAS; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControlEnumerable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControlEnumerable.sol deleted file mode 100644 index 354e1be..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/AccessControlEnumerable.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) - -pragma solidity ^0.8.0; - -import "./IAccessControlEnumerable.sol"; -import "./AccessControl.sol"; -import "../utils/structs/EnumerableSet.sol"; - -/** - * @dev Extension of {AccessControl} that allows enumerating the members of each role. - */ -abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { - using EnumerableSet for EnumerableSet.AddressSet; - - mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Returns one of the accounts that have `role`. `index` must be a - * value between 0 and {getRoleMemberCount}, non-inclusive. - * - * Role bearers are not sorted in any particular way, and their ordering may - * change at any point. - * - * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure - * you perform all queries on the same block. See the following - * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] - * for more information. - */ - function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { - return _roleMembers[role].at(index); - } - - /** - * @dev Returns the number of accounts that have `role`. Can be used - * together with {getRoleMember} to enumerate all bearers of a role. - */ - function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { - return _roleMembers[role].length(); - } - - /** - * @dev Overload {_grantRole} to track enumerable memberships - */ - function _grantRole(bytes32 role, address account) internal virtual override { - super._grantRole(role, account); - _roleMembers[role].add(account); - } - - /** - * @dev Overload {_revokeRole} to track enumerable memberships - */ - function _revokeRole(bytes32 role, address account) internal virtual override { - super._revokeRole(role, account); - _roleMembers[role].remove(account); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol deleted file mode 100644 index f773ecc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) - -pragma solidity ^0.8.0; - -/** - * @dev External interface of AccessControl declared to support ERC165 detection. - */ -interface IAccessControl { - /** - * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` - * - * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite - * {RoleAdminChanged} not being emitted signaling this. - * - * _Available since v3.1._ - */ - event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); - - /** - * @dev Emitted when `account` is granted `role`. - * - * `sender` is the account that originated the contract call, an admin role - * bearer except when using {AccessControl-_setupRole}. - */ - event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Emitted when `account` is revoked `role`. - * - * `sender` is the account that originated the contract call: - * - if using `revokeRole`, it is the admin role bearer - * - if using `renounceRole`, it is the role bearer (i.e. `account`) - */ - event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Returns `true` if `account` has been granted `role`. - */ - function hasRole(bytes32 role, address account) external view returns (bool); - - /** - * @dev Returns the admin role that controls `role`. See {grantRole} and - * {revokeRole}. - * - * To change a role's admin, use {AccessControl-_setRoleAdmin}. - */ - function getRoleAdmin(bytes32 role) external view returns (bytes32); - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function grantRole(bytes32 role, address account) external; - - /** - * @dev Revokes `role` from `account`. - * - * If `account` had been granted `role`, emits a {RoleRevoked} event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function revokeRole(bytes32 role, address account) external; - - /** - * @dev Revokes `role` from the calling account. - * - * Roles are often managed via {grantRole} and {revokeRole}: this function's - * purpose is to provide a mechanism for accounts to lose their privileges - * if they are compromised (such as when a trusted device is misplaced). - * - * If the calling account had been granted `role`, emits a {RoleRevoked} - * event. - * - * Requirements: - * - * - the caller must be `account`. - */ - function renounceRole(bytes32 role, address account) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/IAccessControlEnumerable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/IAccessControlEnumerable.sol deleted file mode 100644 index 61aaf57..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/IAccessControlEnumerable.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) - -pragma solidity ^0.8.0; - -import "./IAccessControl.sol"; - -/** - * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. - */ -interface IAccessControlEnumerable is IAccessControl { - /** - * @dev Returns one of the accounts that have `role`. `index` must be a - * value between 0 and {getRoleMemberCount}, non-inclusive. - * - * Role bearers are not sorted in any particular way, and their ordering may - * change at any point. - * - * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure - * you perform all queries on the same block. See the following - * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] - * for more information. - */ - function getRoleMember(bytes32 role, uint256 index) external view returns (address); - - /** - * @dev Returns the number of accounts that have `role`. Can be used - * together with {getRoleMember} to enumerate all bearers of a role. - */ - function getRoleMemberCount(bytes32 role) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/Ownable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/Ownable.sol deleted file mode 100644 index 6d4e866..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/Ownable.sol +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) - -pragma solidity ^0.8.0; - -import "../utils/Context.sol"; - -/** - * @dev Contract module which provides a basic access control mechanism, where - * there is an account (an owner) that can be granted exclusive access to - * specific functions. - * - * By default, the owner account will be the one that deploys the contract. This - * can later be changed with {transferOwnership}. - * - * This module is used through inheritance. It will make available the modifier - * `onlyOwner`, which can be applied to your functions to restrict their use to - * the owner. - */ -abstract contract Ownable is Context { - address private _owner; - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - /** - * @dev Initializes the contract setting the deployer as the initial owner. - */ - constructor() { - _transferOwnership(_msgSender()); - } - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - _checkOwner(); - _; - } - - /** - * @dev Returns the address of the current owner. - */ - function owner() public view virtual returns (address) { - return _owner; - } - - /** - * @dev Throws if the sender is not the owner. - */ - function _checkOwner() internal view virtual { - require(owner() == _msgSender(), "Ownable: caller is not the owner"); - } - - /** - * @dev Leaves the contract without owner. It will not be possible to call - * `onlyOwner` functions anymore. Can only be called by the current owner. - * - * NOTE: Renouncing ownership will leave the contract without an owner, - * thereby removing any functionality that is only available to the owner. - */ - function renounceOwnership() public virtual onlyOwner { - _transferOwnership(address(0)); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Can only be called by the current owner. - */ - function transferOwnership(address newOwner) public virtual onlyOwner { - require(newOwner != address(0), "Ownable: new owner is the zero address"); - _transferOwnership(newOwner); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Internal function without access restriction. - */ - function _transferOwnership(address newOwner) internal virtual { - address oldOwner = _owner; - _owner = newOwner; - emit OwnershipTransferred(oldOwner, newOwner); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/README.adoc deleted file mode 100644 index 0959e1a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/access/README.adoc +++ /dev/null @@ -1,23 +0,0 @@ -= Access Control - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/access - -This directory provides ways to restrict who can access the functions of a contract or when they can do it. - -- {AccessControl} provides a general role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts. -- {Ownable} is a simpler mechanism with a single owner "role" that can be assigned to a single account. This simpler mechanism can be useful for quick tests but projects with production concerns are likely to outgrow it. - -== Authorization - -{{Ownable}} - -{{IAccessControl}} - -{{AccessControl}} - -{{AccessControlCrossChain}} - -{{IAccessControlEnumerable}} - -{{AccessControlEnumerable}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/CrossChainEnabled.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/CrossChainEnabled.sol deleted file mode 100644 index 4c9b9e5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/CrossChainEnabled.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/CrossChainEnabled.sol) - -pragma solidity ^0.8.4; - -import "./errors.sol"; - -/** - * @dev Provides information for building cross-chain aware contracts. This - * abstract contract provides accessors and modifiers to control the execution - * flow when receiving cross-chain messages. - * - * Actual implementations of cross-chain aware contracts, which are based on - * this abstraction, will have to inherit from a bridge-specific - * specialization. Such specializations are provided under - * `crosschain//CrossChainEnabled.sol`. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabled { - /** - * @dev Throws if the current function call is not the result of a - * cross-chain execution. - */ - modifier onlyCrossChain() { - if (!_isCrossChain()) revert NotCrossChainCall(); - _; - } - - /** - * @dev Throws if the current function call is not the result of a - * cross-chain execution initiated by `account`. - */ - modifier onlyCrossChainSender(address expected) { - address actual = _crossChainSender(); - if (expected != actual) revert InvalidCrossChainSender(actual, expected); - _; - } - - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message. - */ - function _isCrossChain() internal view virtual returns (bool); - - /** - * @dev Returns the address of the sender of the cross-chain message that - * triggered the current function call. - * - * IMPORTANT: Should revert with `NotCrossChainCall` if the current function - * call is not the result of a cross-chain message. - */ - function _crossChainSender() internal view virtual returns (address); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/README.adoc deleted file mode 100644 index 266b153..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/README.adoc +++ /dev/null @@ -1,34 +0,0 @@ -= Cross Chain Awareness - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/crosschain - -This directory provides building blocks to improve cross-chain awareness of smart contracts. - -- {CrossChainEnabled} is an abstraction that contains accessors and modifiers to control the execution flow when receiving cross-chain messages. - -== CrossChainEnabled specializations - -The following specializations of {CrossChainEnabled} provide implementations of the {CrossChainEnabled} abstraction for specific bridges. This can be used to complex cross-chain aware components such as {AccessControlCrossChain}. - -{{CrossChainEnabledAMB}} - -{{CrossChainEnabledArbitrumL1}} - -{{CrossChainEnabledArbitrumL2}} - -{{CrossChainEnabledOptimism}} - -{{CrossChainEnabledPolygonChild}} - -== Libraries for cross-chain - -In addition to the {CrossChainEnabled} abstraction, cross-chain awareness is also available through libraries. These libraries can be used to build complex designs such as contracts with the ability to interact with multiple bridges. - -{{LibAMB}} - -{{LibArbitrumL1}} - -{{LibArbitrumL2}} - -{{LibOptimism}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/amb/CrossChainEnabledAMB.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/amb/CrossChainEnabledAMB.sol deleted file mode 100644 index e69355d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/amb/CrossChainEnabledAMB.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/amb/CrossChainEnabledAMB.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabled.sol"; -import "./LibAMB.sol"; - -/** - * @dev https://docs.tokenbridge.net/amb-bridge/about-amb-bridge[AMB] - * specialization or the {CrossChainEnabled} abstraction. - * - * As of february 2020, AMB bridges are available between the following chains: - * - * - https://docs.tokenbridge.net/eth-xdai-amb-bridge/about-the-eth-xdai-amb[ETH ⇌ xDai] - * - https://docs.tokenbridge.net/eth-qdai-bridge/about-the-eth-qdai-amb[ETH ⇌ qDai] - * - https://docs.tokenbridge.net/eth-etc-amb-bridge/about-the-eth-etc-amb[ETH ⇌ ETC] - * - https://docs.tokenbridge.net/eth-bsc-amb/about-the-eth-bsc-amb[ETH ⇌ BSC] - * - https://docs.tokenbridge.net/eth-poa-amb-bridge/about-the-eth-poa-amb[ETH ⇌ POA] - * - https://docs.tokenbridge.net/bsc-xdai-amb/about-the-bsc-xdai-amb[BSC ⇌ xDai] - * - https://docs.tokenbridge.net/poa-xdai-amb/about-the-poa-xdai-amb[POA ⇌ xDai] - * - https://docs.tokenbridge.net/rinkeby-xdai-amb-bridge/about-the-rinkeby-xdai-amb[Rinkeby ⇌ xDai] - * - https://docs.tokenbridge.net/kovan-sokol-amb-bridge/about-the-kovan-sokol-amb[Kovan ⇌ Sokol] - * - * _Available since v4.6._ - */ -contract CrossChainEnabledAMB is CrossChainEnabled { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _bridge; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) { - _bridge = bridge; - } - - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return LibAMB.isCrossChain(_bridge); - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return LibAMB.crossChainSender(_bridge); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/amb/LibAMB.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/amb/LibAMB.sol deleted file mode 100644 index aef9c43..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/amb/LibAMB.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/amb/LibAMB.sol) - -pragma solidity ^0.8.4; - -import {IAMB as AMB_Bridge} from "../../vendor/amb/IAMB.sol"; -import "../errors.sol"; - -/** - * @dev Primitives for cross-chain aware contracts using the - * https://docs.tokenbridge.net/amb-bridge/about-amb-bridge[AMB] - * family of bridges. - */ -library LibAMB { - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message relayed by `bridge`. - */ - function isCrossChain(address bridge) internal view returns (bool) { - return msg.sender == bridge; - } - - /** - * @dev Returns the address of the sender that triggered the current - * cross-chain message through `bridge`. - * - * NOTE: {isCrossChain} should be checked before trying to recover the - * sender, as it will revert with `NotCrossChainCall` if the current - * function call is not the result of a cross-chain message. - */ - function crossChainSender(address bridge) internal view returns (address) { - if (!isCrossChain(bridge)) revert NotCrossChainCall(); - return AMB_Bridge(bridge).messageSender(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol deleted file mode 100644 index 5068da3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabled.sol"; -import "./LibArbitrumL1.sol"; - -/** - * @dev https://arbitrum.io/[Arbitrum] specialization or the - * {CrossChainEnabled} abstraction the L1 side (mainnet). - * - * This version should only be deployed on L1 to process cross-chain messages - * originating from L2. For the other side, use {CrossChainEnabledArbitrumL2}. - * - * The bridge contract is provided and maintained by the arbitrum team. You can - * find the address of this contract on the rinkeby testnet in - * https://developer.offchainlabs.com/docs/useful_addresses[Arbitrum's developer documentation]. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabledArbitrumL1 is CrossChainEnabled { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _bridge; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) { - _bridge = bridge; - } - - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return LibArbitrumL1.isCrossChain(_bridge); - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return LibArbitrumL1.crossChainSender(_bridge); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol deleted file mode 100644 index 16ebcc9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabled.sol"; -import "./LibArbitrumL2.sol"; - -/** - * @dev https://arbitrum.io/[Arbitrum] specialization or the - * {CrossChainEnabled} abstraction the L2 side (arbitrum). - * - * This version should only be deployed on L2 to process cross-chain messages - * originating from L1. For the other side, use {CrossChainEnabledArbitrumL1}. - * - * Arbitrum L2 includes the `ArbSys` contract at a fixed address. Therefore, - * this specialization of {CrossChainEnabled} does not include a constructor. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabledArbitrumL2 is CrossChainEnabled { - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return LibArbitrumL2.isCrossChain(LibArbitrumL2.ARBSYS); - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return LibArbitrumL2.crossChainSender(LibArbitrumL2.ARBSYS); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/LibArbitrumL1.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/LibArbitrumL1.sol deleted file mode 100644 index 6b591ca..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/LibArbitrumL1.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/arbitrum/LibArbitrumL1.sol) - -pragma solidity ^0.8.4; - -import {IBridge as ArbitrumL1_Bridge} from "../../vendor/arbitrum/IBridge.sol"; -import {IInbox as ArbitrumL1_Inbox} from "../../vendor/arbitrum/IInbox.sol"; -import {IOutbox as ArbitrumL1_Outbox} from "../../vendor/arbitrum/IOutbox.sol"; -import "../errors.sol"; - -/** - * @dev Primitives for cross-chain aware contracts for - * https://arbitrum.io/[Arbitrum]. - * - * This version should only be used on L1 to process cross-chain messages - * originating from L2. For the other side, use {LibArbitrumL2}. - */ -library LibArbitrumL1 { - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message relayed by the `bridge`. - */ - function isCrossChain(address bridge) internal view returns (bool) { - return msg.sender == bridge; - } - - /** - * @dev Returns the address of the sender that triggered the current - * cross-chain message through the `bridge`. - * - * NOTE: {isCrossChain} should be checked before trying to recover the - * sender, as it will revert with `NotCrossChainCall` if the current - * function call is not the result of a cross-chain message. - */ - function crossChainSender(address bridge) internal view returns (address) { - if (!isCrossChain(bridge)) revert NotCrossChainCall(); - - address sender = ArbitrumL1_Outbox(ArbitrumL1_Bridge(bridge).activeOutbox()).l2ToL1Sender(); - require(sender != address(0), "LibArbitrumL1: system messages without sender"); - - return sender; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/LibArbitrumL2.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/LibArbitrumL2.sol deleted file mode 100644 index 1410afd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/arbitrum/LibArbitrumL2.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/arbitrum/LibArbitrumL2.sol) - -pragma solidity ^0.8.4; - -import {IArbSys as ArbitrumL2_Bridge} from "../../vendor/arbitrum/IArbSys.sol"; -import "../errors.sol"; - -/** - * @dev Primitives for cross-chain aware contracts for - * https://arbitrum.io/[Arbitrum]. - * - * This version should only be used on L2 to process cross-chain messages - * originating from L1. For the other side, use {LibArbitrumL1}. - */ -library LibArbitrumL2 { - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message relayed by `arbsys`. - */ - address public constant ARBSYS = 0x0000000000000000000000000000000000000064; - - function isCrossChain(address arbsys) internal view returns (bool) { - return ArbitrumL2_Bridge(arbsys).isTopLevelCall(); - } - - /** - * @dev Returns the address of the sender that triggered the current - * cross-chain message through `arbsys`. - * - * NOTE: {isCrossChain} should be checked before trying to recover the - * sender, as it will revert with `NotCrossChainCall` if the current - * function call is not the result of a cross-chain message. - */ - function crossChainSender(address arbsys) internal view returns (address) { - if (!isCrossChain(arbsys)) revert NotCrossChainCall(); - - return - ArbitrumL2_Bridge(arbsys).wasMyCallersAddressAliased() - ? ArbitrumL2_Bridge(arbsys).myCallersAddressWithoutAliasing() - : msg.sender; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/errors.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/errors.sol deleted file mode 100644 index 004460e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/errors.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/errors.sol) - -pragma solidity ^0.8.4; - -error NotCrossChainCall(); -error InvalidCrossChainSender(address actual, address expected); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol deleted file mode 100644 index 1005864..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/CrossChainEnabledOptimism.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabled.sol"; -import "./LibOptimism.sol"; - -/** - * @dev https://www.optimism.io/[Optimism] specialization or the - * {CrossChainEnabled} abstraction. - * - * The messenger (`CrossDomainMessenger`) contract is provided and maintained by - * the optimism team. You can find the address of this contract on mainnet and - * kovan in the https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/deployments[deployments section of Optimism monorepo]. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabledOptimism is CrossChainEnabled { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _messenger; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address messenger) { - _messenger = messenger; - } - - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return LibOptimism.isCrossChain(_messenger); - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return LibOptimism.crossChainSender(_messenger); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/optimism/LibOptimism.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/optimism/LibOptimism.sol deleted file mode 100644 index d963ade..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/optimism/LibOptimism.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/LibOptimism.sol) - -pragma solidity ^0.8.4; - -import {ICrossDomainMessenger as Optimism_Bridge} from "../../vendor/optimism/ICrossDomainMessenger.sol"; -import "../errors.sol"; - -/** - * @dev Primitives for cross-chain aware contracts for https://www.optimism.io/[Optimism]. - * See the https://community.optimism.io/docs/developers/bridge/messaging/#accessing-msg-sender[documentation] - * for the functionality used here. - */ -library LibOptimism { - /** - * @dev Returns whether the current function call is the result of a - * cross-chain message relayed by `messenger`. - */ - function isCrossChain(address messenger) internal view returns (bool) { - return msg.sender == messenger; - } - - /** - * @dev Returns the address of the sender that triggered the current - * cross-chain message through `messenger`. - * - * NOTE: {isCrossChain} should be checked before trying to recover the - * sender, as it will revert with `NotCrossChainCall` if the current - * function call is not the result of a cross-chain message. - */ - function crossChainSender(address messenger) internal view returns (address) { - if (!isCrossChain(messenger)) revert NotCrossChainCall(); - - return Optimism_Bridge(messenger).xDomainMessageSender(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/polygon/CrossChainEnabledPolygonChild.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/polygon/CrossChainEnabledPolygonChild.sol deleted file mode 100644 index 3918bfe..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/crosschain/polygon/CrossChainEnabledPolygonChild.sol +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/polygon/CrossChainEnabledPolygonChild.sol) - -pragma solidity ^0.8.4; - -import "../CrossChainEnabled.sol"; -import "../../security/ReentrancyGuard.sol"; -import "../../utils/Address.sol"; -import "../../vendor/polygon/IFxMessageProcessor.sol"; - -address constant DEFAULT_SENDER = 0x000000000000000000000000000000000000dEaD; - -/** - * @dev https://polygon.technology/[Polygon] specialization or the - * {CrossChainEnabled} abstraction the child side (polygon/mumbai). - * - * This version should only be deployed on child chain to process cross-chain - * messages originating from the parent chain. - * - * The fxChild contract is provided and maintained by the polygon team. You can - * find the address of this contract polygon and mumbai in - * https://docs.polygon.technology/docs/develop/l1-l2-communication/fx-portal/#contract-addresses[Polygon's Fx-Portal documentation]. - * - * _Available since v4.6._ - */ -abstract contract CrossChainEnabledPolygonChild is IFxMessageProcessor, CrossChainEnabled, ReentrancyGuard { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _fxChild; - address private _sender = DEFAULT_SENDER; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address fxChild) { - _fxChild = fxChild; - } - - /** - * @dev see {CrossChainEnabled-_isCrossChain} - */ - function _isCrossChain() internal view virtual override returns (bool) { - return msg.sender == _fxChild; - } - - /** - * @dev see {CrossChainEnabled-_crossChainSender} - */ - function _crossChainSender() internal view virtual override onlyCrossChain returns (address) { - return _sender; - } - - /** - * @dev External entry point to receive and relay messages originating - * from the fxChild. - * - * Non-reentrancy is crucial to avoid a cross-chain call being able - * to impersonate anyone by just looping through this with user-defined - * arguments. - * - * Note: if _fxChild calls any other function that does a delegate-call, - * then security could be compromised. - */ - function processMessageFromRoot( - uint256, /* stateId */ - address rootMessageSender, - bytes calldata data - ) external override nonReentrant { - if (!_isCrossChain()) revert NotCrossChainCall(); - - _sender = rootMessageSender; - Address.functionDelegateCall(address(this), data, "cross-chain execution failed"); - _sender = DEFAULT_SENDER; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/PaymentSplitter.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/PaymentSplitter.sol deleted file mode 100644 index 381cc35..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/PaymentSplitter.sol +++ /dev/null @@ -1,214 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (finance/PaymentSplitter.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/utils/SafeERC20.sol"; -import "../utils/Address.sol"; -import "../utils/Context.sol"; - -/** - * @title PaymentSplitter - * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware - * that the Ether will be split in this way, since it is handled transparently by the contract. - * - * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each - * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim - * an amount proportional to the percentage of total shares they were assigned. The distribution of shares is set at the - * time of contract deployment and can't be updated thereafter. - * - * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the - * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release} - * function. - * - * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and - * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you - * to run tests before sending real value to this contract. - */ -contract PaymentSplitter is Context { - event PayeeAdded(address account, uint256 shares); - event PaymentReleased(address to, uint256 amount); - event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount); - event PaymentReceived(address from, uint256 amount); - - uint256 private _totalShares; - uint256 private _totalReleased; - - mapping(address => uint256) private _shares; - mapping(address => uint256) private _released; - address[] private _payees; - - mapping(IERC20 => uint256) private _erc20TotalReleased; - mapping(IERC20 => mapping(address => uint256)) private _erc20Released; - - /** - * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at - * the matching position in the `shares` array. - * - * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no - * duplicates in `payees`. - */ - constructor(address[] memory payees, uint256[] memory shares_) payable { - require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch"); - require(payees.length > 0, "PaymentSplitter: no payees"); - - for (uint256 i = 0; i < payees.length; i++) { - _addPayee(payees[i], shares_[i]); - } - } - - /** - * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully - * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the - * reliability of the events, and not the actual splitting of Ether. - * - * To learn more about this see the Solidity documentation for - * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback - * functions]. - */ - receive() external payable virtual { - emit PaymentReceived(_msgSender(), msg.value); - } - - /** - * @dev Getter for the total shares held by payees. - */ - function totalShares() public view returns (uint256) { - return _totalShares; - } - - /** - * @dev Getter for the total amount of Ether already released. - */ - function totalReleased() public view returns (uint256) { - return _totalReleased; - } - - /** - * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20 - * contract. - */ - function totalReleased(IERC20 token) public view returns (uint256) { - return _erc20TotalReleased[token]; - } - - /** - * @dev Getter for the amount of shares held by an account. - */ - function shares(address account) public view returns (uint256) { - return _shares[account]; - } - - /** - * @dev Getter for the amount of Ether already released to a payee. - */ - function released(address account) public view returns (uint256) { - return _released[account]; - } - - /** - * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an - * IERC20 contract. - */ - function released(IERC20 token, address account) public view returns (uint256) { - return _erc20Released[token][account]; - } - - /** - * @dev Getter for the address of the payee number `index`. - */ - function payee(uint256 index) public view returns (address) { - return _payees[index]; - } - - /** - * @dev Getter for the amount of payee's releasable Ether. - */ - function releasable(address account) public view returns (uint256) { - uint256 totalReceived = address(this).balance + totalReleased(); - return _pendingPayment(account, totalReceived, released(account)); - } - - /** - * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an - * IERC20 contract. - */ - function releasable(IERC20 token, address account) public view returns (uint256) { - uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token); - return _pendingPayment(account, totalReceived, released(token, account)); - } - - /** - * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the - * total shares and their previous withdrawals. - */ - function release(address payable account) public virtual { - require(_shares[account] > 0, "PaymentSplitter: account has no shares"); - - uint256 payment = releasable(account); - - require(payment != 0, "PaymentSplitter: account is not due payment"); - - // _totalReleased is the sum of all values in _released. - // If "_totalReleased += payment" does not overflow, then "_released[account] += payment" cannot overflow. - _totalReleased += payment; - unchecked { - _released[account] += payment; - } - - Address.sendValue(account, payment); - emit PaymentReleased(account, payment); - } - - /** - * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their - * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20 - * contract. - */ - function release(IERC20 token, address account) public virtual { - require(_shares[account] > 0, "PaymentSplitter: account has no shares"); - - uint256 payment = releasable(token, account); - - require(payment != 0, "PaymentSplitter: account is not due payment"); - - // _erc20TotalReleased[token] is the sum of all values in _erc20Released[token]. - // If "_erc20TotalReleased[token] += payment" does not overflow, then "_erc20Released[token][account] += payment" - // cannot overflow. - _erc20TotalReleased[token] += payment; - unchecked { - _erc20Released[token][account] += payment; - } - - SafeERC20.safeTransfer(token, account, payment); - emit ERC20PaymentReleased(token, account, payment); - } - - /** - * @dev internal logic for computing the pending payment of an `account` given the token historical balances and - * already released amounts. - */ - function _pendingPayment( - address account, - uint256 totalReceived, - uint256 alreadyReleased - ) private view returns (uint256) { - return (totalReceived * _shares[account]) / _totalShares - alreadyReleased; - } - - /** - * @dev Add a new payee to the contract. - * @param account The address of the payee to add. - * @param shares_ The number of shares owned by the payee. - */ - function _addPayee(address account, uint256 shares_) private { - require(account != address(0), "PaymentSplitter: account is the zero address"); - require(shares_ > 0, "PaymentSplitter: shares are 0"); - require(_shares[account] == 0, "PaymentSplitter: account already has shares"); - - _payees.push(account); - _shares[account] = shares_; - _totalShares = _totalShares + shares_; - emit PayeeAdded(account, shares_); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/README.adoc deleted file mode 100644 index b64af31..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/README.adoc +++ /dev/null @@ -1,20 +0,0 @@ -= Finance - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/finance - -This directory includes primitives for financial systems: - -- {PaymentSplitter} allows to split Ether and ERC20 payments among a group of accounts. The sender does not need to be - aware that the assets will be split in this way, since it is handled transparently by the contract. The split can be - in equal parts or in any other arbitrary proportion. - -- {VestingWallet} handles the vesting of Ether and ERC20 tokens for a given beneficiary. Custody of multiple tokens can - be given to this contract, which will release the token to the beneficiary following a given, customizable, vesting - schedule. - -== Contracts - -{{PaymentSplitter}} - -{{VestingWallet}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol deleted file mode 100644 index ebb5ee5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/finance/VestingWallet.sol +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (finance/VestingWallet.sol) -pragma solidity ^0.8.0; - -import "../token/ERC20/utils/SafeERC20.sol"; -import "../utils/Address.sol"; -import "../utils/Context.sol"; -import "../utils/math/Math.sol"; - -/** - * @title VestingWallet - * @dev This contract handles the vesting of Eth and ERC20 tokens for a given beneficiary. Custody of multiple tokens - * can be given to this contract, which will release the token to the beneficiary following a given vesting schedule. - * The vesting schedule is customizable through the {vestedAmount} function. - * - * Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning. - * Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly) - * be immediately releasable. - */ -contract VestingWallet is Context { - event EtherReleased(uint256 amount); - event ERC20Released(address indexed token, uint256 amount); - - uint256 private _released; - mapping(address => uint256) private _erc20Released; - address private immutable _beneficiary; - uint64 private immutable _start; - uint64 private immutable _duration; - - /** - * @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet. - */ - constructor( - address beneficiaryAddress, - uint64 startTimestamp, - uint64 durationSeconds - ) { - require(beneficiaryAddress != address(0), "VestingWallet: beneficiary is zero address"); - _beneficiary = beneficiaryAddress; - _start = startTimestamp; - _duration = durationSeconds; - } - - /** - * @dev The contract should be able to receive Eth. - */ - receive() external payable virtual {} - - /** - * @dev Getter for the beneficiary address. - */ - function beneficiary() public view virtual returns (address) { - return _beneficiary; - } - - /** - * @dev Getter for the start timestamp. - */ - function start() public view virtual returns (uint256) { - return _start; - } - - /** - * @dev Getter for the vesting duration. - */ - function duration() public view virtual returns (uint256) { - return _duration; - } - - /** - * @dev Amount of eth already released - */ - function released() public view virtual returns (uint256) { - return _released; - } - - /** - * @dev Amount of token already released - */ - function released(address token) public view virtual returns (uint256) { - return _erc20Released[token]; - } - - /** - * @dev Release the native token (ether) that have already vested. - * - * Emits a {EtherReleased} event. - */ - function release() public virtual { - uint256 releasable = vestedAmount(uint64(block.timestamp)) - released(); - _released += releasable; - emit EtherReleased(releasable); - Address.sendValue(payable(beneficiary()), releasable); - } - - /** - * @dev Release the tokens that have already vested. - * - * Emits a {ERC20Released} event. - */ - function release(address token) public virtual { - uint256 releasable = vestedAmount(token, uint64(block.timestamp)) - released(token); - _erc20Released[token] += releasable; - emit ERC20Released(token, releasable); - SafeERC20.safeTransfer(IERC20(token), beneficiary(), releasable); - } - - /** - * @dev Calculates the amount of ether that has already vested. Default implementation is a linear vesting curve. - */ - function vestedAmount(uint64 timestamp) public view virtual returns (uint256) { - return _vestingSchedule(address(this).balance + released(), timestamp); - } - - /** - * @dev Calculates the amount of tokens that has already vested. Default implementation is a linear vesting curve. - */ - function vestedAmount(address token, uint64 timestamp) public view virtual returns (uint256) { - return _vestingSchedule(IERC20(token).balanceOf(address(this)) + released(token), timestamp); - } - - /** - * @dev Virtual implementation of the vesting formula. This returns the amount vested, as a function of time, for - * an asset given its total historical allocation. - */ - function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256) { - if (timestamp < start()) { - return 0; - } else if (timestamp > start() + duration()) { - return totalAllocation; - } else { - return (totalAllocation * (timestamp - start())) / duration(); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/Governor.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/Governor.sol deleted file mode 100644 index 6855163..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/Governor.sol +++ /dev/null @@ -1,596 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (governance/Governor.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/IERC721Receiver.sol"; -import "../token/ERC1155/IERC1155Receiver.sol"; -import "../utils/cryptography/ECDSA.sol"; -import "../utils/cryptography/draft-EIP712.sol"; -import "../utils/introspection/ERC165.sol"; -import "../utils/math/SafeCast.sol"; -import "../utils/structs/DoubleEndedQueue.sol"; -import "../utils/Address.sol"; -import "../utils/Context.sol"; -import "../utils/Timers.sol"; -import "./IGovernor.sol"; - -/** - * @dev Core of the governance system, designed to be extended though various modules. - * - * This contract is abstract and requires several function to be implemented in various modules: - * - * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} - * - A voting module must implement {_getVotes} - * - Additionanly, the {votingPeriod} must also be implemented - * - * _Available since v4.3._ - */ -abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver { - using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; - using SafeCast for uint256; - using Timers for Timers.BlockNumber; - - bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); - bytes32 public constant EXTENDED_BALLOT_TYPEHASH = - keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); - - struct ProposalCore { - Timers.BlockNumber voteStart; - Timers.BlockNumber voteEnd; - bool executed; - bool canceled; - } - - string private _name; - - mapping(uint256 => ProposalCore) private _proposals; - - // This queue keeps track of the governor operating on itself. Calls to functions protected by the - // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, - // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the - // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. - DoubleEndedQueue.Bytes32Deque private _governanceCall; - - /** - * @dev Restricts a function so it can only be executed through governance proposals. For example, governance - * parameter setters in {GovernorSettings} are protected using this modifier. - * - * The governance executing address may be different from the Governor's own address, for example it could be a - * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these - * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, - * for example, additional timelock proposers are not able to change governance parameters without going through the - * governance protocol (since v4.6). - */ - modifier onlyGovernance() { - require(_msgSender() == _executor(), "Governor: onlyGovernance"); - if (_executor() != address(this)) { - bytes32 msgDataHash = keccak256(_msgData()); - // loop until popping the expected operation - throw if deque is empty (operation not authorized) - while (_governanceCall.popFront() != msgDataHash) {} - } - _; - } - - /** - * @dev Sets the value for {name} and {version} - */ - constructor(string memory name_) EIP712(name_, version()) { - _name = name_; - } - - /** - * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) - */ - receive() external payable virtual { - require(_executor() == address(this)); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { - // In addition to the current interfaceId, also support previous version of the interfaceId that did not - // include the castVoteWithReasonAndParams() function as standard - return - interfaceId == - (type(IGovernor).interfaceId ^ - this.castVoteWithReasonAndParams.selector ^ - this.castVoteWithReasonAndParamsBySig.selector ^ - this.getVotesWithParams.selector) || - interfaceId == type(IGovernor).interfaceId || - interfaceId == type(IERC1155Receiver).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @dev See {IGovernor-name}. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev See {IGovernor-version}. - */ - function version() public view virtual override returns (string memory) { - return "1"; - } - - /** - * @dev See {IGovernor-hashProposal}. - * - * The proposal id is produced by hashing the RLC encoded `targets` array, the `values` array, the `calldatas` array - * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id - * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in - * advance, before the proposal is submitted. - * - * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the - * same proposal (with same operation and same description) will have the same id if submitted on multiple governors - * across multiple networks. This also means that in order to execute the same operation twice (on the same - * governor) the proposer will have to change the description in order to avoid proposal id conflicts. - */ - function hashProposal( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public pure virtual override returns (uint256) { - return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); - } - - /** - * @dev See {IGovernor-state}. - */ - function state(uint256 proposalId) public view virtual override returns (ProposalState) { - ProposalCore storage proposal = _proposals[proposalId]; - - if (proposal.executed) { - return ProposalState.Executed; - } - - if (proposal.canceled) { - return ProposalState.Canceled; - } - - uint256 snapshot = proposalSnapshot(proposalId); - - if (snapshot == 0) { - revert("Governor: unknown proposal id"); - } - - if (snapshot >= block.number) { - return ProposalState.Pending; - } - - uint256 deadline = proposalDeadline(proposalId); - - if (deadline >= block.number) { - return ProposalState.Active; - } - - if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { - return ProposalState.Succeeded; - } else { - return ProposalState.Defeated; - } - } - - /** - * @dev See {IGovernor-proposalSnapshot}. - */ - function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { - return _proposals[proposalId].voteStart.getDeadline(); - } - - /** - * @dev See {IGovernor-proposalDeadline}. - */ - function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { - return _proposals[proposalId].voteEnd.getDeadline(); - } - - /** - * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. - */ - function proposalThreshold() public view virtual returns (uint256) { - return 0; - } - - /** - * @dev Amount of votes already cast passes the threshold limit. - */ - function _quorumReached(uint256 proposalId) internal view virtual returns (bool); - - /** - * @dev Is the proposal successful or not. - */ - function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); - - /** - * @dev Get the voting weight of `account` at a specific `blockNumber`, for a vote as described by `params`. - */ - function _getVotes( - address account, - uint256 blockNumber, - bytes memory params - ) internal view virtual returns (uint256); - - /** - * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. - * - * Note: Support is generic and can represent various things depending on the voting system used. - */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory params - ) internal virtual; - - /** - * @dev Default additional encoded parameters used by castVote methods that don't include them - * - * Note: Should be overridden by specific implementations to use an appropriate value, the - * meaning of the additional params, in the context of that implementation - */ - function _defaultParams() internal view virtual returns (bytes memory) { - return ""; - } - - /** - * @dev See {IGovernor-propose}. - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override returns (uint256) { - require( - getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), - "Governor: proposer votes below proposal threshold" - ); - - uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - require(targets.length == values.length, "Governor: invalid proposal length"); - require(targets.length == calldatas.length, "Governor: invalid proposal length"); - require(targets.length > 0, "Governor: empty proposal"); - - ProposalCore storage proposal = _proposals[proposalId]; - require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); - - uint64 snapshot = block.number.toUint64() + votingDelay().toUint64(); - uint64 deadline = snapshot + votingPeriod().toUint64(); - - proposal.voteStart.setDeadline(snapshot); - proposal.voteEnd.setDeadline(deadline); - - emit ProposalCreated( - proposalId, - _msgSender(), - targets, - values, - new string[](targets.length), - calldatas, - snapshot, - deadline, - description - ); - - return proposalId; - } - - /** - * @dev See {IGovernor-execute}. - */ - function execute( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public payable virtual override returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - ProposalState status = state(proposalId); - require( - status == ProposalState.Succeeded || status == ProposalState.Queued, - "Governor: proposal not successful" - ); - _proposals[proposalId].executed = true; - - emit ProposalExecuted(proposalId); - - _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); - _execute(proposalId, targets, values, calldatas, descriptionHash); - _afterExecute(proposalId, targets, values, calldatas, descriptionHash); - - return proposalId; - } - - /** - * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism - */ - function _execute( - uint256, /* proposalId */ - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual { - string memory errorMessage = "Governor: call reverted without message"; - for (uint256 i = 0; i < targets.length; ++i) { - (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); - Address.verifyCallResult(success, returndata, errorMessage); - } - } - - /** - * @dev Hook before execution is triggered. - */ - function _beforeExecute( - uint256, /* proposalId */ - address[] memory targets, - uint256[] memory, /* values */ - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual { - if (_executor() != address(this)) { - for (uint256 i = 0; i < targets.length; ++i) { - if (targets[i] == address(this)) { - _governanceCall.pushBack(keccak256(calldatas[i])); - } - } - } - } - - /** - * @dev Hook after execution is triggered. - */ - function _afterExecute( - uint256, /* proposalId */ - address[] memory, /* targets */ - uint256[] memory, /* values */ - bytes[] memory, /* calldatas */ - bytes32 /*descriptionHash*/ - ) internal virtual { - if (_executor() != address(this)) { - if (!_governanceCall.empty()) { - _governanceCall.clear(); - } - } - } - - /** - * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as - * canceled to allow distinguishing it from executed proposals. - * - * Emits a {IGovernor-ProposalCanceled} event. - */ - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - ProposalState status = state(proposalId); - - require( - status != ProposalState.Canceled && status != ProposalState.Expired && status != ProposalState.Executed, - "Governor: proposal not active" - ); - _proposals[proposalId].canceled = true; - - emit ProposalCanceled(proposalId); - - return proposalId; - } - - /** - * @dev See {IGovernor-getVotes}. - */ - function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { - return _getVotes(account, blockNumber, _defaultParams()); - } - - /** - * @dev See {IGovernor-getVotesWithParams}. - */ - function getVotesWithParams( - address account, - uint256 blockNumber, - bytes memory params - ) public view virtual override returns (uint256) { - return _getVotes(account, blockNumber, params); - } - - /** - * @dev See {IGovernor-castVote}. - */ - function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, ""); - } - - /** - * @dev See {IGovernor-castVoteWithReason}. - */ - function castVoteWithReason( - uint256 proposalId, - uint8 support, - string calldata reason - ) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, reason); - } - - /** - * @dev See {IGovernor-castVoteWithReasonAndParams}. - */ - function castVoteWithReasonAndParams( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params - ) public virtual override returns (uint256) { - address voter = _msgSender(); - return _castVote(proposalId, voter, support, reason, params); - } - - /** - * @dev See {IGovernor-castVoteBySig}. - */ - function castVoteBySig( - uint256 proposalId, - uint8 support, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override returns (uint256) { - address voter = ECDSA.recover( - _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), - v, - r, - s - ); - return _castVote(proposalId, voter, support, ""); - } - - /** - * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. - */ - function castVoteWithReasonAndParamsBySig( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override returns (uint256) { - address voter = ECDSA.recover( - _hashTypedDataV4( - keccak256( - abi.encode( - EXTENDED_BALLOT_TYPEHASH, - proposalId, - support, - keccak256(bytes(reason)), - keccak256(params) - ) - ) - ), - v, - r, - s - ); - - return _castVote(proposalId, voter, support, reason, params); - } - - /** - * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve - * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). - * - * Emits a {IGovernor-VoteCast} event. - */ - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason - ) internal virtual returns (uint256) { - return _castVote(proposalId, account, support, reason, _defaultParams()); - } - - /** - * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve - * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. - * - * Emits a {IGovernor-VoteCast} event. - */ - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal virtual returns (uint256) { - ProposalCore storage proposal = _proposals[proposalId]; - require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); - - uint256 weight = _getVotes(account, proposal.voteStart.getDeadline(), params); - _countVote(proposalId, account, support, weight, params); - - if (params.length == 0) { - emit VoteCast(account, proposalId, support, weight, reason); - } else { - emit VoteCastWithParams(account, proposalId, support, weight, reason, params); - } - - return weight; - } - - /** - * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor - * is some contract other than the governor itself, like when using a timelock, this function can be invoked - * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. - * Note that if the executor is simply the governor itself, use of `relay` is redundant. - */ - function relay( - address target, - uint256 value, - bytes calldata data - ) external virtual onlyGovernance { - Address.functionCallWithValue(target, data, value); - } - - /** - * @dev Address through which the governor executes action. Will be overloaded by module that execute actions - * through another contract such as a timelock. - */ - function _executor() internal view virtual returns (address) { - return address(this); - } - - /** - * @dev See {IERC721Receiver-onERC721Received}. - */ - function onERC721Received( - address, - address, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC721Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155Received}. - */ - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155BatchReceived}. - */ - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol deleted file mode 100644 index 8b21d29..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/IGovernor.sol +++ /dev/null @@ -1,276 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (governance/IGovernor.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165.sol"; - -/** - * @dev Interface of the {Governor} core. - * - * _Available since v4.3._ - */ -abstract contract IGovernor is IERC165 { - enum ProposalState { - Pending, - Active, - Canceled, - Defeated, - Succeeded, - Queued, - Expired, - Executed - } - - /** - * @dev Emitted when a proposal is created. - */ - event ProposalCreated( - uint256 proposalId, - address proposer, - address[] targets, - uint256[] values, - string[] signatures, - bytes[] calldatas, - uint256 startBlock, - uint256 endBlock, - string description - ); - - /** - * @dev Emitted when a proposal is canceled. - */ - event ProposalCanceled(uint256 proposalId); - - /** - * @dev Emitted when a proposal is executed. - */ - event ProposalExecuted(uint256 proposalId); - - /** - * @dev Emitted when a vote is cast without params. - * - * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. - */ - event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); - - /** - * @dev Emitted when a vote is cast with params. - * - * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. - * `params` are additional encoded parameters. Their intepepretation also depends on the voting module used. - */ - event VoteCastWithParams( - address indexed voter, - uint256 proposalId, - uint8 support, - uint256 weight, - string reason, - bytes params - ); - - /** - * @notice module:core - * @dev Name of the governor instance (used in building the ERC712 domain separator). - */ - function name() public view virtual returns (string memory); - - /** - * @notice module:core - * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1" - */ - function version() public view virtual returns (string memory); - - /** - * @notice module:voting - * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to - * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of - * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`. - * - * There are 2 standard keys: `support` and `quorum`. - * - * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`. - * - `quorum=bravo` means that only For votes are counted towards quorum. - * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum. - * - * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique - * name that describes the behavior. For example: - * - * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain. - * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote. - * - * NOTE: The string can be decoded by the standard - * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`] - * JavaScript class. - */ - // solhint-disable-next-line func-name-mixedcase - function COUNTING_MODE() public pure virtual returns (string memory); - - /** - * @notice module:core - * @dev Hashing function used to (re)build the proposal id from the proposal details.. - */ - function hashProposal( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public pure virtual returns (uint256); - - /** - * @notice module:core - * @dev Current state of a proposal, following Compound's convention - */ - function state(uint256 proposalId) public view virtual returns (ProposalState); - - /** - * @notice module:core - * @dev Block number used to retrieve user's votes and quorum. As per Compound's Comp and OpenZeppelin's - * ERC20Votes, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the - * beginning of the following block. - */ - function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256); - - /** - * @notice module:core - * @dev Block number at which votes close. Votes close at the end of this block, so it is possible to cast a vote - * during this block. - */ - function proposalDeadline(uint256 proposalId) public view virtual returns (uint256); - - /** - * @notice module:user-config - * @dev Delay, in number of block, between the proposal is created and the vote starts. This can be increassed to - * leave time for users to buy voting power, of delegate it, before the voting of a proposal starts. - */ - function votingDelay() public view virtual returns (uint256); - - /** - * @notice module:user-config - * @dev Delay, in number of blocks, between the vote start and vote ends. - * - * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting - * duration compared to the voting delay. - */ - function votingPeriod() public view virtual returns (uint256); - - /** - * @notice module:user-config - * @dev Minimum number of cast voted required for a proposal to be successful. - * - * Note: The `blockNumber` parameter corresponds to the snapshot used for counting vote. This allows to scale the - * quorum depending on values such as the totalSupply of a token at this block (see {ERC20Votes}). - */ - function quorum(uint256 blockNumber) public view virtual returns (uint256); - - /** - * @notice module:reputation - * @dev Voting power of an `account` at a specific `blockNumber`. - * - * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or - * multiple), {ERC20Votes} tokens. - */ - function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256); - - /** - * @notice module:reputation - * @dev Voting power of an `account` at a specific `blockNumber` given additional encoded parameters. - */ - function getVotesWithParams( - address account, - uint256 blockNumber, - bytes memory params - ) public view virtual returns (uint256); - - /** - * @notice module:voting - * @dev Returns weither `account` has cast a vote on `proposalId`. - */ - function hasVoted(uint256 proposalId, address account) public view virtual returns (bool); - - /** - * @dev Create a new proposal. Vote start {IGovernor-votingDelay} blocks after the proposal is created and ends - * {IGovernor-votingPeriod} blocks after the voting starts. - * - * Emits a {ProposalCreated} event. - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual returns (uint256 proposalId); - - /** - * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the - * deadline to be reached. - * - * Emits a {ProposalExecuted} event. - * - * Note: some module can modify the requirements for execution, for example by adding an additional timelock. - */ - function execute( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public payable virtual returns (uint256 proposalId); - - /** - * @dev Cast a vote - * - * Emits a {VoteCast} event. - */ - function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance); - - /** - * @dev Cast a vote with a reason - * - * Emits a {VoteCast} event. - */ - function castVoteWithReason( - uint256 proposalId, - uint8 support, - string calldata reason - ) public virtual returns (uint256 balance); - - /** - * @dev Cast a vote with a reason and additional encoded parameters - * - * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. - */ - function castVoteWithReasonAndParams( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params - ) public virtual returns (uint256 balance); - - /** - * @dev Cast a vote using the user's cryptographic signature. - * - * Emits a {VoteCast} event. - */ - function castVoteBySig( - uint256 proposalId, - uint8 support, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual returns (uint256 balance); - - /** - * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature. - * - * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. - */ - function castVoteWithReasonAndParamsBySig( - uint256 proposalId, - uint8 support, - string calldata reason, - bytes memory params, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual returns (uint256 balance); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/README.adoc deleted file mode 100644 index 9e393e9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/README.adoc +++ /dev/null @@ -1,176 +0,0 @@ -= Governance - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/governance - -This directory includes primitives for on-chain governance. - -== Governor - -This modular system of Governor contracts allows the deployment on-chain voting protocols similar to https://compound.finance/docs/governance[Compound's Governor Alpha & Bravo] and beyond, through the ability to easily customize multiple aspects of the protocol. - -[TIP] -==== -For a guided experience, set up your Governor contract using https://wizard.openzeppelin.com/#governor[Contracts Wizard]. - -For a written walkthrough, check out our guide on xref:ROOT:governance.adoc[How to set up on-chain governance]. -==== - -* {Governor}: The core contract that contains all the logic and primitives. It is abstract and requires choosing one of each of the modules below, or custom ones. - -Votes modules determine the source of voting power, and sometimes quorum number. - -* {GovernorVotes}: Extracts voting weight from an {ERC20Votes} token. - -* {GovernorVotesComp}: Extracts voting weight from a COMP-like or {ERC20VotesComp} token. - -* {GovernorVotesQuorumFraction}: Combines with `GovernorVotes` to set the quorum as a fraction of the total token supply. - -Counting modules determine valid voting options. - -* {GovernorCountingSimple}: Simple voting mechanism with 3 voting options: Against, For and Abstain. - -Timelock extensions add a delay for governance decisions to be executed. The workflow is extended to require a `queue` step before execution. With these modules, proposals are executed by the external timelock contract, thus it is the timelock that has to hold the assets that are being governed. - -* {GovernorTimelockControl}: Connects with an instance of {TimelockController}. Allows multiple proposers and executors, in addition to the Governor itself. - -* {GovernorTimelockCompound}: Connects with an instance of Compound's https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[`Timelock`] contract. - -Other extensions can customize the behavior or interface in multiple ways. - -* {GovernorCompatibilityBravo}: Extends the interface to be fully `GovernorBravo`-compatible. Note that events are compatible regardless of whether this extension is included or not. - -* {GovernorSettings}: Manages some of the settings (voting delay, voting period duration, and proposal threshold) in a way that can be updated through a governance proposal, without requiring an upgrade. - -* {GovernorPreventLateQuorum}: Ensures there is a minimum voting period after quorum is reached as a security protection against large voters. - -In addition to modules and extensions, the core contract requires a few virtual functions to be implemented to your particular specifications: - -* <>: Delay (in number of blocks) since the proposal is submitted until voting power is fixed and voting starts. This can be used to enforce a delay after a proposal is published for users to buy tokens, or delegate their votes. -* <>: Delay (in number of blocks) since the proposal starts until voting ends. -* <>: Quorum required for a proposal to be successful. This function includes a `blockNumber` argument so the quorum can adapt through time, for example, to follow a token's `totalSupply`. - -NOTE: Functions of the `Governor` contract do not include access control. If you want to restrict access, you should add these checks by overloading the particular functions. Among these, {Governor-_cancel} is internal by default, and you will have to expose it (with the right access control mechanism) yourself if this function is needed. - -=== Core - -{{IGovernor}} - -{{Governor}} - -=== Modules - -{{GovernorCountingSimple}} - -{{GovernorVotes}} - -{{GovernorVotesQuorumFraction}} - -{{GovernorVotesComp}} - -=== Extensions - -{{GovernorTimelockControl}} - -{{GovernorTimelockCompound}} - -{{GovernorSettings}} - -{{GovernorPreventLateQuorum}} - -{{GovernorCompatibilityBravo}} - -=== Deprecated - -{{GovernorProposalThreshold}} - -== Utils - -{{Votes}} - -== Timelock - -In a governance system, the {TimelockController} contract is in charge of introducing a delay between a proposal and its execution. It can be used with or without a {Governor}. - -{{TimelockController}} - -[[timelock-terminology]] -==== Terminology - -* *Operation:* A transaction (or a set of transactions) that is the subject of the timelock. It has to be scheduled by a proposer and executed by an executor. The timelock enforces a minimum delay between the proposition and the execution (see xref:access-control.adoc#operation_lifecycle[operation lifecycle]). If the operation contains multiple transactions (batch mode), they are executed atomically. Operations are identified by the hash of their content. -* *Operation status:* -** *Unset:* An operation that is not part of the timelock mechanism. -** *Pending:* An operation that has been scheduled, before the timer expires. -** *Ready:* An operation that has been scheduled, after the timer expires. -** *Done:* An operation that has been executed. -* *Predecessor*: An (optional) dependency between operations. An operation can depend on another operation (its predecessor), forcing the execution order of these two operations. -* *Role*: -** *Admin:* An address (smart contract or EOA) that is in charge of granting the roles of Proposer and Executor. -** *Proposer:* An address (smart contract or EOA) that is in charge of scheduling (and cancelling) operations. -** *Executor:* An address (smart contract or EOA) that is in charge of executing operations once the timelock has expired. This role can be given to the zero address to allow anyone to execute operations. - -[[timelock-operation]] -==== Operation structure - -Operation executed by the xref:api:governance.adoc#TimelockController[`TimelockController`] can contain one or multiple subsequent calls. Depending on whether you need to multiple calls to be executed atomically, you can either use simple or batched operations. - -Both operations contain: - -* *Target*, the address of the smart contract that the timelock should operate on. -* *Value*, in wei, that should be sent with the transaction. Most of the time this will be 0. Ether can be deposited before-end or passed along when executing the transaction. -* *Data*, containing the encoded function selector and parameters of the call. This can be produced using a number of tools. For example, a maintenance operation granting role `ROLE` to `ACCOUNT` can be encode using web3js as follows: - -```javascript -const data = timelock.contract.methods.grantRole(ROLE, ACCOUNT).encodeABI() -``` - -* *Predecessor*, that specifies a dependency between operations. This dependency is optional. Use `bytes32(0)` if the operation does not have any dependency. -* *Salt*, used to disambiguate two otherwise identical operations. This can be any random value. - -In the case of batched operations, `target`, `value` and `data` are specified as arrays, which must be of the same length. - -[[timelock-operation-lifecycle]] -==== Operation lifecycle - -Timelocked operations are identified by a unique id (their hash) and follow a specific lifecycle: - -`Unset` -> `Pending` -> `Pending` + `Ready` -> `Done` - -* By calling xref:api:governance.adoc#TimelockController-schedule-address-uint256-bytes-bytes32-bytes32-uint256-[`schedule`] (or xref:api:governance.adoc#TimelockController-scheduleBatch-address---uint256---bytes---bytes32-bytes32-uint256-[`scheduleBatch`]), a proposer moves the operation from the `Unset` to the `Pending` state. This starts a timer that must be longer than the minimum delay. The timer expires at a timestamp accessible through the xref:api:governance.adoc#TimelockController-getTimestamp-bytes32-[`getTimestamp`] method. -* Once the timer expires, the operation automatically gets the `Ready` state. At this point, it can be executed. -* By calling xref:api:governance.adoc#TimelockController-TimelockController-execute-address-uint256-bytes-bytes32-bytes32-[`execute`] (or xref:api:governance.adoc#TimelockController-executeBatch-address---uint256---bytes---bytes32-bytes32-[`executeBatch`]), an executor triggers the operation's underlying transactions and moves it to the `Done` state. If the operation has a predecessor, it has to be in the `Done` state for this transition to succeed. -* xref:api:governance.adoc#TimelockController-TimelockController-cancel-bytes32-[`cancel`] allows proposers to cancel any `Pending` operation. This resets the operation to the `Unset` state. It is thus possible for a proposer to re-schedule an operation that has been cancelled. In this case, the timer restarts when the operation is re-scheduled. - -Operations status can be queried using the functions: - -* xref:api:governance.adoc#TimelockController-isOperationPending-bytes32-[`isOperationPending(bytes32)`] -* xref:api:governance.adoc#TimelockController-isOperationReady-bytes32-[`isOperationReady(bytes32)`] -* xref:api:governance.adoc#TimelockController-isOperationDone-bytes32-[`isOperationDone(bytes32)`] - -[[timelock-roles]] -==== Roles - -[[timelock-admin]] -===== Admin - -The admins are in charge of managing proposers and executors. For the timelock to be self-governed, this role should only be given to the timelock itself. Upon deployment, both the timelock and the deployer have this role. After further configuration and testing, the deployer can renounce this role such that all further maintenance operations have to go through the timelock process. - -This role is identified by the *TIMELOCK_ADMIN_ROLE* value: `0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5` - -[[timelock-proposer]] -===== Proposer - -The proposers are in charge of scheduling (and cancelling) operations. This is a critical role, that should be given to governing entities. This could be an EOA, a multisig, or a DAO. - -WARNING: *Proposer fight:* Having multiple proposers, while providing redundancy in case one becomes unavailable, can be dangerous. As proposer have their say on all operations, they could cancel operations they disagree with, including operations to remove them for the proposers. - -This role is identified by the *PROPOSER_ROLE* value: `0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1` - -[[timelock-executor]] -===== Executor - -The executors are in charge of executing the operations scheduled by the proposers once the timelock expires. Logic dictates that multisig or DAO that are proposers should also be executors in order to guarantee operations that have been scheduled will eventually be executed. However, having additional executors can reduce the cost (the executing transaction does not require validation by the multisig or DAO that proposed it), while ensuring whoever is in charge of execution cannot trigger actions that have not been scheduled by the proposers. Alternatively, it is possible to allow _any_ address to execute a proposal once the timelock has expired by granting the executor role to the zero address. - -This role is identified by the *EXECUTOR_ROLE* value: `0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63` - -WARNING: A live contract without at least one proposer and one executor is locked. Make sure these roles are filled by reliable entities before the deployer renounces its administrative rights in favour of the timelock contract itself. See the {AccessControl} documentation to learn more about role management. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/TimelockController.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/TimelockController.sol deleted file mode 100644 index 91fcbfc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/TimelockController.sol +++ /dev/null @@ -1,417 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (governance/TimelockController.sol) - -pragma solidity ^0.8.0; - -import "../access/AccessControl.sol"; -import "../token/ERC721/IERC721Receiver.sol"; -import "../token/ERC1155/IERC1155Receiver.sol"; -import "../utils/Address.sol"; - -/** - * @dev Contract module which acts as a timelocked controller. When set as the - * owner of an `Ownable` smart contract, it enforces a timelock on all - * `onlyOwner` maintenance operations. This gives time for users of the - * controlled contract to exit before a potentially dangerous maintenance - * operation is applied. - * - * By default, this contract is self administered, meaning administration tasks - * have to go through the timelock process. The proposer (resp executor) role - * is in charge of proposing (resp executing) operations. A common use case is - * to position this {TimelockController} as the owner of a smart contract, with - * a multisig or a DAO as the sole proposer. - * - * _Available since v3.3._ - */ -contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver { - bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE"); - bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); - bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); - bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE"); - uint256 internal constant _DONE_TIMESTAMP = uint256(1); - - mapping(bytes32 => uint256) private _timestamps; - uint256 private _minDelay; - - /** - * @dev Emitted when a call is scheduled as part of operation `id`. - */ - event CallScheduled( - bytes32 indexed id, - uint256 indexed index, - address target, - uint256 value, - bytes data, - bytes32 predecessor, - uint256 delay - ); - - /** - * @dev Emitted when a call is performed as part of operation `id`. - */ - event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data); - - /** - * @dev Emitted when operation `id` is cancelled. - */ - event Cancelled(bytes32 indexed id); - - /** - * @dev Emitted when the minimum delay for future operations is modified. - */ - event MinDelayChange(uint256 oldDuration, uint256 newDuration); - - /** - * @dev Initializes the contract with a given `minDelay`, and a list of - * initial proposers and executors. The proposers receive both the - * proposer and the canceller role (for backward compatibility). The - * executors receive the executor role. - * - * NOTE: At construction, both the deployer and the timelock itself are - * administrators. This helps further configuration of the timelock by the - * deployer. After configuration is done, it is recommended that the - * deployer renounces its admin position and relies on timelocked - * operations to perform future maintenance. - */ - constructor( - uint256 minDelay, - address[] memory proposers, - address[] memory executors - ) { - _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE); - _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE); - _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE); - _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE); - - // deployer + self administration - _setupRole(TIMELOCK_ADMIN_ROLE, _msgSender()); - _setupRole(TIMELOCK_ADMIN_ROLE, address(this)); - - // register proposers and cancellers - for (uint256 i = 0; i < proposers.length; ++i) { - _setupRole(PROPOSER_ROLE, proposers[i]); - _setupRole(CANCELLER_ROLE, proposers[i]); - } - - // register executors - for (uint256 i = 0; i < executors.length; ++i) { - _setupRole(EXECUTOR_ROLE, executors[i]); - } - - _minDelay = minDelay; - emit MinDelayChange(0, minDelay); - } - - /** - * @dev Modifier to make a function callable only by a certain role. In - * addition to checking the sender's role, `address(0)` 's role is also - * considered. Granting a role to `address(0)` is equivalent to enabling - * this role for everyone. - */ - modifier onlyRoleOrOpenRole(bytes32 role) { - if (!hasRole(role, address(0))) { - _checkRole(role, _msgSender()); - } - _; - } - - /** - * @dev Contract might receive/hold ETH as part of the maintenance process. - */ - receive() external payable {} - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, AccessControl) returns (bool) { - return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Returns whether an id correspond to a registered operation. This - * includes both Pending, Ready and Done operations. - */ - function isOperation(bytes32 id) public view virtual returns (bool registered) { - return getTimestamp(id) > 0; - } - - /** - * @dev Returns whether an operation is pending or not. - */ - function isOperationPending(bytes32 id) public view virtual returns (bool pending) { - return getTimestamp(id) > _DONE_TIMESTAMP; - } - - /** - * @dev Returns whether an operation is ready or not. - */ - function isOperationReady(bytes32 id) public view virtual returns (bool ready) { - uint256 timestamp = getTimestamp(id); - return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp; - } - - /** - * @dev Returns whether an operation is done or not. - */ - function isOperationDone(bytes32 id) public view virtual returns (bool done) { - return getTimestamp(id) == _DONE_TIMESTAMP; - } - - /** - * @dev Returns the timestamp at with an operation becomes ready (0 for - * unset operations, 1 for done operations). - */ - function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) { - return _timestamps[id]; - } - - /** - * @dev Returns the minimum delay for an operation to become valid. - * - * This value can be changed by executing an operation that calls `updateDelay`. - */ - function getMinDelay() public view virtual returns (uint256 duration) { - return _minDelay; - } - - /** - * @dev Returns the identifier of an operation containing a single - * transaction. - */ - function hashOperation( - address target, - uint256 value, - bytes calldata data, - bytes32 predecessor, - bytes32 salt - ) public pure virtual returns (bytes32 hash) { - return keccak256(abi.encode(target, value, data, predecessor, salt)); - } - - /** - * @dev Returns the identifier of an operation containing a batch of - * transactions. - */ - function hashOperationBatch( - address[] calldata targets, - uint256[] calldata values, - bytes[] calldata payloads, - bytes32 predecessor, - bytes32 salt - ) public pure virtual returns (bytes32 hash) { - return keccak256(abi.encode(targets, values, payloads, predecessor, salt)); - } - - /** - * @dev Schedule an operation containing a single transaction. - * - * Emits a {CallScheduled} event. - * - * Requirements: - * - * - the caller must have the 'proposer' role. - */ - function schedule( - address target, - uint256 value, - bytes calldata data, - bytes32 predecessor, - bytes32 salt, - uint256 delay - ) public virtual onlyRole(PROPOSER_ROLE) { - bytes32 id = hashOperation(target, value, data, predecessor, salt); - _schedule(id, delay); - emit CallScheduled(id, 0, target, value, data, predecessor, delay); - } - - /** - * @dev Schedule an operation containing a batch of transactions. - * - * Emits one {CallScheduled} event per transaction in the batch. - * - * Requirements: - * - * - the caller must have the 'proposer' role. - */ - function scheduleBatch( - address[] calldata targets, - uint256[] calldata values, - bytes[] calldata payloads, - bytes32 predecessor, - bytes32 salt, - uint256 delay - ) public virtual onlyRole(PROPOSER_ROLE) { - require(targets.length == values.length, "TimelockController: length mismatch"); - require(targets.length == payloads.length, "TimelockController: length mismatch"); - - bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); - _schedule(id, delay); - for (uint256 i = 0; i < targets.length; ++i) { - emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay); - } - } - - /** - * @dev Schedule an operation that is to becomes valid after a given delay. - */ - function _schedule(bytes32 id, uint256 delay) private { - require(!isOperation(id), "TimelockController: operation already scheduled"); - require(delay >= getMinDelay(), "TimelockController: insufficient delay"); - _timestamps[id] = block.timestamp + delay; - } - - /** - * @dev Cancel an operation. - * - * Requirements: - * - * - the caller must have the 'canceller' role. - */ - function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) { - require(isOperationPending(id), "TimelockController: operation cannot be cancelled"); - delete _timestamps[id]; - - emit Cancelled(id); - } - - /** - * @dev Execute an (ready) operation containing a single transaction. - * - * Emits a {CallExecuted} event. - * - * Requirements: - * - * - the caller must have the 'executor' role. - */ - // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending, - // thus any modifications to the operation during reentrancy should be caught. - // slither-disable-next-line reentrancy-eth - function execute( - address target, - uint256 value, - bytes calldata payload, - bytes32 predecessor, - bytes32 salt - ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { - bytes32 id = hashOperation(target, value, payload, predecessor, salt); - - _beforeCall(id, predecessor); - _execute(target, value, payload); - emit CallExecuted(id, 0, target, value, payload); - _afterCall(id); - } - - /** - * @dev Execute an (ready) operation containing a batch of transactions. - * - * Emits one {CallExecuted} event per transaction in the batch. - * - * Requirements: - * - * - the caller must have the 'executor' role. - */ - function executeBatch( - address[] calldata targets, - uint256[] calldata values, - bytes[] calldata payloads, - bytes32 predecessor, - bytes32 salt - ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { - require(targets.length == values.length, "TimelockController: length mismatch"); - require(targets.length == payloads.length, "TimelockController: length mismatch"); - - bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); - - _beforeCall(id, predecessor); - for (uint256 i = 0; i < targets.length; ++i) { - address target = targets[i]; - uint256 value = values[i]; - bytes calldata payload = payloads[i]; - _execute(target, value, payload); - emit CallExecuted(id, i, target, value, payload); - } - _afterCall(id); - } - - /** - * @dev Execute an operation's call. - */ - function _execute( - address target, - uint256 value, - bytes calldata data - ) internal virtual { - (bool success, ) = target.call{value: value}(data); - require(success, "TimelockController: underlying transaction reverted"); - } - - /** - * @dev Checks before execution of an operation's calls. - */ - function _beforeCall(bytes32 id, bytes32 predecessor) private view { - require(isOperationReady(id), "TimelockController: operation is not ready"); - require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency"); - } - - /** - * @dev Checks after execution of an operation's calls. - */ - function _afterCall(bytes32 id) private { - require(isOperationReady(id), "TimelockController: operation is not ready"); - _timestamps[id] = _DONE_TIMESTAMP; - } - - /** - * @dev Changes the minimum timelock duration for future operations. - * - * Emits a {MinDelayChange} event. - * - * Requirements: - * - * - the caller must be the timelock itself. This can only be achieved by scheduling and later executing - * an operation where the timelock is the target and the data is the ABI-encoded call to this function. - */ - function updateDelay(uint256 newDelay) external virtual { - require(msg.sender == address(this), "TimelockController: caller must be timelock"); - emit MinDelayChange(_minDelay, newDelay); - _minDelay = newDelay; - } - - /** - * @dev See {IERC721Receiver-onERC721Received}. - */ - function onERC721Received( - address, - address, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC721Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155Received}. - */ - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; - } - - /** - * @dev See {IERC1155Receiver-onERC1155BatchReceived}. - */ - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/compatibility/GovernorCompatibilityBravo.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/compatibility/GovernorCompatibilityBravo.sol deleted file mode 100644 index f54c62c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/compatibility/GovernorCompatibilityBravo.sol +++ /dev/null @@ -1,285 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/compatibility/GovernorCompatibilityBravo.sol) - -pragma solidity ^0.8.0; - -import "../../utils/math/SafeCast.sol"; -import "../extensions/IGovernorTimelock.sol"; -import "../Governor.sol"; -import "./IGovernorCompatibilityBravo.sol"; - -/** - * @dev Compatibility layer that implements GovernorBravo compatibility on to of {Governor}. - * - * This compatibility layer includes a voting system and requires a {IGovernorTimelock} compatible module to be added - * through inheritance. It does not include token bindings, not does it include any variable upgrade patterns. - * - * NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit. - * - * _Available since v4.3._ - */ -abstract contract GovernorCompatibilityBravo is IGovernorTimelock, IGovernorCompatibilityBravo, Governor { - enum VoteType { - Against, - For, - Abstain - } - - struct ProposalDetails { - address proposer; - address[] targets; - uint256[] values; - string[] signatures; - bytes[] calldatas; - uint256 forVotes; - uint256 againstVotes; - uint256 abstainVotes; - mapping(address => Receipt) receipts; - bytes32 descriptionHash; - } - - mapping(uint256 => ProposalDetails) private _proposalDetails; - - // solhint-disable-next-line func-name-mixedcase - function COUNTING_MODE() public pure virtual override returns (string memory) { - return "support=bravo&quorum=bravo"; - } - - // ============================================== Proposal lifecycle ============================================== - /** - * @dev See {IGovernor-propose}. - */ - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override(IGovernor, Governor) returns (uint256) { - _storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description); - return super.propose(targets, values, calldatas, description); - } - - /** - * @dev See {IGovernorCompatibilityBravo-propose}. - */ - function propose( - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas, - string memory description - ) public virtual override returns (uint256) { - _storeProposal(_msgSender(), targets, values, signatures, calldatas, description); - return propose(targets, values, _encodeCalldata(signatures, calldatas), description); - } - - /** - * @dev See {IGovernorCompatibilityBravo-queue}. - */ - function queue(uint256 proposalId) public virtual override { - ProposalDetails storage details = _proposalDetails[proposalId]; - queue( - details.targets, - details.values, - _encodeCalldata(details.signatures, details.calldatas), - details.descriptionHash - ); - } - - /** - * @dev See {IGovernorCompatibilityBravo-execute}. - */ - function execute(uint256 proposalId) public payable virtual override { - ProposalDetails storage details = _proposalDetails[proposalId]; - execute( - details.targets, - details.values, - _encodeCalldata(details.signatures, details.calldatas), - details.descriptionHash - ); - } - - function cancel(uint256 proposalId) public virtual override { - ProposalDetails storage details = _proposalDetails[proposalId]; - - require( - _msgSender() == details.proposer || getVotes(details.proposer, block.number - 1) < proposalThreshold(), - "GovernorBravo: proposer above threshold" - ); - - _cancel( - details.targets, - details.values, - _encodeCalldata(details.signatures, details.calldatas), - details.descriptionHash - ); - } - - /** - * @dev Encodes calldatas with optional function signature. - */ - function _encodeCalldata(string[] memory signatures, bytes[] memory calldatas) - private - pure - returns (bytes[] memory) - { - bytes[] memory fullcalldatas = new bytes[](calldatas.length); - - for (uint256 i = 0; i < signatures.length; ++i) { - fullcalldatas[i] = bytes(signatures[i]).length == 0 - ? calldatas[i] - : abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), calldatas[i]); - } - - return fullcalldatas; - } - - /** - * @dev Store proposal metadata for later lookup - */ - function _storeProposal( - address proposer, - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas, - string memory description - ) private { - bytes32 descriptionHash = keccak256(bytes(description)); - uint256 proposalId = hashProposal(targets, values, _encodeCalldata(signatures, calldatas), descriptionHash); - - ProposalDetails storage details = _proposalDetails[proposalId]; - if (details.descriptionHash == bytes32(0)) { - details.proposer = proposer; - details.targets = targets; - details.values = values; - details.signatures = signatures; - details.calldatas = calldatas; - details.descriptionHash = descriptionHash; - } - } - - // ==================================================== Views ===================================================== - /** - * @dev See {IGovernorCompatibilityBravo-proposals}. - */ - function proposals(uint256 proposalId) - public - view - virtual - override - returns ( - uint256 id, - address proposer, - uint256 eta, - uint256 startBlock, - uint256 endBlock, - uint256 forVotes, - uint256 againstVotes, - uint256 abstainVotes, - bool canceled, - bool executed - ) - { - id = proposalId; - eta = proposalEta(proposalId); - startBlock = proposalSnapshot(proposalId); - endBlock = proposalDeadline(proposalId); - - ProposalDetails storage details = _proposalDetails[proposalId]; - proposer = details.proposer; - forVotes = details.forVotes; - againstVotes = details.againstVotes; - abstainVotes = details.abstainVotes; - - ProposalState status = state(proposalId); - canceled = status == ProposalState.Canceled; - executed = status == ProposalState.Executed; - } - - /** - * @dev See {IGovernorCompatibilityBravo-getActions}. - */ - function getActions(uint256 proposalId) - public - view - virtual - override - returns ( - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas - ) - { - ProposalDetails storage details = _proposalDetails[proposalId]; - return (details.targets, details.values, details.signatures, details.calldatas); - } - - /** - * @dev See {IGovernorCompatibilityBravo-getReceipt}. - */ - function getReceipt(uint256 proposalId, address voter) public view virtual override returns (Receipt memory) { - return _proposalDetails[proposalId].receipts[voter]; - } - - /** - * @dev See {IGovernorCompatibilityBravo-quorumVotes}. - */ - function quorumVotes() public view virtual override returns (uint256) { - return quorum(block.number - 1); - } - - // ==================================================== Voting ==================================================== - /** - * @dev See {IGovernor-hasVoted}. - */ - function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { - return _proposalDetails[proposalId].receipts[account].hasVoted; - } - - /** - * @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum. - */ - function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { - ProposalDetails storage details = _proposalDetails[proposalId]; - return quorum(proposalSnapshot(proposalId)) <= details.forVotes; - } - - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be scritly over the againstVotes. - */ - function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { - ProposalDetails storage details = _proposalDetails[proposalId]; - return details.forVotes > details.againstVotes; - } - - /** - * @dev See {Governor-_countVote}. In this module, the support follows Governor Bravo. - */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory // params - ) internal virtual override { - ProposalDetails storage details = _proposalDetails[proposalId]; - Receipt storage receipt = details.receipts[account]; - - require(!receipt.hasVoted, "GovernorCompatibilityBravo: vote already cast"); - receipt.hasVoted = true; - receipt.support = support; - receipt.votes = SafeCast.toUint96(weight); - - if (support == uint8(VoteType.Against)) { - details.againstVotes += weight; - } else if (support == uint8(VoteType.For)) { - details.forVotes += weight; - } else if (support == uint8(VoteType.Abstain)) { - details.abstainVotes += weight; - } else { - revert("GovernorCompatibilityBravo: invalid vote type"); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/compatibility/IGovernorCompatibilityBravo.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/compatibility/IGovernorCompatibilityBravo.sol deleted file mode 100644 index 83e4e1a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/compatibility/IGovernorCompatibilityBravo.sol +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (governance/compatibility/IGovernorCompatibilityBravo.sol) - -pragma solidity ^0.8.0; - -import "../IGovernor.sol"; - -/** - * @dev Interface extension that adds missing functions to the {Governor} core to provide `GovernorBravo` compatibility. - * - * _Available since v4.3._ - */ -abstract contract IGovernorCompatibilityBravo is IGovernor { - /** - * @dev Proposal structure from Compound Governor Bravo. Not actually used by the compatibility layer, as - * {{proposal}} returns a very different structure. - */ - struct Proposal { - uint256 id; - address proposer; - uint256 eta; - address[] targets; - uint256[] values; - string[] signatures; - bytes[] calldatas; - uint256 startBlock; - uint256 endBlock; - uint256 forVotes; - uint256 againstVotes; - uint256 abstainVotes; - bool canceled; - bool executed; - mapping(address => Receipt) receipts; - } - - /** - * @dev Receipt structure from Compound Governor Bravo - */ - struct Receipt { - bool hasVoted; - uint8 support; - uint96 votes; - } - - /** - * @dev Part of the Governor Bravo's interface. - */ - function quorumVotes() public view virtual returns (uint256); - - /** - * @dev Part of the Governor Bravo's interface: _"The official record of all proposals ever proposed"_. - */ - function proposals(uint256) - public - view - virtual - returns ( - uint256 id, - address proposer, - uint256 eta, - uint256 startBlock, - uint256 endBlock, - uint256 forVotes, - uint256 againstVotes, - uint256 abstainVotes, - bool canceled, - bool executed - ); - - /** - * @dev Part of the Governor Bravo's interface: _"Function used to propose a new proposal"_. - */ - function propose( - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas, - string memory description - ) public virtual returns (uint256); - - /** - * @dev Part of the Governor Bravo's interface: _"Queues a proposal of state succeeded"_. - */ - function queue(uint256 proposalId) public virtual; - - /** - * @dev Part of the Governor Bravo's interface: _"Executes a queued proposal if eta has passed"_. - */ - function execute(uint256 proposalId) public payable virtual; - - /** - * @dev Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold. - */ - function cancel(uint256 proposalId) public virtual; - - /** - * @dev Part of the Governor Bravo's interface: _"Gets actions of a proposal"_. - */ - function getActions(uint256 proposalId) - public - view - virtual - returns ( - address[] memory targets, - uint256[] memory values, - string[] memory signatures, - bytes[] memory calldatas - ); - - /** - * @dev Part of the Governor Bravo's interface: _"Gets the receipt for a voter on a given proposal"_. - */ - function getReceipt(uint256 proposalId, address voter) public view virtual returns (Receipt memory); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol deleted file mode 100644 index ce28aa3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sol +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorCountingSimple.sol) - -pragma solidity ^0.8.0; - -import "../Governor.sol"; - -/** - * @dev Extension of {Governor} for simple, 3 options, vote counting. - * - * _Available since v4.3._ - */ -abstract contract GovernorCountingSimple is Governor { - /** - * @dev Supported vote types. Matches Governor Bravo ordering. - */ - enum VoteType { - Against, - For, - Abstain - } - - struct ProposalVote { - uint256 againstVotes; - uint256 forVotes; - uint256 abstainVotes; - mapping(address => bool) hasVoted; - } - - mapping(uint256 => ProposalVote) private _proposalVotes; - - /** - * @dev See {IGovernor-COUNTING_MODE}. - */ - // solhint-disable-next-line func-name-mixedcase - function COUNTING_MODE() public pure virtual override returns (string memory) { - return "support=bravo&quorum=for,abstain"; - } - - /** - * @dev See {IGovernor-hasVoted}. - */ - function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { - return _proposalVotes[proposalId].hasVoted[account]; - } - - /** - * @dev Accessor to the internal vote counts. - */ - function proposalVotes(uint256 proposalId) - public - view - virtual - returns ( - uint256 againstVotes, - uint256 forVotes, - uint256 abstainVotes - ) - { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - return (proposalvote.againstVotes, proposalvote.forVotes, proposalvote.abstainVotes); - } - - /** - * @dev See {Governor-_quorumReached}. - */ - function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - return quorum(proposalSnapshot(proposalId)) <= proposalvote.forVotes + proposalvote.abstainVotes; - } - - /** - * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. - */ - function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - return proposalvote.forVotes > proposalvote.againstVotes; - } - - /** - * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo). - */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory // params - ) internal virtual override { - ProposalVote storage proposalvote = _proposalVotes[proposalId]; - - require(!proposalvote.hasVoted[account], "GovernorVotingSimple: vote already cast"); - proposalvote.hasVoted[account] = true; - - if (support == uint8(VoteType.Against)) { - proposalvote.againstVotes += weight; - } else if (support == uint8(VoteType.For)) { - proposalvote.forVotes += weight; - } else if (support == uint8(VoteType.Abstain)) { - proposalvote.abstainVotes += weight; - } else { - revert("GovernorVotingSimple: invalid value for enum VoteType"); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol deleted file mode 100644 index a26bbf0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sol +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorPreventLateQuorum.sol) - -pragma solidity ^0.8.0; - -import "../Governor.sol"; -import "../../utils/math/Math.sol"; - -/** - * @dev A module that ensures there is a minimum voting period after quorum is reached. This prevents a large voter from - * swaying a vote and triggering quorum at the last minute, by ensuring there is always time for other voters to react - * and try to oppose the decision. - * - * If a vote causes quorum to be reached, the proposal's voting period may be extended so that it does not end before at - * least a given number of blocks have passed (the "vote extension" parameter). This parameter can be set by the - * governance executor (e.g. through a governance proposal). - * - * _Available since v4.5._ - */ -abstract contract GovernorPreventLateQuorum is Governor { - using SafeCast for uint256; - using Timers for Timers.BlockNumber; - - uint64 private _voteExtension; - mapping(uint256 => Timers.BlockNumber) private _extendedDeadlines; - - /// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period. - event ProposalExtended(uint256 indexed proposalId, uint64 extendedDeadline); - - /// @dev Emitted when the {lateQuorumVoteExtension} parameter is changed. - event LateQuorumVoteExtensionSet(uint64 oldVoteExtension, uint64 newVoteExtension); - - /** - * @dev Initializes the vote extension parameter: the number of blocks that are required to pass since a proposal - * reaches quorum until its voting period ends. If necessary the voting period will be extended beyond the one set - * at proposal creation. - */ - constructor(uint64 initialVoteExtension) { - _setLateQuorumVoteExtension(initialVoteExtension); - } - - /** - * @dev Returns the proposal deadline, which may have been extended beyond that set at proposal creation, if the - * proposal reached quorum late in the voting period. See {Governor-proposalDeadline}. - */ - function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { - return Math.max(super.proposalDeadline(proposalId), _extendedDeadlines[proposalId].getDeadline()); - } - - /** - * @dev Casts a vote and detects if it caused quorum to be reached, potentially extending the voting period. See - * {Governor-_castVote}. - * - * May emit a {ProposalExtended} event. - */ - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal virtual override returns (uint256) { - uint256 result = super._castVote(proposalId, account, support, reason, params); - - Timers.BlockNumber storage extendedDeadline = _extendedDeadlines[proposalId]; - - if (extendedDeadline.isUnset() && _quorumReached(proposalId)) { - uint64 extendedDeadlineValue = block.number.toUint64() + lateQuorumVoteExtension(); - - if (extendedDeadlineValue > proposalDeadline(proposalId)) { - emit ProposalExtended(proposalId, extendedDeadlineValue); - } - - extendedDeadline.setDeadline(extendedDeadlineValue); - } - - return result; - } - - /** - * @dev Returns the current value of the vote extension parameter: the number of blocks that are required to pass - * from the time a proposal reaches quorum until its voting period ends. - */ - function lateQuorumVoteExtension() public view virtual returns (uint64) { - return _voteExtension; - } - - /** - * @dev Changes the {lateQuorumVoteExtension}. This operation can only be performed by the governance executor, - * generally through a governance proposal. - * - * Emits a {LateQuorumVoteExtensionSet} event. - */ - function setLateQuorumVoteExtension(uint64 newVoteExtension) public virtual onlyGovernance { - _setLateQuorumVoteExtension(newVoteExtension); - } - - /** - * @dev Changes the {lateQuorumVoteExtension}. This is an internal function that can be exposed in a public function - * like {setLateQuorumVoteExtension} if another access control mechanism is needed. - * - * Emits a {LateQuorumVoteExtensionSet} event. - */ - function _setLateQuorumVoteExtension(uint64 newVoteExtension) internal virtual { - emit LateQuorumVoteExtensionSet(_voteExtension, newVoteExtension); - _voteExtension = newVoteExtension; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorProposalThreshold.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorProposalThreshold.sol deleted file mode 100644 index 3feebac..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorProposalThreshold.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorProposalThreshold.sol) - -pragma solidity ^0.8.0; - -import "../Governor.sol"; - -/** - * @dev Extension of {Governor} for proposal restriction to token holders with a minimum balance. - * - * _Available since v4.3._ - * _Deprecated since v4.4._ - */ -abstract contract GovernorProposalThreshold is Governor { - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override returns (uint256) { - return super.propose(targets, values, calldatas, description); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol deleted file mode 100644 index a3187c6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sol +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorSettings.sol) - -pragma solidity ^0.8.0; - -import "../Governor.sol"; - -/** - * @dev Extension of {Governor} for settings updatable through governance. - * - * _Available since v4.4._ - */ -abstract contract GovernorSettings is Governor { - uint256 private _votingDelay; - uint256 private _votingPeriod; - uint256 private _proposalThreshold; - - event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay); - event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod); - event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold); - - /** - * @dev Initialize the governance parameters. - */ - constructor( - uint256 initialVotingDelay, - uint256 initialVotingPeriod, - uint256 initialProposalThreshold - ) { - _setVotingDelay(initialVotingDelay); - _setVotingPeriod(initialVotingPeriod); - _setProposalThreshold(initialProposalThreshold); - } - - /** - * @dev See {IGovernor-votingDelay}. - */ - function votingDelay() public view virtual override returns (uint256) { - return _votingDelay; - } - - /** - * @dev See {IGovernor-votingPeriod}. - */ - function votingPeriod() public view virtual override returns (uint256) { - return _votingPeriod; - } - - /** - * @dev See {Governor-proposalThreshold}. - */ - function proposalThreshold() public view virtual override returns (uint256) { - return _proposalThreshold; - } - - /** - * @dev Update the voting delay. This operation can only be performed through a governance proposal. - * - * Emits a {VotingDelaySet} event. - */ - function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance { - _setVotingDelay(newVotingDelay); - } - - /** - * @dev Update the voting period. This operation can only be performed through a governance proposal. - * - * Emits a {VotingPeriodSet} event. - */ - function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance { - _setVotingPeriod(newVotingPeriod); - } - - /** - * @dev Update the proposal threshold. This operation can only be performed through a governance proposal. - * - * Emits a {ProposalThresholdSet} event. - */ - function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance { - _setProposalThreshold(newProposalThreshold); - } - - /** - * @dev Internal setter for the voting delay. - * - * Emits a {VotingDelaySet} event. - */ - function _setVotingDelay(uint256 newVotingDelay) internal virtual { - emit VotingDelaySet(_votingDelay, newVotingDelay); - _votingDelay = newVotingDelay; - } - - /** - * @dev Internal setter for the voting period. - * - * Emits a {VotingPeriodSet} event. - */ - function _setVotingPeriod(uint256 newVotingPeriod) internal virtual { - // voting period must be at least one block long - require(newVotingPeriod > 0, "GovernorSettings: voting period too low"); - emit VotingPeriodSet(_votingPeriod, newVotingPeriod); - _votingPeriod = newVotingPeriod; - } - - /** - * @dev Internal setter for the proposal threshold. - * - * Emits a {ProposalThresholdSet} event. - */ - function _setProposalThreshold(uint256 newProposalThreshold) internal virtual { - emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold); - _proposalThreshold = newProposalThreshold; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol deleted file mode 100644 index 2fa539e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sol +++ /dev/null @@ -1,193 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorTimelockCompound.sol) - -pragma solidity ^0.8.0; - -import "./IGovernorTimelock.sol"; -import "../Governor.sol"; -import "../../utils/math/SafeCast.sol"; -import "../../vendor/compound/ICompoundTimelock.sol"; - -/** - * @dev Extension of {Governor} that binds the execution process to a Compound Timelock. This adds a delay, enforced by - * the external timelock to all successful proposal (in addition to the voting duration). The {Governor} needs to be - * the admin of the timelock for any operation to be performed. A public, unrestricted, - * {GovernorTimelockCompound-__acceptAdmin} is available to accept ownership of the timelock. - * - * Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus, - * the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be - * inaccessible. - * - * _Available since v4.3._ - */ -abstract contract GovernorTimelockCompound is IGovernorTimelock, Governor { - using SafeCast for uint256; - using Timers for Timers.Timestamp; - - struct ProposalTimelock { - Timers.Timestamp timer; - } - - ICompoundTimelock private _timelock; - - mapping(uint256 => ProposalTimelock) private _proposalTimelocks; - - /** - * @dev Emitted when the timelock controller used for proposal execution is modified. - */ - event TimelockChange(address oldTimelock, address newTimelock); - - /** - * @dev Set the timelock. - */ - constructor(ICompoundTimelock timelockAddress) { - _updateTimelock(timelockAddress); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, Governor) returns (bool) { - return interfaceId == type(IGovernorTimelock).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Overridden version of the {Governor-state} function with added support for the `Queued` and `Expired` status. - */ - function state(uint256 proposalId) public view virtual override(IGovernor, Governor) returns (ProposalState) { - ProposalState status = super.state(proposalId); - - if (status != ProposalState.Succeeded) { - return status; - } - - uint256 eta = proposalEta(proposalId); - if (eta == 0) { - return status; - } else if (block.timestamp >= eta + _timelock.GRACE_PERIOD()) { - return ProposalState.Expired; - } else { - return ProposalState.Queued; - } - } - - /** - * @dev Public accessor to check the address of the timelock - */ - function timelock() public view virtual override returns (address) { - return address(_timelock); - } - - /** - * @dev Public accessor to check the eta of a queued proposal - */ - function proposalEta(uint256 proposalId) public view virtual override returns (uint256) { - return _proposalTimelocks[proposalId].timer.getDeadline(); - } - - /** - * @dev Function to queue a proposal to the timelock. - */ - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public virtual override returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful"); - - uint256 eta = block.timestamp + _timelock.delay(); - _proposalTimelocks[proposalId].timer.setDeadline(eta.toUint64()); - for (uint256 i = 0; i < targets.length; ++i) { - require( - !_timelock.queuedTransactions(keccak256(abi.encode(targets[i], values[i], "", calldatas[i], eta))), - "GovernorTimelockCompound: identical proposal action already queued" - ); - _timelock.queueTransaction(targets[i], values[i], "", calldatas[i], eta); - } - - emit ProposalQueued(proposalId, eta); - - return proposalId; - } - - /** - * @dev Overridden execute function that run the already queued proposal through the timelock. - */ - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 /*descriptionHash*/ - ) internal virtual override { - uint256 eta = proposalEta(proposalId); - require(eta > 0, "GovernorTimelockCompound: proposal not yet queued"); - Address.sendValue(payable(_timelock), msg.value); - for (uint256 i = 0; i < targets.length; ++i) { - _timelock.executeTransaction(targets[i], values[i], "", calldatas[i], eta); - } - } - - /** - * @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already - * been queued. - */ - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override returns (uint256) { - uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash); - - uint256 eta = proposalEta(proposalId); - if (eta > 0) { - for (uint256 i = 0; i < targets.length; ++i) { - _timelock.cancelTransaction(targets[i], values[i], "", calldatas[i], eta); - } - _proposalTimelocks[proposalId].timer.reset(); - } - - return proposalId; - } - - /** - * @dev Address through which the governor executes action. In this case, the timelock. - */ - function _executor() internal view virtual override returns (address) { - return address(_timelock); - } - - /** - * @dev Accept admin right over the timelock. - */ - // solhint-disable-next-line private-vars-leading-underscore - function __acceptAdmin() public { - _timelock.acceptAdmin(); - } - - /** - * @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates - * must be proposed, scheduled, and executed through governance proposals. - * - * For security reasons, the timelock must be handed over to another admin before setting up a new one. The two - * operations (hand over the timelock) and do the update can be batched in a single proposal. - * - * Note that if the timelock admin has been handed over in a previous operation, we refuse updates made through the - * timelock if admin of the timelock has already been accepted and the operation is executed outside the scope of - * governance. - - * CAUTION: It is not recommended to change the timelock while there are other queued governance proposals. - */ - function updateTimelock(ICompoundTimelock newTimelock) external virtual onlyGovernance { - _updateTimelock(newTimelock); - } - - function _updateTimelock(ICompoundTimelock newTimelock) private { - emit TimelockChange(address(_timelock), address(newTimelock)); - _timelock = newTimelock; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol deleted file mode 100644 index aaeaf94..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sol +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorTimelockControl.sol) - -pragma solidity ^0.8.0; - -import "./IGovernorTimelock.sol"; -import "../Governor.sol"; -import "../TimelockController.sol"; - -/** - * @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a - * delay, enforced by the {TimelockController} to all successful proposal (in addition to the voting duration). The - * {Governor} needs the proposer (and ideally the executor) roles for the {Governor} to work properly. - * - * Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus, - * the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be - * inaccessible. - * - * WARNING: Setting up the TimelockController to have additional proposers besides the governor is very risky, as it - * grants them powers that they must be trusted or known not to use: 1) {onlyGovernance} functions like {relay} are - * available to them through the timelock, and 2) approved governance proposals can be blocked by them, effectively - * executing a Denial of Service attack. This risk will be mitigated in a future release. - * - * _Available since v4.3._ - */ -abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { - TimelockController private _timelock; - mapping(uint256 => bytes32) private _timelockIds; - - /** - * @dev Emitted when the timelock controller used for proposal execution is modified. - */ - event TimelockChange(address oldTimelock, address newTimelock); - - /** - * @dev Set the timelock. - */ - constructor(TimelockController timelockAddress) { - _updateTimelock(timelockAddress); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, Governor) returns (bool) { - return interfaceId == type(IGovernorTimelock).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Overridden version of the {Governor-state} function with added support for the `Queued` status. - */ - function state(uint256 proposalId) public view virtual override(IGovernor, Governor) returns (ProposalState) { - ProposalState status = super.state(proposalId); - - if (status != ProposalState.Succeeded) { - return status; - } - - // core tracks execution, so we just have to check if successful proposal have been queued. - bytes32 queueid = _timelockIds[proposalId]; - if (queueid == bytes32(0)) { - return status; - } else if (_timelock.isOperationDone(queueid)) { - return ProposalState.Executed; - } else if (_timelock.isOperationPending(queueid)) { - return ProposalState.Queued; - } else { - return ProposalState.Canceled; - } - } - - /** - * @dev Public accessor to check the address of the timelock - */ - function timelock() public view virtual override returns (address) { - return address(_timelock); - } - - /** - * @dev Public accessor to check the eta of a queued proposal - */ - function proposalEta(uint256 proposalId) public view virtual override returns (uint256) { - uint256 eta = _timelock.getTimestamp(_timelockIds[proposalId]); - return eta == 1 ? 0 : eta; // _DONE_TIMESTAMP (1) should be replaced with a 0 value - } - - /** - * @dev Function to queue a proposal to the timelock. - */ - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public virtual override returns (uint256) { - uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - - require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful"); - - uint256 delay = _timelock.getMinDelay(); - _timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, descriptionHash); - _timelock.scheduleBatch(targets, values, calldatas, 0, descriptionHash, delay); - - emit ProposalQueued(proposalId, block.timestamp + delay); - - return proposalId; - } - - /** - * @dev Overridden execute function that run the already queued proposal through the timelock. - */ - function _execute( - uint256, /* proposalId */ - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override { - _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash); - } - - /** - * @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already - * been queued. - */ - // This function can reenter through the external call to the timelock, but we assume the timelock is trusted and - // well behaved (according to TimelockController) and this will not happen. - // slither-disable-next-line reentrancy-no-eth - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override returns (uint256) { - uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash); - - if (_timelockIds[proposalId] != 0) { - _timelock.cancel(_timelockIds[proposalId]); - delete _timelockIds[proposalId]; - } - - return proposalId; - } - - /** - * @dev Address through which the governor executes action. In this case, the timelock. - */ - function _executor() internal view virtual override returns (address) { - return address(_timelock); - } - - /** - * @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates - * must be proposed, scheduled, and executed through governance proposals. - * - * CAUTION: It is not recommended to change the timelock while there are other queued governance proposals. - */ - function updateTimelock(TimelockController newTimelock) external virtual onlyGovernance { - _updateTimelock(newTimelock); - } - - function _updateTimelock(TimelockController newTimelock) private { - emit TimelockChange(address(_timelock), address(newTimelock)); - _timelock = newTimelock; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol deleted file mode 100644 index b328c25..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorVotes.sol) - -pragma solidity ^0.8.0; - -import "../Governor.sol"; -import "../utils/IVotes.sol"; - -/** - * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token. - * - * _Available since v4.3._ - */ -abstract contract GovernorVotes is Governor { - IVotes public immutable token; - - constructor(IVotes tokenAddress) { - token = tokenAddress; - } - - /** - * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). - */ - function _getVotes( - address account, - uint256 blockNumber, - bytes memory /*params*/ - ) internal view virtual override returns (uint256) { - return token.getPastVotes(account, blockNumber); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesComp.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesComp.sol deleted file mode 100644 index 8c4a1f8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesComp.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorVotesComp.sol) - -pragma solidity ^0.8.0; - -import "../Governor.sol"; -import "../../token/ERC20/extensions/ERC20VotesComp.sol"; - -/** - * @dev Extension of {Governor} for voting weight extraction from a Comp token. - * - * _Available since v4.3._ - */ -abstract contract GovernorVotesComp is Governor { - ERC20VotesComp public immutable token; - - constructor(ERC20VotesComp token_) { - token = token_; - } - - /** - * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). - */ - function _getVotes( - address account, - uint256 blockNumber, - bytes memory /*params*/ - ) internal view virtual override returns (uint256) { - return token.getPriorVotes(account, blockNumber); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol deleted file mode 100644 index 40f912c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sol +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (governance/extensions/GovernorVotesQuorumFraction.sol) - -pragma solidity ^0.8.0; - -import "./GovernorVotes.sol"; - -/** - * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a - * fraction of the total supply. - * - * _Available since v4.3._ - */ -abstract contract GovernorVotesQuorumFraction is GovernorVotes { - uint256 private _quorumNumerator; - - event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); - - /** - * @dev Initialize quorum as a fraction of the token's total supply. - * - * The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is - * specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be - * customized by overriding {quorumDenominator}. - */ - constructor(uint256 quorumNumeratorValue) { - _updateQuorumNumerator(quorumNumeratorValue); - } - - /** - * @dev Returns the current quorum numerator. See {quorumDenominator}. - */ - function quorumNumerator() public view virtual returns (uint256) { - return _quorumNumerator; - } - - /** - * @dev Returns the quorum denominator. Defaults to 100, but may be overridden. - */ - function quorumDenominator() public view virtual returns (uint256) { - return 100; - } - - /** - * @dev Returns the quorum for a block number, in terms of number of votes: `supply * numerator / denominator`. - */ - function quorum(uint256 blockNumber) public view virtual override returns (uint256) { - return (token.getPastTotalSupply(blockNumber) * quorumNumerator()) / quorumDenominator(); - } - - /** - * @dev Changes the quorum numerator. - * - * Emits a {QuorumNumeratorUpdated} event. - * - * Requirements: - * - * - Must be called through a governance proposal. - * - New numerator must be smaller or equal to the denominator. - */ - function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance { - _updateQuorumNumerator(newQuorumNumerator); - } - - /** - * @dev Changes the quorum numerator. - * - * Emits a {QuorumNumeratorUpdated} event. - * - * Requirements: - * - * - New numerator must be smaller or equal to the denominator. - */ - function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual { - require( - newQuorumNumerator <= quorumDenominator(), - "GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator" - ); - - uint256 oldQuorumNumerator = _quorumNumerator; - _quorumNumerator = newQuorumNumerator; - - emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/IGovernorTimelock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/IGovernorTimelock.sol deleted file mode 100644 index 40402f6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/extensions/IGovernorTimelock.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol) - -pragma solidity ^0.8.0; - -import "../IGovernor.sol"; - -/** - * @dev Extension of the {IGovernor} for timelock supporting modules. - * - * _Available since v4.3._ - */ -abstract contract IGovernorTimelock is IGovernor { - event ProposalQueued(uint256 proposalId, uint256 eta); - - function timelock() public view virtual returns (address); - - function proposalEta(uint256 proposalId) public view virtual returns (uint256); - - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public virtual returns (uint256 proposalId); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol deleted file mode 100644 index 6317d77..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) -pragma solidity ^0.8.0; - -/** - * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. - * - * _Available since v4.5._ - */ -interface IVotes { - /** - * @dev Emitted when an account changes their delegate. - */ - event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); - - /** - * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. - */ - event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); - - /** - * @dev Returns the current amount of votes that `account` has. - */ - function getVotes(address account) external view returns (uint256); - - /** - * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). - */ - function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); - - /** - * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). - * - * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. - * Votes that have not been delegated are still part of total supply, even though they would not participate in a - * vote. - */ - function getPastTotalSupply(uint256 blockNumber) external view returns (uint256); - - /** - * @dev Returns the delegate that `account` has chosen. - */ - function delegates(address account) external view returns (address); - - /** - * @dev Delegates votes from the sender to `delegatee`. - */ - function delegate(address delegatee) external; - - /** - * @dev Delegates votes from signer to `delegatee`. - */ - function delegateBySig( - address delegatee, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/utils/Votes.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/utils/Votes.sol deleted file mode 100644 index 52d2c0e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/governance/utils/Votes.sol +++ /dev/null @@ -1,211 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (governance/utils/Votes.sol) -pragma solidity ^0.8.0; - -import "../../utils/Context.sol"; -import "../../utils/Counters.sol"; -import "../../utils/Checkpoints.sol"; -import "../../utils/cryptography/draft-EIP712.sol"; -import "./IVotes.sol"; - -/** - * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be - * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of - * "representative" that will pool delegated voting units from different accounts and can then use it to vote in - * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to - * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative. - * - * This contract is often combined with a token contract such that voting units correspond to token units. For an - * example, see {ERC721Votes}. - * - * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed - * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the - * cost of this history tracking optional. - * - * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return - * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the - * previous example, it would be included in {ERC721-_beforeTokenTransfer}). - * - * _Available since v4.5._ - */ -abstract contract Votes is IVotes, Context, EIP712 { - using Checkpoints for Checkpoints.History; - using Counters for Counters.Counter; - - bytes32 private constant _DELEGATION_TYPEHASH = - keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - mapping(address => address) private _delegation; - mapping(address => Checkpoints.History) private _delegateCheckpoints; - Checkpoints.History private _totalCheckpoints; - - mapping(address => Counters.Counter) private _nonces; - - /** - * @dev Returns the current amount of votes that `account` has. - */ - function getVotes(address account) public view virtual override returns (uint256) { - return _delegateCheckpoints[account].latest(); - } - - /** - * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { - return _delegateCheckpoints[account].getAtBlock(blockNumber); - } - - /** - * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). - * - * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. - * Votes that have not been delegated are still part of total supply, even though they would not participate in a - * vote. - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { - require(blockNumber < block.number, "Votes: block not yet mined"); - return _totalCheckpoints.getAtBlock(blockNumber); - } - - /** - * @dev Returns the current total supply of votes. - */ - function _getTotalSupply() internal view virtual returns (uint256) { - return _totalCheckpoints.latest(); - } - - /** - * @dev Returns the delegate that `account` has chosen. - */ - function delegates(address account) public view virtual override returns (address) { - return _delegation[account]; - } - - /** - * @dev Delegates votes from the sender to `delegatee`. - */ - function delegate(address delegatee) public virtual override { - address account = _msgSender(); - _delegate(account, delegatee); - } - - /** - * @dev Delegates votes from signer to `delegatee`. - */ - function delegateBySig( - address delegatee, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override { - require(block.timestamp <= expiry, "Votes: signature expired"); - address signer = ECDSA.recover( - _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), - v, - r, - s - ); - require(nonce == _useNonce(signer), "Votes: invalid nonce"); - _delegate(signer, delegatee); - } - - /** - * @dev Delegate all of `account`'s voting units to `delegatee`. - * - * Emits events {DelegateChanged} and {DelegateVotesChanged}. - */ - function _delegate(address account, address delegatee) internal virtual { - address oldDelegate = delegates(account); - _delegation[account] = delegatee; - - emit DelegateChanged(account, oldDelegate, delegatee); - _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account)); - } - - /** - * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to` - * should be zero. Total supply of voting units will be adjusted with mints and burns. - */ - function _transferVotingUnits( - address from, - address to, - uint256 amount - ) internal virtual { - if (from == address(0)) { - _totalCheckpoints.push(_add, amount); - } - if (to == address(0)) { - _totalCheckpoints.push(_subtract, amount); - } - _moveDelegateVotes(delegates(from), delegates(to), amount); - } - - /** - * @dev Moves delegated votes from one delegate to another. - */ - function _moveDelegateVotes( - address from, - address to, - uint256 amount - ) private { - if (from != to && amount > 0) { - if (from != address(0)) { - (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_subtract, amount); - emit DelegateVotesChanged(from, oldValue, newValue); - } - if (to != address(0)) { - (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_add, amount); - emit DelegateVotesChanged(to, oldValue, newValue); - } - } - } - - function _add(uint256 a, uint256 b) private pure returns (uint256) { - return a + b; - } - - function _subtract(uint256 a, uint256 b) private pure returns (uint256) { - return a - b; - } - - /** - * @dev Consumes a nonce. - * - * Returns the current value and increments nonce. - */ - function _useNonce(address owner) internal virtual returns (uint256 current) { - Counters.Counter storage nonce = _nonces[owner]; - current = nonce.current(); - nonce.increment(); - } - - /** - * @dev Returns an address nonce. - */ - function nonces(address owner) public view virtual returns (uint256) { - return _nonces[owner].current(); - } - - /** - * @dev Returns the contract's {EIP712} domain separator. - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view returns (bytes32) { - return _domainSeparatorV4(); - } - - /** - * @dev Must return the voting units held by an account. - */ - function _getVotingUnits(address) internal view virtual returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol deleted file mode 100644 index f891132..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC1155/IERC1155.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol deleted file mode 100644 index 2aa885f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155MetadataURI.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC1155/extensions/IERC1155MetadataURI.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol deleted file mode 100644 index a6d4ead..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155Receiver.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC1155/IERC1155Receiver.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol deleted file mode 100644 index 5ec44c7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC1271 standard signature validation method for - * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. - * - * _Available since v4.1._ - */ -interface IERC1271 { - /** - * @dev Should return whether the signature provided is valid for the provided data - * @param hash Hash of the data to be signed - * @param signature Signature byte array associated with _data - */ - function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol deleted file mode 100644 index 5fad104..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363.sol) - -pragma solidity ^0.8.0; - -import "./IERC20.sol"; -import "./IERC165.sol"; - -interface IERC1363 is IERC165, IERC20 { - /* - * Note: the ERC-165 identifier for this interface is 0x4bbee2df. - * 0x4bbee2df === - * bytes4(keccak256('transferAndCall(address,uint256)')) ^ - * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ - * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ - * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) - */ - - /* - * Note: the ERC-165 identifier for this interface is 0xfb9ec8ce. - * 0xfb9ec8ce === - * bytes4(keccak256('approveAndCall(address,uint256)')) ^ - * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) - */ - - /** - * @dev Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @return true unless throwing - */ - function transferAndCall(address to, uint256 value) external returns (bool); - - /** - * @dev Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @param data bytes Additional data with no specified format, sent in call to `to` - * @return true unless throwing - */ - function transferAndCall( - address to, - uint256 value, - bytes memory data - ) external returns (bool); - - /** - * @dev Transfer tokens from one address to another and then call `onTransferReceived` on receiver - * @param from address The address which you want to send tokens from - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @return true unless throwing - */ - function transferFromAndCall( - address from, - address to, - uint256 value - ) external returns (bool); - - /** - * @dev Transfer tokens from one address to another and then call `onTransferReceived` on receiver - * @param from address The address which you want to send tokens from - * @param to address The address which you want to transfer to - * @param value uint256 The amount of tokens to be transferred - * @param data bytes Additional data with no specified format, sent in call to `to` - * @return true unless throwing - */ - function transferFromAndCall( - address from, - address to, - uint256 value, - bytes memory data - ) external returns (bool); - - /** - * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender - * and then call `onApprovalReceived` on spender. - * @param spender address The address which will spend the funds - * @param value uint256 The amount of tokens to be spent - */ - function approveAndCall(address spender, uint256 value) external returns (bool); - - /** - * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender - * and then call `onApprovalReceived` on spender. - * @param spender address The address which will spend the funds - * @param value uint256 The amount of tokens to be spent - * @param data bytes Additional data with no specified format, sent in call to `spender` - */ - function approveAndCall( - address spender, - uint256 value, - bytes memory data - ) external returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol deleted file mode 100644 index bc5eadd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363Receiver.sol) - -pragma solidity ^0.8.0; - -interface IERC1363Receiver { - /* - * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. - * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) - */ - - /** - * @notice Handle the receipt of ERC1363 tokens - * @dev Any ERC1363 smart contract calls this function on the recipient - * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the token contract address is always the message sender. - * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function - * @param from address The address which are token transferred from - * @param value uint256 The amount of tokens transferred - * @param data bytes Additional data with no specified format - * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` - * unless throwing - */ - function onTransferReceived( - address operator, - address from, - uint256 value, - bytes memory data - ) external returns (bytes4); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol deleted file mode 100644 index 48f6fd5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1363Spender.sol) - -pragma solidity ^0.8.0; - -interface IERC1363Spender { - /* - * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. - * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) - */ - - /** - * @notice Handle the approval of ERC1363 tokens - * @dev Any ERC1363 smart contract calls this function on the recipient - * after an `approve`. This function MAY throw to revert and reject the - * approval. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the token contract address is always the message sender. - * @param owner address The address which called `approveAndCall` function - * @param value uint256 The amount of tokens to be spent - * @param data bytes Additional data with no specified format - * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` - * unless throwing - */ - function onApprovalReceived( - address owner, - uint256 value, - bytes memory data - ) external returns (bytes4); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol deleted file mode 100644 index b97c4da..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/IERC165.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol deleted file mode 100644 index a83a7a3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1820Implementer.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/IERC1820Implementer.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol deleted file mode 100644 index 1b1ba9f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1820Registry.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/IERC1820Registry.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol deleted file mode 100644 index a819316..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/IERC20.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol deleted file mode 100644 index aa5c639..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20Metadata.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/IERC20Metadata.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol deleted file mode 100644 index 6b05581..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) - -pragma solidity ^0.8.0; - -import "../utils/introspection/IERC165.sol"; - -/** - * @dev Interface for the NFT Royalty Standard. - * - * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal - * support for royalty payments across all NFT marketplaces and ecosystem participants. - * - * _Available since v4.5._ - */ -interface IERC2981 is IERC165 { - /** - * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of - * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. - */ - function royaltyInfo(uint256 tokenId, uint256 salePrice) - external - view - returns (address receiver, uint256 royaltyAmount); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol deleted file mode 100644 index 1238190..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156.sol) - -pragma solidity ^0.8.0; - -import "./IERC3156FlashBorrower.sol"; -import "./IERC3156FlashLender.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol deleted file mode 100644 index c3b4f1e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC3156 FlashBorrower, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - * - * _Available since v4.1._ - */ -interface IERC3156FlashBorrower { - /** - * @dev Receive a flash loan. - * @param initiator The initiator of the loan. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @param fee The additional amount of tokens to repay. - * @param data Arbitrary data structure, intended to contain user-defined parameters. - * @return The keccak256 hash of "IERC3156FlashBorrower.onFlashLoan" - */ - function onFlashLoan( - address initiator, - address token, - uint256 amount, - uint256 fee, - bytes calldata data - ) external returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol deleted file mode 100644 index 3101283..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol) - -pragma solidity ^0.8.0; - -import "./IERC3156FlashBorrower.sol"; - -/** - * @dev Interface of the ERC3156 FlashLender, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - * - * _Available since v4.1._ - */ -interface IERC3156FlashLender { - /** - * @dev The amount of currency available to be lended. - * @param token The loan currency. - * @return The amount of `token` that can be borrowed. - */ - function maxFlashLoan(address token) external view returns (uint256); - - /** - * @dev The fee to be charged for a given loan. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @return The amount of `token` to be charged for the loan, on top of the returned principal. - */ - function flashFee(address token, uint256 amount) external view returns (uint256); - - /** - * @dev Initiate a flash loan. - * @param receiver The receiver of the tokens in the loan, and the receiver of the callback. - * @param token The loan currency. - * @param amount The amount of tokens lent. - * @param data Arbitrary data structure, intended to contain user-defined parameters. - */ - function flashLoan( - IERC3156FlashBorrower receiver, - address token, - uint256 amount, - bytes calldata data - ) external returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol deleted file mode 100644 index 315cb25..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC4626.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/IERC20.sol"; -import "../token/ERC20/extensions/IERC20Metadata.sol"; - -/** - * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in - * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. - * - * _Available since v4.7._ - */ -interface IERC4626 is IERC20, IERC20Metadata { - event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); - - event Withdraw( - address indexed caller, - address indexed receiver, - address indexed owner, - uint256 assets, - uint256 shares - ); - - /** - * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. - * - * - MUST be an ERC-20 token contract. - * - MUST NOT revert. - */ - function asset() external view returns (address assetTokenAddress); - - /** - * @dev Returns the total amount of the underlying asset that is “managed” by Vault. - * - * - SHOULD include any compounding that occurs from yield. - * - MUST be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT revert. - */ - function totalAssets() external view returns (uint256 totalManagedAssets); - - /** - * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal - * scenario where all the conditions are met. - * - * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - * - MUST NOT revert. - * - * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - * from. - */ - function convertToShares(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal - * scenario where all the conditions are met. - * - * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. - * - MUST NOT show any variations depending on the caller. - * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. - * - MUST NOT revert. - * - * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the - * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and - * from. - */ - function convertToAssets(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, - * through a deposit call. - * - * - MUST return a limited value if receiver is subject to some deposit limit. - * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. - * - MUST NOT revert. - */ - function maxDeposit(address receiver) external view returns (uint256 maxAssets); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given - * current on-chain conditions. - * - * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit - * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called - * in the same transaction. - * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the - * deposit would be accepted, regardless if the user has enough tokens approved, etc. - * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by depositing. - */ - function previewDeposit(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. - * - * - MUST emit the Deposit event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * deposit execution, and are accounted for during deposit. - * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not - * approving enough underlying tokens to the Vault contract, etc). - * - * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - */ - function deposit(uint256 assets, address receiver) external returns (uint256 shares); - - /** - * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. - * - MUST return a limited value if receiver is subject to some mint limit. - * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. - * - MUST NOT revert. - */ - function maxMint(address receiver) external view returns (uint256 maxShares); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given - * current on-chain conditions. - * - * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call - * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the - * same transaction. - * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint - * would be accepted, regardless if the user has enough tokens approved, etc. - * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by minting. - */ - function previewMint(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. - * - * - MUST emit the Deposit event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint - * execution, and are accounted for during mint. - * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not - * approving enough underlying tokens to the Vault contract, etc). - * - * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. - */ - function mint(uint256 shares, address receiver) external returns (uint256 assets); - - /** - * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the - * Vault, through a withdraw call. - * - * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - * - MUST NOT revert. - */ - function maxWithdraw(address owner) external view returns (uint256 maxAssets); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, - * given current on-chain conditions. - * - * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw - * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if - * called - * in the same transaction. - * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though - * the withdrawal would be accepted, regardless if the user has enough shares, etc. - * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by depositing. - */ - function previewWithdraw(uint256 assets) external view returns (uint256 shares); - - /** - * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. - * - * - MUST emit the Withdraw event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * withdraw execution, and are accounted for during withdraw. - * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner - * not having enough shares, etc). - * - * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - * Those methods should be performed separately. - */ - function withdraw( - uint256 assets, - address receiver, - address owner - ) external returns (uint256 shares); - - /** - * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, - * through a redeem call. - * - * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. - * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. - * - MUST NOT revert. - */ - function maxRedeem(address owner) external view returns (uint256 maxShares); - - /** - * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, - * given current on-chain conditions. - * - * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call - * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the - * same transaction. - * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the - * redemption would be accepted, regardless if the user has enough shares, etc. - * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. - * - MUST NOT revert. - * - * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in - * share price or some other type of condition, meaning the depositor will lose assets by redeeming. - */ - function previewRedeem(uint256 shares) external view returns (uint256 assets); - - /** - * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. - * - * - MUST emit the Withdraw event. - * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the - * redeem execution, and are accounted for during redeem. - * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner - * not having enough shares, etc). - * - * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. - * Those methods should be performed separately. - */ - function redeem( - uint256 shares, - address receiver, - address owner - ) external returns (uint256 assets); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol deleted file mode 100644 index 822b311..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/IERC721.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol deleted file mode 100644 index e39a5a0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Enumerable.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/IERC721Enumerable.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol deleted file mode 100644 index afe2707..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/IERC721Metadata.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol deleted file mode 100644 index c9c153a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Receiver.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC721/IERC721Receiver.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol deleted file mode 100644 index b97ba7b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC777/IERC777.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol deleted file mode 100644 index 0ce2704..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777Recipient.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC777/IERC777Recipient.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol deleted file mode 100644 index f1f17a2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/IERC777Sender.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC777/IERC777Sender.sol"; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/README.adoc deleted file mode 100644 index b6b96ff..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/README.adoc +++ /dev/null @@ -1,50 +0,0 @@ -= Interfaces - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/interfaces - -== List of standardized interfaces -These interfaces are available as `.sol` files, and also as compiler `.json` ABI files (through the npm package). These -are useful to interact with third party contracts that implement them. - -- {IERC20} -- {IERC20Metadata} -- {IERC165} -- {IERC721} -- {IERC721Receiver} -- {IERC721Enumerable} -- {IERC721Metadata} -- {IERC777} -- {IERC777Recipient} -- {IERC777Sender} -- {IERC1155} -- {IERC1155Receiver} -- {IERC1155MetadataURI} -- {IERC1271} -- {IERC1363} -- {IERC1820Implementer} -- {IERC1820Registry} -- {IERC2612} -- {IERC2981} -- {IERC3156FlashLender} -- {IERC3156FlashBorrower} - -== Detailed ABI - -{{IERC1271}} - -{{IERC1363}} - -{{IERC1363Receiver}} - -{{IERC1820Implementer}} - -{{IERC1820Registry}} - -{{IERC2612}} - -{{IERC2981}} - -{{IERC3156FlashLender}} - -{{IERC3156FlashBorrower}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol deleted file mode 100644 index 3b73d74..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) - -pragma solidity ^0.8.0; - -/** - * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified - * proxy whose upgrades are fully controlled by the current implementation. - */ -interface IERC1822Proxiable { - /** - * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation - * address. - * - * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks - * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this - * function revert if invoked through a proxy. - */ - function proxiableUUID() external view returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC2612.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC2612.sol deleted file mode 100644 index 1b3ae55..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC2612.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (interfaces/draft-IERC2612.sol) - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/draft-IERC20Permit.sol"; - -interface IERC2612 is IERC20Permit {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol deleted file mode 100644 index 8cc14b9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol) - -pragma solidity ^0.8.9; - -import "../utils/Context.sol"; - -/** - * @dev Context variant with ERC2771 support. - */ -abstract contract ERC2771Context is Context { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address private immutable _trustedForwarder; - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address trustedForwarder) { - _trustedForwarder = trustedForwarder; - } - - function isTrustedForwarder(address forwarder) public view virtual returns (bool) { - return forwarder == _trustedForwarder; - } - - function _msgSender() internal view virtual override returns (address sender) { - if (isTrustedForwarder(msg.sender)) { - // The assembly code is more direct than the Solidity version using `abi.decode`. - /// @solidity memory-safe-assembly - assembly { - sender := shr(96, calldataload(sub(calldatasize(), 20))) - } - } else { - return super._msgSender(); - } - } - - function _msgData() internal view virtual override returns (bytes calldata) { - if (isTrustedForwarder(msg.sender)) { - return msg.data[:msg.data.length - 20]; - } else { - return super._msgData(); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/MinimalForwarder.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/MinimalForwarder.sol deleted file mode 100644 index 30b7c91..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/MinimalForwarder.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (metatx/MinimalForwarder.sol) - -pragma solidity ^0.8.0; - -import "../utils/cryptography/ECDSA.sol"; -import "../utils/cryptography/draft-EIP712.sol"; - -/** - * @dev Simple minimal forwarder to be used together with an ERC2771 compatible contract. See {ERC2771Context}. - * - * MinimalForwarder is mainly meant for testing, as it is missing features to be a good production-ready forwarder. This - * contract does not intend to have all the properties that are needed for a sound forwarding system. A fully - * functioning forwarding system with good properties requires more complexity. We suggest you look at other projects - * such as the GSN which do have the goal of building a system like that. - */ -contract MinimalForwarder is EIP712 { - using ECDSA for bytes32; - - struct ForwardRequest { - address from; - address to; - uint256 value; - uint256 gas; - uint256 nonce; - bytes data; - } - - bytes32 private constant _TYPEHASH = - keccak256("ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data)"); - - mapping(address => uint256) private _nonces; - - constructor() EIP712("MinimalForwarder", "0.0.1") {} - - function getNonce(address from) public view returns (uint256) { - return _nonces[from]; - } - - function verify(ForwardRequest calldata req, bytes calldata signature) public view returns (bool) { - address signer = _hashTypedDataV4( - keccak256(abi.encode(_TYPEHASH, req.from, req.to, req.value, req.gas, req.nonce, keccak256(req.data))) - ).recover(signature); - return _nonces[req.from] == req.nonce && signer == req.from; - } - - function execute(ForwardRequest calldata req, bytes calldata signature) - public - payable - returns (bool, bytes memory) - { - require(verify(req, signature), "MinimalForwarder: signature does not match request"); - _nonces[req.from] = req.nonce + 1; - - (bool success, bytes memory returndata) = req.to.call{gas: req.gas, value: req.value}( - abi.encodePacked(req.data, req.from) - ); - - // Validate that the relayer has sent enough gas for the call. - // See https://ronan.eth.link/blog/ethereum-gas-dangers/ - if (gasleft() <= req.gas / 63) { - // We explicitly trigger invalid opcode to consume all gas and bubble-up the effects, since - // neither revert or assert consume all gas since Solidity 0.8.0 - // https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require - /// @solidity memory-safe-assembly - assembly { - invalid() - } - } - - return (success, returndata); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/README.adoc deleted file mode 100644 index eccdeaf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/metatx/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= Meta Transactions - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/metatx - -== Core - -{{ERC2771Context}} - -== Utils - -{{MinimalForwarder}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlCrossChainMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlCrossChainMock.sol deleted file mode 100644 index 90adb74..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlCrossChainMock.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.4; - -import "../access/AccessControlCrossChain.sol"; -import "../crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol"; - -contract AccessControlCrossChainMock is AccessControlCrossChain, CrossChainEnabledArbitrumL2 { - constructor() { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public { - _setRoleAdmin(roleId, adminRoleId); - } - - function senderProtected(bytes32 roleId) public onlyRole(roleId) {} - - function crossChainRoleAlias(bytes32 role) public pure virtual returns (bytes32) { - return _crossChainRoleAlias(role); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlEnumerableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlEnumerableMock.sol deleted file mode 100644 index 7b15e36..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlEnumerableMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/AccessControlEnumerable.sol"; - -contract AccessControlEnumerableMock is AccessControlEnumerable { - constructor() { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public { - _setRoleAdmin(roleId, adminRoleId); - } - - function senderProtected(bytes32 roleId) public onlyRole(roleId) {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlMock.sol deleted file mode 100644 index 86f5147..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AccessControlMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/AccessControl.sol"; - -contract AccessControlMock is AccessControl { - constructor() { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - function setRoleAdmin(bytes32 roleId, bytes32 adminRoleId) public { - _setRoleAdmin(roleId, adminRoleId); - } - - function senderProtected(bytes32 roleId) public onlyRole(roleId) {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AddressImpl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AddressImpl.sol deleted file mode 100644 index 702093c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/AddressImpl.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Address.sol"; - -contract AddressImpl { - string public sharedAnswer; - - event CallReturnValue(string data); - - function isContract(address account) external view returns (bool) { - return Address.isContract(account); - } - - function sendValue(address payable receiver, uint256 amount) external { - Address.sendValue(receiver, amount); - } - - function functionCall(address target, bytes calldata data) external { - bytes memory returnData = Address.functionCall(target, data); - emit CallReturnValue(abi.decode(returnData, (string))); - } - - function functionCallWithValue( - address target, - bytes calldata data, - uint256 value - ) external payable { - bytes memory returnData = Address.functionCallWithValue(target, data, value); - emit CallReturnValue(abi.decode(returnData, (string))); - } - - function functionStaticCall(address target, bytes calldata data) external { - bytes memory returnData = Address.functionStaticCall(target, data); - emit CallReturnValue(abi.decode(returnData, (string))); - } - - function functionDelegateCall(address target, bytes calldata data) external { - bytes memory returnData = Address.functionDelegateCall(target, data); - emit CallReturnValue(abi.decode(returnData, (string))); - } - - // sendValue's tests require the contract to hold Ether - receive() external payable {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ArraysImpl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ArraysImpl.sol deleted file mode 100644 index f720524..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ArraysImpl.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Arrays.sol"; - -contract ArraysImpl { - using Arrays for uint256[]; - - uint256[] private _array; - - constructor(uint256[] memory array) { - _array = array; - } - - function findUpperBound(uint256 element) external view returns (uint256) { - return _array.findUpperBound(element); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/BadBeacon.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/BadBeacon.sol deleted file mode 100644 index bedcfed..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/BadBeacon.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -contract BadBeaconNoImpl {} - -contract BadBeaconNotContract { - function implementation() external pure returns (address) { - return address(0x1); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/Base64Mock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/Base64Mock.sol deleted file mode 100644 index b255487..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/Base64Mock.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Base64.sol"; - -contract Base64Mock { - function encode(bytes memory value) external pure returns (string memory) { - return Base64.encode(value); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/BitmapMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/BitmapMock.sol deleted file mode 100644 index ccf8486..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/BitmapMock.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/structs/BitMaps.sol"; - -contract BitMapMock { - using BitMaps for BitMaps.BitMap; - - BitMaps.BitMap private _bitmap; - - function get(uint256 index) public view returns (bool) { - return _bitmap.get(index); - } - - function setTo(uint256 index, bool value) public { - _bitmap.setTo(index, value); - } - - function set(uint256 index) public { - _bitmap.set(index); - } - - function unset(uint256 index) public { - _bitmap.unset(index); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol deleted file mode 100644 index 926db68..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -contract CallReceiverMock { - string public sharedAnswer; - - event MockFunctionCalled(); - event MockFunctionCalledWithArgs(uint256 a, uint256 b); - - uint256[] private _array; - - function mockFunction() public payable returns (string memory) { - emit MockFunctionCalled(); - - return "0x1234"; - } - - function mockFunctionWithArgs(uint256 a, uint256 b) public payable returns (string memory) { - emit MockFunctionCalledWithArgs(a, b); - - return "0x1234"; - } - - function mockFunctionNonPayable() public returns (string memory) { - emit MockFunctionCalled(); - - return "0x1234"; - } - - function mockStaticFunction() public pure returns (string memory) { - return "0x1234"; - } - - function mockFunctionRevertsNoReason() public payable { - revert(); - } - - function mockFunctionRevertsReason() public payable { - revert("CallReceiverMock: reverting"); - } - - function mockFunctionThrows() public payable { - assert(false); - } - - function mockFunctionOutOfGas() public payable { - for (uint256 i = 0; ; ++i) { - _array.push(i); - } - } - - function mockFunctionWritesStorage() public returns (string memory) { - sharedAnswer = "42"; - return "0x1234"; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CheckpointsImpl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CheckpointsImpl.sol deleted file mode 100644 index 14681ca..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CheckpointsImpl.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Checkpoints.sol"; - -contract CheckpointsImpl { - using Checkpoints for Checkpoints.History; - - Checkpoints.History private _totalCheckpoints; - - function latest() public view returns (uint256) { - return _totalCheckpoints.latest(); - } - - function getAtBlock(uint256 blockNumber) public view returns (uint256) { - return _totalCheckpoints.getAtBlock(blockNumber); - } - - function push(uint256 value) public returns (uint256, uint256) { - return _totalCheckpoints.push(value); - } - - function length() public view returns (uint256) { - return _totalCheckpoints._checkpoints.length; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ClashingImplementation.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ClashingImplementation.sol deleted file mode 100644 index 80aca0c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ClashingImplementation.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -/** - * @dev Implementation contract with an admin() function made to clash with - * @dev TransparentUpgradeableProxy's to test correct functioning of the - * @dev Transparent Proxy feature. - */ -contract ClashingImplementation { - function admin() external pure returns (address) { - return 0x0000000000000000000000000000000011111142; - } - - function delegatedFunction() external pure returns (bool) { - return true; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ClonesMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ClonesMock.sol deleted file mode 100644 index 3719b0a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ClonesMock.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/Clones.sol"; -import "../utils/Address.sol"; - -contract ClonesMock { - using Address for address; - using Clones for address; - - event NewInstance(address instance); - - function clone(address implementation, bytes calldata initdata) public payable { - _initAndEmit(implementation.clone(), initdata); - } - - function cloneDeterministic( - address implementation, - bytes32 salt, - bytes calldata initdata - ) public payable { - _initAndEmit(implementation.cloneDeterministic(salt), initdata); - } - - function predictDeterministicAddress(address implementation, bytes32 salt) public view returns (address predicted) { - return implementation.predictDeterministicAddress(salt); - } - - function _initAndEmit(address instance, bytes memory initdata) private { - if (initdata.length > 0) { - instance.functionCallWithValue(initdata, msg.value); - } - emit NewInstance(instance); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ConditionalEscrowMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ConditionalEscrowMock.sol deleted file mode 100644 index ececf05..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ConditionalEscrowMock.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/escrow/ConditionalEscrow.sol"; - -// mock class using ConditionalEscrow -contract ConditionalEscrowMock is ConditionalEscrow { - mapping(address => bool) private _allowed; - - function setAllowed(address payee, bool allowed) public { - _allowed[payee] = allowed; - } - - function withdrawalAllowed(address payee) public view override returns (bool) { - return _allowed[payee]; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol deleted file mode 100644 index f17af38..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ContextMock.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Context.sol"; - -contract ContextMock is Context { - event Sender(address sender); - - function msgSender() public { - emit Sender(_msgSender()); - } - - event Data(bytes data, uint256 integerValue, string stringValue); - - function msgData(uint256 integerValue, string memory stringValue) public { - emit Data(_msgData(), integerValue, stringValue); - } -} - -contract ContextMockCaller { - function callSender(ContextMock context) public { - context.msgSender(); - } - - function callData( - ContextMock context, - uint256 integerValue, - string memory stringValue - ) public { - context.msgData(integerValue, stringValue); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CountersImpl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CountersImpl.sol deleted file mode 100644 index 651b50b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/CountersImpl.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Counters.sol"; - -contract CountersImpl { - using Counters for Counters.Counter; - - Counters.Counter private _counter; - - function current() public view returns (uint256) { - return _counter.current(); - } - - function increment() public { - _counter.increment(); - } - - function decrement() public { - _counter.decrement(); - } - - function reset() public { - _counter.reset(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/Create2Impl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/Create2Impl.sol deleted file mode 100644 index 070ad36..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/Create2Impl.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Create2.sol"; -import "../utils/introspection/ERC1820Implementer.sol"; - -contract Create2Impl { - function deploy( - uint256 value, - bytes32 salt, - bytes memory code - ) public { - Create2.deploy(value, salt, code); - } - - function deployERC1820Implementer(uint256 value, bytes32 salt) public { - Create2.deploy(value, salt, type(ERC1820Implementer).creationCode); - } - - function computeAddress(bytes32 salt, bytes32 codeHash) public view returns (address) { - return Create2.computeAddress(salt, codeHash); - } - - function computeAddressWithDeployer( - bytes32 salt, - bytes32 codeHash, - address deployer - ) public pure returns (address) { - return Create2.computeAddress(salt, codeHash, deployer); - } - - receive() external payable {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/DoubleEndedQueueMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/DoubleEndedQueueMock.sol deleted file mode 100644 index a9436b0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/DoubleEndedQueueMock.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/structs/DoubleEndedQueue.sol"; - -// Bytes32Deque -contract Bytes32DequeMock { - using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; - - event OperationResult(bytes32 value); - - DoubleEndedQueue.Bytes32Deque private _vector; - - function pushBack(bytes32 value) public { - _vector.pushBack(value); - } - - function pushFront(bytes32 value) public { - _vector.pushFront(value); - } - - function popFront() public returns (bytes32) { - bytes32 value = _vector.popFront(); - emit OperationResult(value); - return value; - } - - function popBack() public returns (bytes32) { - bytes32 value = _vector.popBack(); - emit OperationResult(value); - return value; - } - - function front() public view returns (bytes32) { - return _vector.front(); - } - - function back() public view returns (bytes32) { - return _vector.back(); - } - - function at(uint256 i) public view returns (bytes32) { - return _vector.at(i); - } - - function clear() public { - _vector.clear(); - } - - function length() public view returns (uint256) { - return _vector.length(); - } - - function empty() public view returns (bool) { - return _vector.empty(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol deleted file mode 100644 index d865134..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -abstract contract Impl { - function version() public pure virtual returns (string memory); -} - -contract DummyImplementation { - uint256 public value; - string public text; - uint256[] public values; - - function initializeNonPayable() public { - value = 10; - } - - function initializePayable() public payable { - value = 100; - } - - function initializeNonPayableWithValue(uint256 _value) public { - value = _value; - } - - function initializePayableWithValue(uint256 _value) public payable { - value = _value; - } - - function initialize( - uint256 _value, - string memory _text, - uint256[] memory _values - ) public { - value = _value; - text = _text; - values = _values; - } - - function get() public pure returns (bool) { - return true; - } - - function version() public pure virtual returns (string memory) { - return "V1"; - } - - function reverts() public pure { - require(false, "DummyImplementation reverted"); - } -} - -contract DummyImplementationV2 is DummyImplementation { - function migrate(uint256 newVal) public payable { - value = newVal; - } - - function version() public pure override returns (string memory) { - return "V2"; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ECDSAMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ECDSAMock.sol deleted file mode 100644 index 97bd466..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ECDSAMock.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/cryptography/ECDSA.sol"; - -contract ECDSAMock { - using ECDSA for bytes32; - using ECDSA for bytes; - - function recover(bytes32 hash, bytes memory signature) public pure returns (address) { - return hash.recover(signature); - } - - // solhint-disable-next-line func-name-mixedcase - function recover_v_r_s( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) public pure returns (address) { - return hash.recover(v, r, s); - } - - // solhint-disable-next-line func-name-mixedcase - function recover_r_vs( - bytes32 hash, - bytes32 r, - bytes32 vs - ) public pure returns (address) { - return hash.recover(r, vs); - } - - function toEthSignedMessageHash(bytes32 hash) public pure returns (bytes32) { - return hash.toEthSignedMessageHash(); - } - - function toEthSignedMessageHash(bytes memory s) public pure returns (bytes32) { - return s.toEthSignedMessageHash(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EIP712External.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EIP712External.sol deleted file mode 100644 index 6f24469..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EIP712External.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/cryptography/draft-EIP712.sol"; -import "../utils/cryptography/ECDSA.sol"; - -contract EIP712External is EIP712 { - constructor(string memory name, string memory version) EIP712(name, version) {} - - function domainSeparator() external view returns (bytes32) { - return _domainSeparatorV4(); - } - - function verify( - bytes memory signature, - address signer, - address mailTo, - string memory mailContents - ) external view { - bytes32 digest = _hashTypedDataV4( - keccak256(abi.encode(keccak256("Mail(address to,string contents)"), mailTo, keccak256(bytes(mailContents)))) - ); - address recoveredSigner = ECDSA.recover(digest, signature); - require(recoveredSigner == signer); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155BurnableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155BurnableMock.sol deleted file mode 100644 index 62138f2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155BurnableMock.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC1155/extensions/ERC1155Burnable.sol"; - -contract ERC1155BurnableMock is ERC1155Burnable { - constructor(string memory uri) ERC1155(uri) {} - - function mint( - address to, - uint256 id, - uint256 value, - bytes memory data - ) public { - _mint(to, id, value, data); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155Mock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155Mock.sol deleted file mode 100644 index 0518ac2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155Mock.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC1155/ERC1155.sol"; - -/** - * @title ERC1155Mock - * This mock just publicizes internal functions for testing purposes - */ -contract ERC1155Mock is ERC1155 { - constructor(string memory uri) ERC1155(uri) {} - - function setURI(string memory newuri) public { - _setURI(newuri); - } - - function mint( - address to, - uint256 id, - uint256 value, - bytes memory data - ) public { - _mint(to, id, value, data); - } - - function mintBatch( - address to, - uint256[] memory ids, - uint256[] memory values, - bytes memory data - ) public { - _mintBatch(to, ids, values, data); - } - - function burn( - address owner, - uint256 id, - uint256 value - ) public { - _burn(owner, id, value); - } - - function burnBatch( - address owner, - uint256[] memory ids, - uint256[] memory values - ) public { - _burnBatch(owner, ids, values); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155PausableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155PausableMock.sol deleted file mode 100644 index b1a4a8e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155PausableMock.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./ERC1155Mock.sol"; -import "../token/ERC1155/extensions/ERC1155Pausable.sol"; - -contract ERC1155PausableMock is ERC1155Mock, ERC1155Pausable { - constructor(string memory uri) ERC1155Mock(uri) {} - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual override(ERC1155, ERC1155Pausable) { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155ReceiverMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155ReceiverMock.sol deleted file mode 100644 index 6443a56..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155ReceiverMock.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC1155/IERC1155Receiver.sol"; -import "../utils/introspection/ERC165.sol"; - -contract ERC1155ReceiverMock is ERC165, IERC1155Receiver { - bytes4 private _recRetval; - bool private _recReverts; - bytes4 private _batRetval; - bool private _batReverts; - - event Received(address operator, address from, uint256 id, uint256 value, bytes data, uint256 gas); - event BatchReceived(address operator, address from, uint256[] ids, uint256[] values, bytes data, uint256 gas); - - constructor( - bytes4 recRetval, - bool recReverts, - bytes4 batRetval, - bool batReverts - ) { - _recRetval = recRetval; - _recReverts = recReverts; - _batRetval = batRetval; - _batReverts = batReverts; - } - - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) external override returns (bytes4) { - require(!_recReverts, "ERC1155ReceiverMock: reverting on receive"); - emit Received(operator, from, id, value, data, gasleft()); - return _recRetval; - } - - function onERC1155BatchReceived( - address operator, - address from, - uint256[] calldata ids, - uint256[] calldata values, - bytes calldata data - ) external override returns (bytes4) { - require(!_batReverts, "ERC1155ReceiverMock: reverting on batch receive"); - emit BatchReceived(operator, from, ids, values, data, gasleft()); - return _batRetval; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155SupplyMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155SupplyMock.sol deleted file mode 100644 index 44b2080..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155SupplyMock.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./ERC1155Mock.sol"; -import "../token/ERC1155/extensions/ERC1155Supply.sol"; - -contract ERC1155SupplyMock is ERC1155Mock, ERC1155Supply { - constructor(string memory uri) ERC1155Mock(uri) {} - - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual override(ERC1155, ERC1155Supply) { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155URIStorageMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155URIStorageMock.sol deleted file mode 100644 index e3cbce4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1155URIStorageMock.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./ERC1155Mock.sol"; -import "../token/ERC1155/extensions/ERC1155URIStorage.sol"; - -contract ERC1155URIStorageMock is ERC1155Mock, ERC1155URIStorage { - constructor(string memory _uri) ERC1155Mock(_uri) {} - - function uri(uint256 tokenId) public view virtual override(ERC1155, ERC1155URIStorage) returns (string memory) { - return ERC1155URIStorage.uri(tokenId); - } - - function setURI(uint256 tokenId, string memory _tokenURI) public { - _setURI(tokenId, _tokenURI); - } - - function setBaseURI(string memory baseURI) public { - _setBaseURI(baseURI); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol deleted file mode 100644 index 0152889..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/Ownable.sol"; -import "../interfaces/IERC1271.sol"; -import "../utils/cryptography/ECDSA.sol"; - -contract ERC1271WalletMock is Ownable, IERC1271 { - constructor(address originalOwner) { - transferOwnership(originalOwner); - } - - function isValidSignature(bytes32 hash, bytes memory signature) public view override returns (bytes4 magicValue) { - return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0); - } -} - -contract ERC1271MaliciousMock is IERC1271 { - function isValidSignature(bytes32, bytes memory) public pure override returns (bytes4) { - assembly { - mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - return(0, 32) - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol deleted file mode 100644 index 7a5e5bc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165.sol"; - -/** - * https://eips.ethereum.org/EIPS/eip-214#specification - * From the specification: - * > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead - * throw an exception. - * > These operations include [...], LOG0, LOG1, LOG2, [...] - * - * therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works) - * solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it - */ -contract SupportsInterfaceWithLookupMock is IERC165 { - /* - * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 - */ - bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7; - - /** - * @dev A mapping of interface id to whether or not it's supported. - */ - mapping(bytes4 => bool) private _supportedInterfaces; - - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implement ERC165 itself. - */ - constructor() { - _registerInterface(INTERFACE_ID_ERC165); - } - - /** - * @dev Implement supportsInterface(bytes4) using a lookup table. - */ - function supportsInterface(bytes4 interfaceId) public view override returns (bool) { - return _supportedInterfaces[interfaceId]; - } - - /** - * @dev Private method for registering an interface. - */ - function _registerInterface(bytes4 interfaceId) internal { - require(interfaceId != 0xffffffff, "ERC165InterfacesSupported: invalid interface id"); - _supportedInterfaces[interfaceId] = true; - } -} - -contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock { - constructor(bytes4[] memory interfaceIds) { - for (uint256 i = 0; i < interfaceIds.length; i++) { - _registerInterface(interfaceIds[i]); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol deleted file mode 100644 index 40b6f98..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -contract ERC165MaliciousData { - function supportsInterface(bytes4) public view returns (bool) { - assembly { - mstore(0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - return(0, 32) - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol deleted file mode 100644 index 59cd51a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -contract ERC165MissingData { - function supportsInterface(bytes4 interfaceId) public view {} // missing return -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol deleted file mode 100644 index 486c7f0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sol +++ /dev/null @@ -1,5 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -contract ERC165NotSupported {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165CheckerMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165CheckerMock.sol deleted file mode 100644 index 9ff7e7d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165CheckerMock.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165Checker.sol"; - -contract ERC165CheckerMock { - using ERC165Checker for address; - - function supportsERC165(address account) public view returns (bool) { - return account.supportsERC165(); - } - - function supportsInterface(address account, bytes4 interfaceId) public view returns (bool) { - return account.supportsInterface(interfaceId); - } - - function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) { - return account.supportsAllInterfaces(interfaceIds); - } - - function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool[] memory) { - return account.getSupportedInterfaces(interfaceIds); - } - - function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) public view returns (bool) { - return account.supportsERC165InterfaceUnchecked(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165Mock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165Mock.sol deleted file mode 100644 index c123d0a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165Mock.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165.sol"; - -contract ERC165Mock is ERC165 {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165StorageMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165StorageMock.sol deleted file mode 100644 index 4b0bae9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC165StorageMock.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC165Storage.sol"; - -contract ERC165StorageMock is ERC165Storage { - function registerInterface(bytes4 interfaceId) public { - _registerInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1820ImplementerMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1820ImplementerMock.sol deleted file mode 100644 index a6012d7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC1820ImplementerMock.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/introspection/ERC1820Implementer.sol"; - -contract ERC1820ImplementerMock is ERC1820Implementer { - function registerInterfaceForAddress(bytes32 interfaceHash, address account) public { - _registerInterfaceForAddress(interfaceHash, account); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20BurnableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20BurnableMock.sol deleted file mode 100644 index 0ed6c0c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20BurnableMock.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20Burnable.sol"; - -contract ERC20BurnableMock is ERC20Burnable { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) ERC20(name, symbol) { - _mint(initialAccount, initialBalance); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20CappedMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20CappedMock.sol deleted file mode 100644 index edb36f2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20CappedMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20Capped.sol"; - -contract ERC20CappedMock is ERC20Capped { - constructor( - string memory name, - string memory symbol, - uint256 cap - ) ERC20(name, symbol) ERC20Capped(cap) {} - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20DecimalsMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20DecimalsMock.sol deleted file mode 100644 index 1374cbc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20DecimalsMock.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/ERC20.sol"; - -contract ERC20DecimalsMock is ERC20 { - uint8 private immutable _decimals; - - constructor( - string memory name_, - string memory symbol_, - uint8 decimals_ - ) ERC20(name_, symbol_) { - _decimals = decimals_; - } - - function decimals() public view virtual override returns (uint8) { - return _decimals; - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20FlashMintMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20FlashMintMock.sol deleted file mode 100644 index c777260..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20FlashMintMock.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20FlashMint.sol"; - -contract ERC20FlashMintMock is ERC20FlashMint { - uint256 _flashFeeAmount; - address _flashFeeReceiverAddress; - - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) ERC20(name, symbol) { - _mint(initialAccount, initialBalance); - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function setFlashFee(uint256 amount) public { - _flashFeeAmount = amount; - } - - function flashFee(address token, uint256 amount) public view virtual override returns (uint256) { - super.flashFee(token, amount); - return _flashFeeAmount; - } - - function setFlashFeeReceiver(address receiver) public { - _flashFeeReceiverAddress = receiver; - } - - function flashFeeReceiver() public view returns (address) { - return _flashFeeReceiver(); - } - - function _flashFeeReceiver() internal view override returns (address) { - return _flashFeeReceiverAddress; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20Mock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20Mock.sol deleted file mode 100644 index fd7f991..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20Mock.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/ERC20.sol"; - -// mock class using ERC20 -contract ERC20Mock is ERC20 { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) payable ERC20(name, symbol) { - _mint(initialAccount, initialBalance); - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - function transferInternal( - address from, - address to, - uint256 value - ) public { - _transfer(from, to, value); - } - - function approveInternal( - address owner, - address spender, - uint256 value - ) public { - _approve(owner, spender, value); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20PausableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20PausableMock.sol deleted file mode 100644 index 19160ba..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20PausableMock.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20Pausable.sol"; - -// mock class using ERC20Pausable -contract ERC20PausableMock is ERC20Pausable { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) ERC20(name, symbol) { - _mint(initialAccount, initialBalance); - } - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - function mint(address to, uint256 amount) public { - _mint(to, amount); - } - - function burn(address from, uint256 amount) public { - _burn(from, amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20PermitMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20PermitMock.sol deleted file mode 100644 index 20302bf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20PermitMock.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/draft-ERC20Permit.sol"; - -contract ERC20PermitMock is ERC20Permit { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) payable ERC20(name, symbol) ERC20Permit(name) { - _mint(initialAccount, initialBalance); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20SnapshotMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20SnapshotMock.sol deleted file mode 100644 index cb30483..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20SnapshotMock.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20Snapshot.sol"; - -contract ERC20SnapshotMock is ERC20Snapshot { - constructor( - string memory name, - string memory symbol, - address initialAccount, - uint256 initialBalance - ) ERC20(name, symbol) { - _mint(initialAccount, initialBalance); - } - - function snapshot() public { - _snapshot(); - } - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesCompMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesCompMock.sol deleted file mode 100644 index 171071f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesCompMock.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20VotesComp.sol"; - -contract ERC20VotesCompMock is ERC20VotesComp { - constructor(string memory name, string memory symbol) ERC20(name, symbol) ERC20Permit(name) {} - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesMock.sol deleted file mode 100644 index 0975e8b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20VotesMock.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20Votes.sol"; - -contract ERC20VotesMock is ERC20Votes { - constructor(string memory name, string memory symbol) ERC20(name, symbol) ERC20Permit(name) {} - - function mint(address account, uint256 amount) public { - _mint(account, amount); - } - - function burn(address account, uint256 amount) public { - _burn(account, amount); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20WrapperMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20WrapperMock.sol deleted file mode 100644 index cf34a7a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC20WrapperMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC20Wrapper.sol"; - -contract ERC20WrapperMock is ERC20Wrapper { - constructor( - IERC20 _underlyingToken, - string memory name, - string memory symbol - ) ERC20(name, symbol) ERC20Wrapper(_underlyingToken) {} - - function recover(address account) public returns (uint256) { - return _recover(account); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol deleted file mode 100644 index ee111d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.9; - -import "./ContextMock.sol"; -import "../metatx/ERC2771Context.sol"; - -// By inheriting from ERC2771Context, Context's internal functions are overridden automatically -contract ERC2771ContextMock is ContextMock, ERC2771Context { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address trustedForwarder) ERC2771Context(trustedForwarder) { - emit Sender(_msgSender()); // _msgSender() should be accessible during construction - } - - function _msgSender() internal view virtual override(Context, ERC2771Context) returns (address) { - return ERC2771Context._msgSender(); - } - - function _msgData() internal view virtual override(Context, ERC2771Context) returns (bytes calldata) { - return ERC2771Context._msgData(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol deleted file mode 100644 index 288a278..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/IERC20.sol"; -import "../interfaces/IERC3156.sol"; -import "../utils/Address.sol"; - -/** - * @dev WARNING: this IERC3156FlashBorrower mock implementation is for testing purposes ONLY. - * Writing a secure flash lock borrower is not an easy task, and should be done with the utmost care. - * This is not an example of how it should be done, and no pattern present in this mock should be considered secure. - * Following best practices, always have your contract properly audited before using them to manipulate important funds on - * live networks. - */ -contract ERC3156FlashBorrowerMock is IERC3156FlashBorrower { - bytes32 internal constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan"); - - bool immutable _enableApprove; - bool immutable _enableReturn; - - event BalanceOf(address token, address account, uint256 value); - event TotalSupply(address token, uint256 value); - - constructor(bool enableReturn, bool enableApprove) { - _enableApprove = enableApprove; - _enableReturn = enableReturn; - } - - function onFlashLoan( - address, /*initiator*/ - address token, - uint256 amount, - uint256 fee, - bytes calldata data - ) public override returns (bytes32) { - require(msg.sender == token); - - emit BalanceOf(token, address(this), IERC20(token).balanceOf(address(this))); - emit TotalSupply(token, IERC20(token).totalSupply()); - - if (data.length > 0) { - // WARNING: This code is for testing purposes only! Do not use. - Address.functionCall(token, data); - } - - if (_enableApprove) { - IERC20(token).approve(token, amount + fee); - } - - return _enableReturn ? _RETURN_VALUE : bytes32(0); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC4626Mock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC4626Mock.sol deleted file mode 100644 index 71cefac..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC4626Mock.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC20/extensions/ERC4626.sol"; - -// mock class using ERC20 -contract ERC4626Mock is ERC4626 { - constructor( - IERC20Metadata asset, - string memory name, - string memory symbol - ) ERC20(name, symbol) ERC4626(asset) {} - - function mockMint(address account, uint256 amount) public { - _mint(account, amount); - } - - function mockBurn(address account, uint256 amount) public { - _burn(account, amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721BurnableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721BurnableMock.sol deleted file mode 100644 index b30dbf5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721BurnableMock.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721Burnable.sol"; - -contract ERC721BurnableMock is ERC721Burnable { - constructor(string memory name, string memory symbol) ERC721(name, symbol) {} - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721EnumerableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721EnumerableMock.sol deleted file mode 100644 index 73aee9d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721EnumerableMock.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721Enumerable.sol"; - -/** - * @title ERC721Mock - * This mock just provides a public safeMint, mint, and burn functions for testing purposes - */ -contract ERC721EnumerableMock is ERC721Enumerable { - string private _baseTokenURI; - - constructor(string memory name, string memory symbol) ERC721(name, symbol) {} - - function _baseURI() internal view virtual override returns (string memory) { - return _baseTokenURI; - } - - function setBaseURI(string calldata newBaseTokenURI) public { - _baseTokenURI = newBaseTokenURI; - } - - function baseURI() public view returns (string memory) { - return _baseURI(); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721Mock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721Mock.sol deleted file mode 100644 index 74a0923..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721Mock.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/ERC721.sol"; - -/** - * @title ERC721Mock - * This mock just provides a public safeMint, mint, and burn functions for testing purposes - */ -contract ERC721Mock is ERC721 { - constructor(string memory name, string memory symbol) ERC721(name, symbol) {} - - function baseURI() public view returns (string memory) { - return _baseURI(); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721PausableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721PausableMock.sol deleted file mode 100644 index 8d8e818..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721PausableMock.sol +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721Pausable.sol"; - -/** - * @title ERC721PausableMock - * This mock just provides a public mint, burn and exists functions for testing purposes - */ -contract ERC721PausableMock is ERC721Pausable { - constructor(string memory name, string memory symbol) ERC721(name, symbol) {} - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721ReceiverMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721ReceiverMock.sol deleted file mode 100644 index a4923bf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721ReceiverMock.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/IERC721Receiver.sol"; - -contract ERC721ReceiverMock is IERC721Receiver { - enum Error { - None, - RevertWithMessage, - RevertWithoutMessage, - Panic - } - - bytes4 private immutable _retval; - Error private immutable _error; - - event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas); - - constructor(bytes4 retval, Error error) { - _retval = retval; - _error = error; - } - - function onERC721Received( - address operator, - address from, - uint256 tokenId, - bytes memory data - ) public override returns (bytes4) { - if (_error == Error.RevertWithMessage) { - revert("ERC721ReceiverMock: reverting"); - } else if (_error == Error.RevertWithoutMessage) { - revert(); - } else if (_error == Error.Panic) { - uint256 a = uint256(0) / uint256(0); - a; - } - emit Received(operator, from, tokenId, data, gasleft()); - return _retval; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721RoyaltyMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721RoyaltyMock.sol deleted file mode 100644 index 83a9074..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721RoyaltyMock.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721Royalty.sol"; - -contract ERC721RoyaltyMock is ERC721Royalty { - constructor(string memory name, string memory symbol) ERC721(name, symbol) {} - - function setTokenRoyalty( - uint256 tokenId, - address recipient, - uint96 fraction - ) public { - _setTokenRoyalty(tokenId, recipient, fraction); - } - - function setDefaultRoyalty(address recipient, uint96 fraction) public { - _setDefaultRoyalty(recipient, fraction); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } - - function deleteDefaultRoyalty() public { - _deleteDefaultRoyalty(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721URIStorageMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721URIStorageMock.sol deleted file mode 100644 index 9c3480f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721URIStorageMock.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/ERC721URIStorage.sol"; - -/** - * @title ERC721Mock - * This mock just provides a public safeMint, mint, and burn functions for testing purposes - */ -contract ERC721URIStorageMock is ERC721URIStorage { - string private _baseTokenURI; - - constructor(string memory name, string memory symbol) ERC721(name, symbol) {} - - function _baseURI() internal view virtual override returns (string memory) { - return _baseTokenURI; - } - - function setBaseURI(string calldata newBaseTokenURI) public { - _baseTokenURI = newBaseTokenURI; - } - - function baseURI() public view returns (string memory) { - return _baseURI(); - } - - function setTokenURI(uint256 tokenId, string memory _tokenURI) public { - _setTokenURI(tokenId, _tokenURI); - } - - function exists(uint256 tokenId) public view returns (bool) { - return _exists(tokenId); - } - - function mint(address to, uint256 tokenId) public { - _mint(to, tokenId); - } - - function safeMint(address to, uint256 tokenId) public { - _safeMint(to, tokenId); - } - - function safeMint( - address to, - uint256 tokenId, - bytes memory _data - ) public { - _safeMint(to, tokenId, _data); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721VotesMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721VotesMock.sol deleted file mode 100644 index 0755ace..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC721VotesMock.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC721/extensions/draft-ERC721Votes.sol"; - -contract ERC721VotesMock is ERC721Votes { - constructor(string memory name, string memory symbol) ERC721(name, symbol) EIP712(name, "1") {} - - function getTotalSupply() public view returns (uint256) { - return _getTotalSupply(); - } - - function mint(address account, uint256 tokenId) public { - _mint(account, tokenId); - } - - function burn(uint256 tokenId) public { - _burn(tokenId); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC777Mock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC777Mock.sol deleted file mode 100644 index f8a3b67..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC777Mock.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Context.sol"; -import "../token/ERC777/ERC777.sol"; - -contract ERC777Mock is Context, ERC777 { - event BeforeTokenTransfer(); - - constructor( - address initialHolder, - uint256 initialBalance, - string memory name, - string memory symbol, - address[] memory defaultOperators - ) ERC777(name, symbol, defaultOperators) { - _mint(initialHolder, initialBalance, "", ""); - } - - function mintInternal( - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) public { - _mint(to, amount, userData, operatorData); - } - - function mintInternalExtended( - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData, - bool requireReceptionAck - ) public { - _mint(to, amount, userData, operatorData, requireReceptionAck); - } - - function approveInternal( - address holder, - address spender, - uint256 value - ) public { - _approve(holder, spender, value); - } - - function _beforeTokenTransfer( - address, - address, - address, - uint256 - ) internal override { - emit BeforeTokenTransfer(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC777SenderRecipientMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC777SenderRecipientMock.sol deleted file mode 100644 index 169912f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ERC777SenderRecipientMock.sol +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../token/ERC777/IERC777.sol"; -import "../token/ERC777/IERC777Sender.sol"; -import "../token/ERC777/IERC777Recipient.sol"; -import "../utils/Context.sol"; -import "../utils/introspection/IERC1820Registry.sol"; -import "../utils/introspection/ERC1820Implementer.sol"; - -contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient, ERC1820Implementer { - event TokensToSendCalled( - address operator, - address from, - address to, - uint256 amount, - bytes data, - bytes operatorData, - address token, - uint256 fromBalance, - uint256 toBalance - ); - - event TokensReceivedCalled( - address operator, - address from, - address to, - uint256 amount, - bytes data, - bytes operatorData, - address token, - uint256 fromBalance, - uint256 toBalance - ); - - // Emitted in ERC777Mock. Here for easier decoding - event BeforeTokenTransfer(); - - bool private _shouldRevertSend; - bool private _shouldRevertReceive; - - IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); - - bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender"); - bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); - - function tokensToSend( - address operator, - address from, - address to, - uint256 amount, - bytes calldata userData, - bytes calldata operatorData - ) external override { - if (_shouldRevertSend) { - revert(); - } - - IERC777 token = IERC777(_msgSender()); - - uint256 fromBalance = token.balanceOf(from); - // when called due to burn, to will be the zero address, which will have a balance of 0 - uint256 toBalance = token.balanceOf(to); - - emit TokensToSendCalled( - operator, - from, - to, - amount, - userData, - operatorData, - address(token), - fromBalance, - toBalance - ); - } - - function tokensReceived( - address operator, - address from, - address to, - uint256 amount, - bytes calldata userData, - bytes calldata operatorData - ) external override { - if (_shouldRevertReceive) { - revert(); - } - - IERC777 token = IERC777(_msgSender()); - - uint256 fromBalance = token.balanceOf(from); - // when called due to burn, to will be the zero address, which will have a balance of 0 - uint256 toBalance = token.balanceOf(to); - - emit TokensReceivedCalled( - operator, - from, - to, - amount, - userData, - operatorData, - address(token), - fromBalance, - toBalance - ); - } - - function senderFor(address account) public { - _registerInterfaceForAddress(_TOKENS_SENDER_INTERFACE_HASH, account); - - address self = address(this); - if (account == self) { - registerSender(self); - } - } - - function registerSender(address sender) public { - _erc1820.setInterfaceImplementer(address(this), _TOKENS_SENDER_INTERFACE_HASH, sender); - } - - function recipientFor(address account) public { - _registerInterfaceForAddress(_TOKENS_RECIPIENT_INTERFACE_HASH, account); - - address self = address(this); - if (account == self) { - registerRecipient(self); - } - } - - function registerRecipient(address recipient) public { - _erc1820.setInterfaceImplementer(address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, recipient); - } - - function setShouldRevertSend(bool shouldRevert) public { - _shouldRevertSend = shouldRevert; - } - - function setShouldRevertReceive(bool shouldRevert) public { - _shouldRevertReceive = shouldRevert; - } - - function send( - IERC777 token, - address to, - uint256 amount, - bytes memory data - ) public { - // This is 777's send function, not the Solidity send function - token.send(to, amount, data); // solhint-disable-line check-send-result - } - - function burn( - IERC777 token, - uint256 amount, - bytes memory data - ) public { - token.burn(amount, data); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EnumerableMapMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EnumerableMapMock.sol deleted file mode 100644 index dbdf2b2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EnumerableMapMock.sol +++ /dev/null @@ -1,219 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/structs/EnumerableMap.sol"; - -// UintToAddressMap -contract UintToAddressMapMock { - using EnumerableMap for EnumerableMap.UintToAddressMap; - - event OperationResult(bool result); - - EnumerableMap.UintToAddressMap private _map; - - function contains(uint256 key) public view returns (bool) { - return _map.contains(key); - } - - function set(uint256 key, address value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(uint256 key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (uint256 key, address value) { - return _map.at(index); - } - - function tryGet(uint256 key) public view returns (bool, address) { - return _map.tryGet(key); - } - - function get(uint256 key) public view returns (address) { - return _map.get(key); - } - - function getWithMessage(uint256 key, string calldata errorMessage) public view returns (address) { - return _map.get(key, errorMessage); - } -} - -// AddressToUintMap -contract AddressToUintMapMock { - using EnumerableMap for EnumerableMap.AddressToUintMap; - - event OperationResult(bool result); - - EnumerableMap.AddressToUintMap private _map; - - function contains(address key) public view returns (bool) { - return _map.contains(key); - } - - function set(address key, uint256 value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(address key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (address key, uint256 value) { - return _map.at(index); - } - - function tryGet(address key) public view returns (bool, uint256) { - return _map.tryGet(key); - } - - function get(address key) public view returns (uint256) { - return _map.get(key); - } - - function getWithMessage(address key, string calldata errorMessage) public view returns (uint256) { - return _map.get(key, errorMessage); - } -} - -contract Bytes32ToBytes32MapMock { - using EnumerableMap for EnumerableMap.Bytes32ToBytes32Map; - - event OperationResult(bool result); - - EnumerableMap.Bytes32ToBytes32Map private _map; - - function contains(bytes32 key) public view returns (bool) { - return _map.contains(key); - } - - function set(bytes32 key, bytes32 value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(bytes32 key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (bytes32 key, bytes32 value) { - return _map.at(index); - } - - function tryGet(bytes32 key) public view returns (bool, bytes32) { - return _map.tryGet(key); - } - - function get(bytes32 key) public view returns (bytes32) { - return _map.get(key); - } - - function getWithMessage(bytes32 key, string calldata errorMessage) public view returns (bytes32) { - return _map.get(key, errorMessage); - } -} - -// UintToUintMap -contract UintToUintMapMock { - using EnumerableMap for EnumerableMap.UintToUintMap; - - event OperationResult(bool result); - - EnumerableMap.UintToUintMap private _map; - - function contains(uint256 key) public view returns (bool) { - return _map.contains(key); - } - - function set(uint256 key, uint256 value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(uint256 key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (uint256 key, uint256 value) { - return _map.at(index); - } - - function tryGet(uint256 key) public view returns (bool, uint256) { - return _map.tryGet(key); - } - - function get(uint256 key) public view returns (uint256) { - return _map.get(key); - } - - function getWithMessage(uint256 key, string calldata errorMessage) public view returns (uint256) { - return _map.get(key, errorMessage); - } -} - -// Bytes32ToUintMap -contract Bytes32ToUintMapMock { - using EnumerableMap for EnumerableMap.Bytes32ToUintMap; - - event OperationResult(bool result); - - EnumerableMap.Bytes32ToUintMap private _map; - - function contains(bytes32 key) public view returns (bool) { - return _map.contains(key); - } - - function set(bytes32 key, uint256 value) public { - bool result = _map.set(key, value); - emit OperationResult(result); - } - - function remove(bytes32 key) public { - bool result = _map.remove(key); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _map.length(); - } - - function at(uint256 index) public view returns (bytes32 key, uint256 value) { - return _map.at(index); - } - - function tryGet(bytes32 key) public view returns (bool, uint256) { - return _map.tryGet(key); - } - - function get(bytes32 key) public view returns (uint256) { - return _map.get(key); - } - - function getWithMessage(bytes32 key, string calldata errorMessage) public view returns (uint256) { - return _map.get(key, errorMessage); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EnumerableSetMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EnumerableSetMock.sol deleted file mode 100644 index 922ce46..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EnumerableSetMock.sol +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/structs/EnumerableSet.sol"; - -// Bytes32Set -contract EnumerableBytes32SetMock { - using EnumerableSet for EnumerableSet.Bytes32Set; - - event OperationResult(bool result); - - EnumerableSet.Bytes32Set private _set; - - function contains(bytes32 value) public view returns (bool) { - return _set.contains(value); - } - - function add(bytes32 value) public { - bool result = _set.add(value); - emit OperationResult(result); - } - - function remove(bytes32 value) public { - bool result = _set.remove(value); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _set.length(); - } - - function at(uint256 index) public view returns (bytes32) { - return _set.at(index); - } - - function values() public view returns (bytes32[] memory) { - return _set.values(); - } -} - -// AddressSet -contract EnumerableAddressSetMock { - using EnumerableSet for EnumerableSet.AddressSet; - - event OperationResult(bool result); - - EnumerableSet.AddressSet private _set; - - function contains(address value) public view returns (bool) { - return _set.contains(value); - } - - function add(address value) public { - bool result = _set.add(value); - emit OperationResult(result); - } - - function remove(address value) public { - bool result = _set.remove(value); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _set.length(); - } - - function at(uint256 index) public view returns (address) { - return _set.at(index); - } - - function values() public view returns (address[] memory) { - return _set.values(); - } -} - -// UintSet -contract EnumerableUintSetMock { - using EnumerableSet for EnumerableSet.UintSet; - - event OperationResult(bool result); - - EnumerableSet.UintSet private _set; - - function contains(uint256 value) public view returns (bool) { - return _set.contains(value); - } - - function add(uint256 value) public { - bool result = _set.add(value); - emit OperationResult(result); - } - - function remove(uint256 value) public { - bool result = _set.remove(value); - emit OperationResult(result); - } - - function length() public view returns (uint256) { - return _set.length(); - } - - function at(uint256 index) public view returns (uint256) { - return _set.at(index); - } - - function values() public view returns (uint256[] memory) { - return _set.values(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol deleted file mode 100644 index a11e646..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -contract EtherReceiverMock { - bool private _acceptEther; - - function setAcceptEther(bool acceptEther) public { - _acceptEther = acceptEther; - } - - receive() external payable { - if (!_acceptEther) { - revert(); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorCompMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorCompMock.sol deleted file mode 100644 index c2d8733..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorCompMock.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorCountingSimple.sol"; -import "../governance/extensions/GovernorVotesComp.sol"; - -contract GovernorCompMock is GovernorVotesComp, GovernorCountingSimple { - constructor(string memory name_, ERC20VotesComp token_) Governor(name_) GovernorVotesComp(token_) {} - - function quorum(uint256) public pure override returns (uint256) { - return 0; - } - - function votingDelay() public pure override returns (uint256) { - return 4; - } - - function votingPeriod() public pure override returns (uint256) { - return 16; - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorCompatibilityBravoMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorCompatibilityBravoMock.sol deleted file mode 100644 index 8f295f6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorCompatibilityBravoMock.sol +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/compatibility/GovernorCompatibilityBravo.sol"; -import "../governance/extensions/GovernorTimelockCompound.sol"; -import "../governance/extensions/GovernorSettings.sol"; -import "../governance/extensions/GovernorVotesComp.sol"; - -contract GovernorCompatibilityBravoMock is - GovernorCompatibilityBravo, - GovernorSettings, - GovernorTimelockCompound, - GovernorVotesComp -{ - constructor( - string memory name_, - ERC20VotesComp token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 proposalThreshold_, - ICompoundTimelock timelock_ - ) - Governor(name_) - GovernorTimelockCompound(timelock_) - GovernorSettings(votingDelay_, votingPeriod_, proposalThreshold_) - GovernorVotesComp(token_) - {} - - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(IERC165, Governor, GovernorTimelockCompound) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function quorum(uint256) public pure override returns (uint256) { - return 0; - } - - function state(uint256 proposalId) - public - view - virtual - override(IGovernor, Governor, GovernorTimelockCompound) - returns (ProposalState) - { - return super.state(proposalId); - } - - function proposalEta(uint256 proposalId) - public - view - virtual - override(IGovernorTimelock, GovernorTimelockCompound) - returns (uint256) - { - return super.proposalEta(proposalId); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override(IGovernor, Governor, GovernorCompatibilityBravo) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function queue( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public virtual override(IGovernorTimelock, GovernorTimelockCompound) returns (uint256) { - return super.queue(targets, values, calldatas, salt); - } - - function execute( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public payable virtual override(IGovernor, Governor) returns (uint256) { - return super.execute(targets, values, calldatas, salt); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override(Governor, GovernorTimelockCompound) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - /** - * @notice WARNING: this is for mock purposes only. Ability to the _cancel function should be restricted for live - * deployments. - */ - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) internal virtual override(Governor, GovernorTimelockCompound) returns (uint256 proposalId) { - return super._cancel(targets, values, calldatas, salt); - } - - function _executor() internal view virtual override(Governor, GovernorTimelockCompound) returns (address) { - return super._executor(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorMock.sol deleted file mode 100644 index dafb0a0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorMock.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorProposalThreshold.sol"; -import "../governance/extensions/GovernorSettings.sol"; -import "../governance/extensions/GovernorCountingSimple.sol"; -import "../governance/extensions/GovernorVotesQuorumFraction.sol"; - -contract GovernorMock is - GovernorProposalThreshold, - GovernorSettings, - GovernorVotesQuorumFraction, - GovernorCountingSimple -{ - constructor( - string memory name_, - IVotes token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 quorumNumerator_ - ) - Governor(name_) - GovernorSettings(votingDelay_, votingPeriod_, 0) - GovernorVotes(token_) - GovernorVotesQuorumFraction(quorumNumerator_) - {} - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public virtual override(Governor, GovernorProposalThreshold) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorPreventLateQuorumMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorPreventLateQuorumMock.sol deleted file mode 100644 index 35bddc0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorPreventLateQuorumMock.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorPreventLateQuorum.sol"; -import "../governance/extensions/GovernorSettings.sol"; -import "../governance/extensions/GovernorCountingSimple.sol"; -import "../governance/extensions/GovernorVotes.sol"; - -contract GovernorPreventLateQuorumMock is - GovernorSettings, - GovernorVotes, - GovernorCountingSimple, - GovernorPreventLateQuorum -{ - uint256 private _quorum; - - constructor( - string memory name_, - IVotes token_, - uint256 votingDelay_, - uint256 votingPeriod_, - uint256 quorum_, - uint64 voteExtension_ - ) - Governor(name_) - GovernorSettings(votingDelay_, votingPeriod_, 0) - GovernorVotes(token_) - GovernorPreventLateQuorum(voteExtension_) - { - _quorum = quorum_; - } - - function quorum(uint256) public view virtual override returns (uint256) { - return _quorum; - } - - function proposalDeadline(uint256 proposalId) - public - view - virtual - override(Governor, GovernorPreventLateQuorum) - returns (uint256) - { - return super.proposalDeadline(proposalId); - } - - function proposalThreshold() public view virtual override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal virtual override(Governor, GovernorPreventLateQuorum) returns (uint256) { - return super._castVote(proposalId, account, support, reason, params); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockCompoundMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockCompoundMock.sol deleted file mode 100644 index 88a8829..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockCompoundMock.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorTimelockCompound.sol"; -import "../governance/extensions/GovernorSettings.sol"; -import "../governance/extensions/GovernorCountingSimple.sol"; -import "../governance/extensions/GovernorVotesQuorumFraction.sol"; - -contract GovernorTimelockCompoundMock is - GovernorSettings, - GovernorTimelockCompound, - GovernorVotesQuorumFraction, - GovernorCountingSimple -{ - constructor( - string memory name_, - IVotes token_, - uint256 votingDelay_, - uint256 votingPeriod_, - ICompoundTimelock timelock_, - uint256 quorumNumerator_ - ) - Governor(name_) - GovernorTimelockCompound(timelock_) - GovernorSettings(votingDelay_, votingPeriod_, 0) - GovernorVotes(token_) - GovernorVotesQuorumFraction(quorumNumerator_) - {} - - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(Governor, GovernorTimelockCompound) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } - - /** - * Overriding nightmare - */ - function state(uint256 proposalId) - public - view - virtual - override(Governor, GovernorTimelockCompound) - returns (ProposalState) - { - return super.state(proposalId); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override(Governor, GovernorTimelockCompound) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) internal virtual override(Governor, GovernorTimelockCompound) returns (uint256 proposalId) { - return super._cancel(targets, values, calldatas, salt); - } - - function _executor() internal view virtual override(Governor, GovernorTimelockCompound) returns (address) { - return super._executor(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockControlMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockControlMock.sol deleted file mode 100644 index 455eac9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorTimelockControlMock.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorTimelockControl.sol"; -import "../governance/extensions/GovernorSettings.sol"; -import "../governance/extensions/GovernorCountingSimple.sol"; -import "../governance/extensions/GovernorVotesQuorumFraction.sol"; - -contract GovernorTimelockControlMock is - GovernorSettings, - GovernorTimelockControl, - GovernorVotesQuorumFraction, - GovernorCountingSimple -{ - constructor( - string memory name_, - IVotes token_, - uint256 votingDelay_, - uint256 votingPeriod_, - TimelockController timelock_, - uint256 quorumNumerator_ - ) - Governor(name_) - GovernorTimelockControl(timelock_) - GovernorSettings(votingDelay_, votingPeriod_, 0) - GovernorVotes(token_) - GovernorVotesQuorumFraction(quorumNumerator_) - {} - - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(Governor, GovernorTimelockControl) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, descriptionHash); - } - - /** - * Overriding nightmare - */ - function state(uint256 proposalId) - public - view - virtual - override(Governor, GovernorTimelockControl) - returns (ProposalState) - { - return super.state(proposalId); - } - - function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { - return super.proposalThreshold(); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override(Governor, GovernorTimelockControl) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal virtual override(Governor, GovernorTimelockControl) returns (uint256 proposalId) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() internal view virtual override(Governor, GovernorTimelockControl) returns (address) { - return super._executor(); - } - - function nonGovernanceFunction() external {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorVoteMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorVoteMock.sol deleted file mode 100644 index 60a3d41..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorVoteMock.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorCountingSimple.sol"; -import "../governance/extensions/GovernorVotes.sol"; - -contract GovernorVoteMocks is GovernorVotes, GovernorCountingSimple { - constructor(string memory name_, IVotes token_) Governor(name_) GovernorVotes(token_) {} - - function quorum(uint256) public pure override returns (uint256) { - return 0; - } - - function votingDelay() public pure override returns (uint256) { - return 4; - } - - function votingPeriod() public pure override returns (uint256) { - return 16; - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorWithParamsMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorWithParamsMock.sol deleted file mode 100644 index 35eb7ad..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/GovernorWithParamsMock.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/extensions/GovernorCountingSimple.sol"; -import "../governance/extensions/GovernorVotes.sol"; - -contract GovernorWithParamsMock is GovernorVotes, GovernorCountingSimple { - event CountParams(uint256 uintParam, string strParam); - - constructor(string memory name_, IVotes token_) Governor(name_) GovernorVotes(token_) {} - - function quorum(uint256) public pure override returns (uint256) { - return 0; - } - - function votingDelay() public pure override returns (uint256) { - return 4; - } - - function votingPeriod() public pure override returns (uint256) { - return 16; - } - - function _getVotes( - address account, - uint256 blockNumber, - bytes memory params - ) internal view virtual override(Governor, GovernorVotes) returns (uint256) { - uint256 reduction = 0; - // If the user provides parameters, we reduce the voting weight by the amount of the integer param - if (params.length > 0) { - (reduction, ) = abi.decode(params, (uint256, string)); - } - // reverts on overflow - return super._getVotes(account, blockNumber, params) - reduction; - } - - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 weight, - bytes memory params - ) internal virtual override(Governor, GovernorCountingSimple) { - if (params.length > 0) { - (uint256 _uintParam, string memory _strParam) = abi.decode(params, (uint256, string)); - emit CountParams(_uintParam, _strParam); - } - return super._countVote(proposalId, account, support, weight, params); - } - - function cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 salt - ) public returns (uint256 proposalId) { - return _cancel(targets, values, calldatas, salt); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol deleted file mode 100644 index b24db08..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/InitializableMock.sol +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/utils/Initializable.sol"; - -/** - * @title InitializableMock - * @dev This contract is a mock to test initializable functionality - */ -contract InitializableMock is Initializable { - bool public initializerRan; - bool public onlyInitializingRan; - uint256 public x; - - function initialize() public initializer { - initializerRan = true; - } - - function initializeOnlyInitializing() public onlyInitializing { - onlyInitializingRan = true; - } - - function initializerNested() public initializer { - initialize(); - } - - function onlyInitializingNested() public initializer { - initializeOnlyInitializing(); - } - - function initializeWithX(uint256 _x) public payable initializer { - x = _x; - } - - function nonInitializable(uint256 _x) public payable { - x = _x; - } - - function fail() public pure { - require(false, "InitializableMock forced failure"); - } -} - -contract ConstructorInitializableMock is Initializable { - bool public initializerRan; - bool public onlyInitializingRan; - - constructor() initializer { - initialize(); - initializeOnlyInitializing(); - } - - function initialize() public initializer { - initializerRan = true; - } - - function initializeOnlyInitializing() public onlyInitializing { - onlyInitializingRan = true; - } -} - -contract ChildConstructorInitializableMock is ConstructorInitializableMock { - bool public childInitializerRan; - - constructor() initializer { - childInitialize(); - } - - function childInitialize() public initializer { - childInitializerRan = true; - } -} - -contract ReinitializerMock is Initializable { - uint256 public counter; - - function initialize() public initializer { - doStuff(); - } - - function reinitialize(uint8 i) public reinitializer(i) { - doStuff(); - } - - function nestedReinitialize(uint8 i, uint8 j) public reinitializer(i) { - reinitialize(j); - } - - function chainReinitialize(uint8 i, uint8 j) public { - reinitialize(i); - reinitialize(j); - } - - function disableInitializers() public { - _disableInitializers(); - } - - function doStuff() public onlyInitializing { - counter++; - } -} - -contract DisableNew is Initializable { - constructor() { - _disableInitializers(); - } -} - -contract DisableOld is Initializable { - constructor() initializer {} -} - -contract DisableBad1 is DisableNew, DisableOld {} - -contract DisableBad2 is Initializable { - constructor() initializer { - _disableInitializers(); - } -} - -contract DisableOk is DisableOld, DisableNew {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MathMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MathMock.sol deleted file mode 100644 index a9022aa..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MathMock.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/Math.sol"; - -contract MathMock { - function max(uint256 a, uint256 b) public pure returns (uint256) { - return Math.max(a, b); - } - - function min(uint256 a, uint256 b) public pure returns (uint256) { - return Math.min(a, b); - } - - function average(uint256 a, uint256 b) public pure returns (uint256) { - return Math.average(a, b); - } - - function ceilDiv(uint256 a, uint256 b) public pure returns (uint256) { - return Math.ceilDiv(a, b); - } - - function mulDiv( - uint256 a, - uint256 b, - uint256 denominator, - Math.Rounding direction - ) public pure returns (uint256) { - return Math.mulDiv(a, b, denominator, direction); - } - - function sqrt(uint256 a, Math.Rounding direction) public pure returns (uint256) { - return Math.sqrt(a, direction); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MerkleProofWrapper.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MerkleProofWrapper.sol deleted file mode 100644 index b74459d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MerkleProofWrapper.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/cryptography/MerkleProof.sol"; - -contract MerkleProofWrapper { - function verify( - bytes32[] memory proof, - bytes32 root, - bytes32 leaf - ) public pure returns (bool) { - return MerkleProof.verify(proof, root, leaf); - } - - function verifyCalldata( - bytes32[] calldata proof, - bytes32 root, - bytes32 leaf - ) public pure returns (bool) { - return MerkleProof.verifyCalldata(proof, root, leaf); - } - - function processProof(bytes32[] memory proof, bytes32 leaf) public pure returns (bytes32) { - return MerkleProof.processProof(proof, leaf); - } - - function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) public pure returns (bytes32) { - return MerkleProof.processProofCalldata(proof, leaf); - } - - function multiProofVerify( - bytes32[] memory proofs, - bool[] memory proofFlag, - bytes32 root, - bytes32[] memory leaves - ) public pure returns (bool) { - return MerkleProof.multiProofVerify(proofs, proofFlag, root, leaves); - } - - function multiProofVerifyCalldata( - bytes32[] calldata proofs, - bool[] calldata proofFlag, - bytes32 root, - bytes32[] memory leaves - ) public pure returns (bool) { - return MerkleProof.multiProofVerifyCalldata(proofs, proofFlag, root, leaves); - } - - function processMultiProof( - bytes32[] memory proofs, - bool[] memory proofFlag, - bytes32[] memory leaves - ) public pure returns (bytes32) { - return MerkleProof.processMultiProof(proofs, proofFlag, leaves); - } - - function processMultiProofCalldata( - bytes32[] calldata proofs, - bool[] calldata proofFlag, - bytes32[] memory leaves - ) public pure returns (bytes32) { - return MerkleProof.processMultiProofCalldata(proofs, proofFlag, leaves); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MulticallTest.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MulticallTest.sol deleted file mode 100644 index f1a3a9c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MulticallTest.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./MulticallTokenMock.sol"; - -contract MulticallTest { - function testReturnValues( - MulticallTokenMock multicallToken, - address[] calldata recipients, - uint256[] calldata amounts - ) external { - bytes[] memory calls = new bytes[](recipients.length); - for (uint256 i = 0; i < recipients.length; i++) { - calls[i] = abi.encodeWithSignature("transfer(address,uint256)", recipients[i], amounts[i]); - } - - bytes[] memory results = multicallToken.multicall(calls); - for (uint256 i = 0; i < results.length; i++) { - require(abi.decode(results[i], (bool))); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MulticallTokenMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MulticallTokenMock.sol deleted file mode 100644 index de37968..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MulticallTokenMock.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Multicall.sol"; -import "./ERC20Mock.sol"; - -contract MulticallTokenMock is ERC20Mock, Multicall { - constructor(uint256 initialBalance) ERC20Mock("MulticallToken", "BCT", msg.sender, initialBalance) {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol deleted file mode 100644 index f8b6e46..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sol +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/utils/Initializable.sol"; - -// Sample contracts showing upgradeability with multiple inheritance. -// Child contract inherits from Father and Mother contracts, and Father extends from Gramps. -// -// Human -// / \ -// | Gramps -// | | -// Mother Father -// | | -// -- Child -- - -/** - * Sample base intializable contract that is a human - */ -contract SampleHuman is Initializable { - bool public isHuman; - - function initialize() public initializer { - __SampleHuman_init(); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleHuman_init() internal onlyInitializing { - __SampleHuman_init_unchained(); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleHuman_init_unchained() internal onlyInitializing { - isHuman = true; - } -} - -/** - * Sample base intializable contract that defines a field mother - */ -contract SampleMother is Initializable, SampleHuman { - uint256 public mother; - - function initialize(uint256 value) public virtual initializer { - __SampleMother_init(value); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleMother_init(uint256 value) internal onlyInitializing { - __SampleHuman_init(); - __SampleMother_init_unchained(value); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleMother_init_unchained(uint256 value) internal onlyInitializing { - mother = value; - } -} - -/** - * Sample base intializable contract that defines a field gramps - */ -contract SampleGramps is Initializable, SampleHuman { - string public gramps; - - function initialize(string memory value) public virtual initializer { - __SampleGramps_init(value); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleGramps_init(string memory value) internal onlyInitializing { - __SampleHuman_init(); - __SampleGramps_init_unchained(value); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleGramps_init_unchained(string memory value) internal onlyInitializing { - gramps = value; - } -} - -/** - * Sample base intializable contract that defines a field father and extends from gramps - */ -contract SampleFather is Initializable, SampleGramps { - uint256 public father; - - function initialize(string memory _gramps, uint256 _father) public initializer { - __SampleFather_init(_gramps, _father); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleFather_init(string memory _gramps, uint256 _father) internal onlyInitializing { - __SampleGramps_init(_gramps); - __SampleFather_init_unchained(_father); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleFather_init_unchained(uint256 _father) internal onlyInitializing { - father = _father; - } -} - -/** - * Child extends from mother, father (gramps) - */ -contract SampleChild is Initializable, SampleMother, SampleFather { - uint256 public child; - - function initialize( - uint256 _mother, - string memory _gramps, - uint256 _father, - uint256 _child - ) public initializer { - __SampleChild_init(_mother, _gramps, _father, _child); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleChild_init( - uint256 _mother, - string memory _gramps, - uint256 _father, - uint256 _child - ) internal onlyInitializing { - __SampleMother_init(_mother); - __SampleFather_init(_gramps, _father); - __SampleChild_init_unchained(_child); - } - - // solhint-disable-next-line func-name-mixedcase - function __SampleChild_init_unchained(uint256 _child) internal onlyInitializing { - child = _child; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/OwnableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/OwnableMock.sol deleted file mode 100644 index d60f1c4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/OwnableMock.sol +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../access/Ownable.sol"; - -contract OwnableMock is Ownable {} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol deleted file mode 100644 index 98bcfd5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/PausableMock.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../security/Pausable.sol"; - -contract PausableMock is Pausable { - bool public drasticMeasureTaken; - uint256 public count; - - constructor() { - drasticMeasureTaken = false; - count = 0; - } - - function normalProcess() external whenNotPaused { - count++; - } - - function drasticMeasure() external whenPaused { - drasticMeasureTaken = true; - } - - function pause() external { - _pause(); - } - - function unpause() external { - _unpause(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/PullPaymentMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/PullPaymentMock.sol deleted file mode 100644 index 8a708e3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/PullPaymentMock.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../security/PullPayment.sol"; - -// mock class using PullPayment -contract PullPaymentMock is PullPayment { - constructor() payable {} - - // test helper function to call asyncTransfer - function callTransfer(address dest, uint256 amount) public { - _asyncTransfer(dest, amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol deleted file mode 100644 index 4de1812..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Context.sol"; - -contract ReentrancyAttack is Context { - function callSender(bytes4 data) public { - (bool success, ) = _msgSender().call(abi.encodeWithSelector(data)); - require(success, "ReentrancyAttack: failed call"); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol deleted file mode 100644 index 43425dd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../security/ReentrancyGuard.sol"; -import "./ReentrancyAttack.sol"; - -contract ReentrancyMock is ReentrancyGuard { - uint256 public counter; - - constructor() { - counter = 0; - } - - function callback() external nonReentrant { - _count(); - } - - function countLocalRecursive(uint256 n) public nonReentrant { - if (n > 0) { - _count(); - countLocalRecursive(n - 1); - } - } - - function countThisRecursive(uint256 n) public nonReentrant { - if (n > 0) { - _count(); - (bool success, ) = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1)); - require(success, "ReentrancyMock: failed call"); - } - } - - function countAndCall(ReentrancyAttack attacker) public nonReentrant { - _count(); - bytes4 func = bytes4(keccak256("callback()")); - attacker.callSender(func); - } - - function _count() private { - counter += 1; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol deleted file mode 100644 index be6b501..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/utils/Initializable.sol"; - -contract Implementation1 is Initializable { - uint256 internal _value; - - function initialize() public initializer {} - - function setValue(uint256 _number) public { - _value = _number; - } -} - -contract Implementation2 is Initializable { - uint256 internal _value; - - function initialize() public initializer {} - - function setValue(uint256 _number) public { - _value = _number; - } - - function getValue() public view returns (uint256) { - return _value; - } -} - -contract Implementation3 is Initializable { - uint256 internal _value; - - function initialize() public initializer {} - - function setValue(uint256 _number) public { - _value = _number; - } - - function getValue(uint256 _number) public view returns (uint256) { - return _value + _number; - } -} - -contract Implementation4 is Initializable { - uint256 internal _value; - - function initialize() public initializer {} - - function setValue(uint256 _number) public { - _value = _number; - } - - function getValue() public view returns (uint256) { - return _value; - } - - fallback() external { - _value = 1; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeCastMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeCastMock.sol deleted file mode 100644 index 806ce12..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeCastMock.sol +++ /dev/null @@ -1,266 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/SafeCast.sol"; - -contract SafeCastMock { - using SafeCast for uint256; - using SafeCast for int256; - - function toUint256(int256 a) public pure returns (uint256) { - return a.toUint256(); - } - - function toUint248(uint256 a) public pure returns (uint248) { - return a.toUint248(); - } - - function toUint240(uint256 a) public pure returns (uint240) { - return a.toUint240(); - } - - function toUint232(uint256 a) public pure returns (uint232) { - return a.toUint232(); - } - - function toUint224(uint256 a) public pure returns (uint224) { - return a.toUint224(); - } - - function toUint216(uint256 a) public pure returns (uint216) { - return a.toUint216(); - } - - function toUint208(uint256 a) public pure returns (uint208) { - return a.toUint208(); - } - - function toUint200(uint256 a) public pure returns (uint200) { - return a.toUint200(); - } - - function toUint192(uint256 a) public pure returns (uint192) { - return a.toUint192(); - } - - function toUint184(uint256 a) public pure returns (uint184) { - return a.toUint184(); - } - - function toUint176(uint256 a) public pure returns (uint176) { - return a.toUint176(); - } - - function toUint168(uint256 a) public pure returns (uint168) { - return a.toUint168(); - } - - function toUint160(uint256 a) public pure returns (uint160) { - return a.toUint160(); - } - - function toUint152(uint256 a) public pure returns (uint152) { - return a.toUint152(); - } - - function toUint144(uint256 a) public pure returns (uint144) { - return a.toUint144(); - } - - function toUint136(uint256 a) public pure returns (uint136) { - return a.toUint136(); - } - - function toUint128(uint256 a) public pure returns (uint128) { - return a.toUint128(); - } - - function toUint120(uint256 a) public pure returns (uint120) { - return a.toUint120(); - } - - function toUint112(uint256 a) public pure returns (uint112) { - return a.toUint112(); - } - - function toUint104(uint256 a) public pure returns (uint104) { - return a.toUint104(); - } - - function toUint96(uint256 a) public pure returns (uint96) { - return a.toUint96(); - } - - function toUint88(uint256 a) public pure returns (uint88) { - return a.toUint88(); - } - - function toUint80(uint256 a) public pure returns (uint80) { - return a.toUint80(); - } - - function toUint72(uint256 a) public pure returns (uint72) { - return a.toUint72(); - } - - function toUint64(uint256 a) public pure returns (uint64) { - return a.toUint64(); - } - - function toUint56(uint256 a) public pure returns (uint56) { - return a.toUint56(); - } - - function toUint48(uint256 a) public pure returns (uint48) { - return a.toUint48(); - } - - function toUint40(uint256 a) public pure returns (uint40) { - return a.toUint40(); - } - - function toUint32(uint256 a) public pure returns (uint32) { - return a.toUint32(); - } - - function toUint24(uint256 a) public pure returns (uint24) { - return a.toUint24(); - } - - function toUint16(uint256 a) public pure returns (uint16) { - return a.toUint16(); - } - - function toUint8(uint256 a) public pure returns (uint8) { - return a.toUint8(); - } - - function toInt256(uint256 a) public pure returns (int256) { - return a.toInt256(); - } - - function toInt248(int256 a) public pure returns (int248) { - return a.toInt248(); - } - - function toInt240(int256 a) public pure returns (int240) { - return a.toInt240(); - } - - function toInt232(int256 a) public pure returns (int232) { - return a.toInt232(); - } - - function toInt224(int256 a) public pure returns (int224) { - return a.toInt224(); - } - - function toInt216(int256 a) public pure returns (int216) { - return a.toInt216(); - } - - function toInt208(int256 a) public pure returns (int208) { - return a.toInt208(); - } - - function toInt200(int256 a) public pure returns (int200) { - return a.toInt200(); - } - - function toInt192(int256 a) public pure returns (int192) { - return a.toInt192(); - } - - function toInt184(int256 a) public pure returns (int184) { - return a.toInt184(); - } - - function toInt176(int256 a) public pure returns (int176) { - return a.toInt176(); - } - - function toInt168(int256 a) public pure returns (int168) { - return a.toInt168(); - } - - function toInt160(int256 a) public pure returns (int160) { - return a.toInt160(); - } - - function toInt152(int256 a) public pure returns (int152) { - return a.toInt152(); - } - - function toInt144(int256 a) public pure returns (int144) { - return a.toInt144(); - } - - function toInt136(int256 a) public pure returns (int136) { - return a.toInt136(); - } - - function toInt128(int256 a) public pure returns (int128) { - return a.toInt128(); - } - - function toInt120(int256 a) public pure returns (int120) { - return a.toInt120(); - } - - function toInt112(int256 a) public pure returns (int112) { - return a.toInt112(); - } - - function toInt104(int256 a) public pure returns (int104) { - return a.toInt104(); - } - - function toInt96(int256 a) public pure returns (int96) { - return a.toInt96(); - } - - function toInt88(int256 a) public pure returns (int88) { - return a.toInt88(); - } - - function toInt80(int256 a) public pure returns (int80) { - return a.toInt80(); - } - - function toInt72(int256 a) public pure returns (int72) { - return a.toInt72(); - } - - function toInt64(int256 a) public pure returns (int64) { - return a.toInt64(); - } - - function toInt56(int256 a) public pure returns (int56) { - return a.toInt56(); - } - - function toInt48(int256 a) public pure returns (int48) { - return a.toInt48(); - } - - function toInt40(int256 a) public pure returns (int40) { - return a.toInt40(); - } - - function toInt32(int256 a) public pure returns (int32) { - return a.toInt32(); - } - - function toInt24(int256 a) public pure returns (int24) { - return a.toInt24(); - } - - function toInt16(int256 a) public pure returns (int16) { - return a.toInt16(); - } - - function toInt8(int256 a) public pure returns (int8) { - return a.toInt8(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeERC20Helper.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeERC20Helper.sol deleted file mode 100644 index af3420e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeERC20Helper.sol +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Context.sol"; -import "../token/ERC20/IERC20.sol"; -import "../token/ERC20/extensions/draft-ERC20Permit.sol"; -import "../token/ERC20/utils/SafeERC20.sol"; - -contract ERC20ReturnFalseMock is Context { - uint256 private _allowance; - - // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, - // we write to a dummy state variable. - uint256 private _dummy; - - function transfer(address, uint256) public returns (bool) { - _dummy = 0; - return false; - } - - function transferFrom( - address, - address, - uint256 - ) public returns (bool) { - _dummy = 0; - return false; - } - - function approve(address, uint256) public returns (bool) { - _dummy = 0; - return false; - } - - function allowance(address, address) public view returns (uint256) { - require(_dummy == 0); // Dummy read from a state variable so that the function is view - return 0; - } -} - -contract ERC20ReturnTrueMock is Context { - mapping(address => uint256) private _allowances; - - // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, - // we write to a dummy state variable. - uint256 private _dummy; - - function transfer(address, uint256) public returns (bool) { - _dummy = 0; - return true; - } - - function transferFrom( - address, - address, - uint256 - ) public returns (bool) { - _dummy = 0; - return true; - } - - function approve(address, uint256) public returns (bool) { - _dummy = 0; - return true; - } - - function setAllowance(uint256 allowance_) public { - _allowances[_msgSender()] = allowance_; - } - - function allowance(address owner, address) public view returns (uint256) { - return _allowances[owner]; - } -} - -contract ERC20NoReturnMock is Context { - mapping(address => uint256) private _allowances; - - // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, - // we write to a dummy state variable. - uint256 private _dummy; - - function transfer(address, uint256) public { - _dummy = 0; - } - - function transferFrom( - address, - address, - uint256 - ) public { - _dummy = 0; - } - - function approve(address, uint256) public { - _dummy = 0; - } - - function setAllowance(uint256 allowance_) public { - _allowances[_msgSender()] = allowance_; - } - - function allowance(address owner, address) public view returns (uint256) { - return _allowances[owner]; - } -} - -contract ERC20PermitNoRevertMock is - ERC20("ERC20PermitNoRevertMock", "ERC20PermitNoRevertMock"), - ERC20Permit("ERC20PermitNoRevertMock") -{ - function getChainId() external view returns (uint256) { - return block.chainid; - } - - function permitThatMayRevert( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual { - super.permit(owner, spender, value, deadline, v, r, s); - } - - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override { - try this.permitThatMayRevert(owner, spender, value, deadline, v, r, s) { - // do nothing - } catch { - // do nothing - } - } -} - -contract SafeERC20Wrapper is Context { - using SafeERC20 for IERC20; - - IERC20 private _token; - - constructor(IERC20 token) { - _token = token; - } - - function transfer() public { - _token.safeTransfer(address(0), 0); - } - - function transferFrom() public { - _token.safeTransferFrom(address(0), address(0), 0); - } - - function approve(uint256 amount) public { - _token.safeApprove(address(0), amount); - } - - function increaseAllowance(uint256 amount) public { - _token.safeIncreaseAllowance(address(0), amount); - } - - function decreaseAllowance(uint256 amount) public { - _token.safeDecreaseAllowance(address(0), amount); - } - - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public { - SafeERC20.safePermit(IERC20Permit(address(_token)), owner, spender, value, deadline, v, r, s); - } - - function setAllowance(uint256 allowance_) public { - ERC20ReturnTrueMock(address(_token)).setAllowance(allowance_); - } - - function allowance() public view returns (uint256) { - return _token.allowance(address(0), address(0)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeMathMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeMathMock.sol deleted file mode 100644 index 3d1f472..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SafeMathMock.sol +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/SafeMath.sol"; - -contract SafeMathMock { - function tryAdd(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMath.tryAdd(a, b); - } - - function trySub(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMath.trySub(a, b); - } - - function tryMul(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMath.tryMul(a, b); - } - - function tryDiv(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMath.tryDiv(a, b); - } - - function tryMod(uint256 a, uint256 b) public pure returns (bool flag, uint256 value) { - return SafeMath.tryMod(a, b); - } - - // using the do* naming convention to avoid warnings due to clashing opcode names - - function doAdd(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMath.add(a, b); - } - - function doSub(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMath.sub(a, b); - } - - function doMul(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMath.mul(a, b); - } - - function doDiv(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMath.div(a, b); - } - - function doMod(uint256 a, uint256 b) public pure returns (uint256) { - return SafeMath.mod(a, b); - } - - function subWithMessage( - uint256 a, - uint256 b, - string memory errorMessage - ) public pure returns (uint256) { - return SafeMath.sub(a, b, errorMessage); - } - - function divWithMessage( - uint256 a, - uint256 b, - string memory errorMessage - ) public pure returns (uint256) { - return SafeMath.div(a, b, errorMessage); - } - - function modWithMessage( - uint256 a, - uint256 b, - string memory errorMessage - ) public pure returns (uint256) { - return SafeMath.mod(a, b, errorMessage); - } - - function addMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMath.add(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - function subMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMath.sub(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - function mulMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMath.mul(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - function divMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMath.div(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } - - function modMemoryCheck() public pure returns (uint256 mem) { - uint256 length = 32; - assembly { - mem := mload(0x40) - } - for (uint256 i = 0; i < length; ++i) { - SafeMath.mod(1, 1); - } - assembly { - mem := sub(mload(0x40), mem) - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignatureCheckerMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignatureCheckerMock.sol deleted file mode 100644 index 3b399c1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignatureCheckerMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/cryptography/SignatureChecker.sol"; - -contract SignatureCheckerMock { - using SignatureChecker for address; - - function isValidSignatureNow( - address signer, - bytes32 hash, - bytes memory signature - ) public view returns (bool) { - return signer.isValidSignatureNow(hash, signature); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignedMathMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignedMathMock.sol deleted file mode 100644 index 5a0b270..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignedMathMock.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/SignedMath.sol"; - -contract SignedMathMock { - function max(int256 a, int256 b) public pure returns (int256) { - return SignedMath.max(a, b); - } - - function min(int256 a, int256 b) public pure returns (int256) { - return SignedMath.min(a, b); - } - - function average(int256 a, int256 b) public pure returns (int256) { - return SignedMath.average(a, b); - } - - function abs(int256 n) public pure returns (uint256) { - return SignedMath.abs(n); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignedSafeMathMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignedSafeMathMock.sol deleted file mode 100644 index 8d10217..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SignedSafeMathMock.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/math/SignedSafeMath.sol"; - -contract SignedSafeMathMock { - function mul(int256 a, int256 b) public pure returns (int256) { - return SignedSafeMath.mul(a, b); - } - - function div(int256 a, int256 b) public pure returns (int256) { - return SignedSafeMath.div(a, b); - } - - function sub(int256 a, int256 b) public pure returns (int256) { - return SignedSafeMath.sub(a, b); - } - - function add(int256 a, int256 b) public pure returns (int256) { - return SignedSafeMath.add(a, b); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol deleted file mode 100644 index 6c82dd2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../proxy/utils/Initializable.sol"; - -/** - * @title MigratableMockV1 - * @dev This contract is a mock to test initializable functionality through migrations - */ -contract MigratableMockV1 is Initializable { - uint256 public x; - - function initialize(uint256 value) public payable initializer { - x = value; - } -} - -/** - * @title MigratableMockV2 - * @dev This contract is a mock to test migratable functionality with params - */ -contract MigratableMockV2 is MigratableMockV1 { - bool internal _migratedV2; - uint256 public y; - - function migrate(uint256 value, uint256 anotherValue) public payable { - require(!_migratedV2); - x = value; - y = anotherValue; - _migratedV2 = true; - } -} - -/** - * @title MigratableMockV3 - * @dev This contract is a mock to test migratable functionality without params - */ -contract MigratableMockV3 is MigratableMockV2 { - bool internal _migratedV3; - - function migrate() public payable { - require(!_migratedV3); - uint256 oldX = x; - x = y; - y = oldX; - _migratedV3 = true; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol deleted file mode 100644 index 5d099fc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/StorageSlot.sol"; - -contract StorageSlotMock { - using StorageSlot for bytes32; - - function setBoolean(bytes32 slot, bool value) public { - slot.getBooleanSlot().value = value; - } - - function setAddress(bytes32 slot, address value) public { - slot.getAddressSlot().value = value; - } - - function setBytes32(bytes32 slot, bytes32 value) public { - slot.getBytes32Slot().value = value; - } - - function setUint256(bytes32 slot, uint256 value) public { - slot.getUint256Slot().value = value; - } - - function getBoolean(bytes32 slot) public view returns (bool) { - return slot.getBooleanSlot().value; - } - - function getAddress(bytes32 slot) public view returns (address) { - return slot.getAddressSlot().value; - } - - function getBytes32(bytes32 slot) public view returns (bytes32) { - return slot.getBytes32Slot().value; - } - - function getUint256(bytes32 slot) public view returns (uint256) { - return slot.getUint256Slot().value; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/StringsMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/StringsMock.sol deleted file mode 100644 index b862268..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/StringsMock.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Strings.sol"; - -contract StringsMock { - function fromUint256(uint256 value) public pure returns (string memory) { - return Strings.toString(value); - } - - function fromUint256Hex(uint256 value) public pure returns (string memory) { - return Strings.toHexString(value); - } - - function fromUint256HexFixed(uint256 value, uint256 length) public pure returns (string memory) { - return Strings.toHexString(value, length); - } - - function fromAddressHexFixed(address addr) public pure returns (string memory) { - return Strings.toHexString(addr); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/TimersBlockNumberImpl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/TimersBlockNumberImpl.sol deleted file mode 100644 index 84633e6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/TimersBlockNumberImpl.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Timers.sol"; - -contract TimersBlockNumberImpl { - using Timers for Timers.BlockNumber; - - Timers.BlockNumber private _timer; - - function getDeadline() public view returns (uint64) { - return _timer.getDeadline(); - } - - function setDeadline(uint64 timestamp) public { - _timer.setDeadline(timestamp); - } - - function reset() public { - _timer.reset(); - } - - function isUnset() public view returns (bool) { - return _timer.isUnset(); - } - - function isStarted() public view returns (bool) { - return _timer.isStarted(); - } - - function isPending() public view returns (bool) { - return _timer.isPending(); - } - - function isExpired() public view returns (bool) { - return _timer.isExpired(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/TimersTimestampImpl.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/TimersTimestampImpl.sol deleted file mode 100644 index 07f9a1b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/TimersTimestampImpl.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../utils/Timers.sol"; - -contract TimersTimestampImpl { - using Timers for Timers.Timestamp; - - Timers.Timestamp private _timer; - - function getDeadline() public view returns (uint64) { - return _timer.getDeadline(); - } - - function setDeadline(uint64 timestamp) public { - _timer.setDeadline(timestamp); - } - - function reset() public { - _timer.reset(); - } - - function isUnset() public view returns (bool) { - return _timer.isUnset(); - } - - function isStarted() public view returns (bool) { - return _timer.isStarted(); - } - - function isPending() public view returns (bool) { - return _timer.isPending(); - } - - function isExpired() public view returns (bool) { - return _timer.isExpired(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/UUPS/UUPSLegacy.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/UUPS/UUPSLegacy.sol deleted file mode 100644 index 550a622..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/UUPS/UUPSLegacy.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "./UUPSUpgradeableMock.sol"; - -// This contract implements the pre-4.5 UUPS upgrade function with a rollback test. -// It's used to test that newer UUPS contracts are considered valid upgrades by older UUPS contracts. -contract UUPSUpgradeableLegacyMock is UUPSUpgradeableMock { - // Inlined from ERC1967Upgrade - bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; - - // ERC1967Upgrade._setImplementation is private so we reproduce it here. - // An extra underscore prevents a name clash error. - function __setImplementation(address newImplementation) private { - require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); - StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; - } - - function _upgradeToAndCallSecureLegacyV1( - address newImplementation, - bytes memory data, - bool forceCall - ) internal { - address oldImplementation = _getImplementation(); - - // Initial upgrade and setup call - __setImplementation(newImplementation); - if (data.length > 0 || forceCall) { - Address.functionDelegateCall(newImplementation, data); - } - - // Perform rollback test if not already in progress - StorageSlot.BooleanSlot storage rollbackTesting = StorageSlot.getBooleanSlot(_ROLLBACK_SLOT); - if (!rollbackTesting.value) { - // Trigger rollback using upgradeTo from the new implementation - rollbackTesting.value = true; - Address.functionDelegateCall( - newImplementation, - abi.encodeWithSignature("upgradeTo(address)", oldImplementation) - ); - rollbackTesting.value = false; - // Check rollback was effective - require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades"); - // Finally reset to the new implementation and log the upgrade - _upgradeTo(newImplementation); - } - } - - // hooking into the old mechanism - function upgradeTo(address newImplementation) external virtual override { - _upgradeToAndCallSecureLegacyV1(newImplementation, bytes(""), false); - } - - function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual override { - _upgradeToAndCallSecureLegacyV1(newImplementation, data, false); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/UUPS/UUPSUpgradeableMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/UUPS/UUPSUpgradeableMock.sol deleted file mode 100644 index 367303e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/UUPS/UUPSUpgradeableMock.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../CountersImpl.sol"; -import "../../proxy/utils/UUPSUpgradeable.sol"; - -contract UUPSUpgradeableMock is CountersImpl, UUPSUpgradeable { - // Not having any checks in this function is dangerous! Do not do this outside tests! - function _authorizeUpgrade(address) internal virtual override {} -} - -contract UUPSUpgradeableUnsafeMock is UUPSUpgradeableMock { - function upgradeTo(address newImplementation) external virtual override { - ERC1967Upgrade._upgradeToAndCall(newImplementation, bytes(""), false); - } - - function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual override { - ERC1967Upgrade._upgradeToAndCall(newImplementation, data, false); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol deleted file mode 100644 index b5e0513..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/VotesMock.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../governance/utils/Votes.sol"; - -contract VotesMock is Votes { - mapping(address => uint256) private _balances; - mapping(uint256 => address) private _owners; - - constructor(string memory name) EIP712(name, "1") {} - - function getTotalSupply() public view returns (uint256) { - return _getTotalSupply(); - } - - function delegate(address account, address newDelegation) public { - return _delegate(account, newDelegation); - } - - function _getVotingUnits(address account) internal view virtual override returns (uint256) { - return _balances[account]; - } - - function mint(address account, uint256 voteId) external { - _balances[account] += 1; - _owners[voteId] = account; - _transferVotingUnits(address(0), account, 1); - } - - function burn(uint256 voteId) external { - address owner = _owners[voteId]; - _balances[owner] -= 1; - _transferVotingUnits(owner, address(0), 1); - } - - function getChainId() external view returns (uint256) { - return block.chainid; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol deleted file mode 100644 index 49ffa4b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sol +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// solhint-disable private-vars-leading-underscore -/** - * Copyright 2020 Compound Labs, Inc. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -pragma solidity ^0.8.0; - -contract CompTimelock { - event NewAdmin(address indexed newAdmin); - event NewPendingAdmin(address indexed newPendingAdmin); - event NewDelay(uint256 indexed newDelay); - event CancelTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - event ExecuteTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - event QueueTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - - uint256 public constant GRACE_PERIOD = 14 days; - uint256 public constant MINIMUM_DELAY = 2 days; - uint256 public constant MAXIMUM_DELAY = 30 days; - - address public admin; - address public pendingAdmin; - uint256 public delay; - - mapping(bytes32 => bool) public queuedTransactions; - - constructor(address admin_, uint256 delay_) { - require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay."); - require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay."); - - admin = admin_; - delay = delay_; - } - - receive() external payable {} - - function setDelay(uint256 delay_) public { - require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock."); - require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay."); - require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay."); - delay = delay_; - - emit NewDelay(delay); - } - - function acceptAdmin() public { - require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin."); - admin = msg.sender; - pendingAdmin = address(0); - - emit NewAdmin(admin); - } - - function setPendingAdmin(address pendingAdmin_) public { - require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock."); - pendingAdmin = pendingAdmin_; - - emit NewPendingAdmin(pendingAdmin); - } - - function queueTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) public returns (bytes32) { - require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin."); - require( - eta >= getBlockTimestamp() + delay, - "Timelock::queueTransaction: Estimated execution block must satisfy delay." - ); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - queuedTransactions[txHash] = true; - - emit QueueTransaction(txHash, target, value, signature, data, eta); - return txHash; - } - - function cancelTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) public { - require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin."); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - queuedTransactions[txHash] = false; - - emit CancelTransaction(txHash, target, value, signature, data, eta); - } - - function executeTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) public payable returns (bytes memory) { - require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin."); - - bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); - require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued."); - require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock."); - require(getBlockTimestamp() <= eta + GRACE_PERIOD, "Timelock::executeTransaction: Transaction is stale."); - - queuedTransactions[txHash] = false; - - bytes memory callData; - - if (bytes(signature).length == 0) { - callData = data; - } else { - callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data); - } - - // solium-disable-next-line security/no-call-value - (bool success, bytes memory returnData) = target.call{value: value}(callData); - require(success, "Timelock::executeTransaction: Transaction execution reverted."); - - emit ExecuteTransaction(txHash, target, value, signature, data, eta); - - return returnData; - } - - function getBlockTimestamp() internal view returns (uint256) { - // solium-disable-next-line security/no-block-members - return block.timestamp; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/crosschain/bridges.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/crosschain/bridges.sol deleted file mode 100644 index 1339f43..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/crosschain/bridges.sol +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -import "../../utils/Address.sol"; -import "../../vendor/polygon/IFxMessageProcessor.sol"; - -abstract contract BaseRelayMock { - // needed to parse custom errors - error NotCrossChainCall(); - error InvalidCrossChainSender(address sender, address expected); - - address internal _currentSender; - - function relayAs( - address target, - bytes calldata data, - address sender - ) external virtual { - address previousSender = _currentSender; - - _currentSender = sender; - - (bool success, bytes memory returndata) = target.call(data); - Address.verifyCallResultFromTarget(target, success, returndata, "low-level call reverted"); - - _currentSender = previousSender; - } -} - -/** - * AMB - */ -contract BridgeAMBMock is BaseRelayMock { - function messageSender() public view returns (address) { - return _currentSender; - } -} - -/** - * Arbitrum - */ -contract BridgeArbitrumL1Mock is BaseRelayMock { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable inbox = address(new BridgeArbitrumL1Inbox()); - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable outbox = address(new BridgeArbitrumL1Outbox()); - - function activeOutbox() public view returns (address) { - return outbox; - } - - function currentSender() public view returns (address) { - return _currentSender; - } -} - -contract BridgeArbitrumL1Inbox { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable bridge = msg.sender; -} - -contract BridgeArbitrumL1Outbox { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable bridge = msg.sender; - - function l2ToL1Sender() public view returns (address) { - return BridgeArbitrumL1Mock(bridge).currentSender(); - } -} - -contract BridgeArbitrumL2Mock is BaseRelayMock { - function isTopLevelCall() public view returns (bool) { - return _currentSender != address(0); - } - - function wasMyCallersAddressAliased() public pure returns (bool) { - return true; - } - - function myCallersAddressWithoutAliasing() public view returns (address) { - return _currentSender; - } -} - -/** - * Optimism - */ -contract BridgeOptimismMock is BaseRelayMock { - function xDomainMessageSender() public view returns (address) { - return _currentSender; - } -} - -/** - * Polygon - */ -contract BridgePolygonChildMock is BaseRelayMock { - function relayAs( - address target, - bytes calldata data, - address sender - ) external override { - IFxMessageProcessor(target).processMessageFromRoot(0, sender, data); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/crosschain/receivers.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/crosschain/receivers.sol deleted file mode 100644 index 601a2ac..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/crosschain/receivers.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.4; - -import "../../access/Ownable.sol"; -import "../../crosschain/amb/CrossChainEnabledAMB.sol"; -import "../../crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol"; -import "../../crosschain/arbitrum/CrossChainEnabledArbitrumL2.sol"; -import "../../crosschain/optimism/CrossChainEnabledOptimism.sol"; -import "../../crosschain/polygon/CrossChainEnabledPolygonChild.sol"; - -abstract contract Receiver is CrossChainEnabled { - // we don't use Ownable because it messes up testing for the upgradeable contracts - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address public immutable owner = msg.sender; - - function crossChainRestricted() external onlyCrossChain {} - - function crossChainOwnerRestricted() external onlyCrossChainSender(owner) {} -} - -/** - * AMB - */ -contract CrossChainEnabledAMBMock is Receiver, CrossChainEnabledAMB { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) CrossChainEnabledAMB(bridge) {} -} - -/** - * Arbitrum - */ -contract CrossChainEnabledArbitrumL1Mock is Receiver, CrossChainEnabledArbitrumL1 { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) CrossChainEnabledArbitrumL1(bridge) {} -} - -contract CrossChainEnabledArbitrumL2Mock is Receiver, CrossChainEnabledArbitrumL2 {} - -/** - * Optimism - */ -contract CrossChainEnabledOptimismMock is Receiver, CrossChainEnabledOptimism { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) CrossChainEnabledOptimism(bridge) {} -} - -/** - * Polygon - */ -contract CrossChainEnabledPolygonChildMock is Receiver, CrossChainEnabledPolygonChild { - /// @custom:oz-upgrades-unsafe-allow constructor - constructor(address bridge) CrossChainEnabledPolygonChild(bridge) {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor1.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor1.sol deleted file mode 100644 index a80d840..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor1.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../../governance/Governor.sol"; -import "../../governance/extensions/GovernorCountingSimple.sol"; -import "../../governance/extensions/GovernorVotes.sol"; -import "../../governance/extensions/GovernorVotesQuorumFraction.sol"; -import "../../governance/extensions/GovernorTimelockControl.sol"; - -contract MyGovernor1 is - Governor, - GovernorTimelockControl, - GovernorVotes, - GovernorVotesQuorumFraction, - GovernorCountingSimple -{ - constructor(IVotes _token, TimelockController _timelock) - Governor("MyGovernor") - GovernorVotes(_token) - GovernorVotesQuorumFraction(4) - GovernorTimelockControl(_timelock) - {} - - function votingDelay() public pure override returns (uint256) { - return 1; // 1 block - } - - function votingPeriod() public pure override returns (uint256) { - return 45818; // 1 week - } - - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) { - return super.state(proposalId); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(Governor, IGovernor) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(Governor, GovernorTimelockControl) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor2.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor2.sol deleted file mode 100644 index 34c608c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor2.sol +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../../governance/Governor.sol"; -import "../../governance/extensions/GovernorProposalThreshold.sol"; -import "../../governance/extensions/GovernorCountingSimple.sol"; -import "../../governance/extensions/GovernorVotes.sol"; -import "../../governance/extensions/GovernorVotesQuorumFraction.sol"; -import "../../governance/extensions/GovernorTimelockControl.sol"; - -contract MyGovernor2 is - Governor, - GovernorTimelockControl, - GovernorProposalThreshold, - GovernorVotes, - GovernorVotesQuorumFraction, - GovernorCountingSimple -{ - constructor(IVotes _token, TimelockController _timelock) - Governor("MyGovernor") - GovernorVotes(_token) - GovernorVotesQuorumFraction(4) - GovernorTimelockControl(_timelock) - {} - - function votingDelay() public pure override returns (uint256) { - return 1; // 1 block - } - - function votingPeriod() public pure override returns (uint256) { - return 45818; // 1 week - } - - function proposalThreshold() public pure override returns (uint256) { - return 1000e18; - } - - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl) returns (ProposalState) { - return super.state(proposalId); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(Governor, GovernorProposalThreshold, IGovernor) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(Governor, GovernorTimelockControl) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor3.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor3.sol deleted file mode 100644 index 70e4e87..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/mocks/wizard/MyGovernor3.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.2; - -import "../../governance/Governor.sol"; -import "../../governance/compatibility/GovernorCompatibilityBravo.sol"; -import "../../governance/extensions/GovernorVotes.sol"; -import "../../governance/extensions/GovernorVotesQuorumFraction.sol"; -import "../../governance/extensions/GovernorTimelockControl.sol"; - -contract MyGovernor is - Governor, - GovernorTimelockControl, - GovernorCompatibilityBravo, - GovernorVotes, - GovernorVotesQuorumFraction -{ - constructor(IVotes _token, TimelockController _timelock) - Governor("MyGovernor") - GovernorVotes(_token) - GovernorVotesQuorumFraction(4) - GovernorTimelockControl(_timelock) - {} - - function votingDelay() public pure override returns (uint256) { - return 1; // 1 block - } - - function votingPeriod() public pure override returns (uint256) { - return 45818; // 1 week - } - - function proposalThreshold() public pure override returns (uint256) { - return 1000e18; - } - - // The following functions are overrides required by Solidity. - - function quorum(uint256 blockNumber) - public - view - override(IGovernor, GovernorVotesQuorumFraction) - returns (uint256) - { - return super.quorum(blockNumber); - } - - function state(uint256 proposalId) - public - view - override(Governor, IGovernor, GovernorTimelockControl) - returns (ProposalState) - { - return super.state(proposalId); - } - - function propose( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) public override(Governor, GovernorCompatibilityBravo, IGovernor) returns (uint256) { - return super.propose(targets, values, calldatas, description); - } - - function _execute( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) { - super._execute(proposalId, targets, values, calldatas, descriptionHash); - } - - function _cancel( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - bytes32 descriptionHash - ) internal override(Governor, GovernorTimelockControl) returns (uint256) { - return super._cancel(targets, values, calldatas, descriptionHash); - } - - function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) { - return super._executor(); - } - - function supportsInterface(bytes4 interfaceId) - public - view - override(Governor, IERC165, GovernorTimelockControl) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/package.json b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/package.json deleted file mode 100644 index 4e2c473..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@openzeppelin/contracts", - "description": "Secure Smart Contract library for Solidity", - "version": "4.7.0", - "files": [ - "**/*.sol", - "/build/contracts/*.json", - "!/mocks/**/*" - ], - "scripts": { - "prepare": "bash ../scripts/prepare-contracts-package.sh", - "prepare-docs": "cd ..; npm run prepare-docs" - }, - "repository": { - "type": "git", - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git" - }, - "keywords": [ - "solidity", - "ethereum", - "smart", - "contracts", - "security", - "zeppelin" - ], - "author": "OpenZeppelin Community ", - "license": "MIT", - "bugs": { - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues" - }, - "homepage": "https://openzeppelin.com/contracts/" -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/Clones.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/Clones.sol deleted file mode 100644 index 8d8dc13..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/Clones.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (proxy/Clones.sol) - -pragma solidity ^0.8.0; - -/** - * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for - * deploying minimal proxy contracts, also known as "clones". - * - * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies - * > a minimal bytecode implementation that delegates all calls to a known, fixed address. - * - * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` - * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the - * deterministic method. - * - * _Available since v3.4._ - */ -library Clones { - /** - * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. - * - * This function uses the create opcode, which should never revert. - */ - function clone(address implementation) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - let ptr := mload(0x40) - mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) - mstore(add(ptr, 0x14), shl(0x60, implementation)) - mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) - instance := create(0, ptr, 0x37) - } - require(instance != address(0), "ERC1167: create failed"); - } - - /** - * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. - * - * This function uses the create2 opcode and a `salt` to deterministically deploy - * the clone. Using the same `implementation` and `salt` multiple time will revert, since - * the clones cannot be deployed twice at the same address. - */ - function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { - /// @solidity memory-safe-assembly - assembly { - let ptr := mload(0x40) - mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) - mstore(add(ptr, 0x14), shl(0x60, implementation)) - mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) - instance := create2(0, ptr, 0x37, salt) - } - require(instance != address(0), "ERC1167: create2 failed"); - } - - /** - * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. - */ - function predictDeterministicAddress( - address implementation, - bytes32 salt, - address deployer - ) internal pure returns (address predicted) { - /// @solidity memory-safe-assembly - assembly { - let ptr := mload(0x40) - mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) - mstore(add(ptr, 0x14), shl(0x60, implementation)) - mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000) - mstore(add(ptr, 0x38), shl(0x60, deployer)) - mstore(add(ptr, 0x4c), salt) - mstore(add(ptr, 0x6c), keccak256(ptr, 0x37)) - predicted := keccak256(add(ptr, 0x37), 0x55) - } - } - - /** - * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. - */ - function predictDeterministicAddress(address implementation, bytes32 salt) - internal - view - returns (address predicted) - { - return predictDeterministicAddress(implementation, salt, address(this)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol deleted file mode 100644 index a04d701..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol) - -pragma solidity ^0.8.0; - -import "../Proxy.sol"; -import "./ERC1967Upgrade.sol"; - -/** - * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an - * implementation address that can be changed. This address is stored in storage in the location specified by - * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the - * implementation behind the proxy. - */ -contract ERC1967Proxy is Proxy, ERC1967Upgrade { - /** - * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. - * - * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded - * function call, and allows initializing the storage of the proxy like a Solidity constructor. - */ - constructor(address _logic, bytes memory _data) payable { - _upgradeToAndCall(_logic, _data, false); - } - - /** - * @dev Returns the current implementation address. - */ - function _implementation() internal view virtual override returns (address impl) { - return ERC1967Upgrade._getImplementation(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol deleted file mode 100644 index 77fbdd1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol +++ /dev/null @@ -1,185 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) - -pragma solidity ^0.8.2; - -import "../beacon/IBeacon.sol"; -import "../../interfaces/draft-IERC1822.sol"; -import "../../utils/Address.sol"; -import "../../utils/StorageSlot.sol"; - -/** - * @dev This abstract contract provides getters and event emitting update functions for - * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. - * - * _Available since v4.1._ - * - * @custom:oz-upgrades-unsafe-allow delegatecall - */ -abstract contract ERC1967Upgrade { - // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 - bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; - - /** - * @dev Storage slot with the address of the current implementation. - * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /** - * @dev Emitted when the implementation is upgraded. - */ - event Upgraded(address indexed implementation); - - /** - * @dev Returns the current implementation address. - */ - function _getImplementation() internal view returns (address) { - return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; - } - - /** - * @dev Stores a new address in the EIP1967 implementation slot. - */ - function _setImplementation(address newImplementation) private { - require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); - StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; - } - - /** - * @dev Perform implementation upgrade - * - * Emits an {Upgraded} event. - */ - function _upgradeTo(address newImplementation) internal { - _setImplementation(newImplementation); - emit Upgraded(newImplementation); - } - - /** - * @dev Perform implementation upgrade with additional setup call. - * - * Emits an {Upgraded} event. - */ - function _upgradeToAndCall( - address newImplementation, - bytes memory data, - bool forceCall - ) internal { - _upgradeTo(newImplementation); - if (data.length > 0 || forceCall) { - Address.functionDelegateCall(newImplementation, data); - } - } - - /** - * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. - * - * Emits an {Upgraded} event. - */ - function _upgradeToAndCallUUPS( - address newImplementation, - bytes memory data, - bool forceCall - ) internal { - // Upgrades from old implementations will perform a rollback test. This test requires the new - // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing - // this special case will break upgrade paths from old UUPS implementation to new ones. - if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { - _setImplementation(newImplementation); - } else { - try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { - require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); - } catch { - revert("ERC1967Upgrade: new implementation is not UUPS"); - } - _upgradeToAndCall(newImplementation, data, forceCall); - } - } - - /** - * @dev Storage slot with the admin of the contract. - * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - - /** - * @dev Emitted when the admin account has changed. - */ - event AdminChanged(address previousAdmin, address newAdmin); - - /** - * @dev Returns the current admin. - */ - function _getAdmin() internal view returns (address) { - return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; - } - - /** - * @dev Stores a new address in the EIP1967 admin slot. - */ - function _setAdmin(address newAdmin) private { - require(newAdmin != address(0), "ERC1967: new admin is the zero address"); - StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; - } - - /** - * @dev Changes the admin of the proxy. - * - * Emits an {AdminChanged} event. - */ - function _changeAdmin(address newAdmin) internal { - emit AdminChanged(_getAdmin(), newAdmin); - _setAdmin(newAdmin); - } - - /** - * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. - * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. - */ - bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; - - /** - * @dev Emitted when the beacon is upgraded. - */ - event BeaconUpgraded(address indexed beacon); - - /** - * @dev Returns the current beacon. - */ - function _getBeacon() internal view returns (address) { - return StorageSlot.getAddressSlot(_BEACON_SLOT).value; - } - - /** - * @dev Stores a new beacon in the EIP1967 beacon slot. - */ - function _setBeacon(address newBeacon) private { - require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); - require( - Address.isContract(IBeacon(newBeacon).implementation()), - "ERC1967: beacon implementation is not a contract" - ); - StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; - } - - /** - * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does - * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). - * - * Emits a {BeaconUpgraded} event. - */ - function _upgradeBeaconToAndCall( - address newBeacon, - bytes memory data, - bool forceCall - ) internal { - _setBeacon(newBeacon); - emit BeaconUpgraded(newBeacon); - if (data.length > 0 || forceCall) { - Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol deleted file mode 100644 index 988cf72..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol) - -pragma solidity ^0.8.0; - -/** - * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM - * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to - * be specified by overriding the virtual {_implementation} function. - * - * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a - * different contract through the {_delegate} function. - * - * The success and return data of the delegated call will be returned back to the caller of the proxy. - */ -abstract contract Proxy { - /** - * @dev Delegates the current call to `implementation`. - * - * This function does not return to its internal call site, it will return directly to the external caller. - */ - function _delegate(address implementation) internal virtual { - assembly { - // Copy msg.data. We take full control of memory in this inline assembly - // block because it will not return to Solidity code. We overwrite the - // Solidity scratch pad at memory position 0. - calldatacopy(0, 0, calldatasize()) - - // Call the implementation. - // out and outsize are 0 because we don't know the size yet. - let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) - - // Copy the returned data. - returndatacopy(0, 0, returndatasize()) - - switch result - // delegatecall returns 0 on error. - case 0 { - revert(0, returndatasize()) - } - default { - return(0, returndatasize()) - } - } - } - - /** - * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function - * and {_fallback} should delegate. - */ - function _implementation() internal view virtual returns (address); - - /** - * @dev Delegates the current call to the address returned by `_implementation()`. - * - * This function does not return to its internal call site, it will return directly to the external caller. - */ - function _fallback() internal virtual { - _beforeFallback(); - _delegate(_implementation()); - } - - /** - * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other - * function in the contract matches the call data. - */ - fallback() external payable virtual { - _fallback(); - } - - /** - * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data - * is empty. - */ - receive() external payable virtual { - _fallback(); - } - - /** - * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` - * call, or as part of the Solidity `fallback` or `receive` functions. - * - * If overridden should call `super._beforeFallback()`. - */ - function _beforeFallback() internal virtual {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/README.adoc deleted file mode 100644 index 3112c69..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/README.adoc +++ /dev/null @@ -1,85 +0,0 @@ -= Proxies - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/proxy - -This is a low-level set of contracts implementing different proxy patterns with and without upgradeability. For an in-depth overview of this pattern check out the xref:upgrades-plugins::proxies.adoc[Proxy Upgrade Pattern] page. - -Most of the proxies below are built on an abstract base contract. - -- {Proxy}: Abstract contract implementing the core delegation functionality. - -In order to avoid clashes with the storage variables of the implementation contract behind a proxy, we use https://eips.ethereum.org/EIPS/eip-1967[EIP1967] storage slots. - -- {ERC1967Upgrade}: Internal functions to get and set the storage slots defined in EIP1967. -- {ERC1967Proxy}: A proxy using EIP1967 storage slots. Not upgradeable by default. - -There are two alternative ways to add upgradeability to an ERC1967 proxy. Their differences are explained below in <>. - -- {TransparentUpgradeableProxy}: A proxy with a built in admin and upgrade interface. -- {UUPSUpgradeable}: An upgradeability mechanism to be included in the implementation contract. - -CAUTION: Using upgradeable proxies correctly and securely is a difficult task that requires deep knowledge of the proxy pattern, Solidity, and the EVM. Unless you want a lot of low level control, we recommend using the xref:upgrades-plugins::index.adoc[OpenZeppelin Upgrades Plugins] for Truffle and Hardhat. - -A different family of proxies are beacon proxies. This pattern, popularized by Dharma, allows multiple proxies to be upgraded to a different implementation in a single transaction. - -- {BeaconProxy}: A proxy that retrieves its implementation from a beacon contract. -- {UpgradeableBeacon}: A beacon contract with a built in admin that can upgrade the {BeaconProxy} pointing to it. - -In this pattern, the proxy contract doesn't hold the implementation address in storage like an ERC1967 proxy, instead the address is stored in a separate beacon contract. The `upgrade` operations that are sent to the beacon instead of to the proxy contract, and all proxies that follow that beacon are automatically upgraded. - -Outside the realm of upgradeability, proxies can also be useful to make cheap contract clones, such as those created by an on-chain factory contract that creates many instances of the same contract. These instances are designed to be both cheap to deploy, and cheap to call. - -- {Clones}: A library that can deploy cheap minimal non-upgradeable proxies. - -[[transparent-vs-uups]] -== Transparent vs UUPS Proxies - -The original proxies included in OpenZeppelin followed the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[Transparent Proxy Pattern]. While this pattern is still provided, our recommendation is now shifting towards UUPS proxies, which are both lightweight and versatile. The name UUPS comes from https://eips.ethereum.org/EIPS/eip-1822[EIP1822], which first documented the pattern. - -While both of these share the same interface for upgrades, in UUPS proxies the upgrade is handled by the implementation, and can eventually be removed. Transparent proxies, on the other hand, include the upgrade and admin logic in the proxy itself. This means {TransparentUpgradeableProxy} is more expensive to deploy than what is possible with UUPS proxies. - -UUPS proxies are implemented using an {ERC1967Proxy}. Note that this proxy is not by itself upgradeable. It is the role of the implementation to include, alongside the contract's logic, all the code necessary to update the implementation's address that is stored at a specific slot in the proxy's storage space. This is where the {UUPSUpgradeable} contract comes in. Inheriting from it (and overriding the {xref-UUPSUpgradeable-_authorizeUpgrade-address-}[`_authorizeUpgrade`] function with the relevant access control mechanism) will turn your contract into a UUPS compliant implementation. - -Note that since both proxies use the same storage slot for the implementation address, using a UUPS compliant implementation with a {TransparentUpgradeableProxy} might allow non-admins to perform upgrade operations. - -By default, the upgrade functionality included in {UUPSUpgradeable} contains a security mechanism that will prevent any upgrades to a non UUPS compliant implementation. This prevents upgrades to an implementation contract that wouldn't contain the necessary upgrade mechanism, as it would lock the upgradeability of the proxy forever. This security mechanism can be bypassed by either of: - -- Adding a flag mechanism in the implementation that will disable the upgrade function when triggered. -- Upgrading to an implementation that features an upgrade mechanism without the additional security check, and then upgrading again to another implementation without the upgrade mechanism. - -The current implementation of this security mechanism uses https://eips.ethereum.org/EIPS/eip-1822[EIP1822] to detect the storage slot used by the implementation. A previous implementation, now deprecated, relied on a rollback check. It is possible to upgrade from a contract using the old mechanism to a new one. The inverse is however not possible, as old implementations (before version 4.5) did not include the `ERC1822` interface. - -== Core - -{{Proxy}} - -== ERC1967 - -{{ERC1967Proxy}} - -{{ERC1967Upgrade}} - -== Transparent Proxy - -{{TransparentUpgradeableProxy}} - -{{ProxyAdmin}} - -== Beacon - -{{BeaconProxy}} - -{{IBeacon}} - -{{UpgradeableBeacon}} - -== Minimal Clones - -{{Clones}} - -== Utils - -{{Initializable}} - -{{UUPSUpgradeable}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol deleted file mode 100644 index d217b15..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (proxy/beacon/BeaconProxy.sol) - -pragma solidity ^0.8.0; - -import "./IBeacon.sol"; -import "../Proxy.sol"; -import "../ERC1967/ERC1967Upgrade.sol"; - -/** - * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}. - * - * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't - * conflict with the storage layout of the implementation behind the proxy. - * - * _Available since v3.4._ - */ -contract BeaconProxy is Proxy, ERC1967Upgrade { - /** - * @dev Initializes the proxy with `beacon`. - * - * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This - * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity - * constructor. - * - * Requirements: - * - * - `beacon` must be a contract with the interface {IBeacon}. - */ - constructor(address beacon, bytes memory data) payable { - _upgradeBeaconToAndCall(beacon, data, false); - } - - /** - * @dev Returns the current beacon address. - */ - function _beacon() internal view virtual returns (address) { - return _getBeacon(); - } - - /** - * @dev Returns the current implementation address of the associated beacon. - */ - function _implementation() internal view virtual override returns (address) { - return IBeacon(_getBeacon()).implementation(); - } - - /** - * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}. - * - * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. - * - * Requirements: - * - * - `beacon` must be a contract. - * - The implementation returned by `beacon` must be a contract. - */ - function _setBeacon(address beacon, bytes memory data) internal virtual { - _upgradeBeaconToAndCall(beacon, data, false); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol deleted file mode 100644 index fba3ee2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) - -pragma solidity ^0.8.0; - -/** - * @dev This is the interface that {BeaconProxy} expects of its beacon. - */ -interface IBeacon { - /** - * @dev Must return an address that can be used as a delegate call target. - * - * {BeaconProxy} will check that this address is a contract. - */ - function implementation() external view returns (address); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol deleted file mode 100644 index 5d83ceb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol) - -pragma solidity ^0.8.0; - -import "./IBeacon.sol"; -import "../../access/Ownable.sol"; -import "../../utils/Address.sol"; - -/** - * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their - * implementation contract, which is where they will delegate all function calls. - * - * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon. - */ -contract UpgradeableBeacon is IBeacon, Ownable { - address private _implementation; - - /** - * @dev Emitted when the implementation returned by the beacon is changed. - */ - event Upgraded(address indexed implementation); - - /** - * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the - * beacon. - */ - constructor(address implementation_) { - _setImplementation(implementation_); - } - - /** - * @dev Returns the current implementation address. - */ - function implementation() public view virtual override returns (address) { - return _implementation; - } - - /** - * @dev Upgrades the beacon to a new implementation. - * - * Emits an {Upgraded} event. - * - * Requirements: - * - * - msg.sender must be the owner of the contract. - * - `newImplementation` must be a contract. - */ - function upgradeTo(address newImplementation) public virtual onlyOwner { - _setImplementation(newImplementation); - emit Upgraded(newImplementation); - } - - /** - * @dev Sets the implementation contract address for this beacon - * - * Requirements: - * - * - `newImplementation` must be a contract. - */ - function _setImplementation(address newImplementation) private { - require(Address.isContract(newImplementation), "UpgradeableBeacon: implementation is not a contract"); - _implementation = newImplementation; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol deleted file mode 100644 index 8395342..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol) - -pragma solidity ^0.8.0; - -import "./TransparentUpgradeableProxy.sol"; -import "../../access/Ownable.sol"; - -/** - * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an - * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}. - */ -contract ProxyAdmin is Ownable { - /** - * @dev Returns the current implementation of `proxy`. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - */ - function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) { - // We need to manually run the static call since the getter cannot be flagged as view - // bytes4(keccak256("implementation()")) == 0x5c60da1b - (bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b"); - require(success); - return abi.decode(returndata, (address)); - } - - /** - * @dev Returns the current admin of `proxy`. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - */ - function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) { - // We need to manually run the static call since the getter cannot be flagged as view - // bytes4(keccak256("admin()")) == 0xf851a440 - (bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440"); - require(success); - return abi.decode(returndata, (address)); - } - - /** - * @dev Changes the admin of `proxy` to `newAdmin`. - * - * Requirements: - * - * - This contract must be the current admin of `proxy`. - */ - function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner { - proxy.changeAdmin(newAdmin); - } - - /** - * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - */ - function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner { - proxy.upgradeTo(implementation); - } - - /** - * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See - * {TransparentUpgradeableProxy-upgradeToAndCall}. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - */ - function upgradeAndCall( - TransparentUpgradeableProxy proxy, - address implementation, - bytes memory data - ) public payable virtual onlyOwner { - proxy.upgradeToAndCall{value: msg.value}(implementation, data); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol deleted file mode 100644 index 4de8507..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (proxy/transparent/TransparentUpgradeableProxy.sol) - -pragma solidity ^0.8.0; - -import "../ERC1967/ERC1967Proxy.sol"; - -/** - * @dev 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. - */ -contract TransparentUpgradeableProxy is ERC1967Proxy { - /** - * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and - * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. - */ - constructor( - address _logic, - address admin_, - bytes memory _data - ) payable ERC1967Proxy(_logic, _data) { - _changeAdmin(admin_); - } - - /** - * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. - */ - modifier ifAdmin() { - if (msg.sender == _getAdmin()) { - _; - } else { - _fallback(); - } - } - - /** - * @dev 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` - */ - function admin() external ifAdmin returns (address admin_) { - admin_ = _getAdmin(); - } - - /** - * @dev 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` - */ - function implementation() external ifAdmin returns (address implementation_) { - implementation_ = _implementation(); - } - - /** - * @dev Changes the admin of the proxy. - * - * Emits an {AdminChanged} event. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. - */ - function changeAdmin(address newAdmin) external virtual ifAdmin { - _changeAdmin(newAdmin); - } - - /** - * @dev Upgrade the implementation of the proxy. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. - */ - function upgradeTo(address newImplementation) external ifAdmin { - _upgradeToAndCall(newImplementation, bytes(""), false); - } - - /** - * @dev 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}. - */ - function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { - _upgradeToAndCall(newImplementation, data, true); - } - - /** - * @dev Returns the current admin. - */ - function _admin() internal view virtual returns (address) { - return _getAdmin(); - } - - /** - * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. - */ - function _beforeFallback() internal virtual override { - require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target"); - super._beforeFallback(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol deleted file mode 100644 index 67a81e0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) - -pragma solidity ^0.8.2; - -import "../../utils/Address.sol"; - -/** - * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed - * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an - * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer - * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. - * - * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be - * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in - * case an upgrade adds a module that needs to be initialized. - * - * For example: - * - * [.hljs-theme-light.nopadding] - * ``` - * contract MyToken is ERC20Upgradeable { - * function initialize() initializer public { - * __ERC20_init("MyToken", "MTK"); - * } - * } - * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { - * function initializeV2() reinitializer(2) public { - * __ERC20Permit_init("MyToken"); - * } - * } - * ``` - * - * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as - * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. - * - * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure - * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. - * - * [CAUTION] - * ==== - * Avoid leaving a contract uninitialized. - * - * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation - * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke - * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: - * - * [.hljs-theme-light.nopadding] - * ``` - * /// @custom:oz-upgrades-unsafe-allow constructor - * constructor() { - * _disableInitializers(); - * } - * ``` - * ==== - */ -abstract contract Initializable { - /** - * @dev Indicates that the contract has been initialized. - * @custom:oz-retyped-from bool - */ - uint8 private _initialized; - - /** - * @dev Indicates that the contract is in the process of being initialized. - */ - bool private _initializing; - - /** - * @dev Triggered when the contract has been initialized or reinitialized. - */ - event Initialized(uint8 version); - - /** - * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, - * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. - */ - modifier initializer() { - bool isTopLevelCall = !_initializing; - require( - (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1), - "Initializable: contract is already initialized" - ); - _initialized = 1; - if (isTopLevelCall) { - _initializing = true; - } - _; - if (isTopLevelCall) { - _initializing = false; - emit Initialized(1); - } - } - - /** - * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the - * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be - * used to initialize parent contracts. - * - * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original - * initialization step. This is essential to configure modules that are added through upgrades and that require - * initialization. - * - * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in - * a contract, executing them in the right order is up to the developer or operator. - */ - modifier reinitializer(uint8 version) { - require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); - _initialized = version; - _initializing = true; - _; - _initializing = false; - emit Initialized(version); - } - - /** - * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the - * {initializer} and {reinitializer} modifiers, directly or indirectly. - */ - modifier onlyInitializing() { - require(_initializing, "Initializable: contract is not initializing"); - _; - } - - /** - * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. - * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized - * to any version. It is recommended to use this to lock implementation contracts that are designed to be called - * through proxies. - */ - function _disableInitializers() internal virtual { - require(!_initializing, "Initializable: contract is initializing"); - if (_initialized < type(uint8).max) { - _initialized = type(uint8).max; - emit Initialized(type(uint8).max); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol deleted file mode 100644 index 7ccc503..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) - -pragma solidity ^0.8.0; - -import "../../interfaces/draft-IERC1822.sol"; -import "../ERC1967/ERC1967Upgrade.sol"; - -/** - * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an - * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. - * - * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is - * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing - * `UUPSUpgradeable` with a custom implementation of upgrades. - * - * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. - * - * _Available since v4.1._ - */ -abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade { - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment - address private immutable __self = address(this); - - /** - * @dev Check that the execution is being performed through a delegatecall call and that the execution context is - * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case - * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a - * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to - * fail. - */ - modifier onlyProxy() { - require(address(this) != __self, "Function must be called through delegatecall"); - require(_getImplementation() == __self, "Function must be called through active proxy"); - _; - } - - /** - * @dev Check that the execution is not being performed through a delegate call. This allows a function to be - * callable on the implementing contract but not through proxies. - */ - modifier notDelegated() { - require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); - _; - } - - /** - * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the - * implementation. It is used to validate that the this implementation remains valid after an upgrade. - * - * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks - * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this - * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. - */ - function proxiableUUID() external view virtual override notDelegated returns (bytes32) { - return _IMPLEMENTATION_SLOT; - } - - /** - * @dev Upgrade the implementation of the proxy to `newImplementation`. - * - * Calls {_authorizeUpgrade}. - * - * Emits an {Upgraded} event. - */ - function upgradeTo(address newImplementation) external virtual onlyProxy { - _authorizeUpgrade(newImplementation); - _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); - } - - /** - * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call - * encoded in `data`. - * - * Calls {_authorizeUpgrade}. - * - * Emits an {Upgraded} event. - */ - function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { - _authorizeUpgrade(newImplementation); - _upgradeToAndCallUUPS(newImplementation, data, true); - } - - /** - * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by - * {upgradeTo} and {upgradeToAndCall}. - * - * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. - * - * ```solidity - * function _authorizeUpgrade(address) internal override onlyOwner {} - * ``` - */ - function _authorizeUpgrade(address newImplementation) internal virtual; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/Pausable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/Pausable.sol deleted file mode 100644 index bdd1184..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/Pausable.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) - -pragma solidity ^0.8.0; - -import "../utils/Context.sol"; - -/** - * @dev Contract module which allows children to implement an emergency stop - * mechanism that can be triggered by an authorized account. - * - * This module is used through inheritance. It will make available the - * modifiers `whenNotPaused` and `whenPaused`, which can be applied to - * the functions of your contract. Note that they will not be pausable by - * simply including this module, only once the modifiers are put in place. - */ -abstract contract Pausable is Context { - /** - * @dev Emitted when the pause is triggered by `account`. - */ - event Paused(address account); - - /** - * @dev Emitted when the pause is lifted by `account`. - */ - event Unpaused(address account); - - bool private _paused; - - /** - * @dev Initializes the contract in unpaused state. - */ - constructor() { - _paused = false; - } - - /** - * @dev Modifier to make a function callable only when the contract is not paused. - * - * Requirements: - * - * - The contract must not be paused. - */ - modifier whenNotPaused() { - _requireNotPaused(); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is paused. - * - * Requirements: - * - * - The contract must be paused. - */ - modifier whenPaused() { - _requirePaused(); - _; - } - - /** - * @dev Returns true if the contract is paused, and false otherwise. - */ - function paused() public view virtual returns (bool) { - return _paused; - } - - /** - * @dev Throws if the contract is paused. - */ - function _requireNotPaused() internal view virtual { - require(!paused(), "Pausable: paused"); - } - - /** - * @dev Throws if the contract is not paused. - */ - function _requirePaused() internal view virtual { - require(paused(), "Pausable: not paused"); - } - - /** - * @dev Triggers stopped state. - * - * Requirements: - * - * - The contract must not be paused. - */ - function _pause() internal virtual whenNotPaused { - _paused = true; - emit Paused(_msgSender()); - } - - /** - * @dev Returns to normal state. - * - * Requirements: - * - * - The contract must be paused. - */ - function _unpause() internal virtual whenPaused { - _paused = false; - emit Unpaused(_msgSender()); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/PullPayment.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/PullPayment.sol deleted file mode 100644 index 11ae0e3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/PullPayment.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (security/PullPayment.sol) - -pragma solidity ^0.8.0; - -import "../utils/escrow/Escrow.sol"; - -/** - * @dev Simple implementation of a - * https://consensys.github.io/smart-contract-best-practices/recommendations/#favor-pull-over-push-for-external-calls[pull-payment] - * strategy, where the paying contract doesn't interact directly with the - * receiver account, which must withdraw its payments itself. - * - * Pull-payments are often considered the best practice when it comes to sending - * Ether, security-wise. It prevents recipients from blocking execution, and - * eliminates reentrancy concerns. - * - * TIP: If you would like to learn more about reentrancy and alternative ways - * to protect against it, check out our blog post - * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. - * - * To use, derive from the `PullPayment` contract, and use {_asyncTransfer} - * instead of Solidity's `transfer` function. Payees can query their due - * payments with {payments}, and retrieve them with {withdrawPayments}. - */ -abstract contract PullPayment { - Escrow private immutable _escrow; - - constructor() { - _escrow = new Escrow(); - } - - /** - * @dev Withdraw accumulated payments, forwarding all gas to the recipient. - * - * Note that _any_ account can call this function, not just the `payee`. - * This means that contracts unaware of the `PullPayment` protocol can still - * receive funds this way, by having a separate account call - * {withdrawPayments}. - * - * WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities. - * Make sure you trust the recipient, or are either following the - * checks-effects-interactions pattern or using {ReentrancyGuard}. - * - * @param payee Whose payments will be withdrawn. - * - * Causes the `escrow` to emit a {Withdrawn} event. - */ - function withdrawPayments(address payable payee) public virtual { - _escrow.withdraw(payee); - } - - /** - * @dev Returns the payments owed to an address. - * @param dest The creditor's address. - */ - function payments(address dest) public view returns (uint256) { - return _escrow.depositsOf(dest); - } - - /** - * @dev Called by the payer to store the sent amount as credit to be pulled. - * Funds sent in this way are stored in an intermediate {Escrow} contract, so - * there is no danger of them being spent before withdrawal. - * - * @param dest The destination address of the funds. - * @param amount The amount to transfer. - * - * Causes the `escrow` to emit a {Deposited} event. - */ - function _asyncTransfer(address dest, uint256 amount) internal virtual { - _escrow.deposit{value: amount}(dest); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/README.adoc deleted file mode 100644 index 66f398f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/README.adoc +++ /dev/null @@ -1,20 +0,0 @@ -= Security - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/security - -These contracts aim to cover common security practices. - -* {PullPayment}: A pattern that can be used to avoid reentrancy attacks. -* {ReentrancyGuard}: A modifier that can prevent reentrancy during certain functions. -* {Pausable}: A common emergency response mechanism that can pause functionality while a remediation is pending. - -TIP: For an overview on reentrancy and the possible mechanisms to prevent it, read our article https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. - -== Contracts - -{{PullPayment}} - -{{ReentrancyGuard}} - -{{Pausable}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol deleted file mode 100644 index a0098a2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Contract module that helps prevent reentrant calls to a function. - * - * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier - * available, which can be applied to functions to make sure there are no nested - * (reentrant) calls to them. - * - * Note that because there is a single `nonReentrant` guard, functions marked as - * `nonReentrant` may not call one another. This can be worked around by making - * those functions `private`, and then adding `external` `nonReentrant` entry - * points to them. - * - * TIP: If you would like to learn more about reentrancy and alternative ways - * to protect against it, check out our blog post - * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. - */ -abstract contract ReentrancyGuard { - // Booleans are more expensive than uint256 or any type that takes up a full - // word because each write operation emits an extra SLOAD to first read the - // slot's contents, replace the bits taken up by the boolean, and then write - // back. This is the compiler's defense against contract upgrades and - // pointer aliasing, and it cannot be disabled. - - // The values being non-zero value makes deployment a bit more expensive, - // but in exchange the refund on every call to nonReentrant will be lower in - // amount. Since refunds are capped to a percentage of the total - // transaction's gas, it is best to keep them low in cases like this one, to - // increase the likelihood of the full refund coming into effect. - uint256 private constant _NOT_ENTERED = 1; - uint256 private constant _ENTERED = 2; - - uint256 private _status; - - constructor() { - _status = _NOT_ENTERED; - } - - /** - * @dev Prevents a contract from calling itself, directly or indirectly. - * Calling a `nonReentrant` function from another `nonReentrant` - * function is not supported. It is possible to prevent this from happening - * by making the `nonReentrant` function external, and making it call a - * `private` function that does the actual work. - */ - modifier nonReentrant() { - _nonReentrantBefore(); - _; - _nonReentrantAfter(); - } - - function _nonReentrantBefore() private { - // On the first call to nonReentrant, _notEntered will be true - require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); - - // Any calls to nonReentrant after this point will fail - _status = _ENTERED; - } - - function _nonReentrantAfter() private { - // By storing the original value once again, a refund is triggered (see - // https://eips.ethereum.org/EIPS/eip-2200) - _status = _NOT_ENTERED; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol deleted file mode 100644 index 9e8f79e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol +++ /dev/null @@ -1,517 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol) - -pragma solidity ^0.8.0; - -import "./IERC1155.sol"; -import "./IERC1155Receiver.sol"; -import "./extensions/IERC1155MetadataURI.sol"; -import "../../utils/Address.sol"; -import "../../utils/Context.sol"; -import "../../utils/introspection/ERC165.sol"; - -/** - * @dev Implementation of the basic standard multi-token. - * See https://eips.ethereum.org/EIPS/eip-1155 - * Originally based on code by Enjin: https://github.com/enjin/erc-1155 - * - * _Available since v3.1._ - */ -contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { - using Address for address; - - // Mapping from token ID to account balances - mapping(uint256 => mapping(address => uint256)) private _balances; - - // Mapping from account to operator approvals - mapping(address => mapping(address => bool)) private _operatorApprovals; - - // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json - string private _uri; - - /** - * @dev See {_setURI}. - */ - constructor(string memory uri_) { - _setURI(uri_); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { - return - interfaceId == type(IERC1155).interfaceId || - interfaceId == type(IERC1155MetadataURI).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @dev See {IERC1155MetadataURI-uri}. - * - * This implementation returns the same URI for *all* token types. It relies - * on the token type ID substitution mechanism - * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. - * - * Clients calling this function must replace the `\{id\}` substring with the - * actual token type ID. - */ - function uri(uint256) public view virtual override returns (string memory) { - return _uri; - } - - /** - * @dev See {IERC1155-balanceOf}. - * - * Requirements: - * - * - `account` cannot be the zero address. - */ - function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { - require(account != address(0), "ERC1155: address zero is not a valid owner"); - return _balances[id][account]; - } - - /** - * @dev See {IERC1155-balanceOfBatch}. - * - * Requirements: - * - * - `accounts` and `ids` must have the same length. - */ - function balanceOfBatch(address[] memory accounts, uint256[] memory ids) - public - view - virtual - override - returns (uint256[] memory) - { - require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch"); - - uint256[] memory batchBalances = new uint256[](accounts.length); - - for (uint256 i = 0; i < accounts.length; ++i) { - batchBalances[i] = balanceOf(accounts[i], ids[i]); - } - - return batchBalances; - } - - /** - * @dev See {IERC1155-setApprovalForAll}. - */ - function setApprovalForAll(address operator, bool approved) public virtual override { - _setApprovalForAll(_msgSender(), operator, approved); - } - - /** - * @dev See {IERC1155-isApprovedForAll}. - */ - function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { - return _operatorApprovals[account][operator]; - } - - /** - * @dev See {IERC1155-safeTransferFrom}. - */ - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual override { - require( - from == _msgSender() || isApprovedForAll(from, _msgSender()), - "ERC1155: caller is not token owner nor approved" - ); - _safeTransferFrom(from, to, id, amount, data); - } - - /** - * @dev See {IERC1155-safeBatchTransferFrom}. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual override { - require( - from == _msgSender() || isApprovedForAll(from, _msgSender()), - "ERC1155: caller is not token owner nor approved" - ); - _safeBatchTransferFrom(from, to, ids, amounts, data); - } - - /** - * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - `from` must have a balance of tokens of type `id` of at least `amount`. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the - * acceptance magic value. - */ - function _safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: transfer to the zero address"); - - address operator = _msgSender(); - uint256[] memory ids = _asSingletonArray(id); - uint256[] memory amounts = _asSingletonArray(amount); - - _beforeTokenTransfer(operator, from, to, ids, amounts, data); - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - _balances[id][to] += amount; - - emit TransferSingle(operator, from, to, id, amount); - - _afterTokenTransfer(operator, from, to, ids, amounts, data); - - _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the - * acceptance magic value. - */ - function _safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - require(to != address(0), "ERC1155: transfer to the zero address"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, from, to, ids, amounts, data); - - for (uint256 i = 0; i < ids.length; ++i) { - uint256 id = ids[i]; - uint256 amount = amounts[i]; - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - _balances[id][to] += amount; - } - - emit TransferBatch(operator, from, to, ids, amounts); - - _afterTokenTransfer(operator, from, to, ids, amounts, data); - - _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); - } - - /** - * @dev Sets a new URI for all token types, by relying on the token type ID - * substitution mechanism - * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. - * - * By this mechanism, any occurrence of the `\{id\}` substring in either the - * URI or any of the amounts in the JSON file at said URI will be replaced by - * clients with the token type ID. - * - * For example, the `https://token-cdn-domain/\{id\}.json` URI would be - * interpreted by clients as - * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` - * for token type ID 0x4cce0. - * - * See {uri}. - * - * Because these URIs cannot be meaningfully represented by the {URI} event, - * this function emits no events. - */ - function _setURI(string memory newuri) internal virtual { - _uri = newuri; - } - - /** - * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the - * acceptance magic value. - */ - function _mint( - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: mint to the zero address"); - - address operator = _msgSender(); - uint256[] memory ids = _asSingletonArray(id); - uint256[] memory amounts = _asSingletonArray(amount); - - _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); - - _balances[id][to] += amount; - emit TransferSingle(operator, address(0), to, id, amount); - - _afterTokenTransfer(operator, address(0), to, ids, amounts, data); - - _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `amounts` must have the same length. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the - * acceptance magic value. - */ - function _mintBatch( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: mint to the zero address"); - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); - - for (uint256 i = 0; i < ids.length; i++) { - _balances[ids[i]][to] += amounts[i]; - } - - emit TransferBatch(operator, address(0), to, ids, amounts); - - _afterTokenTransfer(operator, address(0), to, ids, amounts, data); - - _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); - } - - /** - * @dev Destroys `amount` tokens of token type `id` from `from` - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `from` must have at least `amount` tokens of token type `id`. - */ - function _burn( - address from, - uint256 id, - uint256 amount - ) internal virtual { - require(from != address(0), "ERC1155: burn from the zero address"); - - address operator = _msgSender(); - uint256[] memory ids = _asSingletonArray(id); - uint256[] memory amounts = _asSingletonArray(amount); - - _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - - emit TransferSingle(operator, from, address(0), id, amount); - - _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `amounts` must have the same length. - */ - function _burnBatch( - address from, - uint256[] memory ids, - uint256[] memory amounts - ) internal virtual { - require(from != address(0), "ERC1155: burn from the zero address"); - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); - - for (uint256 i = 0; i < ids.length; i++) { - uint256 id = ids[i]; - uint256 amount = amounts[i]; - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - } - - emit TransferBatch(operator, from, address(0), ids, amounts); - - _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); - } - - /** - * @dev Approve `operator` to operate on all of `owner` tokens - * - * Emits an {ApprovalForAll} event. - */ - function _setApprovalForAll( - address owner, - address operator, - bool approved - ) internal virtual { - require(owner != operator, "ERC1155: setting approval status for self"); - _operatorApprovals[owner][operator] = approved; - emit ApprovalForAll(owner, operator, approved); - } - - /** - * @dev Hook that is called before any token transfer. This includes minting - * and burning, as well as batched variants. - * - * The same hook is called on both single and batched variants. For single - * transfers, the length of the `ids` and `amounts` arrays will be 1. - * - * Calling conditions (for each `id` and `amount` pair): - * - * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * of token type `id` will be transferred to `to`. - * - When `from` is zero, `amount` tokens of token type `id` will be minted - * for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` - * will be burned. - * - `from` and `to` are never both zero. - * - `ids` and `amounts` have the same, non-zero length. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - /** - * @dev Hook that is called after any token transfer. This includes minting - * and burning, as well as batched variants. - * - * The same hook is called on both single and batched variants. For single - * transfers, the length of the `id` and `amount` arrays will be 1. - * - * Calling conditions (for each `id` and `amount` pair): - * - * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * of token type `id` will be transferred to `to`. - * - When `from` is zero, `amount` tokens of token type `id` will be minted - * for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` - * will be burned. - * - `from` and `to` are never both zero. - * - `ids` and `amounts` have the same, non-zero length. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _afterTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - function _doSafeTransferAcceptanceCheck( - address operator, - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) private { - if (to.isContract()) { - try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { - if (response != IERC1155Receiver.onERC1155Received.selector) { - revert("ERC1155: ERC1155Receiver rejected tokens"); - } - } catch Error(string memory reason) { - revert(reason); - } catch { - revert("ERC1155: transfer to non-ERC1155Receiver implementer"); - } - } - } - - function _doSafeBatchTransferAcceptanceCheck( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) private { - if (to.isContract()) { - try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( - bytes4 response - ) { - if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { - revert("ERC1155: ERC1155Receiver rejected tokens"); - } - } catch Error(string memory reason) { - revert(reason); - } catch { - revert("ERC1155: transfer to non-ERC1155Receiver implementer"); - } - } - } - - function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { - uint256[] memory array = new uint256[](1); - array[0] = element; - - return array; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol deleted file mode 100644 index 05f74dc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165.sol"; - -/** - * @dev Required interface of an ERC1155 compliant contract, as defined in the - * https://eips.ethereum.org/EIPS/eip-1155[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155 is IERC165 { - /** - * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. - */ - event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); - - /** - * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all - * transfers. - */ - event TransferBatch( - address indexed operator, - address indexed from, - address indexed to, - uint256[] ids, - uint256[] values - ); - - /** - * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to - * `approved`. - */ - event ApprovalForAll(address indexed account, address indexed operator, bool approved); - - /** - * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. - * - * If an {URI} event was emitted for `id`, the standard - * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value - * returned by {IERC1155MetadataURI-uri}. - */ - event URI(string value, uint256 indexed id); - - /** - * @dev Returns the amount of tokens of token type `id` owned by `account`. - * - * Requirements: - * - * - `account` cannot be the zero address. - */ - function balanceOf(address account, uint256 id) external view returns (uint256); - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. - * - * Requirements: - * - * - `accounts` and `ids` must have the same length. - */ - function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) - external - view - returns (uint256[] memory); - - /** - * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, - * - * Emits an {ApprovalForAll} event. - * - * Requirements: - * - * - `operator` cannot be the caller. - */ - function setApprovalForAll(address operator, bool approved) external; - - /** - * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. - * - * See {setApprovalForAll}. - */ - function isApprovedForAll(address account, address operator) external view returns (bool); - - /** - * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. - * - * Emits a {TransferSingle} event. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. - * - `from` must have a balance of tokens of type `id` of at least `amount`. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the - * acceptance magic value. - */ - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) external; - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. - * - * Emits a {TransferBatch} event. - * - * Requirements: - * - * - `ids` and `amounts` must have the same length. - * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the - * acceptance magic value. - */ - function safeBatchTransferFrom( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol deleted file mode 100644 index 0dd271d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165.sol"; - -/** - * @dev _Available since v3.1._ - */ -interface IERC1155Receiver is IERC165 { - /** - * @dev Handles the receipt of a single ERC1155 token type. This function is - * called at the end of a `safeTransferFrom` after the balance has been updated. - * - * NOTE: To accept the transfer, this must return - * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` - * (i.e. 0xf23a6e61, or its own function selector). - * - * @param operator The address which initiated the transfer (i.e. msg.sender) - * @param from The address which previously owned the token - * @param id The ID of the token being transferred - * @param value The amount of tokens being transferred - * @param data Additional data with no specified format - * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed - */ - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) external returns (bytes4); - - /** - * @dev Handles the receipt of a multiple ERC1155 token types. This function - * is called at the end of a `safeBatchTransferFrom` after the balances have - * been updated. - * - * NOTE: To accept the transfer(s), this must return - * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` - * (i.e. 0xbc197c81, or its own function selector). - * - * @param operator The address which initiated the batch transfer (i.e. msg.sender) - * @param from The address which previously owned the token - * @param ids An array containing ids of each token being transferred (order and length must match values array) - * @param values An array containing amounts of each token being transferred (order and length must match ids array) - * @param data Additional data with no specified format - * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed - */ - function onERC1155BatchReceived( - address operator, - address from, - uint256[] calldata ids, - uint256[] calldata values, - bytes calldata data - ) external returns (bytes4); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc deleted file mode 100644 index 13ffbdb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc +++ /dev/null @@ -1,49 +0,0 @@ -= ERC 1155 - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc1155 - -This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-1155[ERC1155 Multi Token Standard]. - -The EIP consists of three interfaces which fulfill different roles, found here as {IERC1155}, {IERC1155MetadataURI} and {IERC1155Receiver}. - -{ERC1155} implements the mandatory {IERC1155} interface, as well as the optional extension {IERC1155MetadataURI}, by relying on the substitution mechanism to use the same URI for all token types, dramatically reducing gas costs. - -Additionally there are multiple custom extensions, including: - -* designation of addresses that can pause token transfers for all users ({ERC1155Pausable}). -* destruction of own tokens ({ERC1155Burnable}). - -NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC1155 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc1155.adoc#Presets[ERC1155 Presets] (such as {ERC1155PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts. - -== Core - -{{IERC1155}} - -{{IERC1155MetadataURI}} - -{{ERC1155}} - -{{IERC1155Receiver}} - -{{ERC1155Receiver}} - -== Extensions - -{{ERC1155Pausable}} - -{{ERC1155Burnable}} - -{{ERC1155Supply}} - -{{ERC1155URIStorage}} - -== Presets - -These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code. - -{{ERC1155PresetMinterPauser}} - -== Utilities - -{{ERC1155Holder}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol deleted file mode 100644 index c82ee41..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/extensions/ERC1155Burnable.sol) - -pragma solidity ^0.8.0; - -import "../ERC1155.sol"; - -/** - * @dev Extension of {ERC1155} that allows token holders to destroy both their - * own tokens and those that they have been approved to use. - * - * _Available since v3.1._ - */ -abstract contract ERC1155Burnable is ERC1155 { - function burn( - address account, - uint256 id, - uint256 value - ) public virtual { - require( - account == _msgSender() || isApprovedForAll(account, _msgSender()), - "ERC1155: caller is not token owner nor approved" - ); - - _burn(account, id, value); - } - - function burnBatch( - address account, - uint256[] memory ids, - uint256[] memory values - ) public virtual { - require( - account == _msgSender() || isApprovedForAll(account, _msgSender()), - "ERC1155: caller is not token owner nor approved" - ); - - _burnBatch(account, ids, values); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol deleted file mode 100644 index 64790e2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Pausable.sol) - -pragma solidity ^0.8.0; - -import "../ERC1155.sol"; -import "../../../security/Pausable.sol"; - -/** - * @dev ERC1155 token with pausable token transfers, minting and burning. - * - * Useful for scenarios such as preventing trades until the end of an evaluation - * period, or having an emergency switch for freezing all token transfers in the - * event of a large bug. - * - * _Available since v3.1._ - */ -abstract contract ERC1155Pausable is ERC1155, Pausable { - /** - * @dev See {ERC1155-_beforeTokenTransfer}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual override { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - - require(!paused(), "ERC1155Pausable: token transfer while paused"); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol deleted file mode 100644 index ec24389..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol) - -pragma solidity ^0.8.0; - -import "../ERC1155.sol"; - -/** - * @dev Extension of ERC1155 that adds tracking of total supply per id. - * - * Useful for scenarios where Fungible and Non-fungible tokens have to be - * clearly identified. Note: While a totalSupply of 1 might mean the - * corresponding is an NFT, there is no guarantees that no other token with the - * same id are not going to be minted. - */ -abstract contract ERC1155Supply is ERC1155 { - mapping(uint256 => uint256) private _totalSupply; - - /** - * @dev Total amount of tokens in with a given id. - */ - function totalSupply(uint256 id) public view virtual returns (uint256) { - return _totalSupply[id]; - } - - /** - * @dev Indicates whether any token exist with a given id, or not. - */ - function exists(uint256 id) public view virtual returns (bool) { - return ERC1155Supply.totalSupply(id) > 0; - } - - /** - * @dev See {ERC1155-_beforeTokenTransfer}. - */ - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual override { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - - if (from == address(0)) { - for (uint256 i = 0; i < ids.length; ++i) { - _totalSupply[ids[i]] += amounts[i]; - } - } - - if (to == address(0)) { - for (uint256 i = 0; i < ids.length; ++i) { - uint256 id = ids[i]; - uint256 amount = amounts[i]; - uint256 supply = _totalSupply[id]; - require(supply >= amount, "ERC1155: burn amount exceeds totalSupply"); - unchecked { - _totalSupply[id] = supply - amount; - } - } - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol deleted file mode 100644 index 623504f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol) - -pragma solidity ^0.8.0; - -import "../../../utils/Strings.sol"; -import "../ERC1155.sol"; - -/** - * @dev ERC1155 token with storage based token URI management. - * Inspired by the ERC721URIStorage extension - * - * _Available since v4.6._ - */ -abstract contract ERC1155URIStorage is ERC1155 { - using Strings for uint256; - - // Optional base URI - string private _baseURI = ""; - - // Optional mapping for token URIs - mapping(uint256 => string) private _tokenURIs; - - /** - * @dev See {IERC1155MetadataURI-uri}. - * - * This implementation returns the concatenation of the `_baseURI` - * and the token-specific uri if the latter is set - * - * This enables the following behaviors: - * - * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation - * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI` - * is empty per default); - * - * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()` - * which in most cases will contain `ERC1155._uri`; - * - * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a - * uri value set, then the result is empty. - */ - function uri(uint256 tokenId) public view virtual override returns (string memory) { - string memory tokenURI = _tokenURIs[tokenId]; - - // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked). - return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId); - } - - /** - * @dev Sets `tokenURI` as the tokenURI of `tokenId`. - */ - function _setURI(uint256 tokenId, string memory tokenURI) internal virtual { - _tokenURIs[tokenId] = tokenURI; - emit URI(uri(tokenId), tokenId); - } - - /** - * @dev Sets `baseURI` as the `_baseURI` for all tokens - */ - function _setBaseURI(string memory baseURI) internal virtual { - _baseURI = baseURI; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol deleted file mode 100644 index 520a297..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) - -pragma solidity ^0.8.0; - -import "../IERC1155.sol"; - -/** - * @dev Interface of the optional ERC1155MetadataExtension interface, as defined - * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. - * - * _Available since v3.1._ - */ -interface IERC1155MetadataURI is IERC1155 { - /** - * @dev Returns the URI for token type `id`. - * - * If the `\{id\}` substring is present in the URI, it must be replaced by - * clients with the actual token type ID. - */ - function uri(uint256 id) external view returns (string memory); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol deleted file mode 100644 index e57fdcc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/presets/ERC1155PresetMinterPauser.sol) - -pragma solidity ^0.8.0; - -import "../ERC1155.sol"; -import "../extensions/ERC1155Burnable.sol"; -import "../extensions/ERC1155Pausable.sol"; -import "../../../access/AccessControlEnumerable.sol"; -import "../../../utils/Context.sol"; - -/** - * @dev {ERC1155} token, including: - * - * - ability for holders to burn (destroy) their tokens - * - a minter role that allows for token minting (creation) - * - a pauser role that allows to stop all token transfers - * - * This contract uses {AccessControl} to lock permissioned functions using the - * different roles - head to its documentation for details. - * - * The account that deploys the contract will be granted the minter and pauser - * roles, as well as the default admin role, which will let it grant both minter - * and pauser roles to other accounts. - * - * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._ - */ -contract ERC1155PresetMinterPauser is Context, AccessControlEnumerable, ERC1155Burnable, ERC1155Pausable { - bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); - bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); - - /** - * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, and `PAUSER_ROLE` to the account that - * deploys the contract. - */ - constructor(string memory uri) ERC1155(uri) { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - - _setupRole(MINTER_ROLE, _msgSender()); - _setupRole(PAUSER_ROLE, _msgSender()); - } - - /** - * @dev Creates `amount` new tokens for `to`, of token type `id`. - * - * See {ERC1155-_mint}. - * - * Requirements: - * - * - the caller must have the `MINTER_ROLE`. - */ - function mint( - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint"); - - _mint(to, id, amount, data); - } - - /** - * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] variant of {mint}. - */ - function mintBatch( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint"); - - _mintBatch(to, ids, amounts, data); - } - - /** - * @dev Pauses all token transfers. - * - * See {ERC1155Pausable} and {Pausable-_pause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function pause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have pauser role to pause"); - _pause(); - } - - /** - * @dev Unpauses all token transfers. - * - * See {ERC1155Pausable} and {Pausable-_unpause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function unpause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have pauser role to unpause"); - _unpause(); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(AccessControlEnumerable, ERC1155) - returns (bool) - { - return super.supportsInterface(interfaceId); - } - - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual override(ERC1155, ERC1155Pausable) { - super._beforeTokenTransfer(operator, from, to, ids, amounts, data); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/README.md b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/README.md deleted file mode 100644 index 468200b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/presets/README.md +++ /dev/null @@ -1 +0,0 @@ -Contract presets are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com/) as a more powerful alternative. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol deleted file mode 100644 index 7249de8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol) - -pragma solidity ^0.8.0; - -import "./ERC1155Receiver.sol"; - -/** - * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens. - * - * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be - * stuck. - * - * @dev _Available since v3.1._ - */ -contract ERC1155Holder is ERC1155Receiver { - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Receiver.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Receiver.sol deleted file mode 100644 index 2e6804a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Receiver.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol) - -pragma solidity ^0.8.0; - -import "../IERC1155Receiver.sol"; -import "../../../utils/introspection/ERC165.sol"; - -/** - * @dev _Available since v3.1._ - */ -abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { - return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol deleted file mode 100644 index 492e261..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol +++ /dev/null @@ -1,389 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) - -pragma solidity ^0.8.0; - -import "./IERC20.sol"; -import "./extensions/IERC20Metadata.sol"; -import "../../utils/Context.sol"; - -/** - * @dev Implementation of the {IERC20} interface. - * - * This implementation is agnostic to the way tokens are created. This means - * that a supply mechanism has to be added in a derived contract using {_mint}. - * For a generic mechanism see {ERC20PresetMinterPauser}. - * - * TIP: For a detailed writeup see our guide - * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How - * to implement supply mechanisms]. - * - * We have followed general OpenZeppelin Contracts guidelines: functions revert - * instead returning `false` on failure. This behavior is nonetheless - * conventional and does not conflict with the expectations of ERC20 - * applications. - * - * Additionally, an {Approval} event is emitted on calls to {transferFrom}. - * This allows applications to reconstruct the allowance for all accounts just - * by listening to said events. Other implementations of the EIP may not emit - * these events, as it isn't required by the specification. - * - * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} - * functions have been added to mitigate the well-known issues around setting - * allowances. See {IERC20-approve}. - */ -contract ERC20 is Context, IERC20, IERC20Metadata { - mapping(address => uint256) private _balances; - - mapping(address => mapping(address => uint256)) private _allowances; - - uint256 private _totalSupply; - - string private _name; - string private _symbol; - - /** - * @dev Sets the values for {name} and {symbol}. - * - * The default value of {decimals} is 18. To select a different value for - * {decimals} you should overload it. - * - * All two of these values are immutable: they can only be set once during - * construction. - */ - constructor(string memory name_, string memory symbol_) { - _name = name_; - _symbol = symbol_; - } - - /** - * @dev Returns the name of the token. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - /** - * @dev Returns the number of decimals used to get its user representation. - * For example, if `decimals` equals `2`, a balance of `505` tokens should - * be displayed to a user as `5.05` (`505 / 10 ** 2`). - * - * Tokens usually opt for a value of 18, imitating the relationship between - * Ether and Wei. This is the value {ERC20} uses, unless this function is - * overridden; - * - * NOTE: This information is only used for _display_ purposes: it in - * no way affects any of the arithmetic of the contract, including - * {IERC20-balanceOf} and {IERC20-transfer}. - */ - function decimals() public view virtual override returns (uint8) { - return 18; - } - - /** - * @dev See {IERC20-totalSupply}. - */ - function totalSupply() public view virtual override returns (uint256) { - return _totalSupply; - } - - /** - * @dev See {IERC20-balanceOf}. - */ - function balanceOf(address account) public view virtual override returns (uint256) { - return _balances[account]; - } - - /** - * @dev See {IERC20-transfer}. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - the caller must have a balance of at least `amount`. - */ - function transfer(address to, uint256 amount) public virtual override returns (bool) { - address owner = _msgSender(); - _transfer(owner, to, amount); - return true; - } - - /** - * @dev See {IERC20-allowance}. - */ - function allowance(address owner, address spender) public view virtual override returns (uint256) { - return _allowances[owner][spender]; - } - - /** - * @dev See {IERC20-approve}. - * - * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on - * `transferFrom`. This is semantically equivalent to an infinite approval. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function approve(address spender, uint256 amount) public virtual override returns (bool) { - address owner = _msgSender(); - _approve(owner, spender, amount); - return true; - } - - /** - * @dev See {IERC20-transferFrom}. - * - * Emits an {Approval} event indicating the updated allowance. This is not - * required by the EIP. See the note at the beginning of {ERC20}. - * - * NOTE: Does not update the allowance if the current allowance - * is the maximum `uint256`. - * - * Requirements: - * - * - `from` and `to` cannot be the zero address. - * - `from` must have a balance of at least `amount`. - * - the caller must have allowance for ``from``'s tokens of at least - * `amount`. - */ - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual override returns (bool) { - address spender = _msgSender(); - _spendAllowance(from, spender, amount); - _transfer(from, to, amount); - return true; - } - - /** - * @dev Atomically increases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { - address owner = _msgSender(); - _approve(owner, spender, allowance(owner, spender) + addedValue); - return true; - } - - /** - * @dev Atomically decreases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `spender` must have allowance for the caller of at least - * `subtractedValue`. - */ - function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { - address owner = _msgSender(); - uint256 currentAllowance = allowance(owner, spender); - require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); - unchecked { - _approve(owner, spender, currentAllowance - subtractedValue); - } - - return true; - } - - /** - * @dev Moves `amount` of tokens from `from` to `to`. - * - * This internal function is equivalent to {transfer}, and can be used to - * e.g. implement automatic token fees, slashing mechanisms, etc. - * - * Emits a {Transfer} event. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `from` must have a balance of at least `amount`. - */ - function _transfer( - address from, - address to, - uint256 amount - ) internal virtual { - require(from != address(0), "ERC20: transfer from the zero address"); - require(to != address(0), "ERC20: transfer to the zero address"); - - _beforeTokenTransfer(from, to, amount); - - uint256 fromBalance = _balances[from]; - require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); - unchecked { - _balances[from] = fromBalance - amount; - // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by - // decrementing then incrementing. - _balances[to] += amount; - } - - emit Transfer(from, to, amount); - - _afterTokenTransfer(from, to, amount); - } - - /** @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. - * - * Emits a {Transfer} event with `from` set to the zero address. - * - * Requirements: - * - * - `account` cannot be the zero address. - */ - function _mint(address account, uint256 amount) internal virtual { - require(account != address(0), "ERC20: mint to the zero address"); - - _beforeTokenTransfer(address(0), account, amount); - - _totalSupply += amount; - unchecked { - // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. - _balances[account] += amount; - } - emit Transfer(address(0), account, amount); - - _afterTokenTransfer(address(0), account, amount); - } - - /** - * @dev Destroys `amount` tokens from `account`, reducing the - * total supply. - * - * Emits a {Transfer} event with `to` set to the zero address. - * - * Requirements: - * - * - `account` cannot be the zero address. - * - `account` must have at least `amount` tokens. - */ - function _burn(address account, uint256 amount) internal virtual { - require(account != address(0), "ERC20: burn from the zero address"); - - _beforeTokenTransfer(account, address(0), amount); - - uint256 accountBalance = _balances[account]; - require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); - unchecked { - _balances[account] = accountBalance - amount; - // Overflow not possible: amount <= accountBalance <= totalSupply. - _totalSupply -= amount; - } - - emit Transfer(account, address(0), amount); - - _afterTokenTransfer(account, address(0), amount); - } - - /** - * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. - * - * This internal function is equivalent to `approve`, and can be used to - * e.g. set automatic allowances for certain subsystems, etc. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `owner` cannot be the zero address. - * - `spender` cannot be the zero address. - */ - function _approve( - address owner, - address spender, - uint256 amount - ) internal virtual { - require(owner != address(0), "ERC20: approve from the zero address"); - require(spender != address(0), "ERC20: approve to the zero address"); - - _allowances[owner][spender] = amount; - emit Approval(owner, spender, amount); - } - - /** - * @dev Updates `owner` s allowance for `spender` based on spent `amount`. - * - * Does not update the allowance amount in case of infinite allowance. - * Revert if not enough allowance is available. - * - * Might emit an {Approval} event. - */ - function _spendAllowance( - address owner, - address spender, - uint256 amount - ) internal virtual { - uint256 currentAllowance = allowance(owner, spender); - if (currentAllowance != type(uint256).max) { - require(currentAllowance >= amount, "ERC20: insufficient allowance"); - unchecked { - _approve(owner, spender, currentAllowance - amount); - } - } - } - - /** - * @dev Hook that is called before any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} - - /** - * @dev Hook that is called after any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * has been transferred to `to`. - * - when `from` is zero, `amount` tokens have been minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens have been burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol deleted file mode 100644 index b816bfe..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC20 standard as defined in the EIP. - */ -interface IERC20 { - /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). - * - * Note that `value` may be zero. - */ - event Transfer(address indexed from, address indexed to, uint256 value); - - /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` is the new allowance. - */ - event Approval(address indexed owner, address indexed spender, uint256 value); - - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by `account`. - */ - function balanceOf(address account) external view returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `to`. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transfer(address to, uint256 amount) external returns (bool); - - /** - * @dev Returns the remaining number of tokens that `spender` will be - * allowed to spend on behalf of `owner` through {transferFrom}. This is - * zero by default. - * - * This value changes when {approve} or {transferFrom} are called. - */ - function allowance(address owner, address spender) external view returns (uint256); - - /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * IMPORTANT: Beware that changing an allowance with this method brings the risk - * that someone may use both the old and the new allowance by unfortunate - * transaction ordering. One possible solution to mitigate this race - * condition is to first reduce the spender's allowance to 0 and set the - * desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * - * Emits an {Approval} event. - */ - function approve(address spender, uint256 amount) external returns (bool); - - /** - * @dev Moves `amount` tokens from `from` to `to` using the - * allowance mechanism. `amount` is then deducted from the caller's - * allowance. - * - * Returns a boolean value indicating whether the operation succeeded. - * - * Emits a {Transfer} event. - */ - function transferFrom( - address from, - address to, - uint256 amount - ) external returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc deleted file mode 100644 index ae2ce36..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc +++ /dev/null @@ -1,86 +0,0 @@ -= ERC 20 - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc20 - -This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-20[ERC20 Token Standard]. - -TIP: For an overview of ERC20 tokens and a walk through on how to create a token contract read our xref:ROOT:erc20.adoc[ERC20 guide]. - -There are a few core contracts that implement the behavior specified in the EIP: - -* {IERC20}: the interface all ERC20 implementations should conform to. -* {IERC20Metadata}: the extended ERC20 interface including the <>, <> and <> functions. -* {ERC20}: the implementation of the ERC20 interface, including the <>, <> and <> optional standard extension to the base interface. - -Additionally there are multiple custom extensions, including: - -* {ERC20Burnable}: destruction of own tokens. -* {ERC20Capped}: enforcement of a cap to the total supply when minting tokens. -* {ERC20Pausable}: ability to pause token transfers. -* {ERC20Snapshot}: efficient storage of past token balances to be later queried at any point in time. -* {ERC20Permit}: gasless approval of tokens (standardized as ERC2612). -* {ERC20FlashMint}: token level support for flash loans through the minting and burning of ephemeral tokens (standardized as ERC3156). -* {ERC20Votes}: support for voting and vote delegation. -* {ERC20VotesComp}: support for voting and vote delegation (compatible with Compound's token, with uint96 restrictions). -* {ERC20Wrapper}: wrapper to create an ERC20 backed by another ERC20, with deposit and withdraw methods. Useful in conjunction with {ERC20Votes}. -* {ERC4626}: tokenized vault that manages shares (represented as ERC20) that are backed by assets (another ERC20). - -Finally, there are some utilities to interact with ERC20 contracts in various ways. - -* {SafeERC20}: a wrapper around the interface that eliminates the need to handle boolean return values. -* {TokenTimelock}: hold tokens for a beneficiary until a specified time. - -The following related EIPs are in draft status. - -- {ERC20Permit} - -NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC20 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc20.adoc#Presets[ERC20 Presets] (such as {ERC20PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts. - -== Core - -{{IERC20}} - -{{IERC20Metadata}} - -{{ERC20}} - -== Extensions - -{{ERC20Burnable}} - -{{ERC20Capped}} - -{{ERC20Pausable}} - -{{ERC20Snapshot}} - -{{ERC20Votes}} - -{{ERC20VotesComp}} - -{{ERC20Wrapper}} - -{{ERC20FlashMint}} - -{{ERC4626}} - -== Draft EIPs - -The following EIPs are still in Draft status. Due to their nature as drafts, the details of these contracts may change and we cannot guarantee their xref:ROOT:releases-stability.adoc[stability]. Minor releases of OpenZeppelin Contracts may contain breaking changes for the contracts in this directory, which will be duly announced in the https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md[changelog]. The EIPs included here are used by projects in production and this may make them less likely to change significantly. - -{{ERC20Permit}} - -== Presets - -These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code. - -{{ERC20PresetMinterPauser}} - -{{ERC20PresetFixedSupply}} - -== Utilities - -{{SafeERC20}} - -{{TokenTimelock}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol deleted file mode 100644 index 1cd08ee..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) - -pragma solidity ^0.8.0; - -import "../ERC20.sol"; -import "../../../utils/Context.sol"; - -/** - * @dev Extension of {ERC20} that allows token holders to destroy both their own - * tokens and those that they have an allowance for, in a way that can be - * recognized off-chain (via event analysis). - */ -abstract contract ERC20Burnable is Context, ERC20 { - /** - * @dev Destroys `amount` tokens from the caller. - * - * See {ERC20-_burn}. - */ - function burn(uint256 amount) public virtual { - _burn(_msgSender(), amount); - } - - /** - * @dev Destroys `amount` tokens from `account`, deducting from the caller's - * allowance. - * - * See {ERC20-_burn} and {ERC20-allowance}. - * - * Requirements: - * - * - the caller must have allowance for ``accounts``'s tokens of at least - * `amount`. - */ - function burnFrom(address account, uint256 amount) public virtual { - _spendAllowance(account, _msgSender(), amount); - _burn(account, amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol deleted file mode 100644 index 16f830d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol) - -pragma solidity ^0.8.0; - -import "../ERC20.sol"; - -/** - * @dev Extension of {ERC20} that adds a cap to the supply of tokens. - */ -abstract contract ERC20Capped is ERC20 { - uint256 private immutable _cap; - - /** - * @dev Sets the value of the `cap`. This value is immutable, it can only be - * set once during construction. - */ - constructor(uint256 cap_) { - require(cap_ > 0, "ERC20Capped: cap is 0"); - _cap = cap_; - } - - /** - * @dev Returns the cap on the token's total supply. - */ - function cap() public view virtual returns (uint256) { - return _cap; - } - - /** - * @dev See {ERC20-_mint}. - */ - function _mint(address account, uint256 amount) internal virtual override { - require(ERC20.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded"); - super._mint(account, amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol deleted file mode 100644 index 38dbc3e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20FlashMint.sol) - -pragma solidity ^0.8.0; - -import "../../../interfaces/IERC3156FlashBorrower.sol"; -import "../../../interfaces/IERC3156FlashLender.sol"; -import "../ERC20.sol"; - -/** - * @dev Implementation of the ERC3156 Flash loans extension, as defined in - * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156]. - * - * Adds the {flashLoan} method, which provides flash loan support at the token - * level. By default there is no fee, but this can be changed by overriding {flashFee}. - * - * _Available since v4.1._ - */ -abstract contract ERC20FlashMint is ERC20, IERC3156FlashLender { - bytes32 private constant _RETURN_VALUE = keccak256("ERC3156FlashBorrower.onFlashLoan"); - - /** - * @dev Returns the maximum amount of tokens available for loan. - * @param token The address of the token that is requested. - * @return The amount of token that can be loaned. - */ - function maxFlashLoan(address token) public view virtual override returns (uint256) { - return token == address(this) ? type(uint256).max - ERC20.totalSupply() : 0; - } - - /** - * @dev Returns the fee applied when doing flash loans. By default this - * implementation has 0 fees. This function can be overloaded to make - * the flash loan mechanism deflationary. - * @param token The token to be flash loaned. - * @param amount The amount of tokens to be loaned. - * @return The fees applied to the corresponding flash loan. - */ - function flashFee(address token, uint256 amount) public view virtual override returns (uint256) { - require(token == address(this), "ERC20FlashMint: wrong token"); - // silence warning about unused variable without the addition of bytecode. - amount; - return 0; - } - - /** - * @dev Returns the receiver address of the flash fee. By default this - * implementation returns the address(0) which means the fee amount will be burnt. - * This function can be overloaded to change the fee receiver. - * @return The address for which the flash fee will be sent to. - */ - function _flashFeeReceiver() internal view virtual returns (address) { - return address(0); - } - - /** - * @dev Performs a flash loan. New tokens are minted and sent to the - * `receiver`, who is required to implement the {IERC3156FlashBorrower} - * interface. By the end of the flash loan, the receiver is expected to own - * amount + fee tokens and have them approved back to the token contract itself so - * they can be burned. - * @param receiver The receiver of the flash loan. Should implement the - * {IERC3156FlashBorrower.onFlashLoan} interface. - * @param token The token to be flash loaned. Only `address(this)` is - * supported. - * @param amount The amount of tokens to be loaned. - * @param data An arbitrary datafield that is passed to the receiver. - * @return `true` if the flash loan was successful. - */ - // This function can reenter, but it doesn't pose a risk because it always preserves the property that the amount - // minted at the beginning is always recovered and burned at the end, or else the entire function will revert. - // slither-disable-next-line reentrancy-no-eth - function flashLoan( - IERC3156FlashBorrower receiver, - address token, - uint256 amount, - bytes calldata data - ) public virtual override returns (bool) { - require(amount <= maxFlashLoan(token), "ERC20FlashMint: amount exceeds maxFlashLoan"); - uint256 fee = flashFee(token, amount); - _mint(address(receiver), amount); - require( - receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE, - "ERC20FlashMint: invalid return value" - ); - address flashFeeReceiver = _flashFeeReceiver(); - _spendAllowance(address(receiver), address(this), amount + fee); - if (fee == 0 || flashFeeReceiver == address(0)) { - _burn(address(receiver), amount + fee); - } else { - _burn(address(receiver), amount); - _transfer(address(receiver), flashFeeReceiver, fee); - } - return true; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol deleted file mode 100644 index e448e96..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol) - -pragma solidity ^0.8.0; - -import "../ERC20.sol"; -import "../../../security/Pausable.sol"; - -/** - * @dev ERC20 token with pausable token transfers, minting and burning. - * - * Useful for scenarios such as preventing trades until the end of an evaluation - * period, or having an emergency switch for freezing all token transfers in the - * event of a large bug. - */ -abstract contract ERC20Pausable is ERC20, Pausable { - /** - * @dev See {ERC20-_beforeTokenTransfer}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - super._beforeTokenTransfer(from, to, amount); - - require(!paused(), "ERC20Pausable: token transfer while paused"); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Snapshot.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Snapshot.sol deleted file mode 100644 index 0b46fc6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Snapshot.sol +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol) - -pragma solidity ^0.8.0; - -import "../ERC20.sol"; -import "../../../utils/Arrays.sol"; -import "../../../utils/Counters.sol"; - -/** - * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and - * total supply at the time are recorded for later access. - * - * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. - * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different - * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be - * used to create an efficient ERC20 forking mechanism. - * - * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a - * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot - * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id - * and the account address. - * - * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it - * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this - * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract. - * - * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient - * alternative consider {ERC20Votes}. - * - * ==== Gas Costs - * - * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log - * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much - * smaller since identical balances in subsequent snapshots are stored as a single entry. - * - * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is - * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent - * transfers will have normal cost until the next snapshot, and so on. - */ - -abstract contract ERC20Snapshot is ERC20 { - // Inspired by Jordi Baylina's MiniMeToken to record historical balances: - // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol - - using Arrays for uint256[]; - using Counters for Counters.Counter; - - // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a - // Snapshot struct, but that would impede usage of functions that work on an array. - struct Snapshots { - uint256[] ids; - uint256[] values; - } - - mapping(address => Snapshots) private _accountBalanceSnapshots; - Snapshots private _totalSupplySnapshots; - - // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid. - Counters.Counter private _currentSnapshotId; - - /** - * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created. - */ - event Snapshot(uint256 id); - - /** - * @dev Creates a new snapshot and returns its snapshot id. - * - * Emits a {Snapshot} event that contains the same id. - * - * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a - * set of accounts, for example using {AccessControl}, or it may be open to the public. - * - * [WARNING] - * ==== - * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking, - * you must consider that it can potentially be used by attackers in two ways. - * - * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow - * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target - * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs - * section above. - * - * We haven't measured the actual numbers; if this is something you're interested in please reach out to us. - * ==== - */ - function _snapshot() internal virtual returns (uint256) { - _currentSnapshotId.increment(); - - uint256 currentId = _getCurrentSnapshotId(); - emit Snapshot(currentId); - return currentId; - } - - /** - * @dev Get the current snapshotId - */ - function _getCurrentSnapshotId() internal view virtual returns (uint256) { - return _currentSnapshotId.current(); - } - - /** - * @dev Retrieves the balance of `account` at the time `snapshotId` was created. - */ - function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) { - (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]); - - return snapshotted ? value : balanceOf(account); - } - - /** - * @dev Retrieves the total supply at the time `snapshotId` was created. - */ - function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) { - (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots); - - return snapshotted ? value : totalSupply(); - } - - // Update balance and/or total supply snapshots before the values are modified. This is implemented - // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - super._beforeTokenTransfer(from, to, amount); - - if (from == address(0)) { - // mint - _updateAccountSnapshot(to); - _updateTotalSupplySnapshot(); - } else if (to == address(0)) { - // burn - _updateAccountSnapshot(from); - _updateTotalSupplySnapshot(); - } else { - // transfer - _updateAccountSnapshot(from); - _updateAccountSnapshot(to); - } - } - - function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) { - require(snapshotId > 0, "ERC20Snapshot: id is 0"); - require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id"); - - // When a valid snapshot is queried, there are three possibilities: - // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never - // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds - // to this id is the current one. - // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the - // requested id, and its value is the one to return. - // c) More snapshots were created after the requested one, and the queried value was later modified. There will be - // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is - // larger than the requested one. - // - // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if - // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does - // exactly this. - - uint256 index = snapshots.ids.findUpperBound(snapshotId); - - if (index == snapshots.ids.length) { - return (false, 0); - } else { - return (true, snapshots.values[index]); - } - } - - function _updateAccountSnapshot(address account) private { - _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account)); - } - - function _updateTotalSupplySnapshot() private { - _updateSnapshot(_totalSupplySnapshots, totalSupply()); - } - - function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { - uint256 currentId = _getCurrentSnapshotId(); - if (_lastSnapshotId(snapshots.ids) < currentId) { - snapshots.ids.push(currentId); - snapshots.values.push(currentValue); - } - } - - function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) { - if (ids.length == 0) { - return 0; - } else { - return ids[ids.length - 1]; - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol deleted file mode 100644 index c0e88bc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sol +++ /dev/null @@ -1,249 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol) - -pragma solidity ^0.8.0; - -import "./draft-ERC20Permit.sol"; -import "../../../utils/math/Math.sol"; -import "../../../governance/utils/IVotes.sol"; -import "../../../utils/math/SafeCast.sol"; -import "../../../utils/cryptography/ECDSA.sol"; - -/** - * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's, - * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1. - * - * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module. - * - * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either - * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting - * power can be queried through the public accessors {getVotes} and {getPastVotes}. - * - * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it - * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. - * - * _Available since v4.2._ - */ -abstract contract ERC20Votes is IVotes, ERC20Permit { - struct Checkpoint { - uint32 fromBlock; - uint224 votes; - } - - bytes32 private constant _DELEGATION_TYPEHASH = - keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); - - mapping(address => address) private _delegates; - mapping(address => Checkpoint[]) private _checkpoints; - Checkpoint[] private _totalSupplyCheckpoints; - - /** - * @dev Get the `pos`-th checkpoint for `account`. - */ - function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) { - return _checkpoints[account][pos]; - } - - /** - * @dev Get number of checkpoints for `account`. - */ - function numCheckpoints(address account) public view virtual returns (uint32) { - return SafeCast.toUint32(_checkpoints[account].length); - } - - /** - * @dev Get the address `account` is currently delegating to. - */ - function delegates(address account) public view virtual override returns (address) { - return _delegates[account]; - } - - /** - * @dev Gets the current votes balance for `account` - */ - function getVotes(address account) public view virtual override returns (uint256) { - uint256 pos = _checkpoints[account].length; - return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes; - } - - /** - * @dev Retrieve the number of votes for `account` at the end of `blockNumber`. - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { - require(blockNumber < block.number, "ERC20Votes: block not yet mined"); - return _checkpointsLookup(_checkpoints[account], blockNumber); - } - - /** - * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. - * It is but NOT the sum of all the delegated votes! - * - * Requirements: - * - * - `blockNumber` must have been already mined - */ - function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { - require(blockNumber < block.number, "ERC20Votes: block not yet mined"); - return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber); - } - - /** - * @dev Lookup a value in a list of (sorted) checkpoints. - */ - function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) { - // We run a binary search to look for the earliest checkpoint taken after `blockNumber`. - // - // During the loop, the index of the wanted checkpoint remains in the range [low-1, high). - // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant. - // - If the middle checkpoint is after `blockNumber`, we look in [low, mid) - // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high) - // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not - // out of bounds (in which case we're looking too far in the past and the result is 0). - // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is - // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out - // the same. - uint256 high = ckpts.length; - uint256 low = 0; - while (low < high) { - uint256 mid = Math.average(low, high); - if (ckpts[mid].fromBlock > blockNumber) { - high = mid; - } else { - low = mid + 1; - } - } - - return high == 0 ? 0 : ckpts[high - 1].votes; - } - - /** - * @dev Delegate votes from the sender to `delegatee`. - */ - function delegate(address delegatee) public virtual override { - _delegate(_msgSender(), delegatee); - } - - /** - * @dev Delegates votes from signer to `delegatee` - */ - function delegateBySig( - address delegatee, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override { - require(block.timestamp <= expiry, "ERC20Votes: signature expired"); - address signer = ECDSA.recover( - _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), - v, - r, - s - ); - require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce"); - _delegate(signer, delegatee); - } - - /** - * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1). - */ - function _maxSupply() internal view virtual returns (uint224) { - return type(uint224).max; - } - - /** - * @dev Snapshots the totalSupply after it has been increased. - */ - function _mint(address account, uint256 amount) internal virtual override { - super._mint(account, amount); - require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes"); - - _writeCheckpoint(_totalSupplyCheckpoints, _add, amount); - } - - /** - * @dev Snapshots the totalSupply after it has been decreased. - */ - function _burn(address account, uint256 amount) internal virtual override { - super._burn(account, amount); - - _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount); - } - - /** - * @dev Move voting power when tokens are transferred. - * - * Emits a {DelegateVotesChanged} event. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - super._afterTokenTransfer(from, to, amount); - - _moveVotingPower(delegates(from), delegates(to), amount); - } - - /** - * @dev Change delegation for `delegator` to `delegatee`. - * - * Emits events {DelegateChanged} and {DelegateVotesChanged}. - */ - function _delegate(address delegator, address delegatee) internal virtual { - address currentDelegate = delegates(delegator); - uint256 delegatorBalance = balanceOf(delegator); - _delegates[delegator] = delegatee; - - emit DelegateChanged(delegator, currentDelegate, delegatee); - - _moveVotingPower(currentDelegate, delegatee, delegatorBalance); - } - - function _moveVotingPower( - address src, - address dst, - uint256 amount - ) private { - if (src != dst && amount > 0) { - if (src != address(0)) { - (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); - emit DelegateVotesChanged(src, oldWeight, newWeight); - } - - if (dst != address(0)) { - (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount); - emit DelegateVotesChanged(dst, oldWeight, newWeight); - } - } - } - - function _writeCheckpoint( - Checkpoint[] storage ckpts, - function(uint256, uint256) view returns (uint256) op, - uint256 delta - ) private returns (uint256 oldWeight, uint256 newWeight) { - uint256 pos = ckpts.length; - oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes; - newWeight = op(oldWeight, delta); - - if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) { - ckpts[pos - 1].votes = SafeCast.toUint224(newWeight); - } else { - ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)})); - } - } - - function _add(uint256 a, uint256 b) private pure returns (uint256) { - return a + b; - } - - function _subtract(uint256 a, uint256 b) private pure returns (uint256) { - return a - b; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20VotesComp.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20VotesComp.sol deleted file mode 100644 index 0461310..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20VotesComp.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20VotesComp.sol) - -pragma solidity ^0.8.0; - -import "./ERC20Votes.sol"; - -/** - * @dev Extension of ERC20 to support Compound's voting and delegation. This version exactly matches Compound's - * interface, with the drawback of only supporting supply up to (2^96^ - 1). - * - * NOTE: You should use this contract if you need exact compatibility with COMP (for example in order to use your token - * with Governor Alpha or Bravo) and if you are sure the supply cap of 2^96^ is enough for you. Otherwise, use the - * {ERC20Votes} variant of this module. - * - * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either - * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting - * power can be queried through the public accessors {getCurrentVotes} and {getPriorVotes}. - * - * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it - * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. - * - * _Available since v4.2._ - */ -abstract contract ERC20VotesComp is ERC20Votes { - /** - * @dev Comp version of the {getVotes} accessor, with `uint96` return type. - */ - function getCurrentVotes(address account) external view virtual returns (uint96) { - return SafeCast.toUint96(getVotes(account)); - } - - /** - * @dev Comp version of the {getPastVotes} accessor, with `uint96` return type. - */ - function getPriorVotes(address account, uint256 blockNumber) external view virtual returns (uint96) { - return SafeCast.toUint96(getPastVotes(account, blockNumber)); - } - - /** - * @dev Maximum token supply. Reduced to `type(uint96).max` (2^96^ - 1) to fit COMP interface. - */ - function _maxSupply() internal view virtual override returns (uint224) { - return type(uint96).max; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol deleted file mode 100644 index 8b153ff..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20Wrapper.sol) - -pragma solidity ^0.8.0; - -import "../ERC20.sol"; -import "../utils/SafeERC20.sol"; - -/** - * @dev Extension of the ERC20 token contract to support token wrapping. - * - * Users can deposit and withdraw "underlying tokens" and receive a matching number of "wrapped tokens". This is useful - * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the - * wrapping of an existing "basic" ERC20 into a governance token. - * - * _Available since v4.2._ - */ -abstract contract ERC20Wrapper is ERC20 { - IERC20 public immutable underlying; - - constructor(IERC20 underlyingToken) { - underlying = underlyingToken; - } - - /** - * @dev See {ERC20-decimals}. - */ - function decimals() public view virtual override returns (uint8) { - try IERC20Metadata(address(underlying)).decimals() returns (uint8 value) { - return value; - } catch { - return super.decimals(); - } - } - - /** - * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens. - */ - function depositFor(address account, uint256 amount) public virtual returns (bool) { - SafeERC20.safeTransferFrom(underlying, _msgSender(), address(this), amount); - _mint(account, amount); - return true; - } - - /** - * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens. - */ - function withdrawTo(address account, uint256 amount) public virtual returns (bool) { - _burn(_msgSender(), amount); - SafeERC20.safeTransfer(underlying, account, amount); - return true; - } - - /** - * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal - * function that can be exposed with access control if desired. - */ - function _recover(address account) internal virtual returns (uint256) { - uint256 value = underlying.balanceOf(address(this)) - totalSupply(); - _mint(account, value); - return value; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol deleted file mode 100644 index c770285..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC4626.sol) - -pragma solidity ^0.8.0; - -import "../ERC20.sol"; -import "../utils/SafeERC20.sol"; -import "../../../interfaces/IERC4626.sol"; -import "../../../utils/math/Math.sol"; - -/** - * @dev Implementation of the ERC4626 "Tokenized Vault Standard" as defined in - * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626]. - * - * This extension allows the minting and burning of "shares" (represented using the ERC20 inheritance) in exchange for - * underlying "assets" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends - * the ERC20 standard. Any additional extensions included along it would affect the "shares" token represented by this - * contract and not the "assets" token which is an independent contract. - * - * CAUTION: Deposits and withdrawals may incur unexpected slippage. Users should verify that the amount received of - * shares or assets is as expected. EOAs should operate through a wrapper that performs these checks such as - * https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router]. - * - * _Available since v4.7._ - */ -abstract contract ERC4626 is ERC20, IERC4626 { - using Math for uint256; - - IERC20Metadata private immutable _asset; - - /** - * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777). - */ - constructor(IERC20Metadata asset_) { - _asset = asset_; - } - - /** @dev See {IERC4626-asset}. */ - function asset() public view virtual override returns (address) { - return address(_asset); - } - - /** @dev See {IERC4626-totalAssets}. */ - function totalAssets() public view virtual override returns (uint256) { - return _asset.balanceOf(address(this)); - } - - /** @dev See {IERC4626-convertToShares}. */ - function convertToShares(uint256 assets) public view virtual override returns (uint256 shares) { - return _convertToShares(assets, Math.Rounding.Down); - } - - /** @dev See {IERC4626-convertToAssets}. */ - function convertToAssets(uint256 shares) public view virtual override returns (uint256 assets) { - return _convertToAssets(shares, Math.Rounding.Down); - } - - /** @dev See {IERC4626-maxDeposit}. */ - function maxDeposit(address) public view virtual override returns (uint256) { - return _isVaultCollateralized() ? type(uint256).max : 0; - } - - /** @dev See {IERC4626-maxMint}. */ - function maxMint(address) public view virtual override returns (uint256) { - return type(uint256).max; - } - - /** @dev See {IERC4626-maxWithdraw}. */ - function maxWithdraw(address owner) public view virtual override returns (uint256) { - return _convertToAssets(balanceOf(owner), Math.Rounding.Down); - } - - /** @dev See {IERC4626-maxRedeem}. */ - function maxRedeem(address owner) public view virtual override returns (uint256) { - return balanceOf(owner); - } - - /** @dev See {IERC4626-previewDeposit}. */ - function previewDeposit(uint256 assets) public view virtual override returns (uint256) { - return _convertToShares(assets, Math.Rounding.Down); - } - - /** @dev See {IERC4626-previewMint}. */ - function previewMint(uint256 shares) public view virtual override returns (uint256) { - return _convertToAssets(shares, Math.Rounding.Up); - } - - /** @dev See {IERC4626-previewWithdraw}. */ - function previewWithdraw(uint256 assets) public view virtual override returns (uint256) { - return _convertToShares(assets, Math.Rounding.Up); - } - - /** @dev See {IERC4626-previewRedeem}. */ - function previewRedeem(uint256 shares) public view virtual override returns (uint256) { - return _convertToAssets(shares, Math.Rounding.Down); - } - - /** @dev See {IERC4626-deposit}. */ - function deposit(uint256 assets, address receiver) public virtual override returns (uint256) { - require(assets <= maxDeposit(receiver), "ERC4626: deposit more than max"); - - uint256 shares = previewDeposit(assets); - _deposit(_msgSender(), receiver, assets, shares); - - return shares; - } - - /** @dev See {IERC4626-mint}. */ - function mint(uint256 shares, address receiver) public virtual override returns (uint256) { - require(shares <= maxMint(receiver), "ERC4626: mint more than max"); - - uint256 assets = previewMint(shares); - _deposit(_msgSender(), receiver, assets, shares); - - return assets; - } - - /** @dev See {IERC4626-withdraw}. */ - function withdraw( - uint256 assets, - address receiver, - address owner - ) public virtual override returns (uint256) { - require(assets <= maxWithdraw(owner), "ERC4626: withdraw more than max"); - - uint256 shares = previewWithdraw(assets); - _withdraw(_msgSender(), receiver, owner, assets, shares); - - return shares; - } - - /** @dev See {IERC4626-redeem}. */ - function redeem( - uint256 shares, - address receiver, - address owner - ) public virtual override returns (uint256) { - require(shares <= maxRedeem(owner), "ERC4626: redeem more than max"); - - uint256 assets = previewRedeem(shares); - _withdraw(_msgSender(), receiver, owner, assets, shares); - - return assets; - } - - /** - * @dev Internal conversion function (from assets to shares) with support for rounding direction. - * - * Will revert if assets > 0, totalSupply > 0 and totalAssets = 0. That corresponds to a case where any asset - * would represent an infinite amout of shares. - */ - function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256 shares) { - uint256 supply = totalSupply(); - return - (assets == 0 || supply == 0) - ? assets.mulDiv(10**decimals(), 10**_asset.decimals(), rounding) - : assets.mulDiv(supply, totalAssets(), rounding); - } - - /** - * @dev Internal conversion function (from shares to assets) with support for rounding direction. - */ - function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view virtual returns (uint256 assets) { - uint256 supply = totalSupply(); - return - (supply == 0) - ? shares.mulDiv(10**_asset.decimals(), 10**decimals(), rounding) - : shares.mulDiv(totalAssets(), supply, rounding); - } - - /** - * @dev Deposit/mint common workflow. - */ - function _deposit( - address caller, - address receiver, - uint256 assets, - uint256 shares - ) internal virtual { - // If _asset is ERC777, `transferFrom` can trigger a reenterancy BEFORE the transfer happens through the - // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer, - // calls the vault, which is assumed not malicious. - // - // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the - // assets are transfered and before the shares are minted, which is a valid state. - // slither-disable-next-line reentrancy-no-eth - SafeERC20.safeTransferFrom(_asset, caller, address(this), assets); - _mint(receiver, shares); - - emit Deposit(caller, receiver, assets, shares); - } - - /** - * @dev Withdraw/redeem common workflow. - */ - function _withdraw( - address caller, - address receiver, - address owner, - uint256 assets, - uint256 shares - ) internal virtual { - if (caller != owner) { - _spendAllowance(owner, caller, shares); - } - - // If _asset is ERC777, `transfer` can trigger a reentrancy AFTER the transfer happens through the - // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer, - // calls the vault, which is assumed not malicious. - // - // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the - // shares are burned and after the assets are transfered, which is a valid state. - _burn(owner, shares); - SafeERC20.safeTransfer(_asset, receiver, assets); - - emit Withdraw(caller, receiver, owner, assets, shares); - } - - function _isVaultCollateralized() private view returns (bool) { - return totalAssets() > 0 || totalSupply() == 0; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol deleted file mode 100644 index 83ba6ac..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) - -pragma solidity ^0.8.0; - -import "../IERC20.sol"; - -/** - * @dev Interface for the optional metadata functions from the ERC20 standard. - * - * _Available since v4.1._ - */ -interface IERC20Metadata is IERC20 { - /** - * @dev Returns the name of the token. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the symbol of the token. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the decimals places of the token. - */ - function decimals() external view returns (uint8); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-ERC20Permit.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-ERC20Permit.sol deleted file mode 100644 index 63aeb52..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-ERC20Permit.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol) - -pragma solidity ^0.8.0; - -import "./draft-IERC20Permit.sol"; -import "../ERC20.sol"; -import "../../../utils/cryptography/draft-EIP712.sol"; -import "../../../utils/cryptography/ECDSA.sol"; -import "../../../utils/Counters.sol"; - -/** - * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in - * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. - * - * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by - * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't - * need to send a transaction, and thus is not required to hold Ether at all. - * - * _Available since v3.4._ - */ -abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { - using Counters for Counters.Counter; - - mapping(address => Counters.Counter) private _nonces; - - // solhint-disable-next-line var-name-mixedcase - bytes32 private constant _PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - /** - * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. - * However, to ensure consistency with the upgradeable transpiler, we will continue - * to reserve a slot. - * @custom:oz-renamed-from _PERMIT_TYPEHASH - */ - // solhint-disable-next-line var-name-mixedcase - bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; - - /** - * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. - * - * It's a good idea to use the same `name` that is defined as the ERC20 token name. - */ - constructor(string memory name) EIP712(name, "1") {} - - /** - * @dev See {IERC20Permit-permit}. - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override { - require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); - - bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); - - bytes32 hash = _hashTypedDataV4(structHash); - - address signer = ECDSA.recover(hash, v, r, s); - require(signer == owner, "ERC20Permit: invalid signature"); - - _approve(owner, spender, value); - } - - /** - * @dev See {IERC20Permit-nonces}. - */ - function nonces(address owner) public view virtual override returns (uint256) { - return _nonces[owner].current(); - } - - /** - * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view override returns (bytes32) { - return _domainSeparatorV4(); - } - - /** - * @dev "Consume a nonce": return the current value and increment. - * - * _Available since v4.1._ - */ - function _useNonce(address owner) internal virtual returns (uint256 current) { - Counters.Counter storage nonce = _nonces[owner]; - current = nonce.current(); - nonce.increment(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol deleted file mode 100644 index 6363b14..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in - * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. - * - * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by - * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't - * need to send a transaction, and thus is not required to hold Ether at all. - */ -interface IERC20Permit { - /** - * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, - * given ``owner``'s signed approval. - * - * IMPORTANT: The same issues {IERC20-approve} has related to transaction - * ordering also apply here. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `deadline` must be a timestamp in the future. - * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` - * over the EIP712-formatted function arguments. - * - the signature must use ``owner``'s current nonce (see {nonces}). - * - * For more information on the signature format, see the - * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP - * section]. - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) external; - - /** - * @dev Returns the current nonce for `owner`. This value must be - * included whenever a signature is generated for {permit}. - * - * Every successful call to {permit} increases ``owner``'s nonce by one. This - * prevents a signature from being used multiple times. - */ - function nonces(address owner) external view returns (uint256); - - /** - * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. - */ - // solhint-disable-next-line func-name-mixedcase - function DOMAIN_SEPARATOR() external view returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol deleted file mode 100644 index 52afef3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/presets/ERC20PresetFixedSupply.sol) -pragma solidity ^0.8.0; - -import "../extensions/ERC20Burnable.sol"; - -/** - * @dev {ERC20} token, including: - * - * - Preminted initial supply - * - Ability for holders to burn (destroy) their tokens - * - No access control mechanism (for minting/pausing) and hence no governance - * - * This contract uses {ERC20Burnable} to include burn capabilities - head to - * its documentation for details. - * - * _Available since v3.4._ - * - * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._ - */ -contract ERC20PresetFixedSupply is ERC20Burnable { - /** - * @dev Mints `initialSupply` amount of token and transfers them to `owner`. - * - * See {ERC20-constructor}. - */ - constructor( - string memory name, - string memory symbol, - uint256 initialSupply, - address owner - ) ERC20(name, symbol) { - _mint(owner, initialSupply); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol deleted file mode 100644 index e711a89..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/presets/ERC20PresetMinterPauser.sol) - -pragma solidity ^0.8.0; - -import "../ERC20.sol"; -import "../extensions/ERC20Burnable.sol"; -import "../extensions/ERC20Pausable.sol"; -import "../../../access/AccessControlEnumerable.sol"; -import "../../../utils/Context.sol"; - -/** - * @dev {ERC20} token, including: - * - * - ability for holders to burn (destroy) their tokens - * - a minter role that allows for token minting (creation) - * - a pauser role that allows to stop all token transfers - * - * This contract uses {AccessControl} to lock permissioned functions using the - * different roles - head to its documentation for details. - * - * The account that deploys the contract will be granted the minter and pauser - * roles, as well as the default admin role, which will let it grant both minter - * and pauser roles to other accounts. - * - * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._ - */ -contract ERC20PresetMinterPauser is Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable { - bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); - bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); - - /** - * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the - * account that deploys the contract. - * - * See {ERC20-constructor}. - */ - constructor(string memory name, string memory symbol) ERC20(name, symbol) { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - - _setupRole(MINTER_ROLE, _msgSender()); - _setupRole(PAUSER_ROLE, _msgSender()); - } - - /** - * @dev Creates `amount` new tokens for `to`. - * - * See {ERC20-_mint}. - * - * Requirements: - * - * - the caller must have the `MINTER_ROLE`. - */ - function mint(address to, uint256 amount) public virtual { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint"); - _mint(to, amount); - } - - /** - * @dev Pauses all token transfers. - * - * See {ERC20Pausable} and {Pausable-_pause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function pause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause"); - _pause(); - } - - /** - * @dev Unpauses all token transfers. - * - * See {ERC20Pausable} and {Pausable-_unpause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function unpause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause"); - _unpause(); - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override(ERC20, ERC20Pausable) { - super._beforeTokenTransfer(from, to, amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/README.md b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/README.md deleted file mode 100644 index 468200b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/presets/README.md +++ /dev/null @@ -1 +0,0 @@ -Contract presets are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com/) as a more powerful alternative. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol deleted file mode 100644 index 37d25f5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) - -pragma solidity ^0.8.0; - -import "../IERC20.sol"; -import "../extensions/draft-IERC20Permit.sol"; -import "../../../utils/Address.sol"; - -/** - * @title SafeERC20 - * @dev Wrappers around ERC20 operations that throw on failure (when the token - * contract returns false). Tokens that return no value (and instead revert or - * throw on failure) are also supported, non-reverting calls are assumed to be - * successful. - * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, - * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. - */ -library SafeERC20 { - using Address for address; - - function safeTransfer( - IERC20 token, - address to, - uint256 value - ) internal { - _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); - } - - function safeTransferFrom( - IERC20 token, - address from, - address to, - uint256 value - ) internal { - _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); - } - - /** - * @dev Deprecated. This function has issues similar to the ones found in - * {IERC20-approve}, and its usage is discouraged. - * - * Whenever possible, use {safeIncreaseAllowance} and - * {safeDecreaseAllowance} instead. - */ - function safeApprove( - IERC20 token, - address spender, - uint256 value - ) internal { - // safeApprove should only be called when setting an initial allowance, - // or when resetting it to zero. To increase and decrease it, use - // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' - require( - (value == 0) || (token.allowance(address(this), spender) == 0), - "SafeERC20: approve from non-zero to non-zero allowance" - ); - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); - } - - function safeIncreaseAllowance( - IERC20 token, - address spender, - uint256 value - ) internal { - uint256 newAllowance = token.allowance(address(this), spender) + value; - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); - } - - function safeDecreaseAllowance( - IERC20 token, - address spender, - uint256 value - ) internal { - unchecked { - uint256 oldAllowance = token.allowance(address(this), spender); - require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); - uint256 newAllowance = oldAllowance - value; - _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); - } - } - - function safePermit( - IERC20Permit token, - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) internal { - uint256 nonceBefore = token.nonces(owner); - token.permit(owner, spender, value, deadline, v, r, s); - uint256 nonceAfter = token.nonces(owner); - require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); - } - - /** - * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement - * on the return value: the return value is optional (but if data is returned, it must not be false). - * @param token The token targeted by the call. - * @param data The call data (encoded using abi.encode or one of its variants). - */ - function _callOptionalReturn(IERC20 token, bytes memory data) private { - // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since - // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that - // the target address contains contract code and also asserts for success in the low-level call. - - bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); - if (returndata.length > 0) { - // Return data is optional - require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/utils/TokenTimelock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/utils/TokenTimelock.sol deleted file mode 100644 index d879a7e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC20/utils/TokenTimelock.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/utils/TokenTimelock.sol) - -pragma solidity ^0.8.0; - -import "./SafeERC20.sol"; - -/** - * @dev A token holder contract that will allow a beneficiary to extract the - * tokens after a given release time. - * - * Useful for simple vesting schedules like "advisors get all of their tokens - * after 1 year". - */ -contract TokenTimelock { - using SafeERC20 for IERC20; - - // ERC20 basic token contract being held - IERC20 private immutable _token; - - // beneficiary of tokens after they are released - address private immutable _beneficiary; - - // timestamp when token release is enabled - uint256 private immutable _releaseTime; - - /** - * @dev Deploys a timelock instance that is able to hold the token specified, and will only release it to - * `beneficiary_` when {release} is invoked after `releaseTime_`. The release time is specified as a Unix timestamp - * (in seconds). - */ - constructor( - IERC20 token_, - address beneficiary_, - uint256 releaseTime_ - ) { - require(releaseTime_ > block.timestamp, "TokenTimelock: release time is before current time"); - _token = token_; - _beneficiary = beneficiary_; - _releaseTime = releaseTime_; - } - - /** - * @dev Returns the token being held. - */ - function token() public view virtual returns (IERC20) { - return _token; - } - - /** - * @dev Returns the beneficiary that will receive the tokens. - */ - function beneficiary() public view virtual returns (address) { - return _beneficiary; - } - - /** - * @dev Returns the time when the tokens are released in seconds since Unix epoch (i.e. Unix timestamp). - */ - function releaseTime() public view virtual returns (uint256) { - return _releaseTime; - } - - /** - * @dev Transfers tokens held by the timelock to the beneficiary. Will only succeed if invoked after the release - * time. - */ - function release() public virtual { - require(block.timestamp >= releaseTime(), "TokenTimelock: current time is before release time"); - - uint256 amount = token().balanceOf(address(this)); - require(amount > 0, "TokenTimelock: no tokens to release"); - - token().safeTransfer(beneficiary(), amount); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol deleted file mode 100644 index c6246c3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol +++ /dev/null @@ -1,454 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol) - -pragma solidity ^0.8.0; - -import "./IERC721.sol"; -import "./IERC721Receiver.sol"; -import "./extensions/IERC721Metadata.sol"; -import "../../utils/Address.sol"; -import "../../utils/Context.sol"; -import "../../utils/Strings.sol"; -import "../../utils/introspection/ERC165.sol"; - -/** - * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including - * the Metadata extension, but not including the Enumerable extension, which is available separately as - * {ERC721Enumerable}. - */ -contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { - using Address for address; - using Strings for uint256; - - // Token name - string private _name; - - // Token symbol - string private _symbol; - - // Mapping from token ID to owner address - mapping(uint256 => address) private _owners; - - // Mapping owner address to token count - mapping(address => uint256) private _balances; - - // Mapping from token ID to approved address - mapping(uint256 => address) private _tokenApprovals; - - // Mapping from owner to operator approvals - mapping(address => mapping(address => bool)) private _operatorApprovals; - - /** - * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. - */ - constructor(string memory name_, string memory symbol_) { - _name = name_; - _symbol = symbol_; - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { - return - interfaceId == type(IERC721).interfaceId || - interfaceId == type(IERC721Metadata).interfaceId || - super.supportsInterface(interfaceId); - } - - /** - * @dev See {IERC721-balanceOf}. - */ - function balanceOf(address owner) public view virtual override returns (uint256) { - require(owner != address(0), "ERC721: address zero is not a valid owner"); - return _balances[owner]; - } - - /** - * @dev See {IERC721-ownerOf}. - */ - function ownerOf(uint256 tokenId) public view virtual override returns (address) { - address owner = _owners[tokenId]; - require(owner != address(0), "ERC721: invalid token ID"); - return owner; - } - - /** - * @dev See {IERC721Metadata-name}. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev See {IERC721Metadata-symbol}. - */ - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - /** - * @dev See {IERC721Metadata-tokenURI}. - */ - function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { - _requireMinted(tokenId); - - string memory baseURI = _baseURI(); - return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; - } - - /** - * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each - * token will be the concatenation of the `baseURI` and the `tokenId`. Empty - * by default, can be overridden in child contracts. - */ - function _baseURI() internal view virtual returns (string memory) { - return ""; - } - - /** - * @dev See {IERC721-approve}. - */ - function approve(address to, uint256 tokenId) public virtual override { - address owner = ERC721.ownerOf(tokenId); - require(to != owner, "ERC721: approval to current owner"); - - require( - _msgSender() == owner || isApprovedForAll(owner, _msgSender()), - "ERC721: approve caller is not token owner nor approved for all" - ); - - _approve(to, tokenId); - } - - /** - * @dev See {IERC721-getApproved}. - */ - function getApproved(uint256 tokenId) public view virtual override returns (address) { - _requireMinted(tokenId); - - return _tokenApprovals[tokenId]; - } - - /** - * @dev See {IERC721-setApprovalForAll}. - */ - function setApprovalForAll(address operator, bool approved) public virtual override { - _setApprovalForAll(_msgSender(), operator, approved); - } - - /** - * @dev See {IERC721-isApprovedForAll}. - */ - function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { - return _operatorApprovals[owner][operator]; - } - - /** - * @dev See {IERC721-transferFrom}. - */ - function transferFrom( - address from, - address to, - uint256 tokenId - ) public virtual override { - //solhint-disable-next-line max-line-length - require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved"); - - _transfer(from, to, tokenId); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId - ) public virtual override { - safeTransferFrom(from, to, tokenId, ""); - } - - /** - * @dev See {IERC721-safeTransferFrom}. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes memory data - ) public virtual override { - require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved"); - _safeTransfer(from, to, tokenId, data); - } - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients - * are aware of the ERC721 protocol to prevent tokens from being forever locked. - * - * `data` is additional data, it has no specified format and it is sent in call to `to`. - * - * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. - * implement alternative mechanisms to perform token transfer, such as signature-based. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function _safeTransfer( - address from, - address to, - uint256 tokenId, - bytes memory data - ) internal virtual { - _transfer(from, to, tokenId); - require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); - } - - /** - * @dev Returns whether `tokenId` exists. - * - * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. - * - * Tokens start existing when they are minted (`_mint`), - * and stop existing when they are burned (`_burn`). - */ - function _exists(uint256 tokenId) internal view virtual returns (bool) { - return _owners[tokenId] != address(0); - } - - /** - * @dev Returns whether `spender` is allowed to manage `tokenId`. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { - address owner = ERC721.ownerOf(tokenId); - return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); - } - - /** - * @dev Safely mints `tokenId` and transfers it to `to`. - * - * Requirements: - * - * - `tokenId` must not exist. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function _safeMint(address to, uint256 tokenId) internal virtual { - _safeMint(to, tokenId, ""); - } - - /** - * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is - * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. - */ - function _safeMint( - address to, - uint256 tokenId, - bytes memory data - ) internal virtual { - _mint(to, tokenId); - require( - _checkOnERC721Received(address(0), to, tokenId, data), - "ERC721: transfer to non ERC721Receiver implementer" - ); - } - - /** - * @dev Mints `tokenId` and transfers it to `to`. - * - * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible - * - * Requirements: - * - * - `tokenId` must not exist. - * - `to` cannot be the zero address. - * - * Emits a {Transfer} event. - */ - function _mint(address to, uint256 tokenId) internal virtual { - require(to != address(0), "ERC721: mint to the zero address"); - require(!_exists(tokenId), "ERC721: token already minted"); - - _beforeTokenTransfer(address(0), to, tokenId); - - _balances[to] += 1; - _owners[tokenId] = to; - - emit Transfer(address(0), to, tokenId); - - _afterTokenTransfer(address(0), to, tokenId); - } - - /** - * @dev Destroys `tokenId`. - * The approval is cleared when the token is burned. - * - * Requirements: - * - * - `tokenId` must exist. - * - * Emits a {Transfer} event. - */ - function _burn(uint256 tokenId) internal virtual { - address owner = ERC721.ownerOf(tokenId); - - _beforeTokenTransfer(owner, address(0), tokenId); - - // Clear approvals - delete _tokenApprovals[tokenId]; - - _balances[owner] -= 1; - delete _owners[tokenId]; - - emit Transfer(owner, address(0), tokenId); - - _afterTokenTransfer(owner, address(0), tokenId); - } - - /** - * @dev Transfers `tokenId` from `from` to `to`. - * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - `tokenId` token must be owned by `from`. - * - * Emits a {Transfer} event. - */ - function _transfer( - address from, - address to, - uint256 tokenId - ) internal virtual { - require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); - require(to != address(0), "ERC721: transfer to the zero address"); - - _beforeTokenTransfer(from, to, tokenId); - - // Clear approvals from the previous owner - delete _tokenApprovals[tokenId]; - - _balances[from] -= 1; - _balances[to] += 1; - _owners[tokenId] = to; - - emit Transfer(from, to, tokenId); - - _afterTokenTransfer(from, to, tokenId); - } - - /** - * @dev Approve `to` to operate on `tokenId` - * - * Emits an {Approval} event. - */ - function _approve(address to, uint256 tokenId) internal virtual { - _tokenApprovals[tokenId] = to; - emit Approval(ERC721.ownerOf(tokenId), to, tokenId); - } - - /** - * @dev Approve `operator` to operate on all of `owner` tokens - * - * Emits an {ApprovalForAll} event. - */ - function _setApprovalForAll( - address owner, - address operator, - bool approved - ) internal virtual { - require(owner != operator, "ERC721: approve to caller"); - _operatorApprovals[owner][operator] = approved; - emit ApprovalForAll(owner, operator, approved); - } - - /** - * @dev Reverts if the `tokenId` has not been minted yet. - */ - function _requireMinted(uint256 tokenId) internal view virtual { - require(_exists(tokenId), "ERC721: invalid token ID"); - } - - /** - * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. - * The call is not executed if the target address is not a contract. - * - * @param from address representing the previous owner of the given token ID - * @param to target address that will receive the tokens - * @param tokenId uint256 ID of the token to be transferred - * @param data bytes optional data to send along with the call - * @return bool whether the call correctly returned the expected magic value - */ - function _checkOnERC721Received( - address from, - address to, - uint256 tokenId, - bytes memory data - ) private returns (bool) { - if (to.isContract()) { - try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { - return retval == IERC721Receiver.onERC721Received.selector; - } catch (bytes memory reason) { - if (reason.length == 0) { - revert("ERC721: transfer to non ERC721Receiver implementer"); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } else { - return true; - } - } - - /** - * @dev Hook that is called before any token transfer. This includes minting - * and burning. - * - * Calling conditions: - * - * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be - * transferred to `to`. - * - When `from` is zero, `tokenId` will be minted for `to`. - * - When `to` is zero, ``from``'s `tokenId` will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual {} - - /** - * @dev Hook that is called after any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol deleted file mode 100644 index 4bb973b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) - -pragma solidity ^0.8.0; - -import "../../utils/introspection/IERC165.sol"; - -/** - * @dev Required interface of an ERC721 compliant contract. - */ -interface IERC721 is IERC165 { - /** - * @dev Emitted when `tokenId` token is transferred from `from` to `to`. - */ - event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); - - /** - * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. - */ - event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); - - /** - * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. - */ - event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - - /** - * @dev Returns the number of tokens in ``owner``'s account. - */ - function balanceOf(address owner) external view returns (uint256 balance); - - /** - * @dev Returns the owner of the `tokenId` token. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function ownerOf(uint256 tokenId) external view returns (address owner); - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes calldata data - ) external; - - /** - * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients - * are aware of the ERC721 protocol to prevent tokens from being forever locked. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must exist and be owned by `from`. - * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. - * - * Emits a {Transfer} event. - */ - function safeTransferFrom( - address from, - address to, - uint256 tokenId - ) external; - - /** - * @dev Transfers `tokenId` token from `from` to `to`. - * - * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. - * - * Requirements: - * - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - `tokenId` token must be owned by `from`. - * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - * - * Emits a {Transfer} event. - */ - function transferFrom( - address from, - address to, - uint256 tokenId - ) external; - - /** - * @dev Gives permission to `to` to transfer `tokenId` token to another account. - * The approval is cleared when the token is transferred. - * - * Only a single account can be approved at a time, so approving the zero address clears previous approvals. - * - * Requirements: - * - * - The caller must own the token or be an approved operator. - * - `tokenId` must exist. - * - * Emits an {Approval} event. - */ - function approve(address to, uint256 tokenId) external; - - /** - * @dev Approve or remove `operator` as an operator for the caller. - * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. - * - * Requirements: - * - * - The `operator` cannot be the caller. - * - * Emits an {ApprovalForAll} event. - */ - function setApprovalForAll(address operator, bool _approved) external; - - /** - * @dev Returns the account approved for `tokenId` token. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function getApproved(uint256 tokenId) external view returns (address operator); - - /** - * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. - * - * See {setApprovalForAll} - */ - function isApprovedForAll(address owner, address operator) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol deleted file mode 100644 index de67209..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) - -pragma solidity ^0.8.0; - -/** - * @title ERC721 token receiver interface - * @dev Interface for any contract that wants to support safeTransfers - * from ERC721 asset contracts. - */ -interface IERC721Receiver { - /** - * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} - * by `operator` from `from`, this function is called. - * - * It must return its Solidity selector to confirm the token transfer. - * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. - * - * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. - */ - function onERC721Received( - address operator, - address from, - uint256 tokenId, - bytes calldata data - ) external returns (bytes4); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc deleted file mode 100644 index 9295957..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc +++ /dev/null @@ -1,67 +0,0 @@ -= ERC 721 - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc721 - -This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-721[ERC721 Non-Fungible Token Standard]. - -TIP: For a walk through on how to create an ERC721 token read our xref:ROOT:erc721.adoc[ERC721 guide]. - -The EIP specifies four interfaces: - -* {IERC721}: Core functionality required in all compliant implementation. -* {IERC721Metadata}: Optional extension that adds name, symbol, and token URI, almost always included. -* {IERC721Enumerable}: Optional extension that allows enumerating the tokens on chain, often not included since it requires large gas overhead. -* {IERC721Receiver}: An interface that must be implemented by contracts if they want to accept tokens through `safeTransferFrom`. - -OpenZeppelin Contracts provides implementations of all four interfaces: - -* {ERC721}: The core and metadata extensions, with a base URI mechanism. -* {ERC721Enumerable}: The enumerable extension. -* {ERC721Holder}: A bare bones implementation of the receiver interface. - -Additionally there are a few of other extensions: - -* {ERC721URIStorage}: A more flexible but more expensive way of storing metadata. -* {ERC721Votes}: Support for voting and vote delegation. -* {ERC721Royalty}: A way to signal royalty information following ERC2981. -* {ERC721Pausable}: A primitive to pause contract operation. -* {ERC721Burnable}: A way for token holders to burn their own tokens. - -NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC721 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc721.adoc#Presets[ERC721 Presets] (such as {ERC721PresetMinterPauserAutoId}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts. - -== Core - -{{IERC721}} - -{{IERC721Metadata}} - -{{IERC721Enumerable}} - -{{ERC721}} - -{{ERC721Enumerable}} - -{{IERC721Receiver}} - -== Extensions - -{{ERC721Pausable}} - -{{ERC721Burnable}} - -{{ERC721URIStorage}} - -{{ERC721Votes}} - -{{ERC721Royalty}} - -== Presets - -These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code. - -{{ERC721PresetMinterPauserAutoId}} - -== Utilities - -{{ERC721Holder}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol deleted file mode 100644 index 2775648..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol) - -pragma solidity ^0.8.0; - -import "../ERC721.sol"; -import "../../../utils/Context.sol"; - -/** - * @title ERC721 Burnable Token - * @dev ERC721 Token that can be burned (destroyed). - */ -abstract contract ERC721Burnable is Context, ERC721 { - /** - * @dev Burns `tokenId`. See {ERC721-_burn}. - * - * Requirements: - * - * - The caller must own `tokenId` or be an approved operator. - */ - function burn(uint256 tokenId) public virtual { - //solhint-disable-next-line max-line-length - require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved"); - _burn(tokenId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol deleted file mode 100644 index 46afd5d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol +++ /dev/null @@ -1,163 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol) - -pragma solidity ^0.8.0; - -import "../ERC721.sol"; -import "./IERC721Enumerable.sol"; - -/** - * @dev This implements an optional extension of {ERC721} defined in the EIP that adds - * enumerability of all the token ids in the contract as well as all token ids owned by each - * account. - */ -abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { - // Mapping from owner to list of owned token IDs - mapping(address => mapping(uint256 => uint256)) private _ownedTokens; - - // Mapping from token ID to index of the owner tokens list - mapping(uint256 => uint256) private _ownedTokensIndex; - - // Array with all token ids, used for enumeration - uint256[] private _allTokens; - - // Mapping from token id to position in the allTokens array - mapping(uint256 => uint256) private _allTokensIndex; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { - return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. - */ - function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { - require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); - return _ownedTokens[owner][index]; - } - - /** - * @dev See {IERC721Enumerable-totalSupply}. - */ - function totalSupply() public view virtual override returns (uint256) { - return _allTokens.length; - } - - /** - * @dev See {IERC721Enumerable-tokenByIndex}. - */ - function tokenByIndex(uint256 index) public view virtual override returns (uint256) { - require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); - return _allTokens[index]; - } - - /** - * @dev Hook that is called before any token transfer. This includes minting - * and burning. - * - * Calling conditions: - * - * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be - * transferred to `to`. - * - When `from` is zero, `tokenId` will be minted for `to`. - * - When `to` is zero, ``from``'s `tokenId` will be burned. - * - `from` cannot be the zero address. - * - `to` cannot be the zero address. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual override { - super._beforeTokenTransfer(from, to, tokenId); - - if (from == address(0)) { - _addTokenToAllTokensEnumeration(tokenId); - } else if (from != to) { - _removeTokenFromOwnerEnumeration(from, tokenId); - } - if (to == address(0)) { - _removeTokenFromAllTokensEnumeration(tokenId); - } else if (to != from) { - _addTokenToOwnerEnumeration(to, tokenId); - } - } - - /** - * @dev Private function to add a token to this extension's ownership-tracking data structures. - * @param to address representing the new owner of the given token ID - * @param tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { - uint256 length = ERC721.balanceOf(to); - _ownedTokens[to][length] = tokenId; - _ownedTokensIndex[tokenId] = length; - } - - /** - * @dev Private function to add a token to this extension's token tracking data structures. - * @param tokenId uint256 ID of the token to be added to the tokens list - */ - function _addTokenToAllTokensEnumeration(uint256 tokenId) private { - _allTokensIndex[tokenId] = _allTokens.length; - _allTokens.push(tokenId); - } - - /** - * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that - * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for - * gas optimizations e.g. when performing a transfer operation (avoiding double writes). - * This has O(1) time complexity, but alters the order of the _ownedTokens array. - * @param from address representing the previous owner of the given token ID - * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { - // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and - // then delete the last slot (swap and pop). - - uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; - uint256 tokenIndex = _ownedTokensIndex[tokenId]; - - // When the token to delete is the last token, the swap operation is unnecessary - if (tokenIndex != lastTokenIndex) { - uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; - - _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token - _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index - } - - // This also deletes the contents at the last position of the array - delete _ownedTokensIndex[tokenId]; - delete _ownedTokens[from][lastTokenIndex]; - } - - /** - * @dev Private function to remove a token from this extension's token tracking data structures. - * This has O(1) time complexity, but alters the order of the _allTokens array. - * @param tokenId uint256 ID of the token to be removed from the tokens list - */ - function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { - // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and - // then delete the last slot (swap and pop). - - uint256 lastTokenIndex = _allTokens.length - 1; - uint256 tokenIndex = _allTokensIndex[tokenId]; - - // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so - // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding - // an 'if' statement (like in _removeTokenFromOwnerEnumeration) - uint256 lastTokenId = _allTokens[lastTokenIndex]; - - _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token - _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index - - // This also deletes the contents at the last position of the array - delete _allTokensIndex[tokenId]; - _allTokens.pop(); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol deleted file mode 100644 index fbf8b63..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Pausable.sol) - -pragma solidity ^0.8.0; - -import "../ERC721.sol"; -import "../../../security/Pausable.sol"; - -/** - * @dev ERC721 token with pausable token transfers, minting and burning. - * - * Useful for scenarios such as preventing trades until the end of an evaluation - * period, or having an emergency switch for freezing all token transfers in the - * event of a large bug. - */ -abstract contract ERC721Pausable is ERC721, Pausable { - /** - * @dev See {ERC721-_beforeTokenTransfer}. - * - * Requirements: - * - * - the contract must not be paused. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual override { - super._beforeTokenTransfer(from, to, tokenId); - - require(!paused(), "ERC721Pausable: token transfer while paused"); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol deleted file mode 100644 index f9414da..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/ERC721Royalty.sol) - -pragma solidity ^0.8.0; - -import "../ERC721.sol"; -import "../../common/ERC2981.sol"; -import "../../../utils/introspection/ERC165.sol"; - -/** - * @dev Extension of ERC721 with the ERC2981 NFT Royalty Standard, a standardized way to retrieve royalty payment - * information. - * - * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for - * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. - * - * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See - * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to - * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. - * - * _Available since v4.5._ - */ -abstract contract ERC721Royalty is ERC2981, ERC721 { - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { - return super.supportsInterface(interfaceId); - } - - /** - * @dev See {ERC721-_burn}. This override additionally clears the royalty information for the token. - */ - function _burn(uint256 tokenId) internal virtual override { - super._burn(tokenId); - _resetTokenRoyalty(tokenId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol deleted file mode 100644 index e83a5ed..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol) - -pragma solidity ^0.8.0; - -import "../ERC721.sol"; - -/** - * @dev ERC721 token with storage based token URI management. - */ -abstract contract ERC721URIStorage is ERC721 { - using Strings for uint256; - - // Optional mapping for token URIs - mapping(uint256 => string) private _tokenURIs; - - /** - * @dev See {IERC721Metadata-tokenURI}. - */ - function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { - _requireMinted(tokenId); - - string memory _tokenURI = _tokenURIs[tokenId]; - string memory base = _baseURI(); - - // If there is no base URI, return the token URI. - if (bytes(base).length == 0) { - return _tokenURI; - } - // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). - if (bytes(_tokenURI).length > 0) { - return string(abi.encodePacked(base, _tokenURI)); - } - - return super.tokenURI(tokenId); - } - - /** - * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. - * - * Requirements: - * - * - `tokenId` must exist. - */ - function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { - require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); - _tokenURIs[tokenId] = _tokenURI; - } - - /** - * @dev See {ERC721-_burn}. This override additionally checks to see if a - * token-specific URI was set for the token, and if so, it deletes the token URI from - * the storage mapping. - */ - function _burn(uint256 tokenId) internal virtual override { - super._burn(tokenId); - - if (bytes(_tokenURIs[tokenId]).length != 0) { - delete _tokenURIs[tokenId]; - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol deleted file mode 100644 index dfea427..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) - -pragma solidity ^0.8.0; - -import "../IERC721.sol"; - -/** - * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721Enumerable is IERC721 { - /** - * @dev Returns the total amount of tokens stored by the contract. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns a token ID owned by `owner` at a given `index` of its token list. - * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. - */ - function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); - - /** - * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. - * Use along with {totalSupply} to enumerate all tokens. - */ - function tokenByIndex(uint256 index) external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol deleted file mode 100644 index dca77ba..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) - -pragma solidity ^0.8.0; - -import "../IERC721.sol"; - -/** - * @title ERC-721 Non-Fungible Token Standard, optional metadata extension - * @dev See https://eips.ethereum.org/EIPS/eip-721 - */ -interface IERC721Metadata is IERC721 { - /** - * @dev Returns the token collection name. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the token collection symbol. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. - */ - function tokenURI(uint256 tokenId) external view returns (string memory); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/draft-ERC721Votes.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/draft-ERC721Votes.sol deleted file mode 100644 index b4ec91e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/extensions/draft-ERC721Votes.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/extensions/draft-ERC721Votes.sol) - -pragma solidity ^0.8.0; - -import "../ERC721.sol"; -import "../../../governance/utils/Votes.sol"; - -/** - * @dev Extension of ERC721 to support voting and delegation as implemented by {Votes}, where each individual NFT counts - * as 1 vote unit. - * - * Tokens do not count as votes until they are delegated, because votes must be tracked which incurs an additional cost - * on every transfer. Token holders can either delegate to a trusted representative who will decide how to make use of - * the votes in governance decisions, or they can delegate to themselves to be their own representative. - * - * _Available since v4.5._ - */ -abstract contract ERC721Votes is ERC721, Votes { - /** - * @dev Adjusts votes when tokens are transferred. - * - * Emits a {Votes-DelegateVotesChanged} event. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual override { - _transferVotingUnits(from, to, 1); - super._afterTokenTransfer(from, to, tokenId); - } - - /** - * @dev Returns the balance of `account`. - */ - function _getVotingUnits(address account) internal view virtual override returns (uint256) { - return balanceOf(account); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol deleted file mode 100644 index 11b9787..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol) - -pragma solidity ^0.8.0; - -import "../ERC721.sol"; -import "../extensions/ERC721Enumerable.sol"; -import "../extensions/ERC721Burnable.sol"; -import "../extensions/ERC721Pausable.sol"; -import "../../../access/AccessControlEnumerable.sol"; -import "../../../utils/Context.sol"; -import "../../../utils/Counters.sol"; - -/** - * @dev {ERC721} token, including: - * - * - ability for holders to burn (destroy) their tokens - * - a minter role that allows for token minting (creation) - * - a pauser role that allows to stop all token transfers - * - token ID and URI autogeneration - * - * This contract uses {AccessControl} to lock permissioned functions using the - * different roles - head to its documentation for details. - * - * The account that deploys the contract will be granted the minter and pauser - * roles, as well as the default admin role, which will let it grant both minter - * and pauser roles to other accounts. - * - * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._ - */ -contract ERC721PresetMinterPauserAutoId is - Context, - AccessControlEnumerable, - ERC721Enumerable, - ERC721Burnable, - ERC721Pausable -{ - using Counters for Counters.Counter; - - bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); - bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); - - Counters.Counter private _tokenIdTracker; - - string private _baseTokenURI; - - /** - * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the - * account that deploys the contract. - * - * Token URIs will be autogenerated based on `baseURI` and their token IDs. - * See {ERC721-tokenURI}. - */ - constructor( - string memory name, - string memory symbol, - string memory baseTokenURI - ) ERC721(name, symbol) { - _baseTokenURI = baseTokenURI; - - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - - _setupRole(MINTER_ROLE, _msgSender()); - _setupRole(PAUSER_ROLE, _msgSender()); - } - - function _baseURI() internal view virtual override returns (string memory) { - return _baseTokenURI; - } - - /** - * @dev Creates a new token for `to`. Its token ID will be automatically - * assigned (and available on the emitted {IERC721-Transfer} event), and the token - * URI autogenerated based on the base URI passed at construction. - * - * See {ERC721-_mint}. - * - * Requirements: - * - * - the caller must have the `MINTER_ROLE`. - */ - function mint(address to) public virtual { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint"); - - // We cannot just use balanceOf to create the new tokenId because tokens - // can be burned (destroyed), so we need a separate counter. - _mint(to, _tokenIdTracker.current()); - _tokenIdTracker.increment(); - } - - /** - * @dev Pauses all token transfers. - * - * See {ERC721Pausable} and {Pausable-_pause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function pause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause"); - _pause(); - } - - /** - * @dev Unpauses all token transfers. - * - * See {ERC721Pausable} and {Pausable-_unpause}. - * - * Requirements: - * - * - the caller must have the `PAUSER_ROLE`. - */ - function unpause() public virtual { - require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause"); - _unpause(); - } - - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId - ) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) { - super._beforeTokenTransfer(from, to, tokenId); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) - public - view - virtual - override(AccessControlEnumerable, ERC721, ERC721Enumerable) - returns (bool) - { - return super.supportsInterface(interfaceId); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/presets/README.md b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/presets/README.md deleted file mode 100644 index 468200b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/presets/README.md +++ /dev/null @@ -1 +0,0 @@ -Contract presets are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com/) as a more powerful alternative. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol deleted file mode 100644 index 394926d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol) - -pragma solidity ^0.8.0; - -import "../IERC721Receiver.sol"; - -/** - * @dev Implementation of the {IERC721Receiver} interface. - * - * Accepts all token transfers. - * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. - */ -contract ERC721Holder is IERC721Receiver { - /** - * @dev See {IERC721Receiver-onERC721Received}. - * - * Always returns `IERC721Receiver.onERC721Received.selector`. - */ - function onERC721Received( - address, - address, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC721Received.selector; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/ERC777.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/ERC777.sol deleted file mode 100644 index a461004..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/ERC777.sol +++ /dev/null @@ -1,547 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC777/ERC777.sol) - -pragma solidity ^0.8.0; - -import "./IERC777.sol"; -import "./IERC777Recipient.sol"; -import "./IERC777Sender.sol"; -import "../ERC20/IERC20.sol"; -import "../../utils/Address.sol"; -import "../../utils/Context.sol"; -import "../../utils/introspection/IERC1820Registry.sol"; - -/** - * @dev Implementation of the {IERC777} interface. - * - * This implementation is agnostic to the way tokens are created. This means - * that a supply mechanism has to be added in a derived contract using {_mint}. - * - * Support for ERC20 is included in this contract, as specified by the EIP: both - * the ERC777 and ERC20 interfaces can be safely used when interacting with it. - * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token - * movements. - * - * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there - * are no special restrictions in the amount of tokens that created, moved, or - * destroyed. This makes integration with ERC20 applications seamless. - */ -contract ERC777 is Context, IERC777, IERC20 { - using Address for address; - - IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); - - mapping(address => uint256) private _balances; - - uint256 private _totalSupply; - - string private _name; - string private _symbol; - - bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender"); - bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); - - // This isn't ever read from - it's only used to respond to the defaultOperators query. - address[] private _defaultOperatorsArray; - - // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators). - mapping(address => bool) private _defaultOperators; - - // For each account, a mapping of its operators and revoked default operators. - mapping(address => mapping(address => bool)) private _operators; - mapping(address => mapping(address => bool)) private _revokedDefaultOperators; - - // ERC20-allowances - mapping(address => mapping(address => uint256)) private _allowances; - - /** - * @dev `defaultOperators` may be an empty array. - */ - constructor( - string memory name_, - string memory symbol_, - address[] memory defaultOperators_ - ) { - _name = name_; - _symbol = symbol_; - - _defaultOperatorsArray = defaultOperators_; - for (uint256 i = 0; i < defaultOperators_.length; i++) { - _defaultOperators[defaultOperators_[i]] = true; - } - - // register interfaces - _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this)); - _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this)); - } - - /** - * @dev See {IERC777-name}. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev See {IERC777-symbol}. - */ - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - /** - * @dev See {ERC20-decimals}. - * - * Always returns 18, as per the - * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility). - */ - function decimals() public pure virtual returns (uint8) { - return 18; - } - - /** - * @dev See {IERC777-granularity}. - * - * This implementation always returns `1`. - */ - function granularity() public view virtual override returns (uint256) { - return 1; - } - - /** - * @dev See {IERC777-totalSupply}. - */ - function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) { - return _totalSupply; - } - - /** - * @dev Returns the amount of tokens owned by an account (`tokenHolder`). - */ - function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) { - return _balances[tokenHolder]; - } - - /** - * @dev See {IERC777-send}. - * - * Also emits a {IERC20-Transfer} event for ERC20 compatibility. - */ - function send( - address recipient, - uint256 amount, - bytes memory data - ) public virtual override { - _send(_msgSender(), recipient, amount, data, "", true); - } - - /** - * @dev See {IERC20-transfer}. - * - * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient} - * interface if it is a contract. - * - * Also emits a {Sent} event. - */ - function transfer(address recipient, uint256 amount) public virtual override returns (bool) { - _send(_msgSender(), recipient, amount, "", "", false); - return true; - } - - /** - * @dev See {IERC777-burn}. - * - * Also emits a {IERC20-Transfer} event for ERC20 compatibility. - */ - function burn(uint256 amount, bytes memory data) public virtual override { - _burn(_msgSender(), amount, data, ""); - } - - /** - * @dev See {IERC777-isOperatorFor}. - */ - function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) { - return - operator == tokenHolder || - (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) || - _operators[tokenHolder][operator]; - } - - /** - * @dev See {IERC777-authorizeOperator}. - */ - function authorizeOperator(address operator) public virtual override { - require(_msgSender() != operator, "ERC777: authorizing self as operator"); - - if (_defaultOperators[operator]) { - delete _revokedDefaultOperators[_msgSender()][operator]; - } else { - _operators[_msgSender()][operator] = true; - } - - emit AuthorizedOperator(operator, _msgSender()); - } - - /** - * @dev See {IERC777-revokeOperator}. - */ - function revokeOperator(address operator) public virtual override { - require(operator != _msgSender(), "ERC777: revoking self as operator"); - - if (_defaultOperators[operator]) { - _revokedDefaultOperators[_msgSender()][operator] = true; - } else { - delete _operators[_msgSender()][operator]; - } - - emit RevokedOperator(operator, _msgSender()); - } - - /** - * @dev See {IERC777-defaultOperators}. - */ - function defaultOperators() public view virtual override returns (address[] memory) { - return _defaultOperatorsArray; - } - - /** - * @dev See {IERC777-operatorSend}. - * - * Emits {Sent} and {IERC20-Transfer} events. - */ - function operatorSend( - address sender, - address recipient, - uint256 amount, - bytes memory data, - bytes memory operatorData - ) public virtual override { - require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder"); - _send(sender, recipient, amount, data, operatorData, true); - } - - /** - * @dev See {IERC777-operatorBurn}. - * - * Emits {Burned} and {IERC20-Transfer} events. - */ - function operatorBurn( - address account, - uint256 amount, - bytes memory data, - bytes memory operatorData - ) public virtual override { - require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder"); - _burn(account, amount, data, operatorData); - } - - /** - * @dev See {IERC20-allowance}. - * - * Note that operator and allowance concepts are orthogonal: operators may - * not have allowance, and accounts with allowance may not be operators - * themselves. - */ - function allowance(address holder, address spender) public view virtual override returns (uint256) { - return _allowances[holder][spender]; - } - - /** - * @dev See {IERC20-approve}. - * - * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on - * `transferFrom`. This is semantically equivalent to an infinite approval. - * - * Note that accounts cannot have allowance issued by their operators. - */ - function approve(address spender, uint256 value) public virtual override returns (bool) { - address holder = _msgSender(); - _approve(holder, spender, value); - return true; - } - - /** - * @dev See {IERC20-transferFrom}. - * - * NOTE: Does not update the allowance if the current allowance - * is the maximum `uint256`. - * - * Note that operator and allowance concepts are orthogonal: operators cannot - * call `transferFrom` (unless they have allowance), and accounts with - * allowance cannot call `operatorSend` (unless they are operators). - * - * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events. - */ - function transferFrom( - address holder, - address recipient, - uint256 amount - ) public virtual override returns (bool) { - address spender = _msgSender(); - _spendAllowance(holder, spender, amount); - _send(holder, recipient, amount, "", "", false); - return true; - } - - /** - * @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. - * - * If a send hook is registered for `account`, the corresponding function - * will be called with the caller address as the `operator` and with - * `userData` and `operatorData`. - * - * See {IERC777Sender} and {IERC777Recipient}. - * - * Emits {Minted} and {IERC20-Transfer} events. - * - * Requirements - * - * - `account` cannot be the zero address. - * - if `account` is a contract, it must implement the {IERC777Recipient} - * interface. - */ - function _mint( - address account, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) internal virtual { - _mint(account, amount, userData, operatorData, true); - } - - /** - * @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. - * - * If `requireReceptionAck` is set to true, and if a send hook is - * registered for `account`, the corresponding function will be called with - * `operator`, `data` and `operatorData`. - * - * See {IERC777Sender} and {IERC777Recipient}. - * - * Emits {Minted} and {IERC20-Transfer} events. - * - * Requirements - * - * - `account` cannot be the zero address. - * - if `account` is a contract, it must implement the {IERC777Recipient} - * interface. - */ - function _mint( - address account, - uint256 amount, - bytes memory userData, - bytes memory operatorData, - bool requireReceptionAck - ) internal virtual { - require(account != address(0), "ERC777: mint to the zero address"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, address(0), account, amount); - - // Update state variables - _totalSupply += amount; - _balances[account] += amount; - - _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck); - - emit Minted(operator, account, amount, userData, operatorData); - emit Transfer(address(0), account, amount); - } - - /** - * @dev Send tokens - * @param from address token holder address - * @param to address recipient address - * @param amount uint256 amount of tokens to transfer - * @param userData bytes extra information provided by the token holder (if any) - * @param operatorData bytes extra information provided by the operator (if any) - * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient - */ - function _send( - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData, - bool requireReceptionAck - ) internal virtual { - require(from != address(0), "ERC777: transfer from the zero address"); - require(to != address(0), "ERC777: transfer to the zero address"); - - address operator = _msgSender(); - - _callTokensToSend(operator, from, to, amount, userData, operatorData); - - _move(operator, from, to, amount, userData, operatorData); - - _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck); - } - - /** - * @dev Burn tokens - * @param from address token holder address - * @param amount uint256 amount of tokens to burn - * @param data bytes extra information provided by the token holder - * @param operatorData bytes extra information provided by the operator (if any) - */ - function _burn( - address from, - uint256 amount, - bytes memory data, - bytes memory operatorData - ) internal virtual { - require(from != address(0), "ERC777: burn from the zero address"); - - address operator = _msgSender(); - - _callTokensToSend(operator, from, address(0), amount, data, operatorData); - - _beforeTokenTransfer(operator, from, address(0), amount); - - // Update state variables - uint256 fromBalance = _balances[from]; - require(fromBalance >= amount, "ERC777: burn amount exceeds balance"); - unchecked { - _balances[from] = fromBalance - amount; - } - _totalSupply -= amount; - - emit Burned(operator, from, amount, data, operatorData); - emit Transfer(from, address(0), amount); - } - - function _move( - address operator, - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) private { - _beforeTokenTransfer(operator, from, to, amount); - - uint256 fromBalance = _balances[from]; - require(fromBalance >= amount, "ERC777: transfer amount exceeds balance"); - unchecked { - _balances[from] = fromBalance - amount; - } - _balances[to] += amount; - - emit Sent(operator, from, to, amount, userData, operatorData); - emit Transfer(from, to, amount); - } - - /** - * @dev See {ERC20-_approve}. - * - * Note that accounts cannot have allowance issued by their operators. - */ - function _approve( - address holder, - address spender, - uint256 value - ) internal virtual { - require(holder != address(0), "ERC777: approve from the zero address"); - require(spender != address(0), "ERC777: approve to the zero address"); - - _allowances[holder][spender] = value; - emit Approval(holder, spender, value); - } - - /** - * @dev Call from.tokensToSend() if the interface is registered - * @param operator address operator requesting the transfer - * @param from address token holder address - * @param to address recipient address - * @param amount uint256 amount of tokens to transfer - * @param userData bytes extra information provided by the token holder (if any) - * @param operatorData bytes extra information provided by the operator (if any) - */ - function _callTokensToSend( - address operator, - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData - ) private { - address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH); - if (implementer != address(0)) { - IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData); - } - } - - /** - * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but - * tokensReceived() was not registered for the recipient - * @param operator address operator requesting the transfer - * @param from address token holder address - * @param to address recipient address - * @param amount uint256 amount of tokens to transfer - * @param userData bytes extra information provided by the token holder (if any) - * @param operatorData bytes extra information provided by the operator (if any) - * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient - */ - function _callTokensReceived( - address operator, - address from, - address to, - uint256 amount, - bytes memory userData, - bytes memory operatorData, - bool requireReceptionAck - ) private { - address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH); - if (implementer != address(0)) { - IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData); - } else if (requireReceptionAck) { - require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient"); - } - } - - /** - * @dev Updates `owner` s allowance for `spender` based on spent `amount`. - * - * Does not update the allowance amount in case of infinite allowance. - * Revert if not enough allowance is available. - * - * Might emit an {Approval} event. - */ - function _spendAllowance( - address owner, - address spender, - uint256 amount - ) internal virtual { - uint256 currentAllowance = allowance(owner, spender); - if (currentAllowance != type(uint256).max) { - require(currentAllowance >= amount, "ERC777: insufficient allowance"); - unchecked { - _approve(owner, spender, currentAllowance - amount); - } - } - } - - /** - * @dev Hook that is called before any token transfer. This includes - * calls to {send}, {transfer}, {operatorSend}, minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be to transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256 amount - ) internal virtual {} -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777.sol deleted file mode 100644 index dbeab53..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777.sol +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC777/IERC777.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC777Token standard as defined in the EIP. - * - * This contract uses the - * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let - * token holders and recipients react to token movements by using setting implementers - * for the associated interfaces in said registry. See {IERC1820Registry} and - * {ERC1820Implementer}. - */ -interface IERC777 { - /** - * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`. - * - * Note that some additional user `data` and `operatorData` can be logged in the event. - */ - event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); - - /** - * @dev Emitted when `operator` destroys `amount` tokens from `account`. - * - * Note that some additional user `data` and `operatorData` can be logged in the event. - */ - event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); - - /** - * @dev Emitted when `operator` is made operator for `tokenHolder` - */ - event AuthorizedOperator(address indexed operator, address indexed tokenHolder); - - /** - * @dev Emitted when `operator` is revoked its operator status for `tokenHolder` - */ - event RevokedOperator(address indexed operator, address indexed tokenHolder); - - /** - * @dev Returns the name of the token. - */ - function name() external view returns (string memory); - - /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() external view returns (string memory); - - /** - * @dev Returns the smallest part of the token that is not divisible. This - * means all token operations (creation, movement and destruction) must have - * amounts that are a multiple of this number. - * - * For most token contracts, this value will equal 1. - */ - function granularity() external view returns (uint256); - - /** - * @dev Returns the amount of tokens in existence. - */ - function totalSupply() external view returns (uint256); - - /** - * @dev Returns the amount of tokens owned by an account (`owner`). - */ - function balanceOf(address owner) external view returns (uint256); - - /** - * @dev Moves `amount` tokens from the caller's account to `recipient`. - * - * If send or receive hooks are registered for the caller and `recipient`, - * the corresponding functions will be called with `data` and empty - * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. - * - * Emits a {Sent} event. - * - * Requirements - * - * - the caller must have at least `amount` tokens. - * - `recipient` cannot be the zero address. - * - if `recipient` is a contract, it must implement the {IERC777Recipient} - * interface. - */ - function send( - address recipient, - uint256 amount, - bytes calldata data - ) external; - - /** - * @dev Destroys `amount` tokens from the caller's account, reducing the - * total supply. - * - * If a send hook is registered for the caller, the corresponding function - * will be called with `data` and empty `operatorData`. See {IERC777Sender}. - * - * Emits a {Burned} event. - * - * Requirements - * - * - the caller must have at least `amount` tokens. - */ - function burn(uint256 amount, bytes calldata data) external; - - /** - * @dev Returns true if an account is an operator of `tokenHolder`. - * Operators can send and burn tokens on behalf of their owners. All - * accounts are their own operator. - * - * See {operatorSend} and {operatorBurn}. - */ - function isOperatorFor(address operator, address tokenHolder) external view returns (bool); - - /** - * @dev Make an account an operator of the caller. - * - * See {isOperatorFor}. - * - * Emits an {AuthorizedOperator} event. - * - * Requirements - * - * - `operator` cannot be calling address. - */ - function authorizeOperator(address operator) external; - - /** - * @dev Revoke an account's operator status for the caller. - * - * See {isOperatorFor} and {defaultOperators}. - * - * Emits a {RevokedOperator} event. - * - * Requirements - * - * - `operator` cannot be calling address. - */ - function revokeOperator(address operator) external; - - /** - * @dev Returns the list of default operators. These accounts are operators - * for all token holders, even if {authorizeOperator} was never called on - * them. - * - * This list is immutable, but individual holders may revoke these via - * {revokeOperator}, in which case {isOperatorFor} will return false. - */ - function defaultOperators() external view returns (address[] memory); - - /** - * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must - * be an operator of `sender`. - * - * If send or receive hooks are registered for `sender` and `recipient`, - * the corresponding functions will be called with `data` and - * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. - * - * Emits a {Sent} event. - * - * Requirements - * - * - `sender` cannot be the zero address. - * - `sender` must have at least `amount` tokens. - * - the caller must be an operator for `sender`. - * - `recipient` cannot be the zero address. - * - if `recipient` is a contract, it must implement the {IERC777Recipient} - * interface. - */ - function operatorSend( - address sender, - address recipient, - uint256 amount, - bytes calldata data, - bytes calldata operatorData - ) external; - - /** - * @dev Destroys `amount` tokens from `account`, reducing the total supply. - * The caller must be an operator of `account`. - * - * If a send hook is registered for `account`, the corresponding function - * will be called with `data` and `operatorData`. See {IERC777Sender}. - * - * Emits a {Burned} event. - * - * Requirements - * - * - `account` cannot be the zero address. - * - `account` must have at least `amount` tokens. - * - the caller must be an operator for `account`. - */ - function operatorBurn( - address account, - uint256 amount, - bytes calldata data, - bytes calldata operatorData - ) external; - - event Sent( - address indexed operator, - address indexed from, - address indexed to, - uint256 amount, - bytes data, - bytes operatorData - ); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Recipient.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Recipient.sol deleted file mode 100644 index 717dd8f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Recipient.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP. - * - * Accounts can be notified of {IERC777} tokens being sent to them by having a - * contract implement this interface (contract holders can be their own - * implementer) and registering it on the - * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. - * - * See {IERC1820Registry} and {ERC1820Implementer}. - */ -interface IERC777Recipient { - /** - * @dev Called by an {IERC777} token contract whenever tokens are being - * moved or created into a registered account (`to`). The type of operation - * is conveyed by `from` being the zero address or not. - * - * This call occurs _after_ the token contract's state is updated, so - * {IERC777-balanceOf}, etc., can be used to query the post-operation state. - * - * This function may revert to prevent the operation from being executed. - */ - function tokensReceived( - address operator, - address from, - address to, - uint256 amount, - bytes calldata userData, - bytes calldata operatorData - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Sender.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Sender.sol deleted file mode 100644 index 969e3e3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/IERC777Sender.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Sender.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC777TokensSender standard as defined in the EIP. - * - * {IERC777} Token holders can be notified of operations performed on their - * tokens by having a contract implement this interface (contract holders can be - * their own implementer) and registering it on the - * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. - * - * See {IERC1820Registry} and {ERC1820Implementer}. - */ -interface IERC777Sender { - /** - * @dev Called by an {IERC777} token contract whenever a registered holder's - * (`from`) tokens are about to be moved or destroyed. The type of operation - * is conveyed by `to` being the zero address or not. - * - * This call occurs _before_ the token contract's state is updated, so - * {IERC777-balanceOf}, etc., can be used to query the pre-operation state. - * - * This function may revert to prevent the operation from being executed. - */ - function tokensToSend( - address operator, - address from, - address to, - uint256 amount, - bytes calldata userData, - bytes calldata operatorData - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/README.adoc deleted file mode 100644 index 5012a31..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/README.adoc +++ /dev/null @@ -1,30 +0,0 @@ -= ERC 777 - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc777 - -This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-777[ERC777 token standard]. - -TIP: For an overview of ERC777 tokens and a walk through on how to create a token contract read our xref:ROOT:erc777.adoc[ERC777 guide]. - -The token behavior itself is implemented in the core contracts: {IERC777}, {ERC777}. - -Additionally there are interfaces used to develop contracts that react to token movements: {IERC777Sender}, {IERC777Recipient}. - -== Core - -{{IERC777}} - -{{ERC777}} - -== Hooks - -{{IERC777Sender}} - -{{IERC777Recipient}} - -== Presets - -These contracts are preconfigured combinations of features. They can be used through inheritance or as models to copy and paste their source code. - -{{ERC777PresetFixedSupply}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/presets/ERC777PresetFixedSupply.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/presets/ERC777PresetFixedSupply.sol deleted file mode 100644 index 8bd4b79..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/ERC777/presets/ERC777PresetFixedSupply.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (token/ERC777/presets/ERC777PresetFixedSupply.sol) -pragma solidity ^0.8.0; - -import "../ERC777.sol"; - -/** - * @dev {ERC777} token, including: - * - * - Preminted initial supply - * - No access control mechanism (for minting/pausing) and hence no governance - * - * _Available since v3.4._ - */ -contract ERC777PresetFixedSupply is ERC777 { - /** - * @dev Mints `initialSupply` amount of token and transfers them to `owner`. - * - * See {ERC777-constructor}. - */ - constructor( - string memory name, - string memory symbol, - address[] memory defaultOperators, - uint256 initialSupply, - address owner - ) ERC777(name, symbol, defaultOperators) { - _mint(owner, initialSupply, "", ""); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol deleted file mode 100644 index 604dba3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) - -pragma solidity ^0.8.0; - -import "../../interfaces/IERC2981.sol"; -import "../../utils/introspection/ERC165.sol"; - -/** - * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. - * - * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for - * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. - * - * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the - * fee is specified in basis points by default. - * - * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See - * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to - * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. - * - * _Available since v4.5._ - */ -abstract contract ERC2981 is IERC2981, ERC165 { - struct RoyaltyInfo { - address receiver; - uint96 royaltyFraction; - } - - RoyaltyInfo private _defaultRoyaltyInfo; - mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { - return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @inheritdoc IERC2981 - */ - function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { - RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; - - if (royalty.receiver == address(0)) { - royalty = _defaultRoyaltyInfo; - } - - uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); - - return (royalty.receiver, royaltyAmount); - } - - /** - * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a - * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an - * override. - */ - function _feeDenominator() internal pure virtual returns (uint96) { - return 10000; - } - - /** - * @dev Sets the royalty information that all ids in this contract will default to. - * - * Requirements: - * - * - `receiver` cannot be the zero address. - * - `feeNumerator` cannot be greater than the fee denominator. - */ - function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { - require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); - require(receiver != address(0), "ERC2981: invalid receiver"); - - _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); - } - - /** - * @dev Removes default royalty information. - */ - function _deleteDefaultRoyalty() internal virtual { - delete _defaultRoyaltyInfo; - } - - /** - * @dev Sets the royalty information for a specific token id, overriding the global default. - * - * Requirements: - * - * - `receiver` cannot be the zero address. - * - `feeNumerator` cannot be greater than the fee denominator. - */ - function _setTokenRoyalty( - uint256 tokenId, - address receiver, - uint96 feeNumerator - ) internal virtual { - require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); - require(receiver != address(0), "ERC2981: Invalid parameters"); - - _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); - } - - /** - * @dev Resets royalty information for the token id back to the global default. - */ - function _resetTokenRoyalty(uint256 tokenId) internal virtual { - delete _tokenRoyaltyInfo[tokenId]; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/common/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/common/README.adoc deleted file mode 100644 index af61674..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/token/common/README.adoc +++ /dev/null @@ -1,10 +0,0 @@ -= Common (Tokens) - -Functionality that is common to multiple token standards. - -* {ERC2981}: NFT Royalties compatible with both ERC721 and ERC1155. -** For ERC721 consider {ERC721Royalty} which clears the royalty information from storage on burn. - -== Contracts - -{{ERC2981}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Address.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Address.sol deleted file mode 100644 index 69f3bf8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Address.sol +++ /dev/null @@ -1,244 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) - -pragma solidity ^0.8.1; - -/** - * @dev Collection of functions related to the address type - */ -library Address { - /** - * @dev Returns true if `account` is a contract. - * - * [IMPORTANT] - * ==== - * It is unsafe to assume that an address for which this function returns - * false is an externally-owned account (EOA) and not a contract. - * - * Among others, `isContract` will return false for the following - * types of addresses: - * - * - an externally-owned account - * - a contract in construction - * - an address where a contract will be created - * - an address where a contract lived, but was destroyed - * ==== - * - * [IMPORTANT] - * ==== - * You shouldn't rely on `isContract` to protect against flash loan attacks! - * - * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets - * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract - * constructor. - * ==== - */ - function isContract(address account) internal view returns (bool) { - // This method relies on extcodesize/address.code.length, which returns 0 - // for contracts in construction, since the code is only stored at the end - // of the constructor execution. - - return account.code.length > 0; - } - - /** - * @dev Replacement for Solidity's `transfer`: sends `amount` wei to - * `recipient`, forwarding all available gas and reverting on errors. - * - * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost - * of certain opcodes, possibly making contracts go over the 2300 gas limit - * imposed by `transfer`, making them unable to receive funds via - * `transfer`. {sendValue} removes this limitation. - * - * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. - * - * IMPORTANT: because control is transferred to `recipient`, care must be - * taken to not create reentrancy vulnerabilities. Consider using - * {ReentrancyGuard} or the - * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. - */ - function sendValue(address payable recipient, uint256 amount) internal { - require(address(this).balance >= amount, "Address: insufficient balance"); - - (bool success, ) = recipient.call{value: amount}(""); - require(success, "Address: unable to send value, recipient may have reverted"); - } - - /** - * @dev Performs a Solidity function call using a low level `call`. A - * plain `call` is an unsafe replacement for a function call: use this - * function instead. - * - * If `target` reverts with a revert reason, it is bubbled up by this - * function (like regular Solidity function calls). - * - * Returns the raw returned data. To convert to the expected return value, - * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. - * - * Requirements: - * - * - `target` must be a contract. - * - calling `target` with `data` must not revert. - * - * _Available since v3.1._ - */ - function functionCall(address target, bytes memory data) internal returns (bytes memory) { - return functionCallWithValue(target, data, 0, "Address: low-level call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with - * `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCall( - address target, - bytes memory data, - string memory errorMessage - ) internal returns (bytes memory) { - return functionCallWithValue(target, data, 0, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but also transferring `value` wei to `target`. - * - * Requirements: - * - * - the calling contract must have an ETH balance of at least `value`. - * - the called Solidity function must be `payable`. - * - * _Available since v3.1._ - */ - function functionCallWithValue( - address target, - bytes memory data, - uint256 value - ) internal returns (bytes memory) { - return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); - } - - /** - * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but - * with `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCallWithValue( - address target, - bytes memory data, - uint256 value, - string memory errorMessage - ) internal returns (bytes memory) { - require(address(this).balance >= value, "Address: insufficient balance for call"); - (bool success, bytes memory returndata) = target.call{value: value}(data); - return verifyCallResultFromTarget(target, success, returndata, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but performing a static call. - * - * _Available since v3.3._ - */ - function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { - return functionStaticCall(target, data, "Address: low-level static call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], - * but performing a static call. - * - * _Available since v3.3._ - */ - function functionStaticCall( - address target, - bytes memory data, - string memory errorMessage - ) internal view returns (bytes memory) { - (bool success, bytes memory returndata) = target.staticcall(data); - return verifyCallResultFromTarget(target, success, returndata, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but performing a delegate call. - * - * _Available since v3.4._ - */ - function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { - return functionDelegateCall(target, data, "Address: low-level delegate call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], - * but performing a delegate call. - * - * _Available since v3.4._ - */ - function functionDelegateCall( - address target, - bytes memory data, - string memory errorMessage - ) internal returns (bytes memory) { - (bool success, bytes memory returndata) = target.delegatecall(data); - return verifyCallResultFromTarget(target, success, returndata, errorMessage); - } - - /** - * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling - * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. - * - * _Available since v4.8._ - */ - function verifyCallResultFromTarget( - address target, - bool success, - bytes memory returndata, - string memory errorMessage - ) internal view returns (bytes memory) { - if (success) { - if (returndata.length == 0) { - // only check isContract if the call was successful and the return data is empty - // otherwise we already know that it was a contract - require(isContract(target), "Address: call to non-contract"); - } - return returndata; - } else { - _revert(returndata, errorMessage); - } - } - - /** - * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the - * revert reason or using the provided one. - * - * _Available since v4.3._ - */ - function verifyCallResult( - bool success, - bytes memory returndata, - string memory errorMessage - ) internal pure returns (bytes memory) { - if (success) { - return returndata; - } else { - _revert(returndata, errorMessage); - } - } - - function _revert(bytes memory returndata, string memory errorMessage) private pure { - // Look for revert reason and bubble it up if present - if (returndata.length > 0) { - // The easiest way to bubble the revert reason is using memory via assembly - /// @solidity memory-safe-assembly - assembly { - let returndata_size := mload(returndata) - revert(add(32, returndata), returndata_size) - } - } else { - revert(errorMessage); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Arrays.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Arrays.sol deleted file mode 100644 index 0783614..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Arrays.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol) - -pragma solidity ^0.8.0; - -import "./math/Math.sol"; - -/** - * @dev Collection of functions related to array types. - */ -library Arrays { - /** - * @dev Searches a sorted `array` and returns the first index that contains - * a value greater or equal to `element`. If no such index exists (i.e. all - * values in the array are strictly less than `element`), the array length is - * returned. Time complexity O(log n). - * - * `array` is expected to be sorted in ascending order, and to contain no - * repeated elements. - */ - function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { - if (array.length == 0) { - return 0; - } - - uint256 low = 0; - uint256 high = array.length; - - while (low < high) { - uint256 mid = Math.average(low, high); - - // Note that mid will always be strictly less than high (i.e. it will be a valid array index) - // because Math.average rounds down (it does integer division with truncation). - if (array[mid] > element) { - high = mid; - } else { - low = mid + 1; - } - } - - // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. - if (low > 0 && array[low - 1] == element) { - return low - 1; - } else { - return low; - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Base64.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Base64.sol deleted file mode 100644 index 4e08cd5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Base64.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Provides a set of functions to operate with Base64 strings. - * - * _Available since v4.5._ - */ -library Base64 { - /** - * @dev Base64 Encoding/Decoding Table - */ - string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - /** - * @dev Converts a `bytes` to its Bytes64 `string` representation. - */ - function encode(bytes memory data) internal pure returns (string memory) { - /** - * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence - * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol - */ - if (data.length == 0) return ""; - - // Loads the table into memory - string memory table = _TABLE; - - // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter - // and split into 4 numbers of 6 bits. - // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up - // - `data.length + 2` -> Round up - // - `/ 3` -> Number of 3-bytes chunks - // - `4 *` -> 4 characters for each chunk - string memory result = new string(4 * ((data.length + 2) / 3)); - - /// @solidity memory-safe-assembly - assembly { - // Prepare the lookup table (skip the first "length" byte) - let tablePtr := add(table, 1) - - // Prepare result pointer, jump over length - let resultPtr := add(result, 32) - - // Run over the input, 3 bytes at a time - for { - let dataPtr := data - let endPtr := add(data, mload(data)) - } lt(dataPtr, endPtr) { - - } { - // Advance 3 bytes - dataPtr := add(dataPtr, 3) - let input := mload(dataPtr) - - // To write each character, shift the 3 bytes (18 bits) chunk - // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) - // and apply logical AND with 0x3F which is the number of - // the previous character in the ASCII table prior to the Base64 Table - // The result is then added to the table to get the character to write, - // and finally write it in the result pointer but with a left shift - // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits - - mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) - resultPtr := add(resultPtr, 1) // Advance - - mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) - resultPtr := add(resultPtr, 1) // Advance - - mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) - resultPtr := add(resultPtr, 1) // Advance - - mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) - resultPtr := add(resultPtr, 1) // Advance - } - - // When data `bytes` is not exactly 3 bytes long - // it is padded with `=` characters at the end - switch mod(mload(data), 3) - case 1 { - mstore8(sub(resultPtr, 1), 0x3d) - mstore8(sub(resultPtr, 2), 0x3d) - } - case 2 { - mstore8(sub(resultPtr, 1), 0x3d) - } - } - - return result; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Checkpoints.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Checkpoints.sol deleted file mode 100644 index 606098b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Checkpoints.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (utils/Checkpoints.sol) -pragma solidity ^0.8.0; - -import "./math/Math.sol"; -import "./math/SafeCast.sol"; - -/** - * @dev This library defines the `History` struct, for checkpointing values as they change at different points in - * time, and later looking up past values by block number. See {Votes} as an example. - * - * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new - * checkpoint for the current transaction block using the {push} function. - * - * _Available since v4.5._ - */ -library Checkpoints { - struct Checkpoint { - uint32 _blockNumber; - uint224 _value; - } - - struct History { - Checkpoint[] _checkpoints; - } - - /** - * @dev Returns the value in the latest checkpoint, or zero if there are no checkpoints. - */ - function latest(History storage self) internal view returns (uint256) { - uint256 pos = self._checkpoints.length; - return pos == 0 ? 0 : self._checkpoints[pos - 1]._value; - } - - /** - * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one - * before it is returned, or zero otherwise. - */ - function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { - require(blockNumber < block.number, "Checkpoints: block not yet mined"); - - uint256 high = self._checkpoints.length; - uint256 low = 0; - while (low < high) { - uint256 mid = Math.average(low, high); - if (self._checkpoints[mid]._blockNumber > blockNumber) { - high = mid; - } else { - low = mid + 1; - } - } - return high == 0 ? 0 : self._checkpoints[high - 1]._value; - } - - /** - * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block. - * - * Returns previous value and new value. - */ - function push(History storage self, uint256 value) internal returns (uint256, uint256) { - uint256 pos = self._checkpoints.length; - uint256 old = latest(self); - if (pos > 0 && self._checkpoints[pos - 1]._blockNumber == block.number) { - self._checkpoints[pos - 1]._value = SafeCast.toUint224(value); - } else { - self._checkpoints.push( - Checkpoint({_blockNumber: SafeCast.toUint32(block.number), _value: SafeCast.toUint224(value)}) - ); - } - return (old, value); - } - - /** - * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will - * be set to `op(latest, delta)`. - * - * Returns previous value and new value. - */ - function push( - History storage self, - function(uint256, uint256) view returns (uint256) op, - uint256 delta - ) internal returns (uint256, uint256) { - return push(self, op(latest(self), delta)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Context.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Context.sol deleted file mode 100644 index f304065..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Context.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Context.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Provides information about the current execution context, including the - * sender of the transaction and its data. While these are generally available - * via msg.sender and msg.data, they should not be accessed in such a direct - * manner, since when dealing with meta-transactions the account sending and - * paying for execution may not be the actual sender (as far as an application - * is concerned). - * - * This contract is only required for intermediate, library-like contracts. - */ -abstract contract Context { - function _msgSender() internal view virtual returns (address) { - return msg.sender; - } - - function _msgData() internal view virtual returns (bytes calldata) { - return msg.data; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Counters.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Counters.sol deleted file mode 100644 index 8a4f2a2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Counters.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) - -pragma solidity ^0.8.0; - -/** - * @title Counters - * @author Matt Condon (@shrugs) - * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number - * of elements in a mapping, issuing ERC721 ids, or counting request ids. - * - * Include with `using Counters for Counters.Counter;` - */ -library Counters { - struct Counter { - // This variable should never be directly accessed by users of the library: interactions must be restricted to - // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add - // this feature: see https://github.com/ethereum/solidity/issues/4637 - uint256 _value; // default: 0 - } - - function current(Counter storage counter) internal view returns (uint256) { - return counter._value; - } - - function increment(Counter storage counter) internal { - unchecked { - counter._value += 1; - } - } - - function decrement(Counter storage counter) internal { - uint256 value = counter._value; - require(value > 0, "Counter: decrement overflow"); - unchecked { - counter._value = value - 1; - } - } - - function reset(Counter storage counter) internal { - counter._value = 0; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Create2.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Create2.sol deleted file mode 100644 index b1e4ee1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Create2.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/Create2.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. - * `CREATE2` can be used to compute in advance the address where a smart - * contract will be deployed, which allows for interesting new mechanisms known - * as 'counterfactual interactions'. - * - * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more - * information. - */ -library Create2 { - /** - * @dev Deploys a contract using `CREATE2`. The address where the contract - * will be deployed can be known in advance via {computeAddress}. - * - * The bytecode for a contract can be obtained from Solidity with - * `type(contractName).creationCode`. - * - * Requirements: - * - * - `bytecode` must not be empty. - * - `salt` must have not been used for `bytecode` already. - * - the factory must have a balance of at least `amount`. - * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. - */ - function deploy( - uint256 amount, - bytes32 salt, - bytes memory bytecode - ) internal returns (address) { - address addr; - require(address(this).balance >= amount, "Create2: insufficient balance"); - require(bytecode.length != 0, "Create2: bytecode length is zero"); - /// @solidity memory-safe-assembly - assembly { - addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) - } - require(addr != address(0), "Create2: Failed on deploy"); - return addr; - } - - /** - * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the - * `bytecodeHash` or `salt` will result in a new destination address. - */ - function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { - return computeAddress(salt, bytecodeHash, address(this)); - } - - /** - * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at - * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. - */ - function computeAddress( - bytes32 salt, - bytes32 bytecodeHash, - address deployer - ) internal pure returns (address) { - bytes32 _data = keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash)); - return address(uint160(uint256(_data))); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Multicall.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Multicall.sol deleted file mode 100644 index bdb8201..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Multicall.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (utils/Multicall.sol) - -pragma solidity ^0.8.0; - -import "./Address.sol"; - -/** - * @dev Provides a function to batch together multiple calls in a single external call. - * - * _Available since v4.1._ - */ -abstract contract Multicall { - /** - * @dev Receives and executes a batch of function calls on this contract. - */ - function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) { - results = new bytes[](data.length); - for (uint256 i = 0; i < data.length; i++) { - results[i] = Address.functionDelegateCall(address(this), data[i]); - } - return results; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/README.adoc b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/README.adoc deleted file mode 100644 index 7fef825..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/README.adoc +++ /dev/null @@ -1,111 +0,0 @@ -= Utilities - -[.readme-notice] -NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/utils - -Miscellaneous contracts and libraries containing utility functions you can use to improve security, work with new data types, or safely use low-level primitives. - -The {Address}, {Arrays}, {Base64} and {Strings} libraries provide more operations related to these native data types, while {SafeCast} adds ways to safely convert between the different signed and unsigned numeric types. -{Multicall} provides a function to batch together multiple calls in a single external call. - -For new data types: - - * {Counters}: a simple way to get a counter that can only be incremented, decremented or reset. Very useful for ID generation, counting contract activity, among others. - * {EnumerableMap}: like Solidity's https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] type, but with key-value _enumeration_: this will let you know how many entries a mapping has, and iterate over them (which is not possible with `mapping`). - * {EnumerableSet}: like {EnumerableMap}, but for https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets]. Can be used to store privileged accounts, issued IDs, etc. - -[NOTE] -==== -Because Solidity does not support generic types, {EnumerableMap} and {EnumerableSet} are specialized to a limited number of key-value types. - -As of v3.0, {EnumerableMap} supports `uint256 -> address` (`UintToAddressMap`), and {EnumerableSet} supports `address` and `uint256` (`AddressSet` and `UintSet`). -==== - -Finally, {Create2} contains all necessary utilities to safely use the https://blog.openzeppelin.com/getting-the-most-out-of-create2/[`CREATE2` EVM opcode], without having to deal with low-level assembly. - -== Math - -{{Math}} - -{{SignedMath}} - -{{SafeCast}} - -{{SafeMath}} - -{{SignedSafeMath}} - -== Cryptography - -{{ECDSA}} - -{{SignatureChecker}} - -{{MerkleProof}} - -{{EIP712}} - -== Escrow - -{{ConditionalEscrow}} - -{{Escrow}} - -{{RefundEscrow}} - -== Introspection - -This set of interfaces and contracts deal with https://en.wikipedia.org/wiki/Type_introspection[type introspection] of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_. - -Ethereum contracts have no native concept of an interface, so applications must usually simply trust they are not making an incorrect call. For trusted setups this is a non-issue, but often unknown and untrusted third-party addresses need to be interacted with. There may even not be any direct calls to them! (e.g. `ERC20` tokens may be sent to a contract that lacks a way to transfer them out of it, locking them forever). In these cases, a contract _declaring_ its interface can be very helpful in preventing errors. - -There are two main ways to approach this. - -* Locally, where a contract implements `IERC165` and declares an interface, and a second one queries it directly via `ERC165Checker`. -* Globally, where a global and unique registry (`IERC1820Registry`) is used to register implementers of a certain interface (`IERC1820Implementer`). It is then the registry that is queried, which allows for more complex setups, like contracts implementing interfaces for externally-owned accounts. - -Note that, in all cases, accounts simply _declare_ their interfaces, but they are not required to actually implement them. This mechanism can therefore be used to both prevent errors and allow for complex interactions (see `ERC777`), but it must not be relied on for security. - -{{IERC165}} - -{{ERC165}} - -{{ERC165Storage}} - -{{ERC165Checker}} - -{{IERC1820Registry}} - -{{IERC1820Implementer}} - -{{ERC1820Implementer}} - -== Data Structures - -{{BitMaps}} - -{{EnumerableMap}} - -{{EnumerableSet}} - -{{DoubleEndedQueue}} - -{{Checkpoints}} - -== Libraries - -{{Create2}} - -{{Address}} - -{{Arrays}} - -{{Base64}} - -{{Counters}} - -{{Strings}} - -{{StorageSlot}} - -{{Multicall}} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol deleted file mode 100644 index 6ab8f5d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Library for reading and writing primitive types to specific storage slots. - * - * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. - * This library helps with reading and writing to such slots without the need for inline assembly. - * - * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. - * - * Example usage to set ERC1967 implementation slot: - * ``` - * contract ERC1967 { - * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - * - * function _getImplementation() internal view returns (address) { - * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; - * } - * - * function _setImplementation(address newImplementation) internal { - * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); - * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; - * } - * } - * ``` - * - * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ - */ -library StorageSlot { - struct AddressSlot { - address value; - } - - struct BooleanSlot { - bool value; - } - - struct Bytes32Slot { - bytes32 value; - } - - struct Uint256Slot { - uint256 value; - } - - /** - * @dev Returns an `AddressSlot` with member `value` located at `slot`. - */ - function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `BooleanSlot` with member `value` located at `slot`. - */ - function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. - */ - function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } - - /** - * @dev Returns an `Uint256Slot` with member `value` located at `slot`. - */ - function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { - /// @solidity memory-safe-assembly - assembly { - r.slot := slot - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Strings.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Strings.sol deleted file mode 100644 index 39e0cf1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Strings.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) - -pragma solidity ^0.8.0; - -/** - * @dev String operations. - */ -library Strings { - bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; - uint8 private constant _ADDRESS_LENGTH = 20; - - /** - * @dev Converts a `uint256` to its ASCII `string` decimal representation. - */ - function toString(uint256 value) internal pure returns (string memory) { - // Inspired by OraclizeAPI's implementation - MIT licence - // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol - - if (value == 0) { - return "0"; - } - uint256 temp = value; - uint256 digits; - while (temp != 0) { - digits++; - temp /= 10; - } - bytes memory buffer = new bytes(digits); - while (value != 0) { - digits -= 1; - buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); - value /= 10; - } - return string(buffer); - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. - */ - function toHexString(uint256 value) internal pure returns (string memory) { - if (value == 0) { - return "0x00"; - } - uint256 temp = value; - uint256 length = 0; - while (temp != 0) { - length++; - temp >>= 8; - } - return toHexString(value, length); - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. - */ - function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { - bytes memory buffer = new bytes(2 * length + 2); - buffer[0] = "0"; - buffer[1] = "x"; - for (uint256 i = 2 * length + 1; i > 1; --i) { - buffer[i] = _HEX_SYMBOLS[value & 0xf]; - value >>= 4; - } - require(value == 0, "Strings: hex length insufficient"); - return string(buffer); - } - - /** - * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. - */ - function toHexString(address addr) internal pure returns (string memory) { - return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Timers.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Timers.sol deleted file mode 100644 index 4bc86f2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/Timers.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Timers.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Tooling for timepoints, timers and delays - */ -library Timers { - struct Timestamp { - uint64 _deadline; - } - - function getDeadline(Timestamp memory timer) internal pure returns (uint64) { - return timer._deadline; - } - - function setDeadline(Timestamp storage timer, uint64 timestamp) internal { - timer._deadline = timestamp; - } - - function reset(Timestamp storage timer) internal { - timer._deadline = 0; - } - - function isUnset(Timestamp memory timer) internal pure returns (bool) { - return timer._deadline == 0; - } - - function isStarted(Timestamp memory timer) internal pure returns (bool) { - return timer._deadline > 0; - } - - function isPending(Timestamp memory timer) internal view returns (bool) { - return timer._deadline > block.timestamp; - } - - function isExpired(Timestamp memory timer) internal view returns (bool) { - return isStarted(timer) && timer._deadline <= block.timestamp; - } - - struct BlockNumber { - uint64 _deadline; - } - - function getDeadline(BlockNumber memory timer) internal pure returns (uint64) { - return timer._deadline; - } - - function setDeadline(BlockNumber storage timer, uint64 timestamp) internal { - timer._deadline = timestamp; - } - - function reset(BlockNumber storage timer) internal { - timer._deadline = 0; - } - - function isUnset(BlockNumber memory timer) internal pure returns (bool) { - return timer._deadline == 0; - } - - function isStarted(BlockNumber memory timer) internal pure returns (bool) { - return timer._deadline > 0; - } - - function isPending(BlockNumber memory timer) internal view returns (bool) { - return timer._deadline > block.number; - } - - function isExpired(BlockNumber memory timer) internal view returns (bool) { - return isStarted(timer) && timer._deadline <= block.number; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol deleted file mode 100644 index 38b2ea3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol) - -pragma solidity ^0.8.0; - -import "../Strings.sol"; - -/** - * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. - * - * These functions can be used to verify that a message was signed by the holder - * of the private keys of a given address. - */ -library ECDSA { - enum RecoverError { - NoError, - InvalidSignature, - InvalidSignatureLength, - InvalidSignatureS, - InvalidSignatureV - } - - function _throwError(RecoverError error) private pure { - if (error == RecoverError.NoError) { - return; // no error: do nothing - } else if (error == RecoverError.InvalidSignature) { - revert("ECDSA: invalid signature"); - } else if (error == RecoverError.InvalidSignatureLength) { - revert("ECDSA: invalid signature length"); - } else if (error == RecoverError.InvalidSignatureS) { - revert("ECDSA: invalid signature 's' value"); - } else if (error == RecoverError.InvalidSignatureV) { - revert("ECDSA: invalid signature 'v' value"); - } - } - - /** - * @dev Returns the address that signed a hashed message (`hash`) with - * `signature` or error string. This address can then be used for verification purposes. - * - * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: - * this function rejects them by requiring the `s` value to be in the lower - * half order, and the `v` value to be either 27 or 28. - * - * IMPORTANT: `hash` _must_ be the result of a hash operation for the - * verification to be secure: it is possible to craft signatures that - * recover to arbitrary addresses for non-hashed data. A safe way to ensure - * this is by receiving a hash of the original message (which may otherwise - * be too long), and then calling {toEthSignedMessageHash} on it. - * - * Documentation for signature generation: - * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] - * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] - * - * _Available since v4.3._ - */ - function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { - // Check the signature length - // - case 65: r,s,v signature (standard) - // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ - if (signature.length == 65) { - bytes32 r; - bytes32 s; - uint8 v; - // ecrecover takes the signature parameters, and the only way to get them - // currently is to use assembly. - /// @solidity memory-safe-assembly - assembly { - r := mload(add(signature, 0x20)) - s := mload(add(signature, 0x40)) - v := byte(0, mload(add(signature, 0x60))) - } - return tryRecover(hash, v, r, s); - } else if (signature.length == 64) { - bytes32 r; - bytes32 vs; - // ecrecover takes the signature parameters, and the only way to get them - // currently is to use assembly. - /// @solidity memory-safe-assembly - assembly { - r := mload(add(signature, 0x20)) - vs := mload(add(signature, 0x40)) - } - return tryRecover(hash, r, vs); - } else { - return (address(0), RecoverError.InvalidSignatureLength); - } - } - - /** - * @dev Returns the address that signed a hashed message (`hash`) with - * `signature`. This address can then be used for verification purposes. - * - * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: - * this function rejects them by requiring the `s` value to be in the lower - * half order, and the `v` value to be either 27 or 28. - * - * IMPORTANT: `hash` _must_ be the result of a hash operation for the - * verification to be secure: it is possible to craft signatures that - * recover to arbitrary addresses for non-hashed data. A safe way to ensure - * this is by receiving a hash of the original message (which may otherwise - * be too long), and then calling {toEthSignedMessageHash} on it. - */ - function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { - (address recovered, RecoverError error) = tryRecover(hash, signature); - _throwError(error); - return recovered; - } - - /** - * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. - * - * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] - * - * _Available since v4.3._ - */ - function tryRecover( - bytes32 hash, - bytes32 r, - bytes32 vs - ) internal pure returns (address, RecoverError) { - bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); - uint8 v = uint8((uint256(vs) >> 255) + 27); - return tryRecover(hash, v, r, s); - } - - /** - * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. - * - * _Available since v4.2._ - */ - function recover( - bytes32 hash, - bytes32 r, - bytes32 vs - ) internal pure returns (address) { - (address recovered, RecoverError error) = tryRecover(hash, r, vs); - _throwError(error); - return recovered; - } - - /** - * @dev Overload of {ECDSA-tryRecover} that receives the `v`, - * `r` and `s` signature fields separately. - * - * _Available since v4.3._ - */ - function tryRecover( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) internal pure returns (address, RecoverError) { - // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature - // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines - // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most - // signatures from current libraries generate a unique signature with an s-value in the lower half order. - // - // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value - // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or - // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept - // these malleable signatures as well. - if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { - return (address(0), RecoverError.InvalidSignatureS); - } - if (v != 27 && v != 28) { - return (address(0), RecoverError.InvalidSignatureV); - } - - // If the signature is valid (and not malleable), return the signer address - address signer = ecrecover(hash, v, r, s); - if (signer == address(0)) { - return (address(0), RecoverError.InvalidSignature); - } - - return (signer, RecoverError.NoError); - } - - /** - * @dev Overload of {ECDSA-recover} that receives the `v`, - * `r` and `s` signature fields separately. - */ - function recover( - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s - ) internal pure returns (address) { - (address recovered, RecoverError error) = tryRecover(hash, v, r, s); - _throwError(error); - return recovered; - } - - /** - * @dev Returns an Ethereum Signed Message, created from a `hash`. This - * produces hash corresponding to the one signed with the - * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] - * JSON-RPC method as part of EIP-191. - * - * See {recover}. - */ - function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { - // 32 is the length in bytes of hash, - // enforced by the type signature above - return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); - } - - /** - * @dev Returns an Ethereum Signed Message, created from `s`. This - * produces hash corresponding to the one signed with the - * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] - * JSON-RPC method as part of EIP-191. - * - * See {recover}. - */ - function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { - return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); - } - - /** - * @dev Returns an Ethereum Signed Typed Data, created from a - * `domainSeparator` and a `structHash`. This produces hash corresponding - * to the one signed with the - * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] - * JSON-RPC method as part of EIP-712. - * - * See {recover}. - */ - function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { - return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol deleted file mode 100644 index 19b2500..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol) - -pragma solidity ^0.8.0; - -/** - * @dev These functions deal with verification of Merkle Tree proofs. - * - * The proofs can be generated using the JavaScript library - * https://github.com/miguelmota/merkletreejs[merkletreejs]. - * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. - * - * See `test/utils/cryptography/MerkleProof.test.js` for some examples. - * - * WARNING: You should avoid using leaf values that are 64 bytes long prior to - * hashing, or use a hash function other than keccak256 for hashing leaves. - * This is because the concatenation of a sorted pair of internal nodes in - * the merkle tree could be reinterpreted as a leaf value. - */ -library MerkleProof { - /** - * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree - * defined by `root`. For this, a `proof` must be provided, containing - * sibling hashes on the branch from the leaf to the root of the tree. Each - * pair of leaves and each pair of pre-images are assumed to be sorted. - */ - function verify( - bytes32[] memory proof, - bytes32 root, - bytes32 leaf - ) internal pure returns (bool) { - return processProof(proof, leaf) == root; - } - - /** - * @dev Calldata version of {verify} - * - * _Available since v4.7._ - */ - function verifyCalldata( - bytes32[] calldata proof, - bytes32 root, - bytes32 leaf - ) internal pure returns (bool) { - return processProofCalldata(proof, leaf) == root; - } - - /** - * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up - * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt - * hash matches the root of the tree. When processing the proof, the pairs - * of leafs & pre-images are assumed to be sorted. - * - * _Available since v4.4._ - */ - function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = _hashPair(computedHash, proof[i]); - } - return computedHash; - } - - /** - * @dev Calldata version of {processProof} - * - * _Available since v4.7._ - */ - function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { - bytes32 computedHash = leaf; - for (uint256 i = 0; i < proof.length; i++) { - computedHash = _hashPair(computedHash, proof[i]); - } - return computedHash; - } - - /** - * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by - * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. - * - * _Available since v4.7._ - */ - function multiProofVerify( - bytes32[] memory proof, - bool[] memory proofFlags, - bytes32 root, - bytes32[] memory leaves - ) internal pure returns (bool) { - return processMultiProof(proof, proofFlags, leaves) == root; - } - - /** - * @dev Calldata version of {multiProofVerify} - * - * _Available since v4.7._ - */ - function multiProofVerifyCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32 root, - bytes32[] memory leaves - ) internal pure returns (bool) { - return processMultiProofCalldata(proof, proofFlags, leaves) == root; - } - - /** - * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`, - * consuming from one or the other at each step according to the instructions given by - * `proofFlags`. - * - * _Available since v4.7._ - */ - function processMultiProof( - bytes32[] memory proof, - bool[] memory proofFlags, - bytes32[] memory leaves - ) internal pure returns (bytes32 merkleRoot) { - // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by - // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the - // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of - // the merkle tree. - uint256 leavesLen = leaves.length; - uint256 totalHashes = proofFlags.length; - - // Check proof validity. - require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); - - // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using - // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". - bytes32[] memory hashes = new bytes32[](totalHashes); - uint256 leafPos = 0; - uint256 hashPos = 0; - uint256 proofPos = 0; - // At each step, we compute the next hash using two values: - // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we - // get the next hash. - // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the - // `proof` array. - for (uint256 i = 0; i < totalHashes; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; - hashes[i] = _hashPair(a, b); - } - - if (totalHashes > 0) { - return hashes[totalHashes - 1]; - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } - } - - /** - * @dev Calldata version of {processMultiProof} - * - * _Available since v4.7._ - */ - function processMultiProofCalldata( - bytes32[] calldata proof, - bool[] calldata proofFlags, - bytes32[] memory leaves - ) internal pure returns (bytes32 merkleRoot) { - // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by - // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the - // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of - // the merkle tree. - uint256 leavesLen = leaves.length; - uint256 totalHashes = proofFlags.length; - - // Check proof validity. - require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); - - // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using - // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". - bytes32[] memory hashes = new bytes32[](totalHashes); - uint256 leafPos = 0; - uint256 hashPos = 0; - uint256 proofPos = 0; - // At each step, we compute the next hash using two values: - // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we - // get the next hash. - // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the - // `proof` array. - for (uint256 i = 0; i < totalHashes; i++) { - bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; - bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; - hashes[i] = _hashPair(a, b); - } - - if (totalHashes > 0) { - return hashes[totalHashes - 1]; - } else if (leavesLen > 0) { - return leaves[0]; - } else { - return proof[0]; - } - } - - function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { - return a < b ? _efficientHash(a, b) : _efficientHash(b, a); - } - - function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, a) - mstore(0x20, b) - value := keccak256(0x00, 0x40) - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol deleted file mode 100644 index 42b222a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/SignatureChecker.sol) - -pragma solidity ^0.8.0; - -import "./ECDSA.sol"; -import "../Address.sol"; -import "../../interfaces/IERC1271.sol"; - -/** - * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA - * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like - * Argent and Gnosis Safe. - * - * _Available since v4.1._ - */ -library SignatureChecker { - /** - * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the - * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`. - * - * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus - * change through time. It could return true at block N and false at block N+1 (or the opposite). - */ - function isValidSignatureNow( - address signer, - bytes32 hash, - bytes memory signature - ) internal view returns (bool) { - (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature); - if (error == ECDSA.RecoverError.NoError && recovered == signer) { - return true; - } - - (bool success, bytes memory result) = signer.staticcall( - abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature) - ); - return (success && - result.length == 32 && - abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/draft-EIP712.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/draft-EIP712.sol deleted file mode 100644 index a32c25b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/cryptography/draft-EIP712.sol +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol) - -pragma solidity ^0.8.0; - -import "./ECDSA.sol"; - -/** - * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. - * - * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, - * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding - * they need in their contracts using a combination of `abi.encode` and `keccak256`. - * - * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding - * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA - * ({_hashTypedDataV4}). - * - * The implementation of the domain separator was designed to be as efficient as possible while still properly updating - * the chain id to protect against replay attacks on an eventual fork of the chain. - * - * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method - * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. - * - * _Available since v3.4._ - */ -abstract contract EIP712 { - /* solhint-disable var-name-mixedcase */ - // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to - // invalidate the cached domain separator if the chain id changes. - bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; - uint256 private immutable _CACHED_CHAIN_ID; - address private immutable _CACHED_THIS; - - bytes32 private immutable _HASHED_NAME; - bytes32 private immutable _HASHED_VERSION; - bytes32 private immutable _TYPE_HASH; - - /* solhint-enable var-name-mixedcase */ - - /** - * @dev Initializes the domain separator and parameter caches. - * - * The meaning of `name` and `version` is specified in - * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: - * - * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. - * - `version`: the current major version of the signing domain. - * - * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart - * contract upgrade]. - */ - constructor(string memory name, string memory version) { - bytes32 hashedName = keccak256(bytes(name)); - bytes32 hashedVersion = keccak256(bytes(version)); - bytes32 typeHash = keccak256( - "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" - ); - _HASHED_NAME = hashedName; - _HASHED_VERSION = hashedVersion; - _CACHED_CHAIN_ID = block.chainid; - _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); - _CACHED_THIS = address(this); - _TYPE_HASH = typeHash; - } - - /** - * @dev Returns the domain separator for the current chain. - */ - function _domainSeparatorV4() internal view returns (bytes32) { - if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { - return _CACHED_DOMAIN_SEPARATOR; - } else { - return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); - } - } - - function _buildDomainSeparator( - bytes32 typeHash, - bytes32 nameHash, - bytes32 versionHash - ) private view returns (bytes32) { - return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); - } - - /** - * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this - * function returns the hash of the fully encoded EIP712 message for this domain. - * - * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: - * - * ```solidity - * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( - * keccak256("Mail(address to,string contents)"), - * mailTo, - * keccak256(bytes(mailContents)) - * ))); - * address signer = ECDSA.recover(digest, signature); - * ``` - */ - function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { - return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/ConditionalEscrow.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/ConditionalEscrow.sol deleted file mode 100644 index 87f5381..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/ConditionalEscrow.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/escrow/ConditionalEscrow.sol) - -pragma solidity ^0.8.0; - -import "./Escrow.sol"; - -/** - * @title ConditionalEscrow - * @dev Base abstract escrow to only allow withdrawal if a condition is met. - * @dev Intended usage: See {Escrow}. Same usage guidelines apply here. - */ -abstract contract ConditionalEscrow is Escrow { - /** - * @dev Returns whether an address is allowed to withdraw their funds. To be - * implemented by derived contracts. - * @param payee The destination address of the funds. - */ - function withdrawalAllowed(address payee) public view virtual returns (bool); - - function withdraw(address payable payee) public virtual override { - require(withdrawalAllowed(payee), "ConditionalEscrow: payee is not allowed to withdraw"); - super.withdraw(payee); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/Escrow.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/Escrow.sol deleted file mode 100644 index 48dd51a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/Escrow.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/escrow/Escrow.sol) - -pragma solidity ^0.8.0; - -import "../../access/Ownable.sol"; -import "../Address.sol"; - -/** - * @title Escrow - * @dev Base escrow contract, holds funds designated for a payee until they - * withdraw them. - * - * Intended usage: This contract (and derived escrow contracts) should be a - * standalone contract, that only interacts with the contract that instantiated - * it. That way, it is guaranteed that all Ether will be handled according to - * the `Escrow` rules, and there is no need to check for payable functions or - * transfers in the inheritance tree. The contract that uses the escrow as its - * payment method should be its owner, and provide public methods redirecting - * to the escrow's deposit and withdraw. - */ -contract Escrow is Ownable { - using Address for address payable; - - event Deposited(address indexed payee, uint256 weiAmount); - event Withdrawn(address indexed payee, uint256 weiAmount); - - mapping(address => uint256) private _deposits; - - function depositsOf(address payee) public view returns (uint256) { - return _deposits[payee]; - } - - /** - * @dev Stores the sent amount as credit to be withdrawn. - * @param payee The destination address of the funds. - * - * Emits a {Deposited} event. - */ - function deposit(address payee) public payable virtual onlyOwner { - uint256 amount = msg.value; - _deposits[payee] += amount; - emit Deposited(payee, amount); - } - - /** - * @dev Withdraw accumulated balance for a payee, forwarding all gas to the - * recipient. - * - * WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities. - * Make sure you trust the recipient, or are either following the - * checks-effects-interactions pattern or using {ReentrancyGuard}. - * - * @param payee The address whose funds will be withdrawn and transferred to. - * - * Emits a {Withdrawn} event. - */ - function withdraw(address payable payee) public virtual onlyOwner { - uint256 payment = _deposits[payee]; - - _deposits[payee] = 0; - - payee.sendValue(payment); - - emit Withdrawn(payee, payment); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/RefundEscrow.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/RefundEscrow.sol deleted file mode 100644 index 0e9621f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/escrow/RefundEscrow.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/escrow/RefundEscrow.sol) - -pragma solidity ^0.8.0; - -import "./ConditionalEscrow.sol"; - -/** - * @title RefundEscrow - * @dev Escrow that holds funds for a beneficiary, deposited from multiple - * parties. - * @dev Intended usage: See {Escrow}. Same usage guidelines apply here. - * @dev The owner account (that is, the contract that instantiates this - * contract) may deposit, close the deposit period, and allow for either - * withdrawal by the beneficiary, or refunds to the depositors. All interactions - * with `RefundEscrow` will be made through the owner contract. - */ -contract RefundEscrow is ConditionalEscrow { - using Address for address payable; - - enum State { - Active, - Refunding, - Closed - } - - event RefundsClosed(); - event RefundsEnabled(); - - State private _state; - address payable private immutable _beneficiary; - - /** - * @dev Constructor. - * @param beneficiary_ The beneficiary of the deposits. - */ - constructor(address payable beneficiary_) { - require(beneficiary_ != address(0), "RefundEscrow: beneficiary is the zero address"); - _beneficiary = beneficiary_; - _state = State.Active; - } - - /** - * @return The current state of the escrow. - */ - function state() public view virtual returns (State) { - return _state; - } - - /** - * @return The beneficiary of the escrow. - */ - function beneficiary() public view virtual returns (address payable) { - return _beneficiary; - } - - /** - * @dev Stores funds that may later be refunded. - * @param refundee The address funds will be sent to if a refund occurs. - */ - function deposit(address refundee) public payable virtual override { - require(state() == State.Active, "RefundEscrow: can only deposit while active"); - super.deposit(refundee); - } - - /** - * @dev Allows for the beneficiary to withdraw their funds, rejecting - * further deposits. - */ - function close() public virtual onlyOwner { - require(state() == State.Active, "RefundEscrow: can only close while active"); - _state = State.Closed; - emit RefundsClosed(); - } - - /** - * @dev Allows for refunds to take place, rejecting further deposits. - */ - function enableRefunds() public virtual onlyOwner { - require(state() == State.Active, "RefundEscrow: can only enable refunds while active"); - _state = State.Refunding; - emit RefundsEnabled(); - } - - /** - * @dev Withdraws the beneficiary's funds. - */ - function beneficiaryWithdraw() public virtual { - require(state() == State.Closed, "RefundEscrow: beneficiary can only withdraw while closed"); - beneficiary().sendValue(address(this).balance); - } - - /** - * @dev Returns whether refundees can withdraw their deposits (be refunded). The overridden function receives a - * 'payee' argument, but we ignore it here since the condition is global, not per-payee. - */ - function withdrawalAllowed(address) public view override returns (bool) { - return state() == State.Refunding; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol deleted file mode 100644 index 3bf5613..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) - -pragma solidity ^0.8.0; - -import "./IERC165.sol"; - -/** - * @dev Implementation of the {IERC165} interface. - * - * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check - * for the additional interface id that will be supported. For example: - * - * ```solidity - * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); - * } - * ``` - * - * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. - */ -abstract contract ERC165 is IERC165 { - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IERC165).interfaceId; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol deleted file mode 100644 index 4cdf342..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Checker.sol) - -pragma solidity ^0.8.0; - -import "./IERC165.sol"; - -/** - * @dev Library used to query support of an interface declared via {IERC165}. - * - * Note that these functions return the actual result of the query: they do not - * `revert` if an interface is not supported. It is up to the caller to decide - * what to do in these cases. - */ -library ERC165Checker { - // As per the EIP-165 spec, no interface should ever match 0xffffffff - bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; - - /** - * @dev Returns true if `account` supports the {IERC165} interface, - */ - function supportsERC165(address account) internal view returns (bool) { - // Any contract that implements ERC165 must explicitly indicate support of - // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid - return - supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && - !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID); - } - - /** - * @dev Returns true if `account` supports the interface defined by - * `interfaceId`. Support for {IERC165} itself is queried automatically. - * - * See {IERC165-supportsInterface}. - */ - function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { - // query support of both ERC165 as per the spec and support of _interfaceId - return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); - } - - /** - * @dev Returns a boolean array where each value corresponds to the - * interfaces passed in and whether they're supported or not. This allows - * you to batch check interfaces for a contract where your expectation - * is that some interfaces may not be supported. - * - * See {IERC165-supportsInterface}. - * - * _Available since v3.4._ - */ - function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) - internal - view - returns (bool[] memory) - { - // an array of booleans corresponding to interfaceIds and whether they're supported or not - bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); - - // query support of ERC165 itself - if (supportsERC165(account)) { - // query support of each interface in interfaceIds - for (uint256 i = 0; i < interfaceIds.length; i++) { - interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); - } - } - - return interfaceIdsSupported; - } - - /** - * @dev Returns true if `account` supports all the interfaces defined in - * `interfaceIds`. Support for {IERC165} itself is queried automatically. - * - * Batch-querying can lead to gas savings by skipping repeated checks for - * {IERC165} support. - * - * See {IERC165-supportsInterface}. - */ - function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { - // query support of ERC165 itself - if (!supportsERC165(account)) { - return false; - } - - // query support of each interface in _interfaceIds - for (uint256 i = 0; i < interfaceIds.length; i++) { - if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { - return false; - } - } - - // all interfaces supported - return true; - } - - /** - * @notice Query if a contract implements an interface, does not check ERC165 support - * @param account The address of the contract to query for support of an interface - * @param interfaceId The interface identifier, as specified in ERC-165 - * @return true if the contract at account indicates support of the interface with - * identifier interfaceId, false otherwise - * @dev Assumes that account contains a contract that supports ERC165, otherwise - * the behavior of this method is undefined. This precondition can be checked - * with {supportsERC165}. - * Interface identification is specified in ERC-165. - */ - function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { - bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); - (bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams); - if (result.length < 32) return false; - return success && abi.decode(result, (uint256)) > 0; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Storage.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Storage.sol deleted file mode 100644 index c99d9f3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165Storage.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol) - -pragma solidity ^0.8.0; - -import "./ERC165.sol"; - -/** - * @dev Storage based implementation of the {IERC165} interface. - * - * Contracts may inherit from this and call {_registerInterface} to declare - * their support of an interface. - */ -abstract contract ERC165Storage is ERC165 { - /** - * @dev Mapping of interface ids to whether or not it's supported. - */ - mapping(bytes4 => bool) private _supportedInterfaces; - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId]; - } - - /** - * @dev Registers the contract as an implementer of the interface defined by - * `interfaceId`. Support of the actual ERC165 interface is automatic and - * registering its interface id is not required. - * - * See {IERC165-supportsInterface}. - * - * Requirements: - * - * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). - */ - function _registerInterface(bytes4 interfaceId) internal virtual { - require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); - _supportedInterfaces[interfaceId] = true; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC1820Implementer.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC1820Implementer.sol deleted file mode 100644 index 1b51396..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/ERC1820Implementer.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC1820Implementer.sol) - -pragma solidity ^0.8.0; - -import "./IERC1820Implementer.sol"; - -/** - * @dev Implementation of the {IERC1820Implementer} interface. - * - * Contracts may inherit from this and call {_registerInterfaceForAddress} to - * declare their willingness to be implementers. - * {IERC1820Registry-setInterfaceImplementer} should then be called for the - * registration to be complete. - */ -contract ERC1820Implementer is IERC1820Implementer { - bytes32 private constant _ERC1820_ACCEPT_MAGIC = keccak256("ERC1820_ACCEPT_MAGIC"); - - mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces; - - /** - * @dev See {IERC1820Implementer-canImplementInterfaceForAddress}. - */ - function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) - public - view - virtual - override - returns (bytes32) - { - return _supportedInterfaces[interfaceHash][account] ? _ERC1820_ACCEPT_MAGIC : bytes32(0x00); - } - - /** - * @dev Declares the contract as willing to be an implementer of - * `interfaceHash` for `account`. - * - * See {IERC1820Registry-setInterfaceImplementer} and - * {IERC1820Registry-interfaceHash}. - */ - function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal virtual { - _supportedInterfaces[interfaceHash][account] = true; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol deleted file mode 100644 index e8cdbdb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC165 standard, as defined in the - * https://eips.ethereum.org/EIPS/eip-165[EIP]. - * - * Implementers can declare support of contract interfaces, which can then be - * queried by others ({ERC165Checker}). - * - * For an implementation, see {ERC165}. - */ -interface IERC165 { - /** - * @dev Returns true if this contract implements the interface defined by - * `interfaceId`. See the corresponding - * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] - * to learn more about how these ids are created. - * - * This function call must use less than 30 000 gas. - */ - function supportsInterface(bytes4 interfaceId) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Implementer.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Implementer.sol deleted file mode 100644 index c4d0b30..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Implementer.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC1820Implementer.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface for an ERC1820 implementer, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820#interface-implementation-erc1820implementerinterface[EIP]. - * Used by contracts that will be registered as implementers in the - * {IERC1820Registry}. - */ -interface IERC1820Implementer { - /** - * @dev Returns a special value (`ERC1820_ACCEPT_MAGIC`) if this contract - * implements `interfaceHash` for `account`. - * - * See {IERC1820Registry-setInterfaceImplementer}. - */ - function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Registry.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Registry.sol deleted file mode 100644 index dcc346e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/introspection/IERC1820Registry.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (utils/introspection/IERC1820Registry.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the global ERC1820 Registry, as defined in the - * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register - * implementers for interfaces in this registry, as well as query support. - * - * Implementers may be shared by multiple accounts, and can also implement more - * than a single interface for each account. Contracts can implement interfaces - * for themselves, but externally-owned accounts (EOA) must delegate this to a - * contract. - * - * {IERC165} interfaces can also be queried via the registry. - * - * For an in-depth explanation and source code analysis, see the EIP text. - */ -interface IERC1820Registry { - event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); - - event ManagerChanged(address indexed account, address indexed newManager); - - /** - * @dev Sets `newManager` as the manager for `account`. A manager of an - * account is able to set interface implementers for it. - * - * By default, each account is its own manager. Passing a value of `0x0` in - * `newManager` will reset the manager to this initial state. - * - * Emits a {ManagerChanged} event. - * - * Requirements: - * - * - the caller must be the current manager for `account`. - */ - function setManager(address account, address newManager) external; - - /** - * @dev Returns the manager for `account`. - * - * See {setManager}. - */ - function getManager(address account) external view returns (address); - - /** - * @dev Sets the `implementer` contract as ``account``'s implementer for - * `interfaceHash`. - * - * `account` being the zero address is an alias for the caller's address. - * The zero address can also be used in `implementer` to remove an old one. - * - * See {interfaceHash} to learn how these are created. - * - * Emits an {InterfaceImplementerSet} event. - * - * Requirements: - * - * - the caller must be the current manager for `account`. - * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not - * end in 28 zeroes). - * - `implementer` must implement {IERC1820Implementer} and return true when - * queried for support, unless `implementer` is the caller. See - * {IERC1820Implementer-canImplementInterfaceForAddress}. - */ - function setInterfaceImplementer( - address account, - bytes32 _interfaceHash, - address implementer - ) external; - - /** - * @dev Returns the implementer of `interfaceHash` for `account`. If no such - * implementer is registered, returns the zero address. - * - * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 - * zeroes), `account` will be queried for support of it. - * - * `account` being the zero address is an alias for the caller's address. - */ - function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); - - /** - * @dev Returns the interface hash for an `interfaceName`, as defined in the - * corresponding - * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. - */ - function interfaceHash(string calldata interfaceName) external pure returns (bytes32); - - /** - * @notice Updates the cache with whether the contract implements an ERC165 interface or not. - * @param account Address of the contract for which to update the cache. - * @param interfaceId ERC165 interface for which to update the cache. - */ - function updateERC165Cache(address account, bytes4 interfaceId) external; - - /** - * @notice Checks whether a contract implements an ERC165 interface or not. - * If the result is not cached a direct lookup on the contract address is performed. - * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling - * {updateERC165Cache} with the contract address. - * @param account Address of the contract to check. - * @param interfaceId ERC165 interface to check. - * @return True if `account` implements `interfaceId`, false otherwise. - */ - function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); - - /** - * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. - * @param account Address of the contract to check. - * @param interfaceId ERC165 interface to check. - * @return True if `account` implements `interfaceId`, false otherwise. - */ - function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/Math.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/Math.sol deleted file mode 100644 index 379407c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/Math.sol +++ /dev/null @@ -1,226 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Standard math utilities missing in the Solidity language. - */ -library Math { - enum Rounding { - Down, // Toward negative infinity - Up, // Toward infinity - Zero // Toward zero - } - - /** - * @dev Returns the largest of two numbers. - */ - function max(uint256 a, uint256 b) internal pure returns (uint256) { - return a >= b ? a : b; - } - - /** - * @dev Returns the smallest of two numbers. - */ - function min(uint256 a, uint256 b) internal pure returns (uint256) { - return a < b ? a : b; - } - - /** - * @dev Returns the average of two numbers. The result is rounded towards - * zero. - */ - function average(uint256 a, uint256 b) internal pure returns (uint256) { - // (a + b) / 2 can overflow. - return (a & b) + (a ^ b) / 2; - } - - /** - * @dev Returns the ceiling of the division of two numbers. - * - * This differs from standard division with `/` in that it rounds up instead - * of rounding down. - */ - function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { - // (a + b - 1) / b can overflow on addition, so we distribute. - return a == 0 ? 0 : (a - 1) / b + 1; - } - - /** - * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 - * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) - * with further edits by Uniswap Labs also under MIT license. - */ - function mulDiv( - uint256 x, - uint256 y, - uint256 denominator - ) internal pure returns (uint256 result) { - unchecked { - // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use - // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 - // variables such that product = prod1 * 2^256 + prod0. - uint256 prod0; // Least significant 256 bits of the product - uint256 prod1; // Most significant 256 bits of the product - assembly { - let mm := mulmod(x, y, not(0)) - prod0 := mul(x, y) - prod1 := sub(sub(mm, prod0), lt(mm, prod0)) - } - - // Handle non-overflow cases, 256 by 256 division. - if (prod1 == 0) { - return prod0 / denominator; - } - - // Make sure the result is less than 2^256. Also prevents denominator == 0. - require(denominator > prod1); - - /////////////////////////////////////////////// - // 512 by 256 division. - /////////////////////////////////////////////// - - // Make division exact by subtracting the remainder from [prod1 prod0]. - uint256 remainder; - assembly { - // Compute remainder using mulmod. - remainder := mulmod(x, y, denominator) - - // Subtract 256 bit number from 512 bit number. - prod1 := sub(prod1, gt(remainder, prod0)) - prod0 := sub(prod0, remainder) - } - - // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. - // See https://cs.stackexchange.com/q/138556/92363. - - // Does not overflow because the denominator cannot be zero at this stage in the function. - uint256 twos = denominator & (~denominator + 1); - assembly { - // Divide denominator by twos. - denominator := div(denominator, twos) - - // Divide [prod1 prod0] by twos. - prod0 := div(prod0, twos) - - // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. - twos := add(div(sub(0, twos), twos), 1) - } - - // Shift in bits from prod1 into prod0. - prod0 |= prod1 * twos; - - // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such - // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for - // four bits. That is, denominator * inv = 1 mod 2^4. - uint256 inverse = (3 * denominator) ^ 2; - - // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works - // in modular arithmetic, doubling the correct bits in each step. - inverse *= 2 - denominator * inverse; // inverse mod 2^8 - inverse *= 2 - denominator * inverse; // inverse mod 2^16 - inverse *= 2 - denominator * inverse; // inverse mod 2^32 - inverse *= 2 - denominator * inverse; // inverse mod 2^64 - inverse *= 2 - denominator * inverse; // inverse mod 2^128 - inverse *= 2 - denominator * inverse; // inverse mod 2^256 - - // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. - // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is - // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 - // is no longer required. - result = prod0 * inverse; - return result; - } - } - - /** - * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. - */ - function mulDiv( - uint256 x, - uint256 y, - uint256 denominator, - Rounding rounding - ) internal pure returns (uint256) { - uint256 result = mulDiv(x, y, denominator); - if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { - result += 1; - } - return result; - } - - /** - * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. - * - * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). - */ - function sqrt(uint256 a) internal pure returns (uint256) { - if (a == 0) { - return 0; - } - - // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. - // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have - // `msb(a) <= a < 2*msb(a)`. - // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. - // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. - // Using an algorithm similar to the msb computation, we are able to compute `result = 2**(k/2)` which is a - // good first approximation of `sqrt(a)` with at least 1 correct bit. - uint256 result = 1; - uint256 x = a; - if (x >> 128 > 0) { - x >>= 128; - result <<= 64; - } - if (x >> 64 > 0) { - x >>= 64; - result <<= 32; - } - if (x >> 32 > 0) { - x >>= 32; - result <<= 16; - } - if (x >> 16 > 0) { - x >>= 16; - result <<= 8; - } - if (x >> 8 > 0) { - x >>= 8; - result <<= 4; - } - if (x >> 4 > 0) { - x >>= 4; - result <<= 2; - } - if (x >> 2 > 0) { - result <<= 1; - } - - // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, - // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at - // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision - // into the expected uint128 result. - unchecked { - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - return min(result, a / result); - } - } - - /** - * @notice Calculates sqrt(a), following the selected rounding direction. - */ - function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { - uint256 result = sqrt(a); - if (rounding == Rounding.Up && result * result < a) { - result += 1; - } - return result; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol deleted file mode 100644 index a4e831f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol +++ /dev/null @@ -1,1135 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow - * checks. - * - * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can - * easily result in undesired exploitation or bugs, since developers usually - * assume that overflows raise errors. `SafeCast` restores this intuition by - * reverting the transaction when such an operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - * - * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing - * all math on `uint256` and `int256` and then downcasting. - */ -library SafeCast { - /** - * @dev Returns the downcasted uint248 from uint256, reverting on - * overflow (when the input is greater than largest uint248). - * - * Counterpart to Solidity's `uint248` operator. - * - * Requirements: - * - * - input must fit into 248 bits - * - * _Available since v4.7._ - */ - function toUint248(uint256 value) internal pure returns (uint248) { - require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); - return uint248(value); - } - - /** - * @dev Returns the downcasted uint240 from uint256, reverting on - * overflow (when the input is greater than largest uint240). - * - * Counterpart to Solidity's `uint240` operator. - * - * Requirements: - * - * - input must fit into 240 bits - * - * _Available since v4.7._ - */ - function toUint240(uint256 value) internal pure returns (uint240) { - require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); - return uint240(value); - } - - /** - * @dev Returns the downcasted uint232 from uint256, reverting on - * overflow (when the input is greater than largest uint232). - * - * Counterpart to Solidity's `uint232` operator. - * - * Requirements: - * - * - input must fit into 232 bits - * - * _Available since v4.7._ - */ - function toUint232(uint256 value) internal pure returns (uint232) { - require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); - return uint232(value); - } - - /** - * @dev Returns the downcasted uint224 from uint256, reverting on - * overflow (when the input is greater than largest uint224). - * - * Counterpart to Solidity's `uint224` operator. - * - * Requirements: - * - * - input must fit into 224 bits - * - * _Available since v4.2._ - */ - function toUint224(uint256 value) internal pure returns (uint224) { - require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); - return uint224(value); - } - - /** - * @dev Returns the downcasted uint216 from uint256, reverting on - * overflow (when the input is greater than largest uint216). - * - * Counterpart to Solidity's `uint216` operator. - * - * Requirements: - * - * - input must fit into 216 bits - * - * _Available since v4.7._ - */ - function toUint216(uint256 value) internal pure returns (uint216) { - require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); - return uint216(value); - } - - /** - * @dev Returns the downcasted uint208 from uint256, reverting on - * overflow (when the input is greater than largest uint208). - * - * Counterpart to Solidity's `uint208` operator. - * - * Requirements: - * - * - input must fit into 208 bits - * - * _Available since v4.7._ - */ - function toUint208(uint256 value) internal pure returns (uint208) { - require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); - return uint208(value); - } - - /** - * @dev Returns the downcasted uint200 from uint256, reverting on - * overflow (when the input is greater than largest uint200). - * - * Counterpart to Solidity's `uint200` operator. - * - * Requirements: - * - * - input must fit into 200 bits - * - * _Available since v4.7._ - */ - function toUint200(uint256 value) internal pure returns (uint200) { - require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); - return uint200(value); - } - - /** - * @dev Returns the downcasted uint192 from uint256, reverting on - * overflow (when the input is greater than largest uint192). - * - * Counterpart to Solidity's `uint192` operator. - * - * Requirements: - * - * - input must fit into 192 bits - * - * _Available since v4.7._ - */ - function toUint192(uint256 value) internal pure returns (uint192) { - require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); - return uint192(value); - } - - /** - * @dev Returns the downcasted uint184 from uint256, reverting on - * overflow (when the input is greater than largest uint184). - * - * Counterpart to Solidity's `uint184` operator. - * - * Requirements: - * - * - input must fit into 184 bits - * - * _Available since v4.7._ - */ - function toUint184(uint256 value) internal pure returns (uint184) { - require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); - return uint184(value); - } - - /** - * @dev Returns the downcasted uint176 from uint256, reverting on - * overflow (when the input is greater than largest uint176). - * - * Counterpart to Solidity's `uint176` operator. - * - * Requirements: - * - * - input must fit into 176 bits - * - * _Available since v4.7._ - */ - function toUint176(uint256 value) internal pure returns (uint176) { - require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); - return uint176(value); - } - - /** - * @dev Returns the downcasted uint168 from uint256, reverting on - * overflow (when the input is greater than largest uint168). - * - * Counterpart to Solidity's `uint168` operator. - * - * Requirements: - * - * - input must fit into 168 bits - * - * _Available since v4.7._ - */ - function toUint168(uint256 value) internal pure returns (uint168) { - require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); - return uint168(value); - } - - /** - * @dev Returns the downcasted uint160 from uint256, reverting on - * overflow (when the input is greater than largest uint160). - * - * Counterpart to Solidity's `uint160` operator. - * - * Requirements: - * - * - input must fit into 160 bits - * - * _Available since v4.7._ - */ - function toUint160(uint256 value) internal pure returns (uint160) { - require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); - return uint160(value); - } - - /** - * @dev Returns the downcasted uint152 from uint256, reverting on - * overflow (when the input is greater than largest uint152). - * - * Counterpart to Solidity's `uint152` operator. - * - * Requirements: - * - * - input must fit into 152 bits - * - * _Available since v4.7._ - */ - function toUint152(uint256 value) internal pure returns (uint152) { - require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); - return uint152(value); - } - - /** - * @dev Returns the downcasted uint144 from uint256, reverting on - * overflow (when the input is greater than largest uint144). - * - * Counterpart to Solidity's `uint144` operator. - * - * Requirements: - * - * - input must fit into 144 bits - * - * _Available since v4.7._ - */ - function toUint144(uint256 value) internal pure returns (uint144) { - require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); - return uint144(value); - } - - /** - * @dev Returns the downcasted uint136 from uint256, reverting on - * overflow (when the input is greater than largest uint136). - * - * Counterpart to Solidity's `uint136` operator. - * - * Requirements: - * - * - input must fit into 136 bits - * - * _Available since v4.7._ - */ - function toUint136(uint256 value) internal pure returns (uint136) { - require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); - return uint136(value); - } - - /** - * @dev Returns the downcasted uint128 from uint256, reverting on - * overflow (when the input is greater than largest uint128). - * - * Counterpart to Solidity's `uint128` operator. - * - * Requirements: - * - * - input must fit into 128 bits - * - * _Available since v2.5._ - */ - function toUint128(uint256 value) internal pure returns (uint128) { - require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); - return uint128(value); - } - - /** - * @dev Returns the downcasted uint120 from uint256, reverting on - * overflow (when the input is greater than largest uint120). - * - * Counterpart to Solidity's `uint120` operator. - * - * Requirements: - * - * - input must fit into 120 bits - * - * _Available since v4.7._ - */ - function toUint120(uint256 value) internal pure returns (uint120) { - require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); - return uint120(value); - } - - /** - * @dev Returns the downcasted uint112 from uint256, reverting on - * overflow (when the input is greater than largest uint112). - * - * Counterpart to Solidity's `uint112` operator. - * - * Requirements: - * - * - input must fit into 112 bits - * - * _Available since v4.7._ - */ - function toUint112(uint256 value) internal pure returns (uint112) { - require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); - return uint112(value); - } - - /** - * @dev Returns the downcasted uint104 from uint256, reverting on - * overflow (when the input is greater than largest uint104). - * - * Counterpart to Solidity's `uint104` operator. - * - * Requirements: - * - * - input must fit into 104 bits - * - * _Available since v4.7._ - */ - function toUint104(uint256 value) internal pure returns (uint104) { - require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); - return uint104(value); - } - - /** - * @dev Returns the downcasted uint96 from uint256, reverting on - * overflow (when the input is greater than largest uint96). - * - * Counterpart to Solidity's `uint96` operator. - * - * Requirements: - * - * - input must fit into 96 bits - * - * _Available since v4.2._ - */ - function toUint96(uint256 value) internal pure returns (uint96) { - require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); - return uint96(value); - } - - /** - * @dev Returns the downcasted uint88 from uint256, reverting on - * overflow (when the input is greater than largest uint88). - * - * Counterpart to Solidity's `uint88` operator. - * - * Requirements: - * - * - input must fit into 88 bits - * - * _Available since v4.7._ - */ - function toUint88(uint256 value) internal pure returns (uint88) { - require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); - return uint88(value); - } - - /** - * @dev Returns the downcasted uint80 from uint256, reverting on - * overflow (when the input is greater than largest uint80). - * - * Counterpart to Solidity's `uint80` operator. - * - * Requirements: - * - * - input must fit into 80 bits - * - * _Available since v4.7._ - */ - function toUint80(uint256 value) internal pure returns (uint80) { - require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); - return uint80(value); - } - - /** - * @dev Returns the downcasted uint72 from uint256, reverting on - * overflow (when the input is greater than largest uint72). - * - * Counterpart to Solidity's `uint72` operator. - * - * Requirements: - * - * - input must fit into 72 bits - * - * _Available since v4.7._ - */ - function toUint72(uint256 value) internal pure returns (uint72) { - require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); - return uint72(value); - } - - /** - * @dev Returns the downcasted uint64 from uint256, reverting on - * overflow (when the input is greater than largest uint64). - * - * Counterpart to Solidity's `uint64` operator. - * - * Requirements: - * - * - input must fit into 64 bits - * - * _Available since v2.5._ - */ - function toUint64(uint256 value) internal pure returns (uint64) { - require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); - return uint64(value); - } - - /** - * @dev Returns the downcasted uint56 from uint256, reverting on - * overflow (when the input is greater than largest uint56). - * - * Counterpart to Solidity's `uint56` operator. - * - * Requirements: - * - * - input must fit into 56 bits - * - * _Available since v4.7._ - */ - function toUint56(uint256 value) internal pure returns (uint56) { - require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); - return uint56(value); - } - - /** - * @dev Returns the downcasted uint48 from uint256, reverting on - * overflow (when the input is greater than largest uint48). - * - * Counterpart to Solidity's `uint48` operator. - * - * Requirements: - * - * - input must fit into 48 bits - * - * _Available since v4.7._ - */ - function toUint48(uint256 value) internal pure returns (uint48) { - require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); - return uint48(value); - } - - /** - * @dev Returns the downcasted uint40 from uint256, reverting on - * overflow (when the input is greater than largest uint40). - * - * Counterpart to Solidity's `uint40` operator. - * - * Requirements: - * - * - input must fit into 40 bits - * - * _Available since v4.7._ - */ - function toUint40(uint256 value) internal pure returns (uint40) { - require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); - return uint40(value); - } - - /** - * @dev Returns the downcasted uint32 from uint256, reverting on - * overflow (when the input is greater than largest uint32). - * - * Counterpart to Solidity's `uint32` operator. - * - * Requirements: - * - * - input must fit into 32 bits - * - * _Available since v2.5._ - */ - function toUint32(uint256 value) internal pure returns (uint32) { - require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); - return uint32(value); - } - - /** - * @dev Returns the downcasted uint24 from uint256, reverting on - * overflow (when the input is greater than largest uint24). - * - * Counterpart to Solidity's `uint24` operator. - * - * Requirements: - * - * - input must fit into 24 bits - * - * _Available since v4.7._ - */ - function toUint24(uint256 value) internal pure returns (uint24) { - require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); - return uint24(value); - } - - /** - * @dev Returns the downcasted uint16 from uint256, reverting on - * overflow (when the input is greater than largest uint16). - * - * Counterpart to Solidity's `uint16` operator. - * - * Requirements: - * - * - input must fit into 16 bits - * - * _Available since v2.5._ - */ - function toUint16(uint256 value) internal pure returns (uint16) { - require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); - return uint16(value); - } - - /** - * @dev Returns the downcasted uint8 from uint256, reverting on - * overflow (when the input is greater than largest uint8). - * - * Counterpart to Solidity's `uint8` operator. - * - * Requirements: - * - * - input must fit into 8 bits - * - * _Available since v2.5._ - */ - function toUint8(uint256 value) internal pure returns (uint8) { - require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); - return uint8(value); - } - - /** - * @dev Converts a signed int256 into an unsigned uint256. - * - * Requirements: - * - * - input must be greater than or equal to 0. - * - * _Available since v3.0._ - */ - function toUint256(int256 value) internal pure returns (uint256) { - require(value >= 0, "SafeCast: value must be positive"); - return uint256(value); - } - - /** - * @dev Returns the downcasted int248 from int256, reverting on - * overflow (when the input is less than smallest int248 or - * greater than largest int248). - * - * Counterpart to Solidity's `int248` operator. - * - * Requirements: - * - * - input must fit into 248 bits - * - * _Available since v4.7._ - */ - function toInt248(int256 value) internal pure returns (int248 downcasted) { - downcasted = int248(value); - require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); - } - - /** - * @dev Returns the downcasted int240 from int256, reverting on - * overflow (when the input is less than smallest int240 or - * greater than largest int240). - * - * Counterpart to Solidity's `int240` operator. - * - * Requirements: - * - * - input must fit into 240 bits - * - * _Available since v4.7._ - */ - function toInt240(int256 value) internal pure returns (int240 downcasted) { - downcasted = int240(value); - require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); - } - - /** - * @dev Returns the downcasted int232 from int256, reverting on - * overflow (when the input is less than smallest int232 or - * greater than largest int232). - * - * Counterpart to Solidity's `int232` operator. - * - * Requirements: - * - * - input must fit into 232 bits - * - * _Available since v4.7._ - */ - function toInt232(int256 value) internal pure returns (int232 downcasted) { - downcasted = int232(value); - require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); - } - - /** - * @dev Returns the downcasted int224 from int256, reverting on - * overflow (when the input is less than smallest int224 or - * greater than largest int224). - * - * Counterpart to Solidity's `int224` operator. - * - * Requirements: - * - * - input must fit into 224 bits - * - * _Available since v4.7._ - */ - function toInt224(int256 value) internal pure returns (int224 downcasted) { - downcasted = int224(value); - require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); - } - - /** - * @dev Returns the downcasted int216 from int256, reverting on - * overflow (when the input is less than smallest int216 or - * greater than largest int216). - * - * Counterpart to Solidity's `int216` operator. - * - * Requirements: - * - * - input must fit into 216 bits - * - * _Available since v4.7._ - */ - function toInt216(int256 value) internal pure returns (int216 downcasted) { - downcasted = int216(value); - require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); - } - - /** - * @dev Returns the downcasted int208 from int256, reverting on - * overflow (when the input is less than smallest int208 or - * greater than largest int208). - * - * Counterpart to Solidity's `int208` operator. - * - * Requirements: - * - * - input must fit into 208 bits - * - * _Available since v4.7._ - */ - function toInt208(int256 value) internal pure returns (int208 downcasted) { - downcasted = int208(value); - require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); - } - - /** - * @dev Returns the downcasted int200 from int256, reverting on - * overflow (when the input is less than smallest int200 or - * greater than largest int200). - * - * Counterpart to Solidity's `int200` operator. - * - * Requirements: - * - * - input must fit into 200 bits - * - * _Available since v4.7._ - */ - function toInt200(int256 value) internal pure returns (int200 downcasted) { - downcasted = int200(value); - require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); - } - - /** - * @dev Returns the downcasted int192 from int256, reverting on - * overflow (when the input is less than smallest int192 or - * greater than largest int192). - * - * Counterpart to Solidity's `int192` operator. - * - * Requirements: - * - * - input must fit into 192 bits - * - * _Available since v4.7._ - */ - function toInt192(int256 value) internal pure returns (int192 downcasted) { - downcasted = int192(value); - require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); - } - - /** - * @dev Returns the downcasted int184 from int256, reverting on - * overflow (when the input is less than smallest int184 or - * greater than largest int184). - * - * Counterpart to Solidity's `int184` operator. - * - * Requirements: - * - * - input must fit into 184 bits - * - * _Available since v4.7._ - */ - function toInt184(int256 value) internal pure returns (int184 downcasted) { - downcasted = int184(value); - require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); - } - - /** - * @dev Returns the downcasted int176 from int256, reverting on - * overflow (when the input is less than smallest int176 or - * greater than largest int176). - * - * Counterpart to Solidity's `int176` operator. - * - * Requirements: - * - * - input must fit into 176 bits - * - * _Available since v4.7._ - */ - function toInt176(int256 value) internal pure returns (int176 downcasted) { - downcasted = int176(value); - require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); - } - - /** - * @dev Returns the downcasted int168 from int256, reverting on - * overflow (when the input is less than smallest int168 or - * greater than largest int168). - * - * Counterpart to Solidity's `int168` operator. - * - * Requirements: - * - * - input must fit into 168 bits - * - * _Available since v4.7._ - */ - function toInt168(int256 value) internal pure returns (int168 downcasted) { - downcasted = int168(value); - require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); - } - - /** - * @dev Returns the downcasted int160 from int256, reverting on - * overflow (when the input is less than smallest int160 or - * greater than largest int160). - * - * Counterpart to Solidity's `int160` operator. - * - * Requirements: - * - * - input must fit into 160 bits - * - * _Available since v4.7._ - */ - function toInt160(int256 value) internal pure returns (int160 downcasted) { - downcasted = int160(value); - require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); - } - - /** - * @dev Returns the downcasted int152 from int256, reverting on - * overflow (when the input is less than smallest int152 or - * greater than largest int152). - * - * Counterpart to Solidity's `int152` operator. - * - * Requirements: - * - * - input must fit into 152 bits - * - * _Available since v4.7._ - */ - function toInt152(int256 value) internal pure returns (int152 downcasted) { - downcasted = int152(value); - require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); - } - - /** - * @dev Returns the downcasted int144 from int256, reverting on - * overflow (when the input is less than smallest int144 or - * greater than largest int144). - * - * Counterpart to Solidity's `int144` operator. - * - * Requirements: - * - * - input must fit into 144 bits - * - * _Available since v4.7._ - */ - function toInt144(int256 value) internal pure returns (int144 downcasted) { - downcasted = int144(value); - require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); - } - - /** - * @dev Returns the downcasted int136 from int256, reverting on - * overflow (when the input is less than smallest int136 or - * greater than largest int136). - * - * Counterpart to Solidity's `int136` operator. - * - * Requirements: - * - * - input must fit into 136 bits - * - * _Available since v4.7._ - */ - function toInt136(int256 value) internal pure returns (int136 downcasted) { - downcasted = int136(value); - require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); - } - - /** - * @dev Returns the downcasted int128 from int256, reverting on - * overflow (when the input is less than smallest int128 or - * greater than largest int128). - * - * Counterpart to Solidity's `int128` operator. - * - * Requirements: - * - * - input must fit into 128 bits - * - * _Available since v3.1._ - */ - function toInt128(int256 value) internal pure returns (int128 downcasted) { - downcasted = int128(value); - require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); - } - - /** - * @dev Returns the downcasted int120 from int256, reverting on - * overflow (when the input is less than smallest int120 or - * greater than largest int120). - * - * Counterpart to Solidity's `int120` operator. - * - * Requirements: - * - * - input must fit into 120 bits - * - * _Available since v4.7._ - */ - function toInt120(int256 value) internal pure returns (int120 downcasted) { - downcasted = int120(value); - require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); - } - - /** - * @dev Returns the downcasted int112 from int256, reverting on - * overflow (when the input is less than smallest int112 or - * greater than largest int112). - * - * Counterpart to Solidity's `int112` operator. - * - * Requirements: - * - * - input must fit into 112 bits - * - * _Available since v4.7._ - */ - function toInt112(int256 value) internal pure returns (int112 downcasted) { - downcasted = int112(value); - require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); - } - - /** - * @dev Returns the downcasted int104 from int256, reverting on - * overflow (when the input is less than smallest int104 or - * greater than largest int104). - * - * Counterpart to Solidity's `int104` operator. - * - * Requirements: - * - * - input must fit into 104 bits - * - * _Available since v4.7._ - */ - function toInt104(int256 value) internal pure returns (int104 downcasted) { - downcasted = int104(value); - require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); - } - - /** - * @dev Returns the downcasted int96 from int256, reverting on - * overflow (when the input is less than smallest int96 or - * greater than largest int96). - * - * Counterpart to Solidity's `int96` operator. - * - * Requirements: - * - * - input must fit into 96 bits - * - * _Available since v4.7._ - */ - function toInt96(int256 value) internal pure returns (int96 downcasted) { - downcasted = int96(value); - require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); - } - - /** - * @dev Returns the downcasted int88 from int256, reverting on - * overflow (when the input is less than smallest int88 or - * greater than largest int88). - * - * Counterpart to Solidity's `int88` operator. - * - * Requirements: - * - * - input must fit into 88 bits - * - * _Available since v4.7._ - */ - function toInt88(int256 value) internal pure returns (int88 downcasted) { - downcasted = int88(value); - require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); - } - - /** - * @dev Returns the downcasted int80 from int256, reverting on - * overflow (when the input is less than smallest int80 or - * greater than largest int80). - * - * Counterpart to Solidity's `int80` operator. - * - * Requirements: - * - * - input must fit into 80 bits - * - * _Available since v4.7._ - */ - function toInt80(int256 value) internal pure returns (int80 downcasted) { - downcasted = int80(value); - require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); - } - - /** - * @dev Returns the downcasted int72 from int256, reverting on - * overflow (when the input is less than smallest int72 or - * greater than largest int72). - * - * Counterpart to Solidity's `int72` operator. - * - * Requirements: - * - * - input must fit into 72 bits - * - * _Available since v4.7._ - */ - function toInt72(int256 value) internal pure returns (int72 downcasted) { - downcasted = int72(value); - require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); - } - - /** - * @dev Returns the downcasted int64 from int256, reverting on - * overflow (when the input is less than smallest int64 or - * greater than largest int64). - * - * Counterpart to Solidity's `int64` operator. - * - * Requirements: - * - * - input must fit into 64 bits - * - * _Available since v3.1._ - */ - function toInt64(int256 value) internal pure returns (int64 downcasted) { - downcasted = int64(value); - require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); - } - - /** - * @dev Returns the downcasted int56 from int256, reverting on - * overflow (when the input is less than smallest int56 or - * greater than largest int56). - * - * Counterpart to Solidity's `int56` operator. - * - * Requirements: - * - * - input must fit into 56 bits - * - * _Available since v4.7._ - */ - function toInt56(int256 value) internal pure returns (int56 downcasted) { - downcasted = int56(value); - require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); - } - - /** - * @dev Returns the downcasted int48 from int256, reverting on - * overflow (when the input is less than smallest int48 or - * greater than largest int48). - * - * Counterpart to Solidity's `int48` operator. - * - * Requirements: - * - * - input must fit into 48 bits - * - * _Available since v4.7._ - */ - function toInt48(int256 value) internal pure returns (int48 downcasted) { - downcasted = int48(value); - require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); - } - - /** - * @dev Returns the downcasted int40 from int256, reverting on - * overflow (when the input is less than smallest int40 or - * greater than largest int40). - * - * Counterpart to Solidity's `int40` operator. - * - * Requirements: - * - * - input must fit into 40 bits - * - * _Available since v4.7._ - */ - function toInt40(int256 value) internal pure returns (int40 downcasted) { - downcasted = int40(value); - require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); - } - - /** - * @dev Returns the downcasted int32 from int256, reverting on - * overflow (when the input is less than smallest int32 or - * greater than largest int32). - * - * Counterpart to Solidity's `int32` operator. - * - * Requirements: - * - * - input must fit into 32 bits - * - * _Available since v3.1._ - */ - function toInt32(int256 value) internal pure returns (int32 downcasted) { - downcasted = int32(value); - require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); - } - - /** - * @dev Returns the downcasted int24 from int256, reverting on - * overflow (when the input is less than smallest int24 or - * greater than largest int24). - * - * Counterpart to Solidity's `int24` operator. - * - * Requirements: - * - * - input must fit into 24 bits - * - * _Available since v4.7._ - */ - function toInt24(int256 value) internal pure returns (int24 downcasted) { - downcasted = int24(value); - require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); - } - - /** - * @dev Returns the downcasted int16 from int256, reverting on - * overflow (when the input is less than smallest int16 or - * greater than largest int16). - * - * Counterpart to Solidity's `int16` operator. - * - * Requirements: - * - * - input must fit into 16 bits - * - * _Available since v3.1._ - */ - function toInt16(int256 value) internal pure returns (int16 downcasted) { - downcasted = int16(value); - require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); - } - - /** - * @dev Returns the downcasted int8 from int256, reverting on - * overflow (when the input is less than smallest int8 or - * greater than largest int8). - * - * Counterpart to Solidity's `int8` operator. - * - * Requirements: - * - * - input must fit into 8 bits - * - * _Available since v3.1._ - */ - function toInt8(int256 value) internal pure returns (int8 downcasted) { - downcasted = int8(value); - require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); - } - - /** - * @dev Converts an unsigned uint256 into a signed int256. - * - * Requirements: - * - * - input must be less than or equal to maxInt256. - * - * _Available since v3.0._ - */ - function toInt256(uint256 value) internal pure returns (int256) { - // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive - require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); - return int256(value); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol deleted file mode 100644 index 550f0e7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) - -pragma solidity ^0.8.0; - -// CAUTION -// This version of SafeMath should only be used with Solidity 0.8 or later, -// because it relies on the compiler's built in overflow checks. - -/** - * @dev Wrappers over Solidity's arithmetic operations. - * - * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler - * now has built in overflow checking. - */ -library SafeMath { - /** - * @dev Returns the addition of two unsigned integers, with an overflow flag. - * - * _Available since v3.4._ - */ - function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - uint256 c = a + b; - if (c < a) return (false, 0); - return (true, c); - } - } - - /** - * @dev Returns the subtraction of two unsigned integers, with an overflow flag. - * - * _Available since v3.4._ - */ - function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - if (b > a) return (false, 0); - return (true, a - b); - } - } - - /** - * @dev Returns the multiplication of two unsigned integers, with an overflow flag. - * - * _Available since v3.4._ - */ - function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) return (true, 0); - uint256 c = a * b; - if (c / a != b) return (false, 0); - return (true, c); - } - } - - /** - * @dev Returns the division of two unsigned integers, with a division by zero flag. - * - * _Available since v3.4._ - */ - function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - if (b == 0) return (false, 0); - return (true, a / b); - } - } - - /** - * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. - * - * _Available since v3.4._ - */ - function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { - unchecked { - if (b == 0) return (false, 0); - return (true, a % b); - } - } - - /** - * @dev Returns the addition of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - return a + b; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return a - b; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - return a * b; - } - - /** - * @dev Returns the integer division of two unsigned integers, reverting on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return a / b; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * reverting when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return a % b; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on - * overflow (when the result is negative). - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {trySub}. - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { - unchecked { - require(b <= a, errorMessage); - return a - b; - } - } - - /** - * @dev Returns the integer division of two unsigned integers, reverting with custom message on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { - unchecked { - require(b > 0, errorMessage); - return a / b; - } - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * reverting with custom message when dividing by zero. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryMod}. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function mod( - uint256 a, - uint256 b, - string memory errorMessage - ) internal pure returns (uint256) { - unchecked { - require(b > 0, errorMessage); - return a % b; - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol deleted file mode 100644 index 5a9d606..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Standard signed math utilities missing in the Solidity language. - */ -library SignedMath { - /** - * @dev Returns the largest of two signed numbers. - */ - function max(int256 a, int256 b) internal pure returns (int256) { - return a >= b ? a : b; - } - - /** - * @dev Returns the smallest of two signed numbers. - */ - function min(int256 a, int256 b) internal pure returns (int256) { - return a < b ? a : b; - } - - /** - * @dev Returns the average of two signed numbers without overflow. - * The result is rounded towards zero. - */ - function average(int256 a, int256 b) internal pure returns (int256) { - // Formula from the book "Hacker's Delight" - int256 x = (a & b) + ((a ^ b) >> 1); - return x + (int256(uint256(x) >> 255) & (a ^ b)); - } - - /** - * @dev Returns the absolute unsigned value of a signed value. - */ - function abs(int256 n) internal pure returns (uint256) { - unchecked { - // must be unchecked in order to support `n = type(int256).min` - return uint256(n >= 0 ? n : -n); - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SignedSafeMath.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SignedSafeMath.sol deleted file mode 100644 index 6704d4c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/math/SignedSafeMath.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/math/SignedSafeMath.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Wrappers over Solidity's arithmetic operations. - * - * NOTE: `SignedSafeMath` is no longer needed starting with Solidity 0.8. The compiler - * now has built in overflow checking. - */ -library SignedSafeMath { - /** - * @dev Returns the multiplication of two signed integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - * - Multiplication cannot overflow. - */ - function mul(int256 a, int256 b) internal pure returns (int256) { - return a * b; - } - - /** - * @dev Returns the integer division of two signed integers. Reverts on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. - * - * Requirements: - * - * - The divisor cannot be zero. - */ - function div(int256 a, int256 b) internal pure returns (int256) { - return a / b; - } - - /** - * @dev Returns the subtraction of two signed integers, reverting on - * overflow. - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - * - Subtraction cannot overflow. - */ - function sub(int256 a, int256 b) internal pure returns (int256) { - return a - b; - } - - /** - * @dev Returns the addition of two signed integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - * - Addition cannot overflow. - */ - function add(int256 a, int256 b) internal pure returns (int256) { - return a + b; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol deleted file mode 100644 index 9721b83..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sol +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol) -pragma solidity ^0.8.0; - -/** - * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential. - * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor]. - */ -library BitMaps { - struct BitMap { - mapping(uint256 => uint256) _data; - } - - /** - * @dev Returns whether the bit at `index` is set. - */ - function get(BitMap storage bitmap, uint256 index) internal view returns (bool) { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - return bitmap._data[bucket] & mask != 0; - } - - /** - * @dev Sets the bit at `index` to the boolean `value`. - */ - function setTo( - BitMap storage bitmap, - uint256 index, - bool value - ) internal { - if (value) { - set(bitmap, index); - } else { - unset(bitmap, index); - } - } - - /** - * @dev Sets the bit at `index`. - */ - function set(BitMap storage bitmap, uint256 index) internal { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - bitmap._data[bucket] |= mask; - } - - /** - * @dev Unsets the bit at `index`. - */ - function unset(BitMap storage bitmap, uint256 index) internal { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - bitmap._data[bucket] &= ~mask; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol deleted file mode 100644 index eae79ad..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sol +++ /dev/null @@ -1,170 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol) -pragma solidity ^0.8.4; - -import "../math/SafeCast.sol"; - -/** - * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of - * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and - * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that - * the existing queue contents are left in storage. - * - * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be - * used in storage, and not in memory. - * ``` - * DoubleEndedQueue.Bytes32Deque queue; - * ``` - * - * _Available since v4.6._ - */ -library DoubleEndedQueue { - /** - * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty. - */ - error Empty(); - - /** - * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds. - */ - error OutOfBounds(); - - /** - * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end - * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely - * assume that these 128-bit indices will not overflow, and use unchecked arithmetic. - * - * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to - * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and - * lead to unexpected behavior. - * - * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at - * data[end - 1]. - */ - struct Bytes32Deque { - int128 _begin; - int128 _end; - mapping(int128 => bytes32) _data; - } - - /** - * @dev Inserts an item at the end of the queue. - */ - function pushBack(Bytes32Deque storage deque, bytes32 value) internal { - int128 backIndex = deque._end; - deque._data[backIndex] = value; - unchecked { - deque._end = backIndex + 1; - } - } - - /** - * @dev Removes the item at the end of the queue and returns it. - * - * Reverts with `Empty` if the queue is empty. - */ - function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) { - if (empty(deque)) revert Empty(); - int128 backIndex; - unchecked { - backIndex = deque._end - 1; - } - value = deque._data[backIndex]; - delete deque._data[backIndex]; - deque._end = backIndex; - } - - /** - * @dev Inserts an item at the beginning of the queue. - */ - function pushFront(Bytes32Deque storage deque, bytes32 value) internal { - int128 frontIndex; - unchecked { - frontIndex = deque._begin - 1; - } - deque._data[frontIndex] = value; - deque._begin = frontIndex; - } - - /** - * @dev Removes the item at the beginning of the queue and returns it. - * - * Reverts with `Empty` if the queue is empty. - */ - function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) { - if (empty(deque)) revert Empty(); - int128 frontIndex = deque._begin; - value = deque._data[frontIndex]; - delete deque._data[frontIndex]; - unchecked { - deque._begin = frontIndex + 1; - } - } - - /** - * @dev Returns the item at the beginning of the queue. - * - * Reverts with `Empty` if the queue is empty. - */ - function front(Bytes32Deque storage deque) internal view returns (bytes32 value) { - if (empty(deque)) revert Empty(); - int128 frontIndex = deque._begin; - return deque._data[frontIndex]; - } - - /** - * @dev Returns the item at the end of the queue. - * - * Reverts with `Empty` if the queue is empty. - */ - function back(Bytes32Deque storage deque) internal view returns (bytes32 value) { - if (empty(deque)) revert Empty(); - int128 backIndex; - unchecked { - backIndex = deque._end - 1; - } - return deque._data[backIndex]; - } - - /** - * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at - * `length(deque) - 1`. - * - * Reverts with `OutOfBounds` if the index is out of bounds. - */ - function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) { - // int256(deque._begin) is a safe upcast - int128 idx = SafeCast.toInt128(int256(deque._begin) + SafeCast.toInt256(index)); - if (idx >= deque._end) revert OutOfBounds(); - return deque._data[idx]; - } - - /** - * @dev Resets the queue back to being empty. - * - * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses - * out on potential gas refunds. - */ - function clear(Bytes32Deque storage deque) internal { - deque._begin = 0; - deque._end = 0; - } - - /** - * @dev Returns the number of items in the queue. - */ - function length(Bytes32Deque storage deque) internal view returns (uint256) { - // The interface preserves the invariant that begin <= end so we assume this will not overflow. - // We also assume there are at most int256.max items in the queue. - unchecked { - return uint256(int256(deque._end) - int256(deque._begin)); - } - } - - /** - * @dev Returns true if the queue is empty. - */ - function empty(Bytes32Deque storage deque) internal view returns (bool) { - return deque._end <= deque._begin; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol deleted file mode 100644 index ba80201..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol +++ /dev/null @@ -1,529 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableMap.sol) - -pragma solidity ^0.8.0; - -import "./EnumerableSet.sol"; - -/** - * @dev Library for managing an enumerable variant of Solidity's - * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] - * type. - * - * Maps have the following properties: - * - * - Entries are added, removed, and checked for existence in constant time - * (O(1)). - * - Entries are enumerated in O(n). No guarantees are made on the ordering. - * - * ``` - * contract Example { - * // Add the library methods - * using EnumerableMap for EnumerableMap.UintToAddressMap; - * - * // Declare a set state variable - * EnumerableMap.UintToAddressMap private myMap; - * } - * ``` - * - * The following map types are supported: - * - * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 - * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 - * - `bytes32 -> bytes32` (`Bytes32ToBytes32`) since v4.6.0 - * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 - * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 - * - * [WARNING] - * ==== - * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. - * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. - * - * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an array of EnumerableMap. - * ==== - */ -library EnumerableMap { - using EnumerableSet for EnumerableSet.Bytes32Set; - - // To implement this library for multiple types with as little code - // repetition as possible, we write it in terms of a generic Map type with - // bytes32 keys and values. - // The Map implementation uses private functions, and user-facing - // implementations (such as Uint256ToAddressMap) are just wrappers around - // the underlying Map. - // This means that we can only create new EnumerableMaps for types that fit - // in bytes32. - - struct Bytes32ToBytes32Map { - // Storage of keys - EnumerableSet.Bytes32Set _keys; - mapping(bytes32 => bytes32) _values; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - Bytes32ToBytes32Map storage map, - bytes32 key, - bytes32 value - ) internal returns (bool) { - map._values[key] = value; - return map._keys.add(key); - } - - /** - * @dev Removes a key-value pair from a map. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { - delete map._values[key]; - return map._keys.remove(key); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { - return map._keys.contains(key); - } - - /** - * @dev Returns the number of key-value pairs in the map. O(1). - */ - function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { - return map._keys.length(); - } - - /** - * @dev Returns the key-value pair stored at position `index` in the map. O(1). - * - * Note that there are no guarantees on the ordering of entries inside the - * array, and it may change when more entries are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { - bytes32 key = map._keys.at(index); - return (key, map._values[key]); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { - bytes32 value = map._values[key]; - if (value == bytes32(0)) { - return (contains(map, key), bytes32(0)); - } else { - return (true, value); - } - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { - bytes32 value = map._values[key]; - require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key"); - return value; - } - - /** - * @dev Same as {_get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {_tryGet}. - */ - function get( - Bytes32ToBytes32Map storage map, - bytes32 key, - string memory errorMessage - ) internal view returns (bytes32) { - bytes32 value = map._values[key]; - require(value != 0 || contains(map, key), errorMessage); - return value; - } - - // UintToUintMap - - struct UintToUintMap { - Bytes32ToBytes32Map _inner; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - UintToUintMap storage map, - uint256 key, - uint256 value - ) internal returns (bool) { - return set(map._inner, bytes32(key), bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { - return remove(map._inner, bytes32(key)); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { - return contains(map._inner, bytes32(key)); - } - - /** - * @dev Returns the number of elements in the map. O(1). - */ - function length(UintToUintMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (uint256(key), uint256(value)); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); - return (success, uint256(value)); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { - return uint256(get(map._inner, bytes32(key))); - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - UintToUintMap storage map, - uint256 key, - string memory errorMessage - ) internal view returns (uint256) { - return uint256(get(map._inner, bytes32(key), errorMessage)); - } - - // UintToAddressMap - - struct UintToAddressMap { - Bytes32ToBytes32Map _inner; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - UintToAddressMap storage map, - uint256 key, - address value - ) internal returns (bool) { - return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { - return remove(map._inner, bytes32(key)); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { - return contains(map._inner, bytes32(key)); - } - - /** - * @dev Returns the number of elements in the map. O(1). - */ - function length(UintToAddressMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (uint256(key), address(uint160(uint256(value)))); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - * - * _Available since v3.4._ - */ - function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); - return (success, address(uint160(uint256(value)))); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { - return address(uint160(uint256(get(map._inner, bytes32(key))))); - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - UintToAddressMap storage map, - uint256 key, - string memory errorMessage - ) internal view returns (address) { - return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage)))); - } - - // AddressToUintMap - - struct AddressToUintMap { - Bytes32ToBytes32Map _inner; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - AddressToUintMap storage map, - address key, - uint256 value - ) internal returns (bool) { - return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(AddressToUintMap storage map, address key) internal returns (bool) { - return remove(map._inner, bytes32(uint256(uint160(key)))); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(AddressToUintMap storage map, address key) internal view returns (bool) { - return contains(map._inner, bytes32(uint256(uint160(key)))); - } - - /** - * @dev Returns the number of elements in the map. O(1). - */ - function length(AddressToUintMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (address(uint160(uint256(key))), uint256(value)); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { - (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); - return (success, uint256(value)); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(AddressToUintMap storage map, address key) internal view returns (uint256) { - return uint256(get(map._inner, bytes32(uint256(uint160(key))))); - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - AddressToUintMap storage map, - address key, - string memory errorMessage - ) internal view returns (uint256) { - return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage)); - } - - // Bytes32ToUintMap - - struct Bytes32ToUintMap { - Bytes32ToBytes32Map _inner; - } - - /** - * @dev Adds a key-value pair to a map, or updates the value for an existing - * key. O(1). - * - * Returns true if the key was added to the map, that is if it was not - * already present. - */ - function set( - Bytes32ToUintMap storage map, - bytes32 key, - uint256 value - ) internal returns (bool) { - return set(map._inner, key, bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the key was removed from the map, that is if it was present. - */ - function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { - return remove(map._inner, key); - } - - /** - * @dev Returns true if the key is in the map. O(1). - */ - function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { - return contains(map._inner, key); - } - - /** - * @dev Returns the number of elements in the map. O(1). - */ - function length(Bytes32ToUintMap storage map) internal view returns (uint256) { - return length(map._inner); - } - - /** - * @dev Returns the element stored at position `index` in the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { - (bytes32 key, bytes32 value) = at(map._inner, index); - return (key, uint256(value)); - } - - /** - * @dev Tries to returns the value associated with `key`. O(1). - * Does not revert if `key` is not in the map. - */ - function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { - (bool success, bytes32 value) = tryGet(map._inner, key); - return (success, uint256(value)); - } - - /** - * @dev Returns the value associated with `key`. O(1). - * - * Requirements: - * - * - `key` must be in the map. - */ - function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { - return uint256(get(map._inner, key)); - } - - /** - * @dev Same as {get}, with a custom error message when `key` is not in the map. - * - * CAUTION: This function is deprecated because it requires allocating memory for the error - * message unnecessarily. For custom revert reasons use {tryGet}. - */ - function get( - Bytes32ToUintMap storage map, - bytes32 key, - string memory errorMessage - ) internal view returns (uint256) { - return uint256(get(map._inner, key, errorMessage)); - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol deleted file mode 100644 index b6c647f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol +++ /dev/null @@ -1,367 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Library for managing - * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive - * types. - * - * Sets have the following properties: - * - * - Elements are added, removed, and checked for existence in constant time - * (O(1)). - * - Elements are enumerated in O(n). No guarantees are made on the ordering. - * - * ``` - * contract Example { - * // Add the library methods - * using EnumerableSet for EnumerableSet.AddressSet; - * - * // Declare a set state variable - * EnumerableSet.AddressSet private mySet; - * } - * ``` - * - * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) - * and `uint256` (`UintSet`) are supported. - * - * [WARNING] - * ==== - * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. - * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. - * - * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. - * ==== - */ -library EnumerableSet { - // To implement this library for multiple types with as little code - // repetition as possible, we write it in terms of a generic Set type with - // bytes32 values. - // The Set implementation uses private functions, and user-facing - // implementations (such as AddressSet) are just wrappers around the - // underlying Set. - // This means that we can only create new EnumerableSets for types that fit - // in bytes32. - - struct Set { - // Storage of set values - bytes32[] _values; - // Position of the value in the `values` array, plus 1 because index 0 - // means a value is not in the set. - mapping(bytes32 => uint256) _indexes; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function _add(Set storage set, bytes32 value) private returns (bool) { - if (!_contains(set, value)) { - set._values.push(value); - // The value is stored at length-1, but we add 1 to all indexes - // and use 0 as a sentinel value - set._indexes[value] = set._values.length; - return true; - } else { - return false; - } - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function _remove(Set storage set, bytes32 value) private returns (bool) { - // We read and store the value's index to prevent multiple reads from the same storage slot - uint256 valueIndex = set._indexes[value]; - - if (valueIndex != 0) { - // Equivalent to contains(set, value) - // To delete an element from the _values array in O(1), we swap the element to delete with the last one in - // the array, and then remove the last element (sometimes called as 'swap and pop'). - // This modifies the order of the array, as noted in {at}. - - uint256 toDeleteIndex = valueIndex - 1; - uint256 lastIndex = set._values.length - 1; - - if (lastIndex != toDeleteIndex) { - bytes32 lastValue = set._values[lastIndex]; - - // Move the last value to the index where the value to delete is - set._values[toDeleteIndex] = lastValue; - // Update the index for the moved value - set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex - } - - // Delete the slot where the moved value was stored - set._values.pop(); - - // Delete the index for the deleted slot - delete set._indexes[value]; - - return true; - } else { - return false; - } - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function _contains(Set storage set, bytes32 value) private view returns (bool) { - return set._indexes[value] != 0; - } - - /** - * @dev Returns the number of values on the set. O(1). - */ - function _length(Set storage set) private view returns (uint256) { - return set._values.length; - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function _at(Set storage set, uint256 index) private view returns (bytes32) { - return set._values[index]; - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function _values(Set storage set) private view returns (bytes32[] memory) { - return set._values; - } - - // Bytes32Set - - struct Bytes32Set { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { - return _add(set._inner, value); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { - return _remove(set._inner, value); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { - return _contains(set._inner, value); - } - - /** - * @dev Returns the number of values in the set. O(1). - */ - function length(Bytes32Set storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { - return _at(set._inner, index); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { - return _values(set._inner); - } - - // AddressSet - - struct AddressSet { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(AddressSet storage set, address value) internal returns (bool) { - return _add(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(AddressSet storage set, address value) internal returns (bool) { - return _remove(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(AddressSet storage set, address value) internal view returns (bool) { - return _contains(set._inner, bytes32(uint256(uint160(value)))); - } - - /** - * @dev Returns the number of values in the set. O(1). - */ - function length(AddressSet storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(AddressSet storage set, uint256 index) internal view returns (address) { - return address(uint160(uint256(_at(set._inner, index)))); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(AddressSet storage set) internal view returns (address[] memory) { - bytes32[] memory store = _values(set._inner); - address[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } - - // UintSet - - struct UintSet { - Set _inner; - } - - /** - * @dev Add a value to a set. O(1). - * - * Returns true if the value was added to the set, that is if it was not - * already present. - */ - function add(UintSet storage set, uint256 value) internal returns (bool) { - return _add(set._inner, bytes32(value)); - } - - /** - * @dev Removes a value from a set. O(1). - * - * Returns true if the value was removed from the set, that is if it was - * present. - */ - function remove(UintSet storage set, uint256 value) internal returns (bool) { - return _remove(set._inner, bytes32(value)); - } - - /** - * @dev Returns true if the value is in the set. O(1). - */ - function contains(UintSet storage set, uint256 value) internal view returns (bool) { - return _contains(set._inner, bytes32(value)); - } - - /** - * @dev Returns the number of values on the set. O(1). - */ - function length(UintSet storage set) internal view returns (uint256) { - return _length(set._inner); - } - - /** - * @dev Returns the value stored at position `index` in the set. O(1). - * - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. - * - * Requirements: - * - * - `index` must be strictly less than {length}. - */ - function at(UintSet storage set, uint256 index) internal view returns (uint256) { - return uint256(_at(set._inner, index)); - } - - /** - * @dev Return the entire set in an array - * - * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed - * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that - * this function has an unbounded cost, and using it as part of a state-changing function may render the function - * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. - */ - function values(UintSet storage set) internal view returns (uint256[] memory) { - bytes32[] memory store = _values(set._inner); - uint256[] memory result; - - /// @solidity memory-safe-assembly - assembly { - result := store - } - - return result; - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/amb/IAMB.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/amb/IAMB.sol deleted file mode 100644 index 1a5d708..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/amb/IAMB.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/amb/IAMB.sol) -pragma solidity ^0.8.0; - -interface IAMB { - event UserRequestForAffirmation(bytes32 indexed messageId, bytes encodedData); - event UserRequestForSignature(bytes32 indexed messageId, bytes encodedData); - event AffirmationCompleted( - address indexed sender, - address indexed executor, - bytes32 indexed messageId, - bool status - ); - event RelayedMessage(address indexed sender, address indexed executor, bytes32 indexed messageId, bool status); - - function messageSender() external view returns (address); - - function maxGasPerTx() external view returns (uint256); - - function transactionHash() external view returns (bytes32); - - function messageId() external view returns (bytes32); - - function messageSourceChainId() external view returns (bytes32); - - function messageCallStatus(bytes32 _messageId) external view returns (bool); - - function failedMessageDataHash(bytes32 _messageId) external view returns (bytes32); - - function failedMessageReceiver(bytes32 _messageId) external view returns (address); - - function failedMessageSender(bytes32 _messageId) external view returns (address); - - function requireToPassMessage( - address _contract, - bytes calldata _data, - uint256 _gas - ) external returns (bytes32); - - function requireToConfirmMessage( - address _contract, - bytes calldata _data, - uint256 _gas - ) external returns (bytes32); - - function sourceChainId() external view returns (uint256); - - function destinationChainId() external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IArbSys.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IArbSys.sol deleted file mode 100644 index 15a1045..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IArbSys.sol +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/arbitrum/IArbSys.sol) -pragma solidity >=0.4.21 <0.9.0; - -/** - * @title Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. Exposes a variety of system-level functionality. - */ -interface IArbSys { - /** - * @notice Get internal version number identifying an ArbOS build - * @return version number as int - */ - function arbOSVersion() external pure returns (uint256); - - function arbChainID() external view returns (uint256); - - /** - * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0) - * @return block number as int - */ - function arbBlockNumber() external view returns (uint256); - - /** - * @notice Send given amount of Eth to dest from sender. - * This is a convenience function, which is equivalent to calling sendTxToL1 with empty calldataForL1. - * @param destination recipient address on L1 - * @return unique identifier for this L2-to-L1 transaction. - */ - function withdrawEth(address destination) external payable returns (uint256); - - /** - * @notice Send a transaction to L1 - * @param destination recipient address on L1 - * @param calldataForL1 (optional) calldata for L1 contract call - * @return a unique identifier for this L2-to-L1 transaction. - */ - function sendTxToL1(address destination, bytes calldata calldataForL1) external payable returns (uint256); - - /** - * @notice get the number of transactions issued by the given external account or the account sequence number of the given contract - * @param account target account - * @return the number of transactions issued by the given external account or the account sequence number of the given contract - */ - function getTransactionCount(address account) external view returns (uint256); - - /** - * @notice get the value of target L2 storage slot - * This function is only callable from address 0 to prevent contracts from being able to call it - * @param account target account - * @param index target index of storage slot - * @return stotage value for the given account at the given index - */ - function getStorageAt(address account, uint256 index) external view returns (uint256); - - /** - * @notice check if current call is coming from l1 - * @return true if the caller of this was called directly from L1 - */ - function isTopLevelCall() external view returns (bool); - - /** - * @notice check if the caller (of this caller of this) is an aliased L1 contract address - * @return true iff the caller's address is an alias for an L1 contract address - */ - function wasMyCallersAddressAliased() external view returns (bool); - - /** - * @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing - * @return address of the caller's caller, without applying L1 contract address aliasing - */ - function myCallersAddressWithoutAliasing() external view returns (address); - - /** - * @notice map L1 sender contract address to its L2 alias - * @param sender sender address - * @param dest destination address - * @return aliased sender address - */ - function mapL1SenderContractAddressToL2Alias(address sender, address dest) external pure returns (address); - - /** - * @notice get the caller's amount of available storage gas - * @return amount of storage gas available to the caller - */ - function getStorageGasAvailable() external view returns (uint256); - - event L2ToL1Transaction( - address caller, - address indexed destination, - uint256 indexed uniqueId, - uint256 indexed batchNumber, - uint256 indexInBatch, - uint256 arbBlockNum, - uint256 ethBlockNum, - uint256 timestamp, - uint256 callvalue, - bytes data - ); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IBridge.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IBridge.sol deleted file mode 100644 index 88d5013..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IBridge.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/arbitrum/IBridge.sol) - -/* - * Copyright 2021, Offchain Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -pragma solidity ^0.8.0; - -interface IBridge { - event MessageDelivered( - uint256 indexed messageIndex, - bytes32 indexed beforeInboxAcc, - address inbox, - uint8 kind, - address sender, - bytes32 messageDataHash - ); - - event BridgeCallTriggered(address indexed outbox, address indexed destAddr, uint256 amount, bytes data); - - event InboxToggle(address indexed inbox, bool enabled); - - event OutboxToggle(address indexed outbox, bool enabled); - - function deliverMessageToInbox( - uint8 kind, - address sender, - bytes32 messageDataHash - ) external payable returns (uint256); - - function executeCall( - address destAddr, - uint256 amount, - bytes calldata data - ) external returns (bool success, bytes memory returnData); - - // These are only callable by the admin - function setInbox(address inbox, bool enabled) external; - - function setOutbox(address inbox, bool enabled) external; - - // View functions - - function activeOutbox() external view returns (address); - - function allowedInboxes(address inbox) external view returns (bool); - - function allowedOutboxes(address outbox) external view returns (bool); - - function inboxAccs(uint256 index) external view returns (bytes32); - - function messageCount() external view returns (uint256); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IInbox.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IInbox.sol deleted file mode 100644 index 75f93ed..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IInbox.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/arbitrum/IInbox.sol) - -/* - * Copyright 2021, Offchain Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -pragma solidity ^0.8.0; - -import "./IMessageProvider.sol"; - -interface IInbox is IMessageProvider { - function sendL2Message(bytes calldata messageData) external returns (uint256); - - function sendUnsignedTransaction( - uint256 maxGas, - uint256 gasPriceBid, - uint256 nonce, - address destAddr, - uint256 amount, - bytes calldata data - ) external returns (uint256); - - function sendContractTransaction( - uint256 maxGas, - uint256 gasPriceBid, - address destAddr, - uint256 amount, - bytes calldata data - ) external returns (uint256); - - function sendL1FundedUnsignedTransaction( - uint256 maxGas, - uint256 gasPriceBid, - uint256 nonce, - address destAddr, - bytes calldata data - ) external payable returns (uint256); - - function sendL1FundedContractTransaction( - uint256 maxGas, - uint256 gasPriceBid, - address destAddr, - bytes calldata data - ) external payable returns (uint256); - - function createRetryableTicket( - address destAddr, - uint256 arbTxCallValue, - uint256 maxSubmissionCost, - address submissionRefundAddress, - address valueRefundAddress, - uint256 maxGas, - uint256 gasPriceBid, - bytes calldata data - ) external payable returns (uint256); - - function createRetryableTicketNoRefundAliasRewrite( - address destAddr, - uint256 arbTxCallValue, - uint256 maxSubmissionCost, - address submissionRefundAddress, - address valueRefundAddress, - uint256 maxGas, - uint256 gasPriceBid, - bytes calldata data - ) external payable returns (uint256); - - function depositEth(uint256 maxSubmissionCost) external payable returns (uint256); - - function bridge() external view returns (address); - - function pauseCreateRetryables() external; - - function unpauseCreateRetryables() external; - - function startRewriteAddress() external; - - function stopRewriteAddress() external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IMessageProvider.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IMessageProvider.sol deleted file mode 100644 index 88d9ba4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IMessageProvider.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/arbitrum/IMessageProvider.sol) - -/* - * Copyright 2021, Offchain Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -pragma solidity ^0.8.0; - -interface IMessageProvider { - event InboxMessageDelivered(uint256 indexed messageNum, bytes data); - - event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IOutbox.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IOutbox.sol deleted file mode 100644 index 95c1080..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/arbitrum/IOutbox.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/arbitrum/IOutbox.sol) - -/* - * Copyright 2021, Offchain Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -pragma solidity ^0.8.0; - -interface IOutbox { - event OutboxEntryCreated( - uint256 indexed batchNum, - uint256 outboxEntryIndex, - bytes32 outputRoot, - uint256 numInBatch - ); - event OutBoxTransactionExecuted( - address indexed destAddr, - address indexed l2Sender, - uint256 indexed outboxEntryIndex, - uint256 transactionIndex - ); - - function l2ToL1Sender() external view returns (address); - - function l2ToL1Block() external view returns (uint256); - - function l2ToL1EthBlock() external view returns (uint256); - - function l2ToL1Timestamp() external view returns (uint256); - - function l2ToL1BatchNum() external view returns (uint256); - - function l2ToL1OutputId() external view returns (bytes32); - - function processOutgoingMessages(bytes calldata sendsData, uint256[] calldata sendLengths) external; - - function outboxEntryExists(uint256 batchNum) external view returns (bool); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol deleted file mode 100644 index fb33a68..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/compound/ICompoundTimelock.sol) - -pragma solidity ^0.8.0; - -/** - * https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[Compound's timelock] interface - */ -interface ICompoundTimelock { - event NewAdmin(address indexed newAdmin); - event NewPendingAdmin(address indexed newPendingAdmin); - event NewDelay(uint256 indexed newDelay); - event CancelTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - event ExecuteTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - event QueueTransaction( - bytes32 indexed txHash, - address indexed target, - uint256 value, - string signature, - bytes data, - uint256 eta - ); - - receive() external payable; - - // solhint-disable-next-line func-name-mixedcase - function GRACE_PERIOD() external view returns (uint256); - - // solhint-disable-next-line func-name-mixedcase - function MINIMUM_DELAY() external view returns (uint256); - - // solhint-disable-next-line func-name-mixedcase - function MAXIMUM_DELAY() external view returns (uint256); - - function admin() external view returns (address); - - function pendingAdmin() external view returns (address); - - function delay() external view returns (uint256); - - function queuedTransactions(bytes32) external view returns (bool); - - function setDelay(uint256) external; - - function acceptAdmin() external; - - function setPendingAdmin(address) external; - - function queueTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) external returns (bytes32); - - function cancelTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) external; - - function executeTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data, - uint256 eta - ) external payable returns (bytes memory); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/compound/LICENSE b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/compound/LICENSE deleted file mode 100644 index 7da2324..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/compound/LICENSE +++ /dev/null @@ -1,11 +0,0 @@ -Copyright 2020 Compound Labs, Inc. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/optimism/ICrossDomainMessenger.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/optimism/ICrossDomainMessenger.sol deleted file mode 100644 index 9cc7977..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/optimism/ICrossDomainMessenger.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/optimism/ICrossDomainMessenger.sol) -pragma solidity >0.5.0 <0.9.0; - -/** - * @title ICrossDomainMessenger - */ -interface ICrossDomainMessenger { - /********** - * Events * - **********/ - - event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); - event RelayedMessage(bytes32 indexed msgHash); - event FailedRelayedMessage(bytes32 indexed msgHash); - - /************* - * Variables * - *************/ - - function xDomainMessageSender() external view returns (address); - - /******************** - * Public Functions * - ********************/ - - /** - * Sends a cross domain message to the target messenger. - * @param _target Target contract address. - * @param _message Message to send to the target. - * @param _gasLimit Gas limit for the provided message. - */ - function sendMessage( - address _target, - bytes calldata _message, - uint32 _gasLimit - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/optimism/LICENSE b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/optimism/LICENSE deleted file mode 100644 index 6a7da52..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/optimism/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright 2020-2021 Optimism - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/polygon/IFxMessageProcessor.sol b/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/polygon/IFxMessageProcessor.sol deleted file mode 100644 index 9f42eb6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/contracts/vendor/polygon/IFxMessageProcessor.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v4.6.0) (vendor/polygon/IFxMessageProcessor.sol) -pragma solidity ^0.8.0; - -interface IFxMessageProcessor { - function processMessageFromRoot( - uint256 stateId, - address rootMessageSender, - bytes calldata data - ) external; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/hardhat.config.js b/lib/morpho-utils/lib/openzeppelin-contracts/hardhat.config.js deleted file mode 100644 index 0bfef82..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/hardhat.config.js +++ /dev/null @@ -1,95 +0,0 @@ -/// ENVVAR -// - CI: output gas report to file instead of stdout -// - COVERAGE: enable coverage report -// - ENABLE_GAS_REPORT: enable gas report -// - COMPILE_MODE: production modes enables optimizations (default: development) -// - COMPILE_VERSION: compiler version (default: 0.8.9) -// - COINMARKETCAP: coinmarkercat api key for USD value in gas report - -const fs = require('fs'); -const path = require('path'); -const argv = require('yargs/yargs')() - .env('') - .options({ - coverage: { - type: 'boolean', - default: false, - }, - gas: { - alias: 'enableGasReport', - type: 'boolean', - default: false, - }, - gasReport: { - alias: 'enableGasReportPath', - type: 'string', - implies: 'gas', - default: undefined, - }, - mode: { - alias: 'compileMode', - type: 'string', - choices: [ 'production', 'development' ], - default: 'development', - }, - ir: { - alias: 'enableIR', - type: 'boolean', - default: false, - }, - compiler: { - alias: 'compileVersion', - type: 'string', - default: '0.8.13', - }, - coinmarketcap: { - alias: 'coinmarketcapApiKey', - type: 'string', - }, - }) - .argv; - -require('@nomiclabs/hardhat-truffle5'); - -if (argv.gas) { - require('hardhat-gas-reporter'); -} - -for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) { - require(path.join(__dirname, 'hardhat', f)); -} - -const withOptimizations = argv.gas || argv.compileMode === 'production'; - -/** - * @type import('hardhat/config').HardhatUserConfig - */ -module.exports = { - solidity: { - version: argv.compiler, - settings: { - optimizer: { - enabled: withOptimizations, - runs: 200, - }, - viaIR: withOptimizations && argv.ir, - }, - }, - networks: { - hardhat: { - blockGasLimit: 10000000, - allowUnlimitedContractSize: !withOptimizations, - }, - }, - gasReporter: { - showMethodSig: true, - currency: 'USD', - outputFile: argv.gasReport, - coinmarketcap: argv.coinmarketcap, - }, -}; - -if (argv.coverage) { - require('solidity-coverage'); - module.exports.networks.hardhat.initialBaseFeePerGas = 0; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/hardhat/env-contract.js b/lib/morpho-utils/lib/openzeppelin-contracts/hardhat/env-contract.js deleted file mode 100644 index 74d54cf..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/hardhat/env-contract.js +++ /dev/null @@ -1,10 +0,0 @@ -extendEnvironment(env => { - const { contract } = env; - - env.contract = function (name, body) { - // remove the default account from the accounts list used in tests, in order - // to protect tests against accidentally passing due to the contract - // deployer being used subsequently as function caller - contract(name, accounts => body(accounts.slice(1))); - }; -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/logo.svg b/lib/morpho-utils/lib/openzeppelin-contracts/logo.svg deleted file mode 100644 index f1e14c2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/logo.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/migrations/.gitkeep b/lib/morpho-utils/lib/openzeppelin-contracts/migrations/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/netlify.toml b/lib/morpho-utils/lib/openzeppelin-contracts/netlify.toml deleted file mode 100644 index 0447f41..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/netlify.toml +++ /dev/null @@ -1,3 +0,0 @@ -[build] -command = "npm run docs" -publish = "build/site" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/package-lock.json b/lib/morpho-utils/lib/openzeppelin-contracts/package-lock.json deleted file mode 100644 index 3af8a14..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/package-lock.json +++ /dev/null @@ -1,32840 +0,0 @@ -{ - "name": "openzeppelin-solidity", - "version": "4.7.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "openzeppelin-solidity", - "version": "4.7.0", - "license": "MIT", - "bin": { - "openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js" - }, - "devDependencies": { - "@nomiclabs/hardhat-truffle5": "^2.0.5", - "@nomiclabs/hardhat-web3": "^2.0.0", - "@openzeppelin/docs-utils": "^0.1.0", - "@openzeppelin/test-helpers": "^0.5.13", - "chai": "^4.2.0", - "eslint": "^7.32.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-mocha": "^10.0.3", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.2.0", - "eth-sig-util": "^3.0.0", - "ethereumjs-util": "^7.0.7", - "ethereumjs-wallet": "^1.0.1", - "graphlib": "^2.1.8", - "hardhat": "^2.9.1", - "hardhat-gas-reporter": "^1.0.4", - "keccak256": "^1.0.2", - "lodash.startcase": "^4.4.0", - "lodash.zip": "^4.2.0", - "merkletreejs": "^0.2.13", - "micromatch": "^4.0.2", - "prettier": "^2.3.0", - "prettier-plugin-solidity": "^1.0.0-beta.16", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "solhint": "^3.3.6", - "solidity-ast": "^0.4.25", - "solidity-coverage": "^0.7.18", - "solidity-docgen": "^0.5.3", - "web3": "^1.3.0", - "yargs": "^17.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/runtime": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.6.tgz", - "integrity": "sha512-t9wi7/AW6XtKahAe20Yw0/mMljKq0B1r2fPdvaAdV/KPDZewFXdaaa6K7lxmZBZ8FBNpCiAT6iHPmd6QO9bKfQ==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@ensdomains/address-encoder": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz", - "integrity": "sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==", - "dev": true, - "dependencies": { - "bech32": "^1.1.3", - "blakejs": "^1.1.0", - "bn.js": "^4.11.8", - "bs58": "^4.0.1", - "crypto-addr-codec": "^0.1.7", - "nano-base32": "^1.0.1", - "ripemd160": "^2.0.2" - } - }, - "node_modules/@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "deprecated": "Please use @ensdomains/ens-contracts", - "dev": true, - "dependencies": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - } - }, - "node_modules/@ensdomains/ensjs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@ensdomains/ensjs/-/ensjs-2.1.0.tgz", - "integrity": "sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.4.4", - "@ensdomains/address-encoder": "^0.1.7", - "@ensdomains/ens": "0.4.5", - "@ensdomains/resolver": "0.2.4", - "content-hash": "^2.5.2", - "eth-ens-namehash": "^2.0.8", - "ethers": "^5.0.13", - "js-sha3": "^0.8.0" - } - }, - "node_modules/@ensdomains/ensjs/node_modules/ethers": { - "version": "5.6.9", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.9.tgz", - "integrity": "sha512-lMGC2zv9HC5EC+8r429WaWu3uWJUCgUCt8xxKCFqkrFuBDZXDYIdzDUECxzjf2BMF8IVBByY1EBoGSL3RTm8RA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.6.4", - "@ethersproject/abstract-provider": "5.6.1", - "@ethersproject/abstract-signer": "5.6.2", - "@ethersproject/address": "5.6.1", - "@ethersproject/base64": "5.6.1", - "@ethersproject/basex": "5.6.1", - "@ethersproject/bignumber": "5.6.2", - "@ethersproject/bytes": "5.6.1", - "@ethersproject/constants": "5.6.1", - "@ethersproject/contracts": "5.6.2", - "@ethersproject/hash": "5.6.1", - "@ethersproject/hdnode": "5.6.2", - "@ethersproject/json-wallets": "5.6.1", - "@ethersproject/keccak256": "5.6.1", - "@ethersproject/logger": "5.6.0", - "@ethersproject/networks": "5.6.4", - "@ethersproject/pbkdf2": "5.6.1", - "@ethersproject/properties": "5.6.0", - "@ethersproject/providers": "5.6.8", - "@ethersproject/random": "5.6.1", - "@ethersproject/rlp": "5.6.1", - "@ethersproject/sha2": "5.6.1", - "@ethersproject/signing-key": "5.6.2", - "@ethersproject/solidity": "5.6.1", - "@ethersproject/strings": "5.6.1", - "@ethersproject/transactions": "5.6.2", - "@ethersproject/units": "5.6.1", - "@ethersproject/wallet": "5.6.2", - "@ethersproject/web": "5.6.1", - "@ethersproject/wordlists": "5.6.1" - } - }, - "node_modules/@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "deprecated": "Please use @ensdomains/ens-contracts", - "dev": true - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@ethereumjs/block": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.3.tgz", - "integrity": "sha512-CegDeryc2DVKnDkg5COQrE0bJfw/p0v3GBk2W5/Dj5dOVfEmb50Ux0GLnSPypooLnfqjwFaorGuT9FokWB3GRg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.6.5", - "@ethereumjs/tx": "^3.5.2", - "ethereumjs-util": "^7.1.5", - "merkle-patricia-tree": "^4.2.4" - } - }, - "node_modules/@ethereumjs/blockchain": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.3.tgz", - "integrity": "sha512-bi0wuNJ1gw4ByNCV56H0Z4Q7D+SxUbwyG12Wxzbvqc89PXLRNR20LBcSUZRKpN0+YCPo6m0XZL/JLio3B52LTw==", - "dev": true, - "dependencies": { - "@ethereumjs/block": "^3.6.2", - "@ethereumjs/common": "^2.6.4", - "@ethereumjs/ethash": "^1.1.0", - "debug": "^4.3.3", - "ethereumjs-util": "^7.1.5", - "level-mem": "^5.0.1", - "lru-cache": "^5.1.1", - "semaphore-async-await": "^1.5.1" - } - }, - "node_modules/@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", - "dev": true, - "dependencies": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" - } - }, - "node_modules/@ethereumjs/ethash": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", - "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", - "dev": true, - "dependencies": { - "@ethereumjs/block": "^3.5.0", - "@types/levelup": "^4.3.0", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.1.1", - "miller-rabin": "^4.0.0" - } - }, - "node_modules/@ethereumjs/ethash/node_modules/buffer-xor": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", - "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.1" - } - }, - "node_modules/@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" - } - }, - "node_modules/@ethereumjs/vm": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.9.3.tgz", - "integrity": "sha512-Ha04TeF8goEglr8eL7hkkYyjhzdZS0PsoRURzYlTF6I0VVId5KjKb0N7MrA8GMgheN+UeTncfTgYx52D/WhEmg==", - "dev": true, - "dependencies": { - "@ethereumjs/block": "^3.6.3", - "@ethereumjs/blockchain": "^5.5.3", - "@ethereumjs/common": "^2.6.5", - "@ethereumjs/tx": "^3.5.2", - "async-eventemitter": "^0.2.4", - "core-js-pure": "^3.0.1", - "debug": "^4.3.3", - "ethereumjs-util": "^7.1.5", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.4", - "rustbn.js": "~0.2.0" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.6.4", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.4.tgz", - "integrity": "sha512-TTeZUlCeIHG6527/2goZA6gW5F8Emoc7MrZDC7hhP84aRGvW3TEdTnZR08Ls88YXM1m2SuK42Osw/jSi3uO8gg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/hash": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.1" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz", - "integrity": "sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.3", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.2", - "@ethersproject/web": "^5.6.1" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz", - "integrity": "sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", - "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.1" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.1.tgz", - "integrity": "sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.1.tgz", - "integrity": "sha512-a52MkVz4vuBXR06nvflPMotld1FJWSj2QT0985v7P/emPZO00PucFAkbcmq2vpVU7Ts7umKiSI6SppiLykVWsA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/properties": "^5.6.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.2.tgz", - "integrity": "sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bignumber/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@ethersproject/bytes": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", - "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.6.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.1.tgz", - "integrity": "sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.6.2" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.2.tgz", - "integrity": "sha512-hguUA57BIKi6WY0kHvZp6PwPlWF87MCeB4B7Z7AbUpTxfFXFdn/3b0GmjZPagIHS+3yhcBJDnuEfU4Xz+Ks/8g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.6.3", - "@ethersproject/abstract-provider": "^5.6.1", - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.2" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.1.tgz", - "integrity": "sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.1" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.2.tgz", - "integrity": "sha512-tERxW8Ccf9CxW2db3WsN01Qao3wFeRsfYY9TCuhmG0xNpl2IO8wgXU3HtWIZ49gUWPggRy4Yg5axU0ACaEKf1Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/basex": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.1", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/sha2": "^5.6.1", - "@ethersproject/signing-key": "^5.6.2", - "@ethersproject/strings": "^5.6.1", - "@ethersproject/transactions": "^5.6.2", - "@ethersproject/wordlists": "^5.6.1" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.1.tgz", - "integrity": "sha512-KfyJ6Zwz3kGeX25nLihPwZYlDqamO6pfGKNnVMWWfEVVp42lTfCZVXXy5Ie8IZTN0HKwAngpIPi7gk4IJzgmqQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/hdnode": "^5.6.2", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.1", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.1", - "@ethersproject/strings": "^5.6.1", - "@ethersproject/transactions": "^5.6.2", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.1.tgz", - "integrity": "sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", - "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.6.4", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.4.tgz", - "integrity": "sha512-KShHeHPahHI2UlWdtDMn2lJETcbtaJge4k7XSjDR9h79QTd6yQJmv6Cp2ZA4JdqWnhszAOLSuJEd9C0PRw7hSQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.6.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.1.tgz", - "integrity": "sha512-k4gRQ+D93zDRPNUfmduNKq065uadC2YjMP/CqwwX5qG6R05f47boq6pLZtV/RnC4NZAYOPH1Cyo54q0c9sshRQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/sha2": "^5.6.1" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", - "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.6.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.6.8", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.8.tgz", - "integrity": "sha512-Wf+CseT/iOJjrGtAOf3ck9zS7AgPmr2fZ3N97r4+YXN3mBePTG2/bJ8DApl9mVwYL+RpYbNxMEkEp4mPGdwG/w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.6.1", - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/base64": "^5.6.1", - "@ethersproject/basex": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/hash": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.3", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.1", - "@ethersproject/rlp": "^5.6.1", - "@ethersproject/sha2": "^5.6.1", - "@ethersproject/strings": "^5.6.1", - "@ethersproject/transactions": "^5.6.2", - "@ethersproject/web": "^5.6.1", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@ethersproject/random": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.1.tgz", - "integrity": "sha512-/wtPNHwbmng+5yi3fkipA8YBT59DdkGRoC2vWk09Dci/q5DlgnMkhIycjHlavrvrjJBkFjO/ueLyT+aUDfc4lA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.1.tgz", - "integrity": "sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.1.tgz", - "integrity": "sha512-5K2GyqcW7G4Yo3uenHegbXRPDgARpWUiXc6RiF7b6i/HXUoWlb7uCARh7BAHg7/qT/Q5ydofNwiZcim9qpjB6g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.2.tgz", - "integrity": "sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@ethersproject/solidity": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.1.tgz", - "integrity": "sha512-KWqVLkUUoLBfL1iwdzUVlkNqAUIFMpbbeH0rgCfKmJp0vFtY4AsaN91gHKo9ZZLkC4UOm3cI3BmMV4N53BOq4g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/sha2": "^5.6.1", - "@ethersproject/strings": "^5.6.1" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.1.tgz", - "integrity": "sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/logger": "^5.6.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.2.tgz", - "integrity": "sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.1", - "@ethersproject/signing-key": "^5.6.2" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.1.tgz", - "integrity": "sha512-rEfSEvMQ7obcx3KWD5EWWx77gqv54K6BKiZzKxkQJqtpriVsICrktIQmKl8ReNToPeIYPnFHpXvKpi068YFZXw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/logger": "^5.6.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.2.tgz", - "integrity": "sha512-lrgh0FDQPuOnHcF80Q3gHYsSUODp6aJLAdDmDV0xKCN/T7D99ta1jGVhulg3PY8wiXEngD0DfM0I2XKXlrqJfg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.6.1", - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/hash": "^5.6.1", - "@ethersproject/hdnode": "^5.6.2", - "@ethersproject/json-wallets": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.1", - "@ethersproject/signing-key": "^5.6.2", - "@ethersproject/transactions": "^5.6.2", - "@ethersproject/wordlists": "^5.6.1" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.1.tgz", - "integrity": "sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.6.1", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.1" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.1.tgz", - "integrity": "sha512-wiPRgBpNbNwCQFoCr8bcWO8o5I810cqO6mkdtKfLKFlLxeCWcnzDi4Alu8iyNzlhYuS9npCwivMbRWF19dyblw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/hash": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.1" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/@noble/hashes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.1.tgz", - "integrity": "sha512-Lkp9+NijmV7eSVZqiUvt3UCuuHeJpUVmRrvh430gyJjJiuJMqkeHf6/A9lQ/smmbWV/0spDeJscscPzyB4waZg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@noble/secp256k1": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.0.tgz", - "integrity": "sha512-DWSsg8zMHOYMYBqIQi96BQuthZrp98LCeMNcUOaffCIVYQ5yxDbNikLF+H7jEnmNNmXbtVic46iCuVWzar+MgA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nomiclabs/hardhat-truffle5": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.6.tgz", - "integrity": "sha512-kzkpVEX36yOmdhCJHesu+1nB+fiaKpMrvUSVd0Ox6Jila+8aSxeHTC4bbEBOIqJcvOQZ3sj5fzuE5VjhNkZkvw==", - "dev": true, - "dependencies": { - "@nomiclabs/truffle-contract": "^4.2.23", - "@types/chai": "^4.2.0", - "chai": "^4.2.0", - "ethereumjs-util": "^7.1.4", - "fs-extra": "^7.0.1" - }, - "peerDependencies": { - "@nomiclabs/hardhat-web3": "^2.0.0", - "hardhat": "^2.6.4", - "web3": "^1.0.0-beta.36" - } - }, - "node_modules/@nomiclabs/hardhat-web3": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz", - "integrity": "sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==", - "dev": true, - "dependencies": { - "@types/bignumber.js": "^5.0.0" - }, - "peerDependencies": { - "hardhat": "^2.0.0", - "web3": "^1.0.0-beta.36" - } - }, - "node_modules/@nomiclabs/truffle-contract": { - "version": "4.5.10", - "resolved": "https://registry.npmjs.org/@nomiclabs/truffle-contract/-/truffle-contract-4.5.10.tgz", - "integrity": "sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ==", - "dev": true, - "dependencies": { - "@ensdomains/ensjs": "^2.0.1", - "@truffle/blockchain-utils": "^0.1.3", - "@truffle/contract-schema": "^3.4.7", - "@truffle/debug-utils": "^6.0.22", - "@truffle/error": "^0.1.0", - "@truffle/interface-adapter": "^0.5.16", - "bignumber.js": "^7.2.1", - "ethereum-ens": "^0.8.0", - "ethers": "^4.0.0-beta.1", - "source-map-support": "^0.5.19" - }, - "peerDependencies": { - "web3": "^1.2.1", - "web3-core-helpers": "^1.2.1", - "web3-core-promievent": "^1.2.1", - "web3-eth-abi": "^1.2.1", - "web3-utils": "^1.2.1" - } - }, - "node_modules/@oclif/command": { - "version": "1.8.16", - "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.8.16.tgz", - "integrity": "sha512-rmVKYEsKzurfRU0xJz+iHelbi1LGlihIWZ7Qvmb/CBz1EkhL7nOkW4SVXmG2dA5Ce0si2gr88i6q4eBOMRNJ1w==", - "dev": true, - "dependencies": { - "@oclif/config": "^1.18.2", - "@oclif/errors": "^1.3.5", - "@oclif/help": "^1.0.1", - "@oclif/parser": "^3.8.6", - "debug": "^4.1.1", - "semver": "^7.3.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@oclif/config": "^1" - } - }, - "node_modules/@oclif/config": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.3.tgz", - "integrity": "sha512-sBpko86IrTscc39EvHUhL+c++81BVTsIZ3ETu/vG+cCdi0N6vb2DoahR67A9FI2CGnxRRHjnTfa3m6LulwNATA==", - "dev": true, - "dependencies": { - "@oclif/errors": "^1.3.5", - "@oclif/parser": "^3.8.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-wsl": "^2.1.1", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/config/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@oclif/config/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@oclif/config/node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/config/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "node_modules/@oclif/core": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-1.9.5.tgz", - "integrity": "sha512-C605Cr4RhHTMXYApLxdVt/PL6IA5cguN6MPvsMjxkvBppk2Fvcsj05dtRdDqShskRpZzHtu65emG1tHy8TWPWQ==", - "dev": true, - "dependencies": { - "@oclif/linewrap": "^1.0.0", - "@oclif/screen": "^3.0.2", - "ansi-escapes": "^4.3.2", - "ansi-styles": "^4.3.0", - "cardinal": "^2.1.1", - "chalk": "^4.1.2", - "clean-stack": "^3.0.1", - "cli-progress": "^3.10.0", - "debug": "^4.3.4", - "ejs": "^3.1.6", - "fs-extra": "^9.1.0", - "get-package-type": "^0.1.0", - "globby": "^11.1.0", - "hyperlinker": "^1.0.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "js-yaml": "^3.14.1", - "natural-orderby": "^2.0.3", - "object-treeify": "^1.1.33", - "password-prompt": "^1.1.2", - "semver": "^7.3.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "supports-hyperlinks": "^2.2.0", - "tslib": "^2.3.1", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@oclif/core/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@oclif/core/node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/core/node_modules/clean-stack": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", - "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@oclif/core/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/@oclif/core/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@oclif/core/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@oclif/core/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@oclif/core/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/core/node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/core/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@oclif/core/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/core/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/core/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/@oclif/core/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "node_modules/@oclif/core/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@oclif/errors": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.3.5.tgz", - "integrity": "sha512-OivucXPH/eLLlOT7FkCMoZXiaVYf8I/w1eTAM1+gKzfhALwWTusxEx7wBmW0uzvkSg/9ovWLycPaBgJbM3LOCQ==", - "dev": true, - "dependencies": { - "clean-stack": "^3.0.0", - "fs-extra": "^8.1", - "indent-string": "^4.0.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/errors/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/errors/node_modules/clean-stack": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", - "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@oclif/errors/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@oclif/errors/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/help": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@oclif/help/-/help-1.0.1.tgz", - "integrity": "sha512-8rsl4RHL5+vBUAKBL6PFI3mj58hjPCp2VYyXD4TAa7IMStikFfOH2gtWmqLzIlxAED2EpD0dfYwo9JJxYsH7Aw==", - "dev": true, - "dependencies": { - "@oclif/config": "1.18.2", - "@oclif/errors": "1.3.5", - "chalk": "^4.1.2", - "indent-string": "^4.0.0", - "lodash": "^4.17.21", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "widest-line": "^3.1.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/help/node_modules/@oclif/config": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.2.tgz", - "integrity": "sha512-cE3qfHWv8hGRCP31j7fIS7BfCflm/BNZ2HNqHexH+fDrdF2f1D5S8VmXWLC77ffv3oDvWyvE9AZeR0RfmHCCaA==", - "dev": true, - "dependencies": { - "@oclif/errors": "^1.3.3", - "@oclif/parser": "^3.8.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-wsl": "^2.1.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/help/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/help/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@oclif/help/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/@oclif/help/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@oclif/help/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@oclif/help/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/help/node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/help/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/help/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/help/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "node_modules/@oclif/help/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@oclif/linewrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", - "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==", - "dev": true - }, - "node_modules/@oclif/parser": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.7.tgz", - "integrity": "sha512-b11xBmIUK+LuuwVGJpFs4LwQN2xj2cBWj2c4z1FtiXGrJ85h9xV6q+k136Hw0tGg1jQoRXuvuBnqQ7es7vO9/Q==", - "dev": true, - "dependencies": { - "@oclif/errors": "^1.3.5", - "@oclif/linewrap": "^1.0.0", - "chalk": "^4.1.0", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@oclif/parser/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@oclif/parser/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "node_modules/@oclif/plugin-help": { - "version": "5.1.12", - "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.1.12.tgz", - "integrity": "sha512-HvH/RubJxqCinP0vUWQLTOboT+SfjfL8h40s+PymkWaldIcXlpoRaJX50vz+SjZIs7uewZwEk8fzLqpF/BWXlg==", - "dev": true, - "dependencies": { - "@oclif/core": "^1.3.6" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@oclif/screen": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.2.tgz", - "integrity": "sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ==", - "dev": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@openzeppelin/contract-loader": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contract-loader/-/contract-loader-0.6.3.tgz", - "integrity": "sha512-cOFIjBjwbGgZhDZsitNgJl0Ye1rd5yu/Yx5LMgeq3u0ZYzldm4uObzHDFq4gjDdoypvyORjjJa3BlFA7eAnVIg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "fs-extra": "^8.1.0" - } - }, - "node_modules/@openzeppelin/contract-loader/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@openzeppelin/docs-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/docs-utils/-/docs-utils-0.1.2.tgz", - "integrity": "sha512-oBchkfFlpqHCee/HaNXPvFy8py9Yi/LTnaE2Vsf+eO4j/FSaupzBsFIgxESjdTScSvJcIOWZFsbZDDRKscg2DQ==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "chokidar": "^3.3.0", - "env-paths": "^2.2.0", - "find-up": "^4.1.0", - "is-port-reachable": "^3.0.0", - "js-yaml": "^3.13.1", - "live-server": "^1.2.1", - "lodash.startcase": "^4.4.0", - "minimist": "^1.2.0" - }, - "bin": { - "oz-docs": "oz-docs.js" - } - }, - "node_modules/@openzeppelin/test-helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@openzeppelin/test-helpers/-/test-helpers-0.5.15.tgz", - "integrity": "sha512-10fS0kyOjc/UObo9iEWPNbC6MCeiQ7z97LDOJBj68g+AAs5pIGEI2h3V6G9TYTIq8VxOdwMQbfjKrx7Y3YZJtA==", - "dev": true, - "dependencies": { - "@openzeppelin/contract-loader": "^0.6.2", - "@truffle/contract": "^4.0.35", - "ansi-colors": "^3.2.3", - "chai": "^4.2.0", - "chai-bn": "^0.2.1", - "ethjs-abi": "^0.2.1", - "lodash.flatten": "^4.4.0", - "semver": "^5.6.0", - "web3": "^1.2.5", - "web3-utils": "^1.2.5" - } - }, - "node_modules/@openzeppelin/test-helpers/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@scure/bip32": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", - "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.1.1", - "@noble/secp256k1": "~1.6.0", - "@scure/base": "~1.1.0" - } - }, - "node_modules/@scure/bip39": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", - "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "@noble/hashes": "~1.1.1", - "@scure/base": "~1.1.0" - } - }, - "node_modules/@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dev": true, - "dependencies": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dev": true, - "dependencies": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dev": true, - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dev": true, - "dependencies": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@solidity-parser/parser": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.2.tgz", - "integrity": "sha512-10cr0s+MtRtqjEw0WFJrm2rwULN30xx7btd/v9cmqME2617/2M5MbHDkFIGIGTa7lwNw4bN9mVGfhlLzrYw8pA==", - "dev": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@truffle/abi-utils": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.13.tgz", - "integrity": "sha512-WzjyNvx+naXmG/XKF+xLI+tJZLUlPGkd29rY4xBCiY9m/xWk0ZUL6gvVvnRr3leLJkBweJUSBiGUW770V8hHOg==", - "dev": true, - "dependencies": { - "change-case": "3.0.2", - "faker": "5.5.3", - "fast-check": "^2.12.1" - } - }, - "node_modules/@truffle/blockchain-utils": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@truffle/blockchain-utils/-/blockchain-utils-0.1.3.tgz", - "integrity": "sha512-K21Wf10u6VmS12/f9OrLN98f1RCqzrmuM2zlsly4b7BF/Xdh55Iq/jNSOnsNUJa+6Iaqqz6zeidquCYu9nTFng==", - "dev": true - }, - "node_modules/@truffle/codec": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.13.1.tgz", - "integrity": "sha512-ZqpfofLEwzcdRYgInHOOoNYLqCEJ+nkYl4NTJkrszMAu9MLnHQjZqrMtfem/H8HDU3OOIgbpFlzipMdrnecjJw==", - "dev": true, - "dependencies": { - "@truffle/abi-utils": "^0.2.13", - "@truffle/compile-common": "^0.7.31", - "big.js": "^6.0.3", - "bn.js": "^5.1.3", - "cbor": "^5.1.0", - "debug": "^4.3.1", - "lodash": "^4.17.21", - "semver": "^7.3.4", - "utf8": "^3.0.0", - "web3-utils": "1.5.3" - } - }, - "node_modules/@truffle/codec/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/codec/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/@truffle/codec/node_modules/eth-lib/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/@truffle/codec/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/codec/node_modules/web3-utils/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/@truffle/compile-common": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.31.tgz", - "integrity": "sha512-BGhWPd6NoI4VZfYBg+RgrCyLaxxq40vDOp6Ouofa1NQdN6LSPwlqWf0JWvPIKFNRp+TA9aWRHGmZntYyE94OZg==", - "dev": true, - "dependencies": { - "@truffle/error": "^0.1.0", - "colors": "1.4.0" - } - }, - "node_modules/@truffle/contract": { - "version": "4.5.14", - "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.5.14.tgz", - "integrity": "sha512-ofdH7As7d+uyG+6wlZWYoBtN/Nb1efyzooHym4du5Hck4l+EHm8brSYZsHPJrEBA8UN05jYUtBrjUuzbJ/eq0w==", - "dev": true, - "dependencies": { - "@ensdomains/ensjs": "^2.0.1", - "@truffle/blockchain-utils": "^0.1.3", - "@truffle/contract-schema": "^3.4.7", - "@truffle/debug-utils": "^6.0.26", - "@truffle/error": "^0.1.0", - "@truffle/interface-adapter": "^0.5.17", - "bignumber.js": "^7.2.1", - "debug": "^4.3.1", - "ethers": "^4.0.32", - "web3": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "node_modules/@truffle/contract-schema": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.7.tgz", - "integrity": "sha512-vbOHMq/a8rVPh+cFMBDDGPqqiKrXXOc+f1kB4znfh3ewOX8rJxZhGJvdMm3WNMJHR5RstqDV7ZIZ7ePwtSXH8Q==", - "dev": true, - "dependencies": { - "ajv": "^6.10.0", - "debug": "^4.3.1" - } - }, - "node_modules/@truffle/contract/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "node_modules/@truffle/contract/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@truffle/contract/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/@truffle/contract/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/@truffle/contract/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/@truffle/contract/node_modules/web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-core/node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/contract/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/debug-utils": { - "version": "6.0.26", - "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.26.tgz", - "integrity": "sha512-+wxeXLRl23rzpOf76PkUTUqbsEzS8zAgLnZKFMEyS/vkVY5CpNVIhddCQcqQcDaIn9BRcmbuB5xMYR6hs8wrSw==", - "dev": true, - "dependencies": { - "@truffle/codec": "^0.13.1", - "@trufflesuite/chromafi": "^3.0.0", - "bn.js": "^5.1.3", - "chalk": "^2.4.2", - "debug": "^4.3.1", - "highlightjs-solidity": "^2.0.5" - } - }, - "node_modules/@truffle/debug-utils/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/debug-utils/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/debug-utils/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/debug-utils/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@truffle/debug-utils/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@truffle/debug-utils/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@truffle/debug-utils/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/debug-utils/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@truffle/error": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.0.tgz", - "integrity": "sha512-RbUfp5VreNhsa2Q4YbBjz18rOQI909pG32bghl1hulO7IpvcqTS+C3Ge5cNbiWQ1WGzy1wIeKLW0tmQtHFB7qg==", - "dev": true - }, - "node_modules/@truffle/interface-adapter": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.17.tgz", - "integrity": "sha512-2MJ+YLAL4y2QqlWc90NKizBLpavcETTzV8EpYkYJgAM326xKrAt+N3wx3f3tgRPSsbdtiEVKf1JRXHmDYQ+xIg==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.5.3" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/eth-lib/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-iban/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/interface-adapter/node_modules/web3-utils/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/@truffle/provider": { - "version": "0.2.55", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.55.tgz", - "integrity": "sha512-Tjs2cZsmRnzgBtFNXwO8cc1W7jIv0UaaLt3fOzks7rSUETo7M11GJ4U+uoCHSntrIW7E6sYS3KecOpzqJPw3Hg==", - "dev": true, - "dependencies": { - "@truffle/error": "^0.1.0", - "@truffle/interface-adapter": "^0.5.17", - "web3": "1.5.3" - } - }, - "node_modules/@truffle/provider/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "node_modules/@truffle/provider/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@truffle/provider/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/@truffle/provider/node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/@truffle/provider/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/@truffle/provider/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/@truffle/provider/node_modules/web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@truffle/provider/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@trufflesuite/chromafi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz", - "integrity": "sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==", - "dev": true, - "dependencies": { - "camelcase": "^4.1.0", - "chalk": "^2.3.2", - "cheerio": "^1.0.0-rc.2", - "detect-indent": "^5.0.0", - "highlight.js": "^10.4.1", - "lodash.merge": "^4.6.2", - "strip-ansi": "^4.0.0", - "strip-indent": "^2.0.0" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@trufflesuite/chromafi/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@trufflesuite/chromafi/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@types/abstract-leveldown": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", - "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==", - "dev": true - }, - "node_modules/@types/bignumber.js": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz", - "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==", - "deprecated": "This is a stub types definition for bignumber.js (https://github.com/MikeMcl/bignumber.js/). bignumber.js provides its own type definitions, so you don't need @types/bignumber.js installed!", - "dev": true, - "dependencies": { - "bignumber.js": "*" - } - }, - "node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/chai": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", - "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", - "dev": true - }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/level-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", - "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==", - "dev": true - }, - "node_modules/@types/levelup": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", - "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", - "dev": true, - "dependencies": { - "@types/abstract-leveldown": "*", - "@types/level-errors": "*", - "@types/node": "*" - } - }, - "node_modules/@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", - "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==", - "dev": true - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/abstract-leveldown": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", - "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/address": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", - "integrity": "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true, - "engines": { - "node": ">=0.3.0" - } - }, - "node_modules/aes-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", - "dev": true - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.4.2" - } - }, - "node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", - "dev": true - }, - "node_modules/antlr4": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", - "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", - "dev": true - }, - "node_modules/antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/apache-crypt": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.5.tgz", - "integrity": "sha512-ICnYQH+DFVmw+S4Q0QY2XRXD8Ne8ewh8HgbuFH4K7022zCxgHM0Hz1xkRnUlEfAXNbwp1Cnhbedu60USIfDxvg==", - "dev": true, - "dependencies": { - "unix-crypt-td-js": "^1.1.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/apache-md5": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.7.tgz", - "integrity": "sha512-JtHjzZmJxtzfTSjsCyHgPR155HBe5WGyUyHTaEkfy46qhwCFKx1Epm6nAxgUG3WfUZP1dWhGqj9Z2NOBeZ+uBw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.reduce": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", - "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ast-parents": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", - "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", - "dev": true - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "node_modules/async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "dev": true, - "dependencies": { - "async": "^2.4.0" - } - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", - "dev": true - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "node_modules/big-integer": { - "version": "1.6.36", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", - "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/big.js": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.0.tgz", - "integrity": "sha512-paIKvJiAaOYdLt6MfnvxkDo64lTOV257XYJyX3oJnJQocIclUn+48k6ZerH/c5FxWE6DGJu1TKDYis7tqHg9kg==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/bigjs" - } - }, - "node_modules/bignumber.js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/body-parser/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-rsa/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-sign/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-reverse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", - "integrity": "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==", - "dev": true - }, - "node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-callsite/node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", - "dev": true, - "dependencies": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - }, - "bin": { - "cdl": "bin/cdl.js" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "node_modules/cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dev": true, - "dependencies": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/cbor/node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-bn": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/chai-bn/-/chai-bn-0.2.2.tgz", - "integrity": "sha512-MzjelH0p8vWn65QKmEq/DLBG1Hle4WeyqT79ANhXZhn/UxRWO0OogkAxi5oGGtfzwU9bZR8mvbvYdoqNVWQwFg==", - "dev": true, - "peerDependencies": { - "bn.js": "^4.11.0", - "chai": "^4.0.0" - } - }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/change-case": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.0.2.tgz", - "integrity": "sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==", - "dev": true, - "dependencies": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dev": true, - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" - } - }, - "node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "dependencies": { - "restore-cursor": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-progress": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.11.2.tgz", - "integrity": "sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA==", - "dev": true, - "dependencies": { - "string-width": "^4.2.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-progress/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-progress/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cli-progress/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-progress/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-progress/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - }, - "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "colors": "^1.1.2" - } - }, - "node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, - "node_modules/commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", - "dev": true - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/constant-case": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", - "integrity": "sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==", - "dev": true, - "dependencies": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, - "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "node_modules/cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", - "dev": true - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-js-pure": { - "version": "3.23.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.3.tgz", - "integrity": "sha512-XpoouuqIj4P+GWtdyV8ZO3/u4KftkeDVMfvp+308eGMhCrA3lVDSmAxO0c6GGOcmgVlaKDrgWVMo49h2ab/TDA==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-addr-codec": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz", - "integrity": "sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg==", - "dev": true, - "dependencies": { - "base-x": "^3.0.8", - "big-integer": "1.6.36", - "blakejs": "^1.1.0", - "bs58": "^4.0.1", - "ripemd160-min": "0.0.6", - "safe-buffer": "^5.2.0", - "sha3": "^2.1.1" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", - "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==", - "dev": true - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "dev": true, - "dependencies": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deferred-leveldown/node_modules/abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", - "dev": true, - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", - "integrity": "sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==", - "dev": true - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "node_modules/ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", - "dev": true, - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/emoji-regex": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", - "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "dev": true, - "dependencies": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/enquirer/node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz", - "integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es5-ext": { - "version": "0.10.61", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", - "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "dependencies": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=0.12.0" - }, - "optionalDependencies": { - "source-map": "~0.2.0" - } - }, - "node_modules/escodegen/node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peerDependencies": { - "eslint": "^7.12.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1 || ^5.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/eslint-plugin-mocha": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.0.5.tgz", - "integrity": "sha512-H5xuD5NStlpaKLqUWYC5BsMx8fHgrIYsdloFbONUTc2vgVNiJcWdKoX29Tt0BO75QgAltplPLIziByMozGGixA==", - "dev": true, - "dependencies": { - "eslint-utils": "^3.0.0", - "rambda": "^7.1.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-mocha/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", - "dev": true, - "dependencies": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "node_modules/eth-ens-namehash/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "node_modules/eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "peerDependencies": { - "@codechecks/client": "^0.1.0" - }, - "peerDependenciesMeta": { - "@codechecks/client": { - "optional": true - } - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/eth-gas-reporter/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/eth-gas-reporter/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.0.tgz", - "integrity": "sha512-wyNVTBR4wIR2yoXdMv4Qt44mTVBpPgSW/DQCTmNO6nQluwpyrAIvmL4mxPbziFuc6VWJQa3rwUxn0nUFU03nyQ==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.1.1", - "@noble/secp256k1": "1.6.0", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eth-gas-reporter/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eth-gas-reporter/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eth-gas-reporter/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/eth-gas-reporter/node_modules/mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/eth-gas-reporter/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/eth-gas-reporter/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eth-gas-reporter/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/eth-gas-reporter/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/eth-gas-reporter/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-gas-reporter/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/eth-gas-reporter/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/eth-gas-reporter/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/eth-gas-reporter/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/eth-lib/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/eth-lib/node_modules/ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "node_modules/eth-sig-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-3.0.1.tgz", - "integrity": "sha512-0Us50HiGGvZgjtWTyAI/+qTzYPMLy5Q451D0Xy68bxq1QMWdoOddDwGvsqcFT27uohKgalM9z/yxplyt+mY2iQ==", - "deprecated": "Deprecated in favor of '@metamask/eth-sig-util'", - "dev": true, - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.0" - } - }, - "node_modules/eth-sig-util/node_modules/ethereumjs-util": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", - "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dev": true, - "dependencies": { - "js-sha3": "^0.8.0" - } - }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethereum-ens": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/ethereum-ens/-/ethereum-ens-0.8.0.tgz", - "integrity": "sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==", - "dev": true, - "dependencies": { - "bluebird": "^3.4.7", - "eth-ens-namehash": "^2.0.0", - "js-sha3": "^0.5.7", - "pako": "^1.0.4", - "underscore": "^1.8.3", - "web3": "^1.0.0-beta.34" - } - }, - "node_modules/ethereum-ens/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethereumjs-util/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/ethereumjs-wallet": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-1.0.2.tgz", - "integrity": "sha512-CCWV4RESJgRdHIvFciVQFnCHfqyhXWchTPlkfp28Qc53ufs+doi5I/cV2+xeK9+qEo25XCWfP9MiL+WEPAZfdA==", - "dev": true, - "dependencies": { - "aes-js": "^3.1.2", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^7.1.2", - "randombytes": "^2.1.0", - "scrypt-js": "^3.0.1", - "utf8": "^3.0.0", - "uuid": "^8.3.2" - } - }, - "node_modules/ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "dependencies": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - } - }, - "node_modules/ethers/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "node_modules/ethers/node_modules/hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/ethers/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "node_modules/ethers/node_modules/scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "node_modules/ethers/node_modules/setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true - }, - "node_modules/ethers/node_modules/uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true - }, - "node_modules/ethjs-abi": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz", - "integrity": "sha512-g2AULSDYI6nEJyJaEVEXtTimRY2aPC2fi7ddSy0W+LXvEVL8Fe1y76o43ecbgdUKwZD+xsmEgX1yJr1Ia3r1IA==", - "dev": true, - "dependencies": { - "bn.js": "4.11.6", - "js-sha3": "0.5.5", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-abi/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - }, - "node_modules/ethjs-abi/node_modules/js-sha3": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", - "integrity": "sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA==", - "dev": true - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dev": true, - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/express/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/express/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "dev": true, - "dependencies": { - "type": "^2.5.0" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", - "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==", - "dev": true - }, - "node_modules/fast-check": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", - "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", - "dev": true, - "dependencies": { - "pure-rand": "^5.0.1" - }, - "engines": { - "node": ">=8.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "bin": { - "testrpc-sc": "index.js" - } - }, - "node_modules/ghost-testrpc/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ghost-testrpc/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ghost-testrpc/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ghost-testrpc/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/globby/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - } - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/hardhat": { - "version": "2.9.9", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.9.tgz", - "integrity": "sha512-Qv7SXnRc0zq1kGXruNnSKpP3eFccXMR5Qv6GVX9hBIJ5efN0PflKPq92aQ5Cv3jrjJeRevLznWZVz7bttXhVfw==", - "dev": true, - "dependencies": { - "@ethereumjs/block": "^3.6.2", - "@ethereumjs/blockchain": "^5.5.2", - "@ethereumjs/common": "^2.6.4", - "@ethereumjs/tx": "^3.5.1", - "@ethereumjs/vm": "^5.9.0", - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.14.1", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^0.1.2", - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.4", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.4", - "mnemonist": "^0.38.0", - "mocha": "^9.2.0", - "p-map": "^4.0.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "slash": "^3.0.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "true-case-path": "^2.2.1", - "tsort": "0.0.1", - "undici": "^5.4.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "bin": { - "hardhat": "internal/cli/cli.js" - }, - "engines": { - "node": "^12.0.0 || ^14.0.0 || ^16.0.0" - }, - "peerDependencies": { - "ts-node": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/hardhat-gas-reporter": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", - "integrity": "sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g==", - "dev": true, - "dependencies": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.24", - "sha1": "^1.1.1" - }, - "peerDependencies": { - "hardhat": "^2.0.2" - } - }, - "node_modules/hardhat/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/hardhat/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/hardhat/node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "node_modules/hardhat/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/hardhat/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/hardhat/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/require-from-string": { - "version": "2.0.2", - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hardhat/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hardhat/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/hardhat/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/hardhat/node_modules/solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/hardhat/node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/hardhat/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-to-string-tag-x": { - "version": "1.4.1", - "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==", - "dev": true, - "dependencies": { - "has-symbol-support-x": "^1.4.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/header-case": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", - "integrity": "sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" - } - }, - "node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/highlightjs-solidity": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.5.tgz", - "integrity": "sha512-ReXxQSGQkODMUgHcWzVSnfDCDrL2HshOYgw3OlIYmfHeRzUPkfJTUIp95pK4CmbiNG2eMTOmNLpfCz9Zq7Cwmg==", - "dev": true - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" - } - }, - "node_modules/http-auth": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", - "integrity": "sha512-Jbx0+ejo2IOx+cRUYAGS1z6RGc6JfYUNkysZM4u4Sfk1uLlGv814F7/PIjQQAuThLdAWxb74JMGd5J8zex1VQg==", - "dev": true, - "dependencies": { - "apache-crypt": "^1.1.2", - "apache-md5": "^1.0.6", - "bcryptjs": "^2.3.0", - "uuid": "^3.0.0" - }, - "engines": { - "node": ">=4.6.1" - } - }, - "node_modules/http-auth/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", - "dev": true - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/hyperlinker": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", - "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "dev": true, - "dependencies": { - "punycode": "2.1.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true - }, - "node_modules/immutable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", - "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/inquirer/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "dependencies": { - "fp-ts": "^1.0.0" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-lower-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", - "integrity": "sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-port-reachable": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-3.1.0.tgz", - "integrity": "sha512-vjc0SSRNZ32s9SbZBzGaiP6YVB+xglLShhgZD/FHMZUXBvQWaV9CtzgeVhjccFJrI6RAMV+LX7NYxueW/A8W5A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "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==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-upper-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", - "integrity": "sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==", - "dev": true, - "dependencies": { - "upper-case": "^1.1.0" - } - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "node_modules/isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "dependencies": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", - "dev": true, - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true - }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - } - }, - "node_modules/keccak256/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/keccak256/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/level-codec": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", - "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", - "dev": true, - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "dev": true, - "dependencies": { - "errno": "~0.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-mem": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", - "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", - "dev": true, - "dependencies": { - "level-packager": "^5.0.3", - "memdown": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-packager": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", - "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", - "dev": true, - "dependencies": { - "encoding-down": "^6.3.0", - "levelup": "^4.3.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-supports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "dev": true, - "dependencies": { - "xtend": "^4.0.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/level-ws": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", - "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^3.1.0", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", - "dev": true, - "dependencies": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/live-server": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.2.tgz", - "integrity": "sha512-t28HXLjITRGoMSrCOv4eZ88viHaBVIjKjdI5PO92Vxlu+twbk6aE0t7dVIaz6ZWkjPilYFV6OSdMYl9ybN2B4w==", - "dev": true, - "dependencies": { - "chokidar": "^2.0.4", - "colors": "1.4.0", - "connect": "^3.6.6", - "cors": "latest", - "event-stream": "3.3.4", - "faye-websocket": "0.11.x", - "http-auth": "3.1.x", - "morgan": "^1.9.1", - "object-assign": "latest", - "opn": "latest", - "proxy-middleware": "latest", - "send": "latest", - "serve-index": "^1.9.1" - }, - "bin": { - "live-server": "live-server.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/live-server/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/live-server/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/live-server/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/live-server/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/live-server/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/live-server/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/live-server/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/live-server/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/live-server/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/live-server/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", - "dev": true - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "node_modules/lodash.zip": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", - "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", - "dev": true - }, - "node_modules/lower-case-first": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", - "integrity": "sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.2" - } - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", - "dev": true - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", - "dev": true - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "node_modules/mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memdown": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", - "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", - "dev": true, - "dependencies": { - "abstract-leveldown": "~6.2.1", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/memdown/node_modules/abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/memdown/node_modules/immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==", - "dev": true - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/merkle-patricia-tree": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz", - "integrity": "sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w==", - "dev": true, - "dependencies": { - "@types/levelup": "^4.3.0", - "ethereumjs-util": "^7.1.4", - "level-mem": "^5.0.1", - "level-ws": "^2.0.0", - "readable-stream": "^3.6.0", - "semaphore-async-await": "^1.5.1" - } - }, - "node_modules/merkletreejs": { - "version": "0.2.32", - "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.2.32.tgz", - "integrity": "sha512-TostQBiwYRIwSE5++jGmacu3ODcKAgqb0Y/pnIohXS7sWxh1gCkSptbmF1a43faehRDpcHf7J/kv0Ml2D/zblQ==", - "dev": true, - "dependencies": { - "bignumber.js": "^9.0.1", - "buffer-reverse": "^1.0.1", - "crypto-js": "^3.1.9-1", - "treeify": "^1.1.0", - "web3-utils": "^1.3.4" - }, - "engines": { - "node": ">= 7.6.0" - } - }, - "node_modules/merkletreejs/node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", - "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", - "dev": true, - "dependencies": { - "mkdirp": "*" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "dependencies": { - "obliterator": "^2.0.0" - } - }, - "node_modules/mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "4.2.1", - "ms": "2.1.3", - "nanoid": "3.3.1", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", - "dev": true - }, - "node_modules/morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "dev": true, - "dependencies": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/morgan/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/morgan/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "varint": "^5.0.0" - } - }, - "node_modules/multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - } - }, - "node_modules/multihashes/node_modules/multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "deprecated": "This module has been superseded by the multiformats module", - "dev": true, - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "node_modules/mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true - }, - "node_modules/nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", - "dev": true, - "optional": true - }, - "node_modules/nano-base32": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nano-base32/-/nano-base32-1.0.1.tgz", - "integrity": "sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==", - "dev": true - }, - "node_modules/nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-orderby": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", - "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.1" - } - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "dependencies": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node_modules/node-environment-flags/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/node-gyp-build": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", - "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", - "dev": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-treeify": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", - "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", - "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", - "dev": true, - "dependencies": { - "array.prototype.reduce": "^1.0.4", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "node_modules/oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", - "dev": true, - "dependencies": { - "http-https": "^1.0.0" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "deprecated": "The package has been renamed to `open`", - "dev": true, - "dependencies": { - "is-wsl": "^1.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==", - "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true - }, - "node_modules/parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", - "dev": true - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", - "dev": true, - "dependencies": { - "entities": "^4.3.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dev": true, - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", - "integrity": "sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==", - "dev": true, - "dependencies": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/password-prompt": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", - "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^3.1.0", - "cross-spawn": "^6.0.5" - } - }, - "node_modules/password-prompt/node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/password-prompt/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/password-prompt/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/password-prompt/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/password-prompt/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/password-prompt/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/password-prompt/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/path-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", - "integrity": "sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "dependencies": { - "through": "~2.3" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-plugin-solidity": { - "version": "1.0.0-beta.19", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz", - "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.14.0", - "emoji-regex": "^10.0.0", - "escape-string-regexp": "^4.0.0", - "semver": "^7.3.5", - "solidity-comments-extractor": "^0.0.7", - "string-width": "^4.2.3" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "prettier": "^2.3.0" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prettier-plugin-solidity/node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/prettier-plugin-solidity/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-middleware": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", - "integrity": "sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.1.tgz", - "integrity": "sha512-ksWccjmXOHU2gJBnH0cK1lSYdvSZ0zLoCMSz/nTGh6hDvCSgcRxDyIcOBD6KNxFz3xhMPm/T267Tbe2JRymKEQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/rambda": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.1.4.tgz", - "integrity": "sha512-bPK8sSiVHIC7CqdWga8R+hRi5hfc4hK6S01lZW4KrLwSNryQoKaCOJA9GNiF20J7Nbe1vejRfR37/ASQXFL5EA==", - "dev": true - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "dev": true, - "dependencies": { - "minimatch": "3.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/recursive-readdir/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "dev": true, - "dependencies": { - "esprima": "~4.0.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "dependencies": { - "req-from": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/req-from/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/ripemd160-min": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/ripemd160-min/-/ripemd160-min-0.0.6.tgz", - "integrity": "sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/rlp/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "dependencies": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "istanbul": "lib/cli.js" - } - }, - "node_modules/sc-istanbul/node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "node_modules/sc-istanbul/node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sc-istanbul/node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true - }, - "node_modules/sc-istanbul/node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/sc-istanbul/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/semaphore-async-await": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", - "integrity": "sha512-b/ptP11hETwYWpeilHXXQiV5UJNJl7ZWWooKRE5eBIYWoom6dZ0SluCIdCtKycsMtZgKWE01/qAw6jblw1YVhg==", - "dev": true, - "engines": { - "node": ">=4.1" - } - }, - "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/send/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/sentence-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", - "integrity": "sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dev": true, - "dependencies": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "dependencies": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sha3": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-2.1.4.tgz", - "integrity": "sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==", - "dev": true, - "dependencies": { - "buffer": "6.0.3" - } - }, - "node_modules/sha3/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/snake-case": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", - "integrity": "sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "dependencies": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - }, - "bin": { - "solcjs": "solcjs" - } - }, - "node_modules/solc/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/solc/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/solc/node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/solc/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/solc/node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true - }, - "node_modules/solc/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solc/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, - "node_modules/solc/node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solc/node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "node_modules/solc/node_modules/yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", - "dev": true, - "dependencies": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "node_modules/solc/node_modules/yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - }, - "node_modules/solhint": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.7.tgz", - "integrity": "sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.14.1", - "ajv": "^6.6.1", - "antlr4": "4.7.1", - "ast-parents": "0.0.1", - "chalk": "^2.4.2", - "commander": "2.18.0", - "cosmiconfig": "^5.0.7", - "eslint": "^5.6.0", - "fast-diff": "^1.1.2", - "glob": "^7.1.3", - "ignore": "^4.0.6", - "js-yaml": "^3.12.0", - "lodash": "^4.17.11", - "semver": "^6.3.0" - }, - "bin": { - "solhint": "solhint.js" - }, - "optionalDependencies": { - "prettier": "^1.14.3" - } - }, - "node_modules/solhint/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/solhint/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/solhint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/solhint/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/solhint/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solhint/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/solhint/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/solhint/node_modules/eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^6.14.0 || ^8.10.0 || >=9.10.0" - } - }, - "node_modules/solhint/node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/solhint/node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/eslint/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/solhint/node_modules/espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "dependencies": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/solhint/node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/solhint/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true, - "optional": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/solhint/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/solhint/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/solhint/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/string-width/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solhint/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solhint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solhint/node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/solhint/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/solhint/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/solidity-ast": { - "version": "0.4.35", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", - "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==", - "dev": true - }, - "node_modules/solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "node_modules/solidity-coverage": { - "version": "0.7.21", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.21.tgz", - "integrity": "sha512-O8nuzJ9yXiKUx3NdzVvHrUW0DxoNVcGzq/I7NzewNO9EZE3wYAQ4l8BwcnV64r4aC/HB6Vnw/q2sF0BQHv/3fg==", - "dev": true, - "dependencies": { - "@solidity-parser/parser": "^0.14.0", - "@truffle/provider": "^0.2.24", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.0" - }, - "bin": { - "solidity-coverage": "plugins/bin.js" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/solidity-coverage/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/solidity-coverage/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/solidity-coverage/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/solidity-coverage/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-docgen": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.5.17.tgz", - "integrity": "sha512-RX5SPLFL9z0ZVBcZ/o5l/TKXMgSjNhWdumLuuv+Dy1O/66sThpHYd0HVpzdwAjVff0Ajk76bYM2zZYiMnqBfng==", - "dev": true, - "dependencies": { - "@oclif/command": "^1.8.0", - "@oclif/config": "^1.17.0", - "@oclif/errors": "^1.3.3", - "@oclif/plugin-help": "^5.0.0", - "globby": "^11.0.0", - "handlebars": "^4.7.6", - "json5": "^2.1.3", - "lodash": "^4.17.15", - "micromatch": "^4.0.2", - "minimatch": "^5.0.0", - "semver": "^7.3.2", - "solc": "^0.6.7" - }, - "bin": { - "solidity-docgen": "dist/cli.js" - } - }, - "node_modules/solidity-docgen/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/solidity-docgen/node_modules/commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "node_modules/solidity-docgen/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "node_modules/solidity-docgen/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/solidity-docgen/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/solidity-docgen/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/solidity-docgen/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/solidity-docgen/node_modules/require-from-string": { - "version": "2.0.2", - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-docgen/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/solidity-docgen/node_modules/solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", - "dev": true, - "dependencies": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solcjs" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/solidity-docgen/node_modules/solc/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "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==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "node_modules/split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dev": true, - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stacktrace-parser/node_modules/type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1" - } - }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/swap-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", - "integrity": "sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==", - "dev": true, - "dependencies": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" - } - }, - "node_modules/swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - } - }, - "node_modules/swarm-js/node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/swarm-js/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "dependencies": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/swarm-js/node_modules/p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/swarm-js/node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/swarm-js/node_modules/url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", - "dev": true, - "dependencies": { - "prepend-http": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "dependencies": { - "get-port": "^3.1.0" - } - }, - "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/table/node_modules/require-from-string": { - "version": "2.0.2", - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", - "dev": true - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "dependencies": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/title-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", - "integrity": "sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==", - "dev": true, - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/true-case-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", - "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==", - "dev": true - }, - "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/uglify-js": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.1.tgz", - "integrity": "sha512-X5BGTIDH8U6IQ1TIRP62YC36k+ULAa1d59BxlWvPUJ1NkW5L3FwcGfEzuVvGmhJFBu0YJ5Ge25tmRISqCmLiRQ==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/underscore": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz", - "integrity": "sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==", - "dev": true - }, - "node_modules/undici": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.5.1.tgz", - "integrity": "sha512-MEvryPLf18HvlCbLSzCW0U00IMftKGI5udnjrQbC5D4P0Hodwffhv+iGfWuJwg16Y/TK11ZFK8i+BPVW2z/eAw==", - "dev": true, - "engines": { - "node": ">=12.18" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unix-crypt-td-js": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", - "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==", - "dev": true - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", - "dev": true - }, - "node_modules/upper-case-first": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", - "integrity": "sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==", - "dev": true, - "dependencies": { - "upper-case": "^1.1.1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", - "dev": true - }, - "node_modules/url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/utf-8-validate": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", - "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true - }, - "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/web3": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", - "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.7.4", - "web3-core": "1.7.4", - "web3-eth": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-shh": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", - "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/web3-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", - "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-requestmanager": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-helpers": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", - "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-method": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", - "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", - "dev": true, - "dependencies": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-promievent": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", - "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-requestmanager": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", - "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", - "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.4", - "web3-providers-http": "1.7.4", - "web3-providers-ipc": "1.7.4", - "web3-providers-ws": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-subscriptions": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", - "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/web3-core/node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/web3-eth": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", - "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", - "dev": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-accounts": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-eth-ens": "1.7.4", - "web3-eth-iban": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-abi": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", - "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", - "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/web3-eth-contract": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", - "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-ens": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", - "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", - "dev": true, - "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-iban": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", - "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-iban/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/web3-eth-personal": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", - "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", - "dev": true, - "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/web3-net": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", - "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", - "dev": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-http": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", - "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", - "dev": true, - "dependencies": { - "web3-core-helpers": "1.7.4", - "xhr2-cookies": "1.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ipc": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", - "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", - "dev": true, - "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-providers-ws": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", - "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", - "dev": true, - "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4", - "websocket": "^1.0.32" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-shh": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", - "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-net": "1.7.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, - "node_modules/which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/widest-line/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", - "dev": true, - "bin": { - "window-size": "cli.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ws": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", - "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dev": true, - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", - "dev": true, - "dependencies": { - "cookiejar": "^2.1.1" - } - }, - "node_modules/xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", - "dev": true, - "engines": { - "node": ">=0.10.32" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", - "dev": true - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/runtime": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.6.tgz", - "integrity": "sha512-t9wi7/AW6XtKahAe20Yw0/mMljKq0B1r2fPdvaAdV/KPDZewFXdaaa6K7lxmZBZ8FBNpCiAT6iHPmd6QO9bKfQ==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@ensdomains/address-encoder": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz", - "integrity": "sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==", - "dev": true, - "requires": { - "bech32": "^1.1.3", - "blakejs": "^1.1.0", - "bn.js": "^4.11.8", - "bs58": "^4.0.1", - "crypto-addr-codec": "^0.1.7", - "nano-base32": "^1.0.1", - "ripemd160": "^2.0.2" - } - }, - "@ensdomains/ens": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", - "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", - "dev": true, - "requires": { - "bluebird": "^3.5.2", - "eth-ens-namehash": "^2.0.8", - "solc": "^0.4.20", - "testrpc": "0.0.1", - "web3-utils": "^1.0.0-beta.31" - } - }, - "@ensdomains/ensjs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@ensdomains/ensjs/-/ensjs-2.1.0.tgz", - "integrity": "sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==", - "dev": true, - "requires": { - "@babel/runtime": "^7.4.4", - "@ensdomains/address-encoder": "^0.1.7", - "@ensdomains/ens": "0.4.5", - "@ensdomains/resolver": "0.2.4", - "content-hash": "^2.5.2", - "eth-ens-namehash": "^2.0.8", - "ethers": "^5.0.13", - "js-sha3": "^0.8.0" - }, - "dependencies": { - "ethers": { - "version": "5.6.9", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.9.tgz", - "integrity": "sha512-lMGC2zv9HC5EC+8r429WaWu3uWJUCgUCt8xxKCFqkrFuBDZXDYIdzDUECxzjf2BMF8IVBByY1EBoGSL3RTm8RA==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.6.4", - "@ethersproject/abstract-provider": "5.6.1", - "@ethersproject/abstract-signer": "5.6.2", - "@ethersproject/address": "5.6.1", - "@ethersproject/base64": "5.6.1", - "@ethersproject/basex": "5.6.1", - "@ethersproject/bignumber": "5.6.2", - "@ethersproject/bytes": "5.6.1", - "@ethersproject/constants": "5.6.1", - "@ethersproject/contracts": "5.6.2", - "@ethersproject/hash": "5.6.1", - "@ethersproject/hdnode": "5.6.2", - "@ethersproject/json-wallets": "5.6.1", - "@ethersproject/keccak256": "5.6.1", - "@ethersproject/logger": "5.6.0", - "@ethersproject/networks": "5.6.4", - "@ethersproject/pbkdf2": "5.6.1", - "@ethersproject/properties": "5.6.0", - "@ethersproject/providers": "5.6.8", - "@ethersproject/random": "5.6.1", - "@ethersproject/rlp": "5.6.1", - "@ethersproject/sha2": "5.6.1", - "@ethersproject/signing-key": "5.6.2", - "@ethersproject/solidity": "5.6.1", - "@ethersproject/strings": "5.6.1", - "@ethersproject/transactions": "5.6.2", - "@ethersproject/units": "5.6.1", - "@ethersproject/wallet": "5.6.2", - "@ethersproject/web": "5.6.1", - "@ethersproject/wordlists": "5.6.1" - } - } - } - }, - "@ensdomains/resolver": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", - "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@ethereumjs/block": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.3.tgz", - "integrity": "sha512-CegDeryc2DVKnDkg5COQrE0bJfw/p0v3GBk2W5/Dj5dOVfEmb50Ux0GLnSPypooLnfqjwFaorGuT9FokWB3GRg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.5", - "@ethereumjs/tx": "^3.5.2", - "ethereumjs-util": "^7.1.5", - "merkle-patricia-tree": "^4.2.4" - } - }, - "@ethereumjs/blockchain": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.3.tgz", - "integrity": "sha512-bi0wuNJ1gw4ByNCV56H0Z4Q7D+SxUbwyG12Wxzbvqc89PXLRNR20LBcSUZRKpN0+YCPo6m0XZL/JLio3B52LTw==", - "dev": true, - "requires": { - "@ethereumjs/block": "^3.6.2", - "@ethereumjs/common": "^2.6.4", - "@ethereumjs/ethash": "^1.1.0", - "debug": "^4.3.3", - "ethereumjs-util": "^7.1.5", - "level-mem": "^5.0.1", - "lru-cache": "^5.1.1", - "semaphore-async-await": "^1.5.1" - } - }, - "@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" - } - }, - "@ethereumjs/ethash": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", - "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", - "dev": true, - "requires": { - "@ethereumjs/block": "^3.5.0", - "@types/levelup": "^4.3.0", - "buffer-xor": "^2.0.1", - "ethereumjs-util": "^7.1.1", - "miller-rabin": "^4.0.0" - }, - "dependencies": { - "buffer-xor": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", - "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.1" - } - } - } - }, - "@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" - } - }, - "@ethereumjs/vm": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.9.3.tgz", - "integrity": "sha512-Ha04TeF8goEglr8eL7hkkYyjhzdZS0PsoRURzYlTF6I0VVId5KjKb0N7MrA8GMgheN+UeTncfTgYx52D/WhEmg==", - "dev": true, - "requires": { - "@ethereumjs/block": "^3.6.3", - "@ethereumjs/blockchain": "^5.5.3", - "@ethereumjs/common": "^2.6.5", - "@ethereumjs/tx": "^3.5.2", - "async-eventemitter": "^0.2.4", - "core-js-pure": "^3.0.1", - "debug": "^4.3.3", - "ethereumjs-util": "^7.1.5", - "functional-red-black-tree": "^1.0.1", - "mcl-wasm": "^0.7.1", - "merkle-patricia-tree": "^4.2.4", - "rustbn.js": "~0.2.0" - } - }, - "@ethersproject/abi": { - "version": "5.6.4", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.4.tgz", - "integrity": "sha512-TTeZUlCeIHG6527/2goZA6gW5F8Emoc7MrZDC7hhP84aRGvW3TEdTnZR08Ls88YXM1m2SuK42Osw/jSi3uO8gg==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/hash": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.1" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz", - "integrity": "sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.3", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.2", - "@ethersproject/web": "^5.6.1" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz", - "integrity": "sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0" - } - }, - "@ethersproject/address": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", - "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.1" - } - }, - "@ethersproject/base64": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.1.tgz", - "integrity": "sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1" - } - }, - "@ethersproject/basex": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.1.tgz", - "integrity": "sha512-a52MkVz4vuBXR06nvflPMotld1FJWSj2QT0985v7P/emPZO00PucFAkbcmq2vpVU7Ts7umKiSI6SppiLykVWsA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/properties": "^5.6.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.2.tgz", - "integrity": "sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "bn.js": "^5.2.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "@ethersproject/bytes": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", - "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/constants": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.1.tgz", - "integrity": "sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.6.2" - } - }, - "@ethersproject/contracts": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.2.tgz", - "integrity": "sha512-hguUA57BIKi6WY0kHvZp6PwPlWF87MCeB4B7Z7AbUpTxfFXFdn/3b0GmjZPagIHS+3yhcBJDnuEfU4Xz+Ks/8g==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.6.3", - "@ethersproject/abstract-provider": "^5.6.1", - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.2" - } - }, - "@ethersproject/hash": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.1.tgz", - "integrity": "sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.1" - } - }, - "@ethersproject/hdnode": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.2.tgz", - "integrity": "sha512-tERxW8Ccf9CxW2db3WsN01Qao3wFeRsfYY9TCuhmG0xNpl2IO8wgXU3HtWIZ49gUWPggRy4Yg5axU0ACaEKf1Q==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/basex": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.1", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/sha2": "^5.6.1", - "@ethersproject/signing-key": "^5.6.2", - "@ethersproject/strings": "^5.6.1", - "@ethersproject/transactions": "^5.6.2", - "@ethersproject/wordlists": "^5.6.1" - } - }, - "@ethersproject/json-wallets": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.1.tgz", - "integrity": "sha512-KfyJ6Zwz3kGeX25nLihPwZYlDqamO6pfGKNnVMWWfEVVp42lTfCZVXXy5Ie8IZTN0HKwAngpIPi7gk4IJzgmqQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/hdnode": "^5.6.2", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/pbkdf2": "^5.6.1", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.1", - "@ethersproject/strings": "^5.6.1", - "@ethersproject/transactions": "^5.6.2", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - }, - "dependencies": { - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - } - } - }, - "@ethersproject/keccak256": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.1.tgz", - "integrity": "sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", - "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", - "dev": true - }, - "@ethersproject/networks": { - "version": "5.6.4", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.4.tgz", - "integrity": "sha512-KShHeHPahHI2UlWdtDMn2lJETcbtaJge4k7XSjDR9h79QTd6yQJmv6Cp2ZA4JdqWnhszAOLSuJEd9C0PRw7hSQ==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.1.tgz", - "integrity": "sha512-k4gRQ+D93zDRPNUfmduNKq065uadC2YjMP/CqwwX5qG6R05f47boq6pLZtV/RnC4NZAYOPH1Cyo54q0c9sshRQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/sha2": "^5.6.1" - } - }, - "@ethersproject/properties": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", - "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/providers": { - "version": "5.6.8", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.8.tgz", - "integrity": "sha512-Wf+CseT/iOJjrGtAOf3ck9zS7AgPmr2fZ3N97r4+YXN3mBePTG2/bJ8DApl9mVwYL+RpYbNxMEkEp4mPGdwG/w==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.6.1", - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/base64": "^5.6.1", - "@ethersproject/basex": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/hash": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.3", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.1", - "@ethersproject/rlp": "^5.6.1", - "@ethersproject/sha2": "^5.6.1", - "@ethersproject/strings": "^5.6.1", - "@ethersproject/transactions": "^5.6.2", - "@ethersproject/web": "^5.6.1", - "bech32": "1.1.4", - "ws": "7.4.6" - }, - "dependencies": { - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "requires": {} - } - } - }, - "@ethersproject/random": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.1.tgz", - "integrity": "sha512-/wtPNHwbmng+5yi3fkipA8YBT59DdkGRoC2vWk09Dci/q5DlgnMkhIycjHlavrvrjJBkFjO/ueLyT+aUDfc4lA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/rlp": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.1.tgz", - "integrity": "sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/sha2": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.1.tgz", - "integrity": "sha512-5K2GyqcW7G4Yo3uenHegbXRPDgARpWUiXc6RiF7b6i/HXUoWlb7uCARh7BAHg7/qT/Q5ydofNwiZcim9qpjB6g==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.2.tgz", - "integrity": "sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "@ethersproject/solidity": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.1.tgz", - "integrity": "sha512-KWqVLkUUoLBfL1iwdzUVlkNqAUIFMpbbeH0rgCfKmJp0vFtY4AsaN91gHKo9ZZLkC4UOm3cI3BmMV4N53BOq4g==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/sha2": "^5.6.1", - "@ethersproject/strings": "^5.6.1" - } - }, - "@ethersproject/strings": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.1.tgz", - "integrity": "sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/transactions": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.2.tgz", - "integrity": "sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.1", - "@ethersproject/signing-key": "^5.6.2" - } - }, - "@ethersproject/units": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.1.tgz", - "integrity": "sha512-rEfSEvMQ7obcx3KWD5EWWx77gqv54K6BKiZzKxkQJqtpriVsICrktIQmKl8ReNToPeIYPnFHpXvKpi068YFZXw==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/constants": "^5.6.1", - "@ethersproject/logger": "^5.6.0" - } - }, - "@ethersproject/wallet": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.2.tgz", - "integrity": "sha512-lrgh0FDQPuOnHcF80Q3gHYsSUODp6aJLAdDmDV0xKCN/T7D99ta1jGVhulg3PY8wiXEngD0DfM0I2XKXlrqJfg==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.6.1", - "@ethersproject/abstract-signer": "^5.6.2", - "@ethersproject/address": "^5.6.1", - "@ethersproject/bignumber": "^5.6.2", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/hash": "^5.6.1", - "@ethersproject/hdnode": "^5.6.2", - "@ethersproject/json-wallets": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/random": "^5.6.1", - "@ethersproject/signing-key": "^5.6.2", - "@ethersproject/transactions": "^5.6.2", - "@ethersproject/wordlists": "^5.6.1" - } - }, - "@ethersproject/web": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.1.tgz", - "integrity": "sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA==", - "dev": true, - "requires": { - "@ethersproject/base64": "^5.6.1", - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.1" - } - }, - "@ethersproject/wordlists": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.1.tgz", - "integrity": "sha512-wiPRgBpNbNwCQFoCr8bcWO8o5I810cqO6mkdtKfLKFlLxeCWcnzDi4Alu8iyNzlhYuS9npCwivMbRWF19dyblw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/hash": "^5.6.1", - "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "requires": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "@noble/hashes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.1.tgz", - "integrity": "sha512-Lkp9+NijmV7eSVZqiUvt3UCuuHeJpUVmRrvh430gyJjJiuJMqkeHf6/A9lQ/smmbWV/0spDeJscscPzyB4waZg==", - "dev": true - }, - "@noble/secp256k1": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.0.tgz", - "integrity": "sha512-DWSsg8zMHOYMYBqIQi96BQuthZrp98LCeMNcUOaffCIVYQ5yxDbNikLF+H7jEnmNNmXbtVic46iCuVWzar+MgA==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@nomiclabs/hardhat-truffle5": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-2.0.6.tgz", - "integrity": "sha512-kzkpVEX36yOmdhCJHesu+1nB+fiaKpMrvUSVd0Ox6Jila+8aSxeHTC4bbEBOIqJcvOQZ3sj5fzuE5VjhNkZkvw==", - "dev": true, - "requires": { - "@nomiclabs/truffle-contract": "^4.2.23", - "@types/chai": "^4.2.0", - "chai": "^4.2.0", - "ethereumjs-util": "^7.1.4", - "fs-extra": "^7.0.1" - } - }, - "@nomiclabs/hardhat-web3": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz", - "integrity": "sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==", - "dev": true, - "requires": { - "@types/bignumber.js": "^5.0.0" - } - }, - "@nomiclabs/truffle-contract": { - "version": "4.5.10", - "resolved": "https://registry.npmjs.org/@nomiclabs/truffle-contract/-/truffle-contract-4.5.10.tgz", - "integrity": "sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ==", - "dev": true, - "requires": { - "@ensdomains/ensjs": "^2.0.1", - "@truffle/blockchain-utils": "^0.1.3", - "@truffle/contract-schema": "^3.4.7", - "@truffle/debug-utils": "^6.0.22", - "@truffle/error": "^0.1.0", - "@truffle/interface-adapter": "^0.5.16", - "bignumber.js": "^7.2.1", - "ethereum-ens": "^0.8.0", - "ethers": "^4.0.0-beta.1", - "source-map-support": "^0.5.19" - } - }, - "@oclif/command": { - "version": "1.8.16", - "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.8.16.tgz", - "integrity": "sha512-rmVKYEsKzurfRU0xJz+iHelbi1LGlihIWZ7Qvmb/CBz1EkhL7nOkW4SVXmG2dA5Ce0si2gr88i6q4eBOMRNJ1w==", - "dev": true, - "requires": { - "@oclif/config": "^1.18.2", - "@oclif/errors": "^1.3.5", - "@oclif/help": "^1.0.1", - "@oclif/parser": "^3.8.6", - "debug": "^4.1.1", - "semver": "^7.3.2" - } - }, - "@oclif/config": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.3.tgz", - "integrity": "sha512-sBpko86IrTscc39EvHUhL+c++81BVTsIZ3ETu/vG+cCdi0N6vb2DoahR67A9FI2CGnxRRHjnTfa3m6LulwNATA==", - "dev": true, - "requires": { - "@oclif/errors": "^1.3.5", - "@oclif/parser": "^3.8.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-wsl": "^2.1.1", - "tslib": "^2.3.1" - }, - "dependencies": { - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - } - } - }, - "@oclif/core": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-1.9.5.tgz", - "integrity": "sha512-C605Cr4RhHTMXYApLxdVt/PL6IA5cguN6MPvsMjxkvBppk2Fvcsj05dtRdDqShskRpZzHtu65emG1tHy8TWPWQ==", - "dev": true, - "requires": { - "@oclif/linewrap": "^1.0.0", - "@oclif/screen": "^3.0.2", - "ansi-escapes": "^4.3.2", - "ansi-styles": "^4.3.0", - "cardinal": "^2.1.1", - "chalk": "^4.1.2", - "clean-stack": "^3.0.1", - "cli-progress": "^3.10.0", - "debug": "^4.3.4", - "ejs": "^3.1.6", - "fs-extra": "^9.1.0", - "get-package-type": "^0.1.0", - "globby": "^11.1.0", - "hyperlinker": "^1.0.0", - "indent-string": "^4.0.0", - "is-wsl": "^2.2.0", - "js-yaml": "^3.14.1", - "natural-orderby": "^2.0.3", - "object-treeify": "^1.1.33", - "password-prompt": "^1.1.2", - "semver": "^7.3.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "supports-color": "^8.1.1", - "supports-hyperlinks": "^2.2.0", - "tslib": "^2.3.1", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "clean-stack": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", - "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", - "dev": true, - "requires": { - "escape-string-regexp": "4.0.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@oclif/errors": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.3.5.tgz", - "integrity": "sha512-OivucXPH/eLLlOT7FkCMoZXiaVYf8I/w1eTAM1+gKzfhALwWTusxEx7wBmW0uzvkSg/9ovWLycPaBgJbM3LOCQ==", - "dev": true, - "requires": { - "clean-stack": "^3.0.0", - "fs-extra": "^8.1", - "indent-string": "^4.0.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "clean-stack": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", - "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", - "dev": true, - "requires": { - "escape-string-regexp": "4.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "@oclif/help": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@oclif/help/-/help-1.0.1.tgz", - "integrity": "sha512-8rsl4RHL5+vBUAKBL6PFI3mj58hjPCp2VYyXD4TAa7IMStikFfOH2gtWmqLzIlxAED2EpD0dfYwo9JJxYsH7Aw==", - "dev": true, - "requires": { - "@oclif/config": "1.18.2", - "@oclif/errors": "1.3.5", - "chalk": "^4.1.2", - "indent-string": "^4.0.0", - "lodash": "^4.17.21", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "widest-line": "^3.1.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "@oclif/config": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.2.tgz", - "integrity": "sha512-cE3qfHWv8hGRCP31j7fIS7BfCflm/BNZ2HNqHexH+fDrdF2f1D5S8VmXWLC77ffv3oDvWyvE9AZeR0RfmHCCaA==", - "dev": true, - "requires": { - "@oclif/errors": "^1.3.3", - "@oclif/parser": "^3.8.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-wsl": "^2.1.1", - "tslib": "^2.0.0" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "@oclif/linewrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", - "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==", - "dev": true - }, - "@oclif/parser": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.7.tgz", - "integrity": "sha512-b11xBmIUK+LuuwVGJpFs4LwQN2xj2cBWj2c4z1FtiXGrJ85h9xV6q+k136Hw0tGg1jQoRXuvuBnqQ7es7vO9/Q==", - "dev": true, - "requires": { - "@oclif/errors": "^1.3.5", - "@oclif/linewrap": "^1.0.0", - "chalk": "^4.1.0", - "tslib": "^2.3.1" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - } - } - }, - "@oclif/plugin-help": { - "version": "5.1.12", - "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.1.12.tgz", - "integrity": "sha512-HvH/RubJxqCinP0vUWQLTOboT+SfjfL8h40s+PymkWaldIcXlpoRaJX50vz+SjZIs7uewZwEk8fzLqpF/BWXlg==", - "dev": true, - "requires": { - "@oclif/core": "^1.3.6" - } - }, - "@oclif/screen": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.2.tgz", - "integrity": "sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ==", - "dev": true - }, - "@openzeppelin/contract-loader": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/contract-loader/-/contract-loader-0.6.3.tgz", - "integrity": "sha512-cOFIjBjwbGgZhDZsitNgJl0Ye1rd5yu/Yx5LMgeq3u0ZYzldm4uObzHDFq4gjDdoypvyORjjJa3BlFA7eAnVIg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "fs-extra": "^8.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "@openzeppelin/docs-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/docs-utils/-/docs-utils-0.1.2.tgz", - "integrity": "sha512-oBchkfFlpqHCee/HaNXPvFy8py9Yi/LTnaE2Vsf+eO4j/FSaupzBsFIgxESjdTScSvJcIOWZFsbZDDRKscg2DQ==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "chokidar": "^3.3.0", - "env-paths": "^2.2.0", - "find-up": "^4.1.0", - "is-port-reachable": "^3.0.0", - "js-yaml": "^3.13.1", - "live-server": "^1.2.1", - "lodash.startcase": "^4.4.0", - "minimist": "^1.2.0" - } - }, - "@openzeppelin/test-helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@openzeppelin/test-helpers/-/test-helpers-0.5.15.tgz", - "integrity": "sha512-10fS0kyOjc/UObo9iEWPNbC6MCeiQ7z97LDOJBj68g+AAs5pIGEI2h3V6G9TYTIq8VxOdwMQbfjKrx7Y3YZJtA==", - "dev": true, - "requires": { - "@openzeppelin/contract-loader": "^0.6.2", - "@truffle/contract": "^4.0.35", - "ansi-colors": "^3.2.3", - "chai": "^4.2.0", - "chai-bn": "^0.2.1", - "ethjs-abi": "^0.2.1", - "lodash.flatten": "^4.4.0", - "semver": "^5.6.0", - "web3": "^1.2.5", - "web3-utils": "^1.2.5" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "@scure/base": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", - "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", - "dev": true - }, - "@scure/bip32": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", - "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", - "dev": true, - "requires": { - "@noble/hashes": "~1.1.1", - "@noble/secp256k1": "~1.6.0", - "@scure/base": "~1.1.0" - } - }, - "@scure/bip39": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", - "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", - "dev": true, - "requires": { - "@noble/hashes": "~1.1.1", - "@scure/base": "~1.1.0" - } - }, - "@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dev": true, - "requires": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dev": true, - "requires": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - } - }, - "@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dev": true, - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true - }, - "@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dev": true, - "requires": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@solidity-parser/parser": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.2.tgz", - "integrity": "sha512-10cr0s+MtRtqjEw0WFJrm2rwULN30xx7btd/v9cmqME2617/2M5MbHDkFIGIGTa7lwNw4bN9mVGfhlLzrYw8pA==", - "dev": true, - "requires": { - "antlr4ts": "^0.5.0-alpha.4" - } - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@truffle/abi-utils": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-0.2.13.tgz", - "integrity": "sha512-WzjyNvx+naXmG/XKF+xLI+tJZLUlPGkd29rY4xBCiY9m/xWk0ZUL6gvVvnRr3leLJkBweJUSBiGUW770V8hHOg==", - "dev": true, - "requires": { - "change-case": "3.0.2", - "faker": "5.5.3", - "fast-check": "^2.12.1" - } - }, - "@truffle/blockchain-utils": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@truffle/blockchain-utils/-/blockchain-utils-0.1.3.tgz", - "integrity": "sha512-K21Wf10u6VmS12/f9OrLN98f1RCqzrmuM2zlsly4b7BF/Xdh55Iq/jNSOnsNUJa+6Iaqqz6zeidquCYu9nTFng==", - "dev": true - }, - "@truffle/codec": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.13.1.tgz", - "integrity": "sha512-ZqpfofLEwzcdRYgInHOOoNYLqCEJ+nkYl4NTJkrszMAu9MLnHQjZqrMtfem/H8HDU3OOIgbpFlzipMdrnecjJw==", - "dev": true, - "requires": { - "@truffle/abi-utils": "^0.2.13", - "@truffle/compile-common": "^0.7.31", - "big.js": "^6.0.3", - "bn.js": "^5.1.3", - "cbor": "^5.1.0", - "debug": "^4.3.1", - "lodash": "^4.17.21", - "semver": "^7.3.4", - "utf8": "^3.0.0", - "web3-utils": "1.5.3" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - } - } - }, - "@truffle/compile-common": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.7.31.tgz", - "integrity": "sha512-BGhWPd6NoI4VZfYBg+RgrCyLaxxq40vDOp6Ouofa1NQdN6LSPwlqWf0JWvPIKFNRp+TA9aWRHGmZntYyE94OZg==", - "dev": true, - "requires": { - "@truffle/error": "^0.1.0", - "colors": "1.4.0" - } - }, - "@truffle/contract": { - "version": "4.5.14", - "resolved": "https://registry.npmjs.org/@truffle/contract/-/contract-4.5.14.tgz", - "integrity": "sha512-ofdH7As7d+uyG+6wlZWYoBtN/Nb1efyzooHym4du5Hck4l+EHm8brSYZsHPJrEBA8UN05jYUtBrjUuzbJ/eq0w==", - "dev": true, - "requires": { - "@ensdomains/ensjs": "^2.0.1", - "@truffle/blockchain-utils": "^0.1.3", - "@truffle/contract-schema": "^3.4.7", - "@truffle/debug-utils": "^6.0.26", - "@truffle/error": "^0.1.0", - "@truffle/interface-adapter": "^0.5.17", - "bignumber.js": "^7.2.1", - "debug": "^4.3.1", - "ethers": "^4.0.32", - "web3": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "requires": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - }, - "dependencies": { - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true - } - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - } - }, - "web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "@truffle/contract-schema": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@truffle/contract-schema/-/contract-schema-3.4.7.tgz", - "integrity": "sha512-vbOHMq/a8rVPh+cFMBDDGPqqiKrXXOc+f1kB4znfh3ewOX8rJxZhGJvdMm3WNMJHR5RstqDV7ZIZ7ePwtSXH8Q==", - "dev": true, - "requires": { - "ajv": "^6.10.0", - "debug": "^4.3.1" - } - }, - "@truffle/debug-utils": { - "version": "6.0.26", - "resolved": "https://registry.npmjs.org/@truffle/debug-utils/-/debug-utils-6.0.26.tgz", - "integrity": "sha512-+wxeXLRl23rzpOf76PkUTUqbsEzS8zAgLnZKFMEyS/vkVY5CpNVIhddCQcqQcDaIn9BRcmbuB5xMYR6hs8wrSw==", - "dev": true, - "requires": { - "@truffle/codec": "^0.13.1", - "@trufflesuite/chromafi": "^3.0.0", - "bn.js": "^5.1.3", - "chalk": "^2.4.2", - "debug": "^4.3.1", - "highlightjs-solidity": "^2.0.5" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@truffle/error": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.1.0.tgz", - "integrity": "sha512-RbUfp5VreNhsa2Q4YbBjz18rOQI909pG32bghl1hulO7IpvcqTS+C3Ge5cNbiWQ1WGzy1wIeKLW0tmQtHFB7qg==", - "dev": true - }, - "@truffle/interface-adapter": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.17.tgz", - "integrity": "sha512-2MJ+YLAL4y2QqlWc90NKizBLpavcETTzV8EpYkYJgAM326xKrAt+N3wx3f3tgRPSsbdtiEVKf1JRXHmDYQ+xIg==", - "dev": true, - "requires": { - "bn.js": "^5.1.3", - "ethers": "^4.0.32", - "web3": "1.5.3" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "requires": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - } - }, - "web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - } - } - }, - "@truffle/provider": { - "version": "0.2.55", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.55.tgz", - "integrity": "sha512-Tjs2cZsmRnzgBtFNXwO8cc1W7jIv0UaaLt3fOzks7rSUETo7M11GJ4U+uoCHSntrIW7E6sYS3KecOpzqJPw3Hg==", - "dev": true, - "requires": { - "@truffle/error": "^0.1.0", - "@truffle/interface-adapter": "^0.5.17", - "web3": "1.5.3" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true - }, - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - }, - "web3": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.5.3.tgz", - "integrity": "sha512-eyBg/1K44flfv0hPjXfKvNwcUfIVDI4NX48qHQe6wd7C8nPSdbWqo9vLy6ksZIt9NLa90HjI8HsGYgnMSUxn6w==", - "dev": true, - "requires": { - "web3-bzz": "1.5.3", - "web3-core": "1.5.3", - "web3-eth": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-shh": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-bzz": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.5.3.tgz", - "integrity": "sha512-SlIkAqG0eS6cBS9Q2eBOTI1XFzqh83RqGJWnyrNZMDxUwsTVHL+zNnaPShVPvrWQA1Ub5b0bx1Kc5+qJVxsTJg==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - } - }, - "web3-core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.5.3.tgz", - "integrity": "sha512-ACTbu8COCu+0eUNmd9pG7Q9EVsNkAg2w3Y7SqhDr+zjTgbSHZV01jXKlapm9z+G3AN/BziV3zGwudClJ4u4xXQ==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-requestmanager": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", - "dev": true, - "requires": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-method": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.5.3.tgz", - "integrity": "sha512-8wJrwQ2qD9ibWieF9oHXwrJsUGrv3XAtEkNeyvyNMpktNTIjxJ2jaFGQUuLiyUrMubD18XXgLk4JS6PJU4Loeg==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.4.0", - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.5.3.tgz", - "integrity": "sha512-9k/Bze2rs8ONix5IZR+hYdMNQv+ark2Ek2kVcrFgWO+LdLgZui/rn8FikPunjE+ub7x7pJaKCgVRbYFXjo3ZWg==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.5.3", - "web3-providers-http": "1.5.3", - "web3-providers-ipc": "1.5.3", - "web3-providers-ws": "1.5.3" - } - }, - "web3-core-subscriptions": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.5.3.tgz", - "integrity": "sha512-L2m9vG1iRN6thvmv/HQwO2YLhOQlmZU8dpLG6GSo9FBN14Uch868Swk0dYVr3rFSYjZ/GETevSXU+O+vhCummA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3" - } - }, - "web3-eth": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.5.3.tgz", - "integrity": "sha512-saFurA1L23Bd7MEf7cBli6/jRdMhD4X/NaMiO2mdMMCXlPujoudlIJf+VWpRWJpsbDFdu7XJ2WHkmBYT5R3p1Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-accounts": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-eth-ens": "1.5.3", - "web3-eth-iban": "1.5.3", - "web3-eth-personal": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-abi": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.5.3" - } - }, - "web3-eth-accounts": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.5.3.tgz", - "integrity": "sha512-pdGhXgeBaEJENMvRT6W9cmji3Zz/46ugFSvmnLLw79qi5EH7XJhKISNVb41eWCrs4am5GhI67GLx5d2s2a72iw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.3.0", - "@ethereumjs/tx": "^3.2.1", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-contract": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.5.3.tgz", - "integrity": "sha512-Gdlt1L6cdHe83k7SdV6xhqCytVtOZkjD0kY/15x441AuuJ4JLubCHuqu69k2Dr3tWifHYVys/vG8QE/W16syGg==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-ens": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.5.3.tgz", - "integrity": "sha512-QmGFFtTGElg0E+3xfCIFhiUF+1imFi9eg/cdsRMUZU4F1+MZCC/ee+IAelYLfNTGsEslCqfAusliKOT9DdGGnw==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-promievent": "1.5.3", - "web3-eth-abi": "1.5.3", - "web3-eth-contract": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - } - }, - "web3-eth-personal": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.5.3.tgz", - "integrity": "sha512-JzibJafR7ak/Icas8uvos3BmUNrZw1vShuNR5Cxjo+vteOC8XMqz1Vr7RH65B4bmlfb3bm9xLxetUHO894+Sew==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.5.3", - "web3-core-helpers": "1.5.3", - "web3-core-method": "1.5.3", - "web3-net": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-net": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.5.3.tgz", - "integrity": "sha512-0W/xHIPvgVXPSdLu0iZYnpcrgNnhzHMC888uMlGP5+qMCt8VuflUZHy7tYXae9Mzsg1kxaJAS5lHVNyeNw4CoQ==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-utils": "1.5.3" - } - }, - "web3-providers-http": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.5.3.tgz", - "integrity": "sha512-5DpUyWGHtDAr2RYmBu34Fu+4gJuBAuNx2POeiJIooUtJ+Mu6pIx4XkONWH6V+Ez87tZAVAsFOkJRTYuzMr3rPw==", - "dev": true, - "requires": { - "web3-core-helpers": "1.5.3", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.5.3.tgz", - "integrity": "sha512-JmeAptugVpmXI39LGxUSAymx0NOFdgpuI1hGQfIhbEAcd4sv7fhfd5D+ZU4oLHbRI8IFr4qfGU0uhR8BXhDzlg==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.5.3" - } - }, - "web3-providers-ws": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.5.3.tgz", - "integrity": "sha512-6DhTw4Q7nm5CFYEUHOJM0gAb3xFx+9gWpVveg3YxJ/ybR1BUvEWo3bLgIJJtX56cYX0WyY6DS35a7f0LOI1kVg==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.5.3", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.5.3.tgz", - "integrity": "sha512-COfEXfsqoV/BkcsNLRxQqnWc1Teb8/9GxdGag5GtPC5gQC/vsN+7hYVJUwNxY9LtJPKYTij2DHHnx6UkITng+Q==", - "dev": true, - "requires": { - "web3-core": "1.5.3", - "web3-core-method": "1.5.3", - "web3-core-subscriptions": "1.5.3", - "web3-net": "1.5.3" - } - }, - "web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - } - } - } - }, - "@trufflesuite/chromafi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz", - "integrity": "sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "chalk": "^2.3.2", - "cheerio": "^1.0.0-rc.2", - "detect-indent": "^5.0.0", - "highlight.js": "^10.4.1", - "lodash.merge": "^4.6.2", - "strip-ansi": "^4.0.0", - "strip-indent": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@types/abstract-leveldown": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", - "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==", - "dev": true - }, - "@types/bignumber.js": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz", - "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==", - "dev": true, - "requires": { - "bignumber.js": "*" - } - }, - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", - "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", - "dev": true - }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@types/level-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.0.tgz", - "integrity": "sha512-/lMtoq/Cf/2DVOm6zE6ORyOM+3ZVm/BvzEZVxUhf6bgh8ZHglXlBqxbxSlJeVp8FCbD3IVvk/VbsaNmDjrQvqQ==", - "dev": true - }, - "@types/levelup": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", - "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", - "dev": true, - "requires": { - "@types/abstract-leveldown": "*", - "@types/level-errors": "*", - "@types/node": "*" - } - }, - "@types/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "@types/node": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", - "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==", - "dev": true - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "abstract-leveldown": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", - "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "address": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.0.tgz", - "integrity": "sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig==", - "dev": true - }, - "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true - }, - "aes-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, - "optional": true - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", - "dev": true - }, - "antlr4": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", - "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==", - "dev": true - }, - "antlr4ts": { - "version": "0.5.0-alpha.4", - "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", - "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "apache-crypt": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.5.tgz", - "integrity": "sha512-ICnYQH+DFVmw+S4Q0QY2XRXD8Ne8ewh8HgbuFH4K7022zCxgHM0Hz1xkRnUlEfAXNbwp1Cnhbedu60USIfDxvg==", - "dev": true, - "requires": { - "unix-crypt-td-js": "^1.1.4" - } - }, - "apache-md5": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.7.tgz", - "integrity": "sha512-JtHjzZmJxtzfTSjsCyHgPR155HBe5WGyUyHTaEkfy46qhwCFKx1Epm6nAxgUG3WfUZP1dWhGqj9Z2NOBeZ+uBw==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true - }, - "array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.reduce": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", - "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - } - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true - }, - "ast-parents": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", - "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "dev": true, - "requires": { - "async": "^2.4.0" - } - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - } - } - }, - "bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", - "dev": true - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "big-integer": { - "version": "1.6.36", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", - "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", - "dev": true - }, - "big.js": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.0.tgz", - "integrity": "sha512-paIKvJiAaOYdLt6MfnvxkDo64lTOV257XYJyX3oJnJQocIclUn+48k6ZerH/c5FxWE6DGJu1TKDYis7tqHg9kg==", - "dev": true - }, - "bignumber.js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-reverse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", - "integrity": "sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==", - "dev": true - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "dev": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true - } - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true - }, - "cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", - "dev": true, - "requires": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "cbor": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-5.2.0.tgz", - "integrity": "sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.1", - "nofilter": "^1.0.4" - }, - "dependencies": { - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true - } - } - }, - "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chai-bn": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/chai-bn/-/chai-bn-0.2.2.tgz", - "integrity": "sha512-MzjelH0p8vWn65QKmEq/DLBG1Hle4WeyqT79ANhXZhn/UxRWO0OogkAxi5oGGtfzwU9bZR8mvbvYdoqNVWQwFg==", - "dev": true, - "requires": {} - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "change-case": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.0.2.tgz", - "integrity": "sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==", - "dev": true, - "requires": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true - }, - "cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dev": true, - "requires": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - } - }, - "cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "dev": true, - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-progress": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.11.2.tgz", - "integrity": "sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA==", - "dev": true, - "requires": { - "string-width": "^4.2.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "cli-table3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, - "commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "constant-case": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", - "integrity": "sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==", - "dev": true, - "requires": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" - } - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true - }, - "core-js-pure": { - "version": "3.23.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.3.tgz", - "integrity": "sha512-XpoouuqIj4P+GWtdyV8ZO3/u4KftkeDVMfvp+308eGMhCrA3lVDSmAxO0c6GGOcmgVlaKDrgWVMo49h2ab/TDA==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "dependencies": { - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true - } - } - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true - }, - "crypto-addr-codec": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz", - "integrity": "sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "big-integer": "1.6.36", - "blakejs": "^1.1.0", - "bs58": "^4.0.1", - "ripemd160-min": "0.0.6", - "safe-buffer": "^5.2.0", - "sha3": "^2.1.1" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", - "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==", - "dev": true - }, - "css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", - "dev": true - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "dev": true, - "requires": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - } - } - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true - }, - "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true - }, - "detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - } - }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true - }, - "domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "requires": { - "domelementtype": "^2.3.0" - } - }, - "domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", - "dev": true, - "requires": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" - } - }, - "dot-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", - "integrity": "sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", - "dev": true, - "requires": { - "jake": "^10.8.5" - } - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "emoji-regex": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz", - "integrity": "sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true - }, - "encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "dev": true, - "requires": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true - } - } - }, - "entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz", - "integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==", - "dev": true - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.61", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", - "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "requires": {} - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - } - } - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "eslint-plugin-mocha": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.0.5.tgz", - "integrity": "sha512-H5xuD5NStlpaKLqUWYC5BsMx8fHgrIYsdloFbONUTc2vgVNiJcWdKoX29Tt0BO75QgAltplPLIziByMozGGixA==", - "dev": true, - "requires": { - "eslint-utils": "^3.0.0", - "rambda": "^7.1.0" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true - }, - "eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", - "dev": true, - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - }, - "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - } - } - }, - "eth-gas-reporter": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz", - "integrity": "sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.0.0-beta.146", - "@solidity-parser/parser": "^0.14.0", - "cli-table3": "^0.5.0", - "colors": "1.4.0", - "ethereum-cryptography": "^1.0.3", - "ethers": "^4.0.40", - "fs-readdir-recursive": "^1.1.0", - "lodash": "^4.17.14", - "markdown-table": "^1.1.3", - "mocha": "^7.1.1", - "req-cwd": "^2.0.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "sha1": "^1.1.1", - "sync-request": "^6.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "ethereum-cryptography": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.0.tgz", - "integrity": "sha512-wyNVTBR4wIR2yoXdMv4Qt44mTVBpPgSW/DQCTmNO6nQluwpyrAIvmL4mxPbziFuc6VWJQa3rwUxn0nUFU03nyQ==", - "dev": true, - "requires": { - "@noble/hashes": "1.1.1", - "@noble/secp256k1": "1.6.0", - "@scure/bip32": "1.1.0", - "@scure/bip39": "1.1.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } - }, - "eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "eth-sig-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-3.0.1.tgz", - "integrity": "sha512-0Us50HiGGvZgjtWTyAI/+qTzYPMLy5Q451D0Xy68bxq1QMWdoOddDwGvsqcFT27uohKgalM9z/yxplyt+mY2iQ==", - "dev": true, - "requires": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", - "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dev": true, - "requires": { - "js-sha3": "^0.8.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereum-ens": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/ethereum-ens/-/ethereum-ens-0.8.0.tgz", - "integrity": "sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==", - "dev": true, - "requires": { - "bluebird": "^3.4.7", - "eth-ens-namehash": "^2.0.0", - "js-sha3": "^0.5.7", - "pako": "^1.0.4", - "underscore": "^1.8.3", - "web3": "^1.0.0-beta.34" - }, - "dependencies": { - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - } - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "ethereumjs-wallet": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-1.0.2.tgz", - "integrity": "sha512-CCWV4RESJgRdHIvFciVQFnCHfqyhXWchTPlkfp28Qc53ufs+doi5I/cV2+xeK9+qEo25XCWfP9MiL+WEPAZfdA==", - "dev": true, - "requires": { - "aes-js": "^3.1.2", - "bs58check": "^2.1.2", - "ethereum-cryptography": "^0.1.3", - "ethereumjs-util": "^7.1.2", - "randombytes": "^2.1.0", - "scrypt-js": "^3.0.1", - "utf8": "^3.0.0", - "uuid": "^8.3.2" - } - }, - "ethers": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.49.tgz", - "integrity": "sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==", - "dev": true, - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.3", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.4", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - }, - "dependencies": { - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", - "dev": true - }, - "scrypt-js": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==", - "dev": true - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==", - "dev": true - } - } - }, - "ethjs-abi": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.2.1.tgz", - "integrity": "sha512-g2AULSDYI6nEJyJaEVEXtTimRY2aPC2fi7ddSy0W+LXvEVL8Fe1y76o43ecbgdUKwZD+xsmEgX1yJr1Ia3r1IA==", - "dev": true, - "requires": { - "bn.js": "4.11.6", - "js-sha3": "0.5.5", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - }, - "js-sha3": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", - "integrity": "sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA==", - "dev": true - } - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dev": true, - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true - }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", - "dev": true, - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "dev": true, - "requires": { - "type": "^2.5.0" - }, - "dependencies": { - "type": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", - "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true - }, - "faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==", - "dev": true - }, - "fast-check": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", - "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", - "dev": true, - "requires": { - "pure-rand": "^5.0.1" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - } - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "requires": { - "minimatch": "^5.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - } - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "hardhat": { - "version": "2.9.9", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.9.tgz", - "integrity": "sha512-Qv7SXnRc0zq1kGXruNnSKpP3eFccXMR5Qv6GVX9hBIJ5efN0PflKPq92aQ5Cv3jrjJeRevLznWZVz7bttXhVfw==", - "dev": true, - "requires": { - "@ethereumjs/block": "^3.6.2", - "@ethereumjs/blockchain": "^5.5.2", - "@ethereumjs/common": "^2.6.4", - "@ethereumjs/tx": "^3.5.1", - "@ethereumjs/vm": "^5.9.0", - "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.14.1", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^0.1.2", - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.4", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "7.2.0", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.4", - "mnemonist": "^0.38.0", - "mocha": "^9.2.0", - "p-map": "^4.0.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "slash": "^3.0.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "true-case-path": "^2.2.1", - "tsort": "0.0.1", - "undici": "^5.4.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "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==", - "dev": true - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "hardhat-gas-reporter": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.8.tgz", - "integrity": "sha512-1G5thPnnhcwLHsFnl759f2tgElvuwdkzxlI65fC9PwxYMEe9cmjkVAAWTf3/3y8uP6ZSPiUiOW8PgZnykmZe0g==", - "dev": true, - "requires": { - "array-uniq": "1.0.3", - "eth-gas-reporter": "^0.2.24", - "sha1": "^1.1.1" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "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==", - "dev": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "header-case": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", - "integrity": "sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" - } - }, - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "dev": true - }, - "highlightjs-solidity": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.5.tgz", - "integrity": "sha512-ReXxQSGQkODMUgHcWzVSnfDCDrL2HshOYgw3OlIYmfHeRzUPkfJTUIp95pK4CmbiNG2eMTOmNLpfCz9Zq7Cwmg==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", - "dev": true, - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" - } - }, - "http-auth": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", - "integrity": "sha512-Jbx0+ejo2IOx+cRUYAGS1z6RGc6JfYUNkysZM4u4Sfk1uLlGv814F7/PIjQQAuThLdAWxb74JMGd5J8zex1VQg==", - "dev": true, - "requires": { - "apache-crypt": "^1.1.2", - "apache-md5": "^1.0.6", - "bcryptjs": "^2.3.0", - "uuid": "^3.0.0" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, - "requires": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "dependencies": { - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", - "dev": true - }, - "http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true - }, - "http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, - "requires": { - "@types/node": "^10.0.3" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "hyperlinker": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", - "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "dev": true, - "requires": { - "punycode": "2.1.0" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true - }, - "immutable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", - "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "dev": true - }, - "io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "requires": { - "fp-ts": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true - }, - "is-lower-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", - "integrity": "sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==", - "dev": true, - "requires": { - "lower-case": "^1.1.0" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-port-reachable": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-3.1.0.tgz", - "integrity": "sha512-vjc0SSRNZ32s9SbZBzGaiP6YVB+xglLShhgZD/FHMZUXBvQWaV9CtzgeVhjccFJrI6RAMV+LX7NYxueW/A8W5A==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "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==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-upper-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", - "integrity": "sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==", - "dev": true, - "requires": { - "upper-case": "^1.1.0" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", - "dev": true, - "requires": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - } - }, - "keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "dev": true, - "requires": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "level-codec": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", - "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", - "dev": true, - "requires": { - "buffer": "^5.6.0" - } - }, - "level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", - "dev": true - }, - "level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - } - }, - "level-mem": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", - "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", - "dev": true, - "requires": { - "level-packager": "^5.0.3", - "memdown": "^5.0.0" - } - }, - "level-packager": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", - "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", - "dev": true, - "requires": { - "encoding-down": "^6.3.0", - "levelup": "^4.3.2" - } - }, - "level-supports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "dev": true, - "requires": { - "xtend": "^4.0.2" - } - }, - "level-ws": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", - "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^3.1.0", - "xtend": "^4.0.1" - } - }, - "levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", - "dev": true, - "requires": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "live-server": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.2.tgz", - "integrity": "sha512-t28HXLjITRGoMSrCOv4eZ88viHaBVIjKjdI5PO92Vxlu+twbk6aE0t7dVIaz6ZWkjPilYFV6OSdMYl9ybN2B4w==", - "dev": true, - "requires": { - "chokidar": "^2.0.4", - "colors": "1.4.0", - "connect": "^3.6.6", - "cors": "latest", - "event-stream": "3.3.4", - "faye-websocket": "0.11.x", - "http-auth": "3.1.x", - "morgan": "^1.9.1", - "object-assign": "latest", - "opn": "latest", - "proxy-middleware": "latest", - "send": "latest", - "serve-index": "^1.9.1" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - } - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "lodash.zip": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", - "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", - "dev": true, - "requires": { - "get-func-name": "^2.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", - "dev": true - }, - "lower-case-first": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", - "integrity": "sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==", - "dev": true, - "requires": { - "lower-case": "^1.1.2" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "mcl-wasm": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", - "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true - }, - "memdown": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", - "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", - "dev": true, - "requires": { - "abstract-leveldown": "~6.2.1", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==", - "dev": true - } - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "merkle-patricia-tree": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz", - "integrity": "sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w==", - "dev": true, - "requires": { - "@types/levelup": "^4.3.0", - "ethereumjs-util": "^7.1.4", - "level-mem": "^5.0.1", - "level-ws": "^2.0.0", - "readable-stream": "^3.6.0", - "semaphore-async-await": "^1.5.1" - } - }, - "merkletreejs": { - "version": "0.2.32", - "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.2.32.tgz", - "integrity": "sha512-TostQBiwYRIwSE5++jGmacu3ODcKAgqb0Y/pnIohXS7sWxh1gCkSptbmF1a43faehRDpcHf7J/kv0Ml2D/zblQ==", - "dev": true, - "requires": { - "bignumber.js": "^9.0.1", - "buffer-reverse": "^1.0.1", - "crypto-js": "^3.1.9-1", - "treeify": "^1.1.0", - "web3-utils": "^1.3.4" - }, - "dependencies": { - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", - "dev": true, - "requires": { - "mkdirp": "*" - } - }, - "mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "requires": { - "obliterator": "^2.0.0" - } - }, - "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "4.2.1", - "ms": "2.1.3", - "nanoid": "3.3.1", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", - "dev": true - }, - "morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "dev": true, - "requires": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "dev": true, - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "dev": true, - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true - }, - "nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", - "dev": true, - "optional": true - }, - "nano-base32": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nano-base32/-/nano-base32-1.0.1.tgz", - "integrity": "sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==", - "dev": true - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", - "dev": true - }, - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "natural-orderby": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", - "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-gyp-build": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", - "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", - "dev": true - }, - "nofilter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.4.tgz", - "integrity": "sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==", - "dev": true - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-treeify": { - "version": "1.1.33", - "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", - "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", - "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", - "dev": true, - "requires": { - "array.prototype.reduce": "^1.0.4", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "obliterator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true - }, - "oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", - "dev": true, - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "opn": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", - "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true - }, - "parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", - "dev": true, - "requires": { - "entities": "^4.3.0" - } - }, - "parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dev": true, - "requires": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascal-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", - "integrity": "sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==", - "dev": true, - "requires": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true - }, - "password-prompt": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", - "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", - "dev": true, - "requires": { - "ansi-escapes": "^3.1.0", - "cross-spawn": "^6.0.5" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "path-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", - "integrity": "sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "requires": { - "through": "~2.3" - } - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "dev": true - }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true - }, - "prettier-plugin-solidity": { - "version": "1.0.0-beta.19", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.19.tgz", - "integrity": "sha512-xxRQ5ZiiZyUoMFLE9h7HnUDXI/daf1tnmL1msEdcKmyh7ZGQ4YklkYLC71bfBpYU2WruTb5/SFLUaEb3RApg5g==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.14.0", - "emoji-regex": "^10.0.0", - "escape-string-regexp": "^4.0.0", - "semver": "^7.3.5", - "solidity-comments-extractor": "^0.0.7", - "string-width": "^4.2.3" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - } - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dev": true, - "requires": { - "asap": "~2.0.6" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "proxy-middleware": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", - "integrity": "sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", - "dev": true - }, - "pure-rand": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.1.tgz", - "integrity": "sha512-ksWccjmXOHU2gJBnH0cK1lSYdvSZ0zLoCMSz/nTGh6hDvCSgcRxDyIcOBD6KNxFz3xhMPm/T267Tbe2JRymKEQ==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "rambda": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.1.4.tgz", - "integrity": "sha512-bPK8sSiVHIC7CqdWga8R+hRi5hfc4hK6S01lZW4KrLwSNryQoKaCOJA9GNiF20J7Nbe1vejRfR37/ASQXFL5EA==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "dev": true, - "requires": { - "minimatch": "3.0.4" - }, - "dependencies": { - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "dev": true, - "requires": { - "esprima": "~4.0.0" - } - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true - }, - "req-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", - "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, - "requires": { - "req-from": "^2.0.0" - } - }, - "req-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", - "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true - } - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "ripemd160-min": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/ripemd160-min/-/ripemd160-min-0.0.6.tgz", - "integrity": "sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==", - "dev": true - }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "requires": { - "bn.js": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semaphore-async-await": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", - "integrity": "sha512-b/ptP11hETwYWpeilHXXQiV5UJNJl7ZWWooKRE5eBIYWoom6dZ0SluCIdCtKycsMtZgKWE01/qAw6jblw1YVhg==", - "dev": true - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "sentence-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", - "integrity": "sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dev": true, - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "requires": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - } - }, - "sha3": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-2.1.4.tgz", - "integrity": "sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==", - "dev": true, - "requires": { - "buffer": "6.0.3" - }, - "dependencies": { - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true - }, - "simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "dev": true, - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - } - } - }, - "snake-case": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", - "integrity": "sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "solc": { - "version": "0.4.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", - "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", - "dev": true, - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", - "dev": true, - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - } - } - }, - "solhint": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.7.tgz", - "integrity": "sha512-NjjjVmXI3ehKkb3aNtRJWw55SUVJ8HMKKodwe0HnejA+k0d2kmhw7jvpa+MCTbcEgt8IWSwx0Hu6aCo/iYOZzQ==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.14.1", - "ajv": "^6.6.1", - "antlr4": "4.7.1", - "ast-parents": "0.0.1", - "chalk": "^2.4.2", - "commander": "2.18.0", - "cosmiconfig": "^5.0.7", - "eslint": "^5.6.0", - "fast-diff": "^1.1.2", - "glob": "^7.1.3", - "ignore": "^4.0.6", - "js-yaml": "^3.12.0", - "lodash": "^4.17.11", - "prettier": "^1.14.3", - "semver": "^6.3.0" - }, - "dependencies": { - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true, - "optional": true - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "solidity-ast": { - "version": "0.4.35", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.35.tgz", - "integrity": "sha512-F5bTDLh3rmDxRmLSrs3qt3nvxJprWSEkS7h2KmuXDx7XTfJ6ZKVTV1rtPIYCqJAuPsU/qa8YUeFn7jdOAZcTPA==", - "dev": true - }, - "solidity-comments-extractor": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz", - "integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==", - "dev": true - }, - "solidity-coverage": { - "version": "0.7.21", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.21.tgz", - "integrity": "sha512-O8nuzJ9yXiKUx3NdzVvHrUW0DxoNVcGzq/I7NzewNO9EZE3wYAQ4l8BwcnV64r4aC/HB6Vnw/q2sF0BQHv/3fg==", - "dev": true, - "requires": { - "@solidity-parser/parser": "^0.14.0", - "@truffle/provider": "^0.2.24", - "chalk": "^2.4.2", - "death": "^1.1.0", - "detect-port": "^1.3.0", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "solidity-docgen": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.5.17.tgz", - "integrity": "sha512-RX5SPLFL9z0ZVBcZ/o5l/TKXMgSjNhWdumLuuv+Dy1O/66sThpHYd0HVpzdwAjVff0Ajk76bYM2zZYiMnqBfng==", - "dev": true, - "requires": { - "@oclif/command": "^1.8.0", - "@oclif/config": "^1.17.0", - "@oclif/errors": "^1.3.3", - "@oclif/plugin-help": "^5.0.0", - "globby": "^11.0.0", - "handlebars": "^4.7.6", - "json5": "^2.1.3", - "lodash": "^4.17.15", - "micromatch": "^4.0.2", - "minimatch": "^5.0.0", - "semver": "^7.3.2", - "solc": "^0.6.7" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "require-from-string": { - "version": "2.0.2", - "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==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "solc": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.12.tgz", - "integrity": "sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==", - "dev": true, - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - } - } - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "source-map-resolve": { - "version": "0.5.3", - "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==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", - "dev": true, - "requires": { - "through": "2" - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - } - } - }, - "stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dev": true, - "requires": { - "type-fest": "^0.7.1" - }, - "dependencies": { - "type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true - } - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", - "dev": true, - "requires": { - "duplexer": "~0.1.1" - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "swap-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", - "integrity": "sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" - } - }, - "swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, - "dependencies": { - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", - "dev": true, - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, - "requires": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - } - }, - "sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, - "requires": { - "get-port": "^3.1.0" - } - }, - "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - } - }, - "testrpc": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", - "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", - "dev": true - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true - } - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true - }, - "title-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", - "integrity": "sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } - } - }, - "treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", - "dev": true - }, - "true-case-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", - "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==", - "dev": true - }, - "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "uglify-js": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.1.tgz", - "integrity": "sha512-X5BGTIDH8U6IQ1TIRP62YC36k+ULAa1d59BxlWvPUJ1NkW5L3FwcGfEzuVvGmhJFBu0YJ5Ge25tmRISqCmLiRQ==", - "dev": true, - "optional": true - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "underscore": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz", - "integrity": "sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==", - "dev": true - }, - "undici": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.5.1.tgz", - "integrity": "sha512-MEvryPLf18HvlCbLSzCW0U00IMftKGI5udnjrQbC5D4P0Hodwffhv+iGfWuJwg16Y/TK11ZFK8i+BPVW2z/eAw==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unix-crypt-td-js": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", - "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", - "dev": true - }, - "upper-case-first": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", - "integrity": "sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==", - "dev": true, - "requires": { - "upper-case": "^1.1.1" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "dev": true - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", - "dev": true - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "utf-8-validate": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", - "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", - "dev": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true - }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.4.tgz", - "integrity": "sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A==", - "dev": true, - "requires": { - "web3-bzz": "1.7.4", - "web3-core": "1.7.4", - "web3-eth": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-shh": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-bzz": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.4.tgz", - "integrity": "sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40" - }, - "dependencies": { - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - } - } - }, - "web3-core": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.4.tgz", - "integrity": "sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-requestmanager": "1.7.4", - "web3-utils": "1.7.4" - }, - "dependencies": { - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "dev": true - } - } - }, - "web3-core-helpers": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz", - "integrity": "sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg==", - "dev": true, - "requires": { - "web3-eth-iban": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-core-method": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.4.tgz", - "integrity": "sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ==", - "dev": true, - "requires": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-core-promievent": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz", - "integrity": "sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz", - "integrity": "sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA==", - "dev": true, - "requires": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.4", - "web3-providers-http": "1.7.4", - "web3-providers-ipc": "1.7.4", - "web3-providers-ws": "1.7.4" - } - }, - "web3-core-subscriptions": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz", - "integrity": "sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4" - } - }, - "web3-eth": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.4.tgz", - "integrity": "sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-accounts": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-eth-ens": "1.7.4", - "web3-eth-iban": "1.7.4", - "web3-eth-personal": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-abi": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz", - "integrity": "sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.7.4" - } - }, - "web3-eth-accounts": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz", - "integrity": "sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - } - } - }, - "web3-eth-contract": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz", - "integrity": "sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-ens": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz", - "integrity": "sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA==", - "dev": true, - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-promievent": "1.7.4", - "web3-eth-abi": "1.7.4", - "web3-eth-contract": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-eth-iban": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz", - "integrity": "sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w==", - "dev": true, - "requires": { - "bn.js": "^5.2.1", - "web3-utils": "1.7.4" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "web3-eth-personal": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz", - "integrity": "sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g==", - "dev": true, - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.7.4", - "web3-core-helpers": "1.7.4", - "web3-core-method": "1.7.4", - "web3-net": "1.7.4", - "web3-utils": "1.7.4" - }, - "dependencies": { - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - } - } - }, - "web3-net": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.4.tgz", - "integrity": "sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-utils": "1.7.4" - } - }, - "web3-providers-http": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.4.tgz", - "integrity": "sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA==", - "dev": true, - "requires": { - "web3-core-helpers": "1.7.4", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz", - "integrity": "sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw==", - "dev": true, - "requires": { - "oboe": "2.1.5", - "web3-core-helpers": "1.7.4" - } - }, - "web3-providers-ws": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz", - "integrity": "sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ==", - "dev": true, - "requires": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.4", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.4.tgz", - "integrity": "sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A==", - "dev": true, - "requires": { - "web3-core": "1.7.4", - "web3-core-method": "1.7.4", - "web3-core-subscriptions": "1.7.4", - "web3-net": "1.7.4" - } - }, - "web3-utils": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.4.tgz", - "integrity": "sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - } - } - }, - "websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, - "which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "ws": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", - "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", - "dev": true, - "requires": {} - }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dev": true, - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dev": true, - "requires": { - "xhr-request": "^1.1.0" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==", - "dev": true, - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/package.json b/lib/morpho-utils/lib/openzeppelin-contracts/package.json deleted file mode 100644 index b85308e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/package.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "name": "openzeppelin-solidity", - "description": "Secure Smart Contract library for Solidity", - "version": "4.7.0", - "files": [ - "/contracts/**/*.sol", - "/build/contracts/*.json", - "!/contracts/mocks/**/*" - ], - "bin": { - "openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js" - }, - "scripts": { - "compile": "hardhat compile", - "coverage": "env COVERAGE=true hardhat coverage", - "docs": "oz-docs", - "docs:watch": "npm run docs watch contracts 'docs/*.hbs' docs/helpers.js", - "prepare-docs": "scripts/prepare-docs.sh", - "lint": "npm run lint:js && npm run lint:sol", - "lint:fix": "npm run lint:js:fix && npm run lint:sol:fix", - "lint:js": "eslint --ignore-path .gitignore .", - "lint:js:fix": "eslint --ignore-path .gitignore . --fix", - "lint:sol": "solhint 'contracts/**/*.sol' && prettier -c 'contracts/**/*.sol'", - "lint:sol:fix": "prettier --write \"contracts/**/*.sol\"", - "clean": "hardhat clean && rimraf build contracts/build", - "prepare": "scripts/prepare.sh", - "prepack": "scripts/prepack.sh", - "generate": "scripts/generate/run.js", - "release": "scripts/release/release.sh", - "version": "scripts/release/version.sh", - "test": "hardhat test", - "test:inheritance": "scripts/checks/inheritance-ordering.js artifacts/build-info/*", - "test:generation": "scripts/checks/generation.sh", - "gas-report": "env ENABLE_GAS_REPORT=true npm run test", - "slither": "npm run clean && slither . --detect reentrancy-eth,reentrancy-no-eth,reentrancy-unlimited-gas" - }, - "repository": { - "type": "git", - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts.git" - }, - "keywords": [ - "solidity", - "ethereum", - "smart", - "contracts", - "security", - "zeppelin" - ], - "author": "OpenZeppelin Community ", - "license": "MIT", - "bugs": { - "url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues" - }, - "homepage": "https://openzeppelin.com/contracts/", - "devDependencies": { - "@nomiclabs/hardhat-truffle5": "^2.0.5", - "@nomiclabs/hardhat-web3": "^2.0.0", - "@openzeppelin/docs-utils": "^0.1.0", - "@openzeppelin/test-helpers": "^0.5.13", - "chai": "^4.2.0", - "eslint": "^7.32.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-mocha": "^10.0.3", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.2.0", - "eth-sig-util": "^3.0.0", - "ethereumjs-util": "^7.0.7", - "ethereumjs-wallet": "^1.0.1", - "graphlib": "^2.1.8", - "hardhat": "^2.9.1", - "hardhat-gas-reporter": "^1.0.4", - "keccak256": "^1.0.2", - "lodash.startcase": "^4.4.0", - "lodash.zip": "^4.2.0", - "merkletreejs": "^0.2.13", - "micromatch": "^4.0.2", - "prettier": "^2.3.0", - "prettier-plugin-solidity": "^1.0.0-beta.16", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "solhint": "^3.3.6", - "solidity-ast": "^0.4.25", - "solidity-coverage": "^0.7.18", - "solidity-docgen": "^0.5.3", - "web3": "^1.3.0", - "yargs": "^17.0.0" - } -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/renovate.json b/lib/morpho-utils/lib/openzeppelin-contracts/renovate.json deleted file mode 100644 index 0ec3e85..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/renovate.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": [ - "github>OpenZeppelin/code-style" - ], - "packageRules": [ - { - "extends": ["packages:eslint"], - "enabled": false - } - ] -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js deleted file mode 100755 index ba1b1be..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const chalk = require('chalk'); -const { argv } = require('yargs') - .env() - .options({ - style: { - type: 'string', - choices: [ 'shell', 'markdown' ], - default: 'shell', - }, - }); - -// Deduce base tx cost from the percentage denominator -const BASE_TX_COST = 21000; - -// Utilities -function sum (...args) { - return args.reduce((a, b) => a + b, 0); -} - -function average (...args) { - return sum(...args) / args.length; -} - -function variation (current, previous) { - return { - value: current, - delta: current - previous, - prcnt: 100 * (current - previous) / (previous - BASE_TX_COST), - }; -} - -// Report class -class Report { - // Read report file - static load (filepath) { - return JSON.parse(fs.readFileSync(filepath, 'utf8')); - } - - // Compare two reports - static compare (update, ref, opts = { hideEqual: true }) { - if (JSON.stringify(update.config.metadata) !== JSON.stringify(ref.config.metadata)) { - throw new Error('Reports produced with non matching metadata'); - } - return Object.keys(update.info.methods) - .filter(key => ref.info.methods[key]) - .filter(key => update.info.methods[key].numberOfCalls > 0) - .filter(key => update.info.methods[key].numberOfCalls === ref.info.methods[key].numberOfCalls) - .map(key => ({ - contract: ref.info.methods[key].contract, - method: ref.info.methods[key].fnSig, - min: variation(...[update, ref].map(x => ~~Math.min(...x.info.methods[key].gasData))), - max: variation(...[update, ref].map(x => ~~Math.max(...x.info.methods[key].gasData))), - avg: variation(...[update, ref].map(x => ~~average(...x.info.methods[key].gasData))), - })) - .filter(row => !opts.hideEqual || (row.min.delta && row.max.delta && row.avg.delta)) - .sort((a, b) => `${a.contract}:${a.method}` < `${b.contract}:${b.method}` ? -1 : 1); - } -} - -// Display -function center (text, length) { - return text.padStart((text.length + length) / 2).padEnd(length); -} - -function plusSign (num) { - return num > 0 ? '+' : ''; -} - -function formatCellShell (cell) { - const format = chalk[cell.delta > 0 ? 'red' : cell.delta < 0 ? 'green' : 'reset']; - return [ - format((isNaN(cell.value) ? '-' : cell.value.toString()).padStart(8)), - format((isNaN(cell.delta) ? '-' : plusSign(cell.delta) + cell.delta.toString()).padStart(8)), - format((isNaN(cell.prcnt) ? '-' : plusSign(cell.prcnt) + cell.prcnt.toFixed(2) + '%').padStart(8)), - ]; -} - -function formatCmpShell (rows) { - const contractLength = Math.max(8, ...rows.map(({ contract }) => contract.length)); - const methodLength = Math.max(7, ...rows.map(({ method }) => method.length)); - - const COLS = [ - { txt: '', length: 0 }, - { txt: 'Contract', length: contractLength }, - { txt: 'Method', length: methodLength }, - { txt: 'Min', length: 30 }, - { txt: 'Avg', length: 30 }, - { txt: 'Max', length: 30 }, - { txt: '', length: 0 }, - ]; - const HEADER = COLS.map(entry => chalk.bold(center(entry.txt, entry.length || 0))).join(' | ').trim(); - const SEPARATOR = COLS.map(({ length }) => length > 0 ? '-'.repeat(length + 2) : '').join('|').trim(); - - return [ - '', - HEADER, - ...rows.map(entry => [ - '', - chalk.grey(entry.contract.padEnd(contractLength)), - entry.method.padEnd(methodLength), - ...formatCellShell(entry.min), - ...formatCellShell(entry.avg), - ...formatCellShell(entry.max), - '', - ].join(' | ').trim()), - '', - ].join(`\n${SEPARATOR}\n`).trim(); -} - -function alignPattern (align) { - switch (align) { - case 'left': - case undefined: - return ':-'; - case 'right': - return '-:'; - case 'center': - return ':-:'; - } -} - -function trend (value) { - return value > 0 - ? ':x:' - : value < 0 - ? ':heavy_check_mark:' - : ':heavy_minus_sign:'; -} - -function formatCellMarkdown (cell) { - return [ - (isNaN(cell.value) ? '-' : cell.value.toString()), - (isNaN(cell.delta) ? '-' : plusSign(cell.delta) + cell.delta.toString()), - (isNaN(cell.prcnt) ? '-' : plusSign(cell.prcnt) + cell.prcnt.toFixed(2) + '%') + trend(cell.delta), - ]; -} - -function formatCmpMarkdown (rows) { - const COLS = [ - { txt: '' }, - { txt: 'Contract', align: 'left' }, - { txt: 'Method', align: 'left' }, - { txt: 'Min', align: 'right' }, - { txt: '(+/-)', align: 'right' }, - { txt: '%', align: 'right' }, - { txt: 'Avg', align: 'right' }, - { txt: '(+/-)', align: 'right' }, - { txt: '%', align: 'right' }, - { txt: 'Max', align: 'right' }, - { txt: '(+/-)', align: 'right' }, - { txt: '%', align: 'right' }, - { txt: '' }, - ]; - const HEADER = COLS.map(entry => entry.txt).join(' | ').trim(); - const SEPARATOR = COLS.map(entry => entry.txt ? alignPattern(entry.align) : '').join('|').trim(); - - return [ - '# Changes to gas costs', - '', - HEADER, - SEPARATOR, - rows.map(entry => [ - '', - entry.contract, - entry.method, - ...formatCellMarkdown(entry.min), - ...formatCellMarkdown(entry.avg), - ...formatCellMarkdown(entry.max), - '', - ].join(' | ').trim()).join('\n'), - '', - ].join('\n').trim(); -} - -// MAIN -const report = Report.compare(Report.load(argv._[0]), Report.load(argv._[1])); - -switch (argv.style) { -case 'markdown': - console.log(formatCmpMarkdown(report)); - break; -case 'shell': -default: - console.log(formatCmpShell(report)); - break; -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/generation.sh b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/generation.sh deleted file mode 100755 index 00d609f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/generation.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -npm run generate -git diff -R --exit-code diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js deleted file mode 100755 index 3ade740..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node - -const path = require('path'); -const graphlib = require('graphlib'); -const { findAll } = require('solidity-ast/utils'); -const { _: artifacts } = require('yargs').argv; - -for (const artifact of artifacts) { - const { output: solcOutput } = require(path.resolve(__dirname, '../..', artifact)); - - const graph = new graphlib.Graph({ directed: true }); - const names = {}; - const linearized = []; - - for (const source in solcOutput.contracts) { - if (source.includes('/mocks/')) { - continue; - } - - for (const contractDef of findAll('ContractDefinition', solcOutput.sources[source].ast)) { - names[contractDef.id] = contractDef.name; - linearized.push(contractDef.linearizedBaseContracts); - - contractDef.linearizedBaseContracts.forEach((c1, i, contracts) => contracts.slice(i + 1).forEach(c2 => { - graph.setEdge(c1, c2); - })); - } - } - - /// graphlib.alg.findCycles will not find minimal cycles. - /// We are only interested int cycles of lengths 2 (needs proof) - graph.nodes().forEach((x, i, nodes) => nodes - .slice(i + 1) - .filter(y => graph.hasEdge(x, y) && graph.hasEdge(y, x)) - .forEach(y => { - console.log(`Conflict between ${names[x]} and ${names[y]} detected in the following dependency chains:`); - linearized - .filter(chain => chain.includes(parseInt(x)) && chain.includes(parseInt(y))) - .forEach(chain => { - const comp = chain.indexOf(parseInt(x)) < chain.indexOf(parseInt(y)) ? '>' : '<'; - console.log(`- ${names[x]} ${comp} ${names[y]} in ${names[chain.find(Boolean)]}`); - // console.log(`- ${names[x]} ${comp} ${names[y]}: ${chain.reverse().map(id => names[id]).join(', ')}`); - }); - process.exitCode = 1; - })); -} - -if (!process.exitCode) { - console.log('Contract ordering is consistent.'); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/gen-nav.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/gen-nav.js deleted file mode 100644 index a03fbd6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/gen-nav.js +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env node - -const path = require('path'); -const proc = require('child_process'); -const startCase = require('lodash.startcase'); - -const baseDir = process.argv[2]; - -const files = proc.execFileSync( - 'find', [baseDir, '-type', 'f'], { encoding: 'utf8' }, -).split('\n').filter(s => s !== ''); - -console.log('.API'); - -function getPageTitle (directory) { - switch (directory) { - case 'metatx': - return 'Meta Transactions'; - case 'common': - return 'Common (Tokens)'; - default: - return startCase(directory); - } -} - -const links = files.map((file) => { - const doc = file.replace(baseDir, ''); - const title = path.parse(file).name; - - return { - xref: `* xref:${doc}[${getPageTitle(title)}]`, - title, - }; -}); - -// Case-insensitive sort based on titles (so 'token/ERC20' gets sorted as 'erc20') -const sortedLinks = links.sort(function (a, b) { - return a.title.toLowerCase().localeCompare(b.title.toLowerCase(), undefined, { numeric: true }); -}); - -for (const link of sortedLinks) { - console.log(link.xref); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/format-lines.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/format-lines.js deleted file mode 100644 index e1f1823..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/format-lines.js +++ /dev/null @@ -1,16 +0,0 @@ -function formatLines (...lines) { - return [...indentEach(0, lines)].join('\n') + '\n'; -} - -function *indentEach (indent, lines) { - for (const line of lines) { - if (Array.isArray(line)) { - yield * indentEach(indent + 1, line); - } else { - const padding = ' '.repeat(indent); - yield * line.split('\n').map(subline => subline === '' ? '' : padding + subline); - } - } -} - -module.exports = formatLines; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/run.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/run.js deleted file mode 100755 index 0072653..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/run.js +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const format = require('./format-lines'); - -function getVersion (path) { - try { - return fs - .readFileSync(path, 'utf8') - .match(/\/\/ OpenZeppelin Contracts \(last updated v[^)]+\)/)[0]; - } catch (err) { - return null; - } -} - -for (const [ file, template ] of Object.entries({ - 'utils/math/SafeCast.sol': './templates/SafeCast', - 'mocks/SafeCastMock.sol': './templates/SafeCastMock', -})) { - const path = `./contracts/${file}`; - const version = getVersion(path); - const content = format( - '// SPDX-License-Identifier: MIT', - (version ? version + ` (${file})\n` : ''), - require(template).trimEnd(), - ); - - fs.writeFileSync(path, content); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js deleted file mode 100755 index 4792d41..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js +++ /dev/null @@ -1,168 +0,0 @@ -const assert = require('assert'); -const format = require('../format-lines'); -const { range } = require('../../helpers'); - -const LENGTHS = range(8, 256, 8).reverse(); // 248 → 8 (in steps of 8) - -// Returns the version of OpenZeppelin Contracts in which a particular function was introduced. -// This is used in the docs for each function. -const version = (selector, length) => { - switch (selector) { - case 'toUint(uint)': { - switch (length) { - case 8: - case 16: - case 32: - case 64: - case 128: - return '2.5'; - case 96: - case 224: - return '4.2'; - default: - assert(LENGTHS.includes(length)); - return '4.7'; - } - } - case 'toInt(int)': { - switch (length) { - case 8: - case 16: - case 32: - case 64: - case 128: - return '3.1'; - default: - assert(LENGTHS.includes(length)); - return '4.7'; - } - } - case 'toUint(int)': { - switch (length) { - case 256: - return '3.0'; - default: - assert(false); - return; - } - } - case 'toInt(uint)': { - switch (length) { - case 256: - return '3.0'; - default: - assert(false); - return; - } - } - default: - assert(false); - } -}; - -const header = `\ -pragma solidity ^0.8.0; - -/** - * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow - * checks. - * - * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can - * easily result in undesired exploitation or bugs, since developers usually - * assume that overflows raise errors. \`SafeCast\` restores this intuition by - * reverting the transaction when such an operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - * - * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing - * all math on \`uint256\` and \`int256\` and then downcasting. - */ -`; - -const toUintDownCast = length => `\ -/** - * @dev Returns the downcasted uint${length} from uint256, reverting on - * overflow (when the input is greater than largest uint${length}). - * - * Counterpart to Solidity's \`uint${length}\` operator. - * - * Requirements: - * - * - input must fit into ${length} bits - * - * _Available since v${version('toUint(uint)', length)}._ - */ -function toUint${length}(uint256 value) internal pure returns (uint${length}) { - require(value <= type(uint${length}).max, "SafeCast: value doesn't fit in ${length} bits"); - return uint${length}(value); -} -`; - -/* eslint-disable max-len */ -const toIntDownCast = length => `\ -/** - * @dev Returns the downcasted int${length} from int256, reverting on - * overflow (when the input is less than smallest int${length} or - * greater than largest int${length}). - * - * Counterpart to Solidity's \`int${length}\` operator. - * - * Requirements: - * - * - input must fit into ${length} bits - * - * _Available since v${version('toInt(int)', length)}._ - */ -function toInt${length}(int256 value) internal pure returns (int${length} downcasted) { - downcasted = int${length}(value); - require(downcasted == value, "SafeCast: value doesn't fit in ${length} bits"); -} -`; -/* eslint-enable max-len */ - -const toInt = length => `\ -/** - * @dev Converts an unsigned uint${length} into a signed int${length}. - * - * Requirements: - * - * - input must be less than or equal to maxInt${length}. - * - * _Available since v${version('toInt(uint)', length)}._ - */ -function toInt${length}(uint${length} value) internal pure returns (int${length}) { - // Note: Unsafe cast below is okay because \`type(int${length}).max\` is guaranteed to be positive - require(value <= uint${length}(type(int${length}).max), "SafeCast: value doesn't fit in an int${length}"); - return int${length}(value); -} -`; - -const toUint = length => `\ -/** - * @dev Converts a signed int${length} into an unsigned uint${length}. - * - * Requirements: - * - * - input must be greater than or equal to 0. - * - * _Available since v${version('toUint(int)', length)}._ - */ -function toUint${length}(int${length} value) internal pure returns (uint${length}) { - require(value >= 0, "SafeCast: value must be positive"); - return uint${length}(value); -} -`; - -// GENERATE -module.exports = format( - header.trimEnd(), - 'library SafeCast {', - [ - ...LENGTHS.map(size => toUintDownCast(size)), - toUint(256), - ...LENGTHS.map(size => toIntDownCast(size)), - toInt(256).trimEnd(), - ], - '}', -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/templates/SafeCastMock.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/templates/SafeCastMock.js deleted file mode 100755 index 9bb64d2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/generate/templates/SafeCastMock.js +++ /dev/null @@ -1,50 +0,0 @@ -const format = require('../format-lines'); -const { range } = require('../../helpers'); - -const LENGTHS = range(8, 256, 8).reverse(); // 248 → 8 (in steps of 8) - -const header = `\ -pragma solidity ^0.8.0; - -import "../utils/math/SafeCast.sol"; -`; - -const toInt = length => `\ -function toInt${length}(uint${length} a) public pure returns (int${length}) { - return a.toInt${length}(); -} -`; - -const toUint = length => `\ -function toUint${length}(int${length} a) public pure returns (uint${length}) { - return a.toUint${length}(); -} -`; - -const toIntDownCast = length => `\ -function toInt${length}(int256 a) public pure returns (int${length}) { - return a.toInt${length}(); -} -`; - -const toUintDownCast = length => `\ -function toUint${length}(uint256 a) public pure returns (uint${length}) { - return a.toUint${length}(); -} -`; - -// GENERATE -module.exports = format( - header, - 'contract SafeCastMock {', - [ - 'using SafeCast for uint256;', - 'using SafeCast for int256;', - '', - toUint(256), - ...LENGTHS.map(size => toUintDownCast(size)), - toInt(256), - ...LENGTHS.map(size => toIntDownCast(size)), - ].flatMap(fn => fn.split('\n')).slice(0, -1), - '}', -); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/git-user-config.sh b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/git-user-config.sh deleted file mode 100644 index e7b81c3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/git-user-config.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -x - -git config user.name 'github-actions' -git config user.email '41898282+github-actions[bot]@users.noreply.github.com' diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/helpers.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/helpers.js deleted file mode 100644 index cbd0e01..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/helpers.js +++ /dev/null @@ -1,23 +0,0 @@ -function chunk (array, size = 1) { - return Array.range(Math.ceil(array.length / size)).map(i => array.slice(i * size, i * size + size)); -} - -function range (start, stop = undefined, step = 1) { - if (!stop) { stop = start; start = 0; } - return start < stop ? Array(Math.ceil((stop - start) / step)).fill().map((_, i) => start + i * step) : []; -} - -function unique (array, op = x => x) { - return array.filter((obj, i) => array.findIndex(entry => op(obj) === op(entry)) === i); -} - -function zip (...args) { - return Array(Math.max(...args.map(arg => arg.length))).fill(null).map((_, i) => args.map(arg => arg[i])); -} - -module.exports = { - chunk, - range, - unique, - zip, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/migrate-imports.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/migrate-imports.js deleted file mode 100755 index bc35253..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/migrate-imports.js +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env node - -const { promises: fs } = require('fs'); -const path = require('path'); - -const pathUpdates = { - // 'access/AccessControl.sol': undefined, - // 'access/Ownable.sol': undefined, - 'access/TimelockController.sol': 'governance/TimelockController.sol', - 'cryptography/ECDSA.sol': 'utils/cryptography/ECDSA.sol', - 'cryptography/MerkleProof.sol': 'utils/cryptography/MerkleProof.sol', - 'drafts/EIP712.sol': 'utils/cryptography/draft-EIP712.sol', - 'drafts/ERC20Permit.sol': 'token/ERC20/extensions/draft-ERC20Permit.sol', - 'drafts/IERC20Permit.sol': 'token/ERC20/extensions/draft-IERC20Permit.sol', - 'GSN/Context.sol': 'utils/Context.sol', - // 'GSN/GSNRecipientERC20Fee.sol': undefined, - // 'GSN/GSNRecipientSignature.sol': undefined, - // 'GSN/GSNRecipient.sol': undefined, - // 'GSN/IRelayHub.sol': undefined, - // 'GSN/IRelayRecipient.sol': undefined, - 'introspection/ERC165Checker.sol': 'utils/introspection/ERC165Checker.sol', - 'introspection/ERC165.sol': 'utils/introspection/ERC165.sol', - 'introspection/ERC1820Implementer.sol': 'utils/introspection/ERC1820Implementer.sol', - 'introspection/IERC165.sol': 'utils/introspection/IERC165.sol', - 'introspection/IERC1820Implementer.sol': 'utils/introspection/IERC1820Implementer.sol', - 'introspection/IERC1820Registry.sol': 'utils/introspection/IERC1820Registry.sol', - 'math/Math.sol': 'utils/math/Math.sol', - 'math/SafeMath.sol': 'utils/math/SafeMath.sol', - 'math/SignedSafeMath.sol': 'utils/math/SignedSafeMath.sol', - 'payment/escrow/ConditionalEscrow.sol': 'utils/escrow/ConditionalEscrow.sol', - 'payment/escrow/Escrow.sol': 'utils/escrow/Escrow.sol', - 'payment/escrow/RefundEscrow.sol': 'utils/escrow/RefundEscrow.sol', - 'payment/PaymentSplitter.sol': 'finance/PaymentSplitter.sol', - 'utils/PaymentSplitter.sol': 'finance/PaymentSplitter.sol', - 'payment/PullPayment.sol': 'security/PullPayment.sol', - 'presets/ERC1155PresetMinterPauser.sol': 'token/ERC1155/presets/ERC1155PresetMinterPauser.sol', - 'presets/ERC20PresetFixedSupply.sol': 'token/ERC20/presets/ERC20PresetFixedSupply.sol', - 'presets/ERC20PresetMinterPauser.sol': 'token/ERC20/presets/ERC20PresetMinterPauser.sol', - 'presets/ERC721PresetMinterPauserAutoId.sol': 'token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol', - 'presets/ERC777PresetFixedSupply.sol': 'token/ERC777/presets/ERC777PresetFixedSupply.sol', - 'proxy/BeaconProxy.sol': 'proxy/beacon/BeaconProxy.sol', - // 'proxy/Clones.sol': undefined, - 'proxy/IBeacon.sol': 'proxy/beacon/IBeacon.sol', - 'proxy/Initializable.sol': 'proxy/utils/Initializable.sol', - 'utils/Initializable.sol': 'proxy/utils/Initializable.sol', - 'proxy/ProxyAdmin.sol': 'proxy/transparent/ProxyAdmin.sol', - // 'proxy/Proxy.sol': undefined, - 'proxy/TransparentUpgradeableProxy.sol': 'proxy/transparent/TransparentUpgradeableProxy.sol', - 'proxy/UpgradeableBeacon.sol': 'proxy/beacon/UpgradeableBeacon.sol', - 'proxy/UpgradeableProxy.sol': 'proxy/ERC1967/ERC1967Proxy.sol', - 'token/ERC1155/ERC1155Burnable.sol': 'token/ERC1155/extensions/ERC1155Burnable.sol', - 'token/ERC1155/ERC1155Holder.sol': 'token/ERC1155/utils/ERC1155Holder.sol', - 'token/ERC1155/ERC1155Pausable.sol': 'token/ERC1155/extensions/ERC1155Pausable.sol', - 'token/ERC1155/ERC1155Receiver.sol': 'token/ERC1155/utils/ERC1155Receiver.sol', - // 'token/ERC1155/ERC1155.sol': undefined, - 'token/ERC1155/IERC1155MetadataURI.sol': 'token/ERC1155/extensions/IERC1155MetadataURI.sol', - // 'token/ERC1155/IERC1155Receiver.sol': undefined, - // 'token/ERC1155/IERC1155.sol': undefined, - 'token/ERC20/ERC20Burnable.sol': 'token/ERC20/extensions/ERC20Burnable.sol', - 'token/ERC20/ERC20Capped.sol': 'token/ERC20/extensions/ERC20Capped.sol', - 'token/ERC20/ERC20Pausable.sol': 'token/ERC20/extensions/ERC20Pausable.sol', - 'token/ERC20/ERC20Snapshot.sol': 'token/ERC20/extensions/ERC20Snapshot.sol', - // 'token/ERC20/ERC20.sol': undefined, - // 'token/ERC20/IERC20.sol': undefined, - 'token/ERC20/SafeERC20.sol': 'token/ERC20/utils/SafeERC20.sol', - 'token/ERC20/TokenTimelock.sol': 'token/ERC20/utils/TokenTimelock.sol', - 'token/ERC721/ERC721Burnable.sol': 'token/ERC721/extensions/ERC721Burnable.sol', - 'token/ERC721/ERC721Holder.sol': 'token/ERC721/utils/ERC721Holder.sol', - 'token/ERC721/ERC721Pausable.sol': 'token/ERC721/extensions/ERC721Pausable.sol', - // 'token/ERC721/ERC721.sol': undefined, - 'token/ERC721/IERC721Enumerable.sol': 'token/ERC721/extensions/IERC721Enumerable.sol', - 'token/ERC721/IERC721Metadata.sol': 'token/ERC721/extensions/IERC721Metadata.sol', - // 'token/ERC721/IERC721Receiver.sol': undefined, - // 'token/ERC721/IERC721.sol': undefined, - // 'token/ERC777/ERC777.sol': undefined, - // 'token/ERC777/IERC777Recipient.sol': undefined, - // 'token/ERC777/IERC777Sender.sol': undefined, - // 'token/ERC777/IERC777.sol': undefined, - // 'utils/Address.sol': undefined, - // 'utils/Arrays.sol': undefined, - // 'utils/Context.sol': undefined, - // 'utils/Counters.sol': undefined, - // 'utils/Create2.sol': undefined, - 'utils/EnumerableMap.sol': 'utils/structs/EnumerableMap.sol', - 'utils/EnumerableSet.sol': 'utils/structs/EnumerableSet.sol', - 'utils/Pausable.sol': 'security/Pausable.sol', - 'utils/ReentrancyGuard.sol': 'security/ReentrancyGuard.sol', - 'utils/SafeCast.sol': 'utils/math/SafeCast.sol', - // 'utils/Strings.sol': undefined, -}; - -async function main (paths = [ 'contracts' ]) { - const files = await listFilesRecursively(paths, /\.sol$/); - - const updatedFiles = []; - for (const file of files) { - if (await updateFile(file, updateImportPaths)) { - updatedFiles.push(file); - } - } - - if (updatedFiles.length > 0) { - console.log(`${updatedFiles.length} file(s) were updated`); - for (const c of updatedFiles) { - console.log('-', c); - } - } else { - console.log('No files were updated'); - } -} - -async function listFilesRecursively (paths, filter) { - const queue = paths; - const files = []; - - while (queue.length > 0) { - const top = queue.shift(); - const stat = await fs.stat(top); - if (stat.isFile()) { - if (top.match(filter)) { - files.push(top); - } - } else if (stat.isDirectory()) { - for (const name of await fs.readdir(top)) { - queue.push(path.join(top, name)); - } - } - } - - return files; -} - -async function updateFile (file, update) { - const content = await fs.readFile(file, 'utf8'); - const updatedContent = update(content); - if (updatedContent !== content) { - await fs.writeFile(file, updatedContent); - return true; - } else { - return false; - } -} - -function updateImportPaths (source) { - for (const [ oldPath, newPath ] of Object.entries(pathUpdates)) { - source = source.replace( - path.join('@openzeppelin/contracts', oldPath), - path.join('@openzeppelin/contracts', newPath), - ); - source = source.replace( - path.join('@openzeppelin/contracts-upgradeable', getUpgradeablePath(oldPath)), - path.join('@openzeppelin/contracts-upgradeable', getUpgradeablePath(newPath)), - ); - } - - return source; -} - -function getUpgradeablePath (file) { - const { dir, name, ext } = path.parse(file); - const upgradeableName = name + 'Upgradeable'; - return path.format({ dir, ext, name: upgradeableName }); -} - -module.exports = { - pathUpdates, - updateImportPaths, - getUpgradeablePath, -}; - -if (require.main === module) { - const args = process.argv.length > 2 ? process.argv.slice(2) : undefined; - main(args).catch(e => { - console.error(e); - process.exit(1); - }); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepack.sh b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepack.sh deleted file mode 100755 index 6f1bd4c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepack.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -shopt -s globstar - -# cross platform `mkdir -p` -node -e 'fs.mkdirSync("build/contracts", { recursive: true })' - -cp artifacts/contracts/**/*.json build/contracts -rm build/contracts/*.dbg.json - -node scripts/remove-ignored-artifacts.js diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-contracts-package.sh b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-contracts-package.sh deleted file mode 100755 index 3f62fd4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-contracts-package.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -# cd to the root of the repo -cd "$(git rev-parse --show-toplevel)" - -# avoids re-compilation during publishing of both packages -if [[ ! -v ALREADY_COMPILED ]]; then - npm run clean - npm run prepare - npm run prepack -fi - -cp README.md contracts/ -mkdir contracts/build contracts/build/contracts -cp -r build/contracts/*.json contracts/build/contracts diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-docs-solc.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-docs-solc.js deleted file mode 100644 index 5c38383..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-docs-solc.js +++ /dev/null @@ -1,16 +0,0 @@ -const hre = require('hardhat'); - -const { getCompilersDir } = require('hardhat/internal/util/global-dir'); -const { CompilerDownloader } = require('hardhat/internal/solidity/compiler/downloader'); -const { Compiler } = require('hardhat/internal/solidity/compiler'); - -const [{ version }] = hre.config.solidity.compilers; - -async function getSolc () { - const downloader = new CompilerDownloader(await getCompilersDir(), { forceSolcJs: true }); - const { compilerPath } = await downloader.getDownloadedCompilerPath(version); - const compiler = new Compiler(compilerPath); - return compiler.getSolc(); -} - -module.exports = Object.assign(getSolc(), { __esModule: true }); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-docs.sh b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-docs.sh deleted file mode 100755 index 0e5a060..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare-docs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit - -OUTDIR=docs/modules/api/pages/ - -if [ ! -d node_modules ]; then - npm ci -fi - -rm -rf "$OUTDIR" - -solidity-docgen \ - -t docs \ - -o "$OUTDIR" \ - -e contracts/mocks,contracts/examples \ - --output-structure readmes \ - --helpers ./docs/helpers.js \ - --solc-module ./scripts/prepare-docs-solc.js - -rm -f "$OUTDIR"/token/*/presets.md - -node scripts/gen-nav.js "$OUTDIR" > "$OUTDIR/../nav.adoc" diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare.sh b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare.sh deleted file mode 100755 index 7014a70..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/prepare.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if [ "${SKIP_COMPILE:-}" == true ]; then - exit -fi - -npm run clean -env COMPILE_MODE=production npm run compile diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/release.sh b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/release.sh deleted file mode 100755 index af5091b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/release.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env bash - -# Exit script as soon as a command fails. -set -o errexit - -# Default the prerelease version suffix to rc -: ${PRERELEASE_SUFFIX:=rc} - -log() { - # Print to stderr to prevent this from being 'returned' - echo "$@" > /dev/stderr -} - -current_version() { - echo "v$(node --print --eval "require('./package.json').version")" -} - -current_release_branch() { - v="$(current_version)" # 3.3.0-rc.0 - vf="${v%-"$PRERELEASE_SUFFIX".*}" # 3.3.0 - r="${vf%.*}" # 3.3 - echo "release-$r" -} - -assert_current_branch() { - current_branch="$(git symbolic-ref --short HEAD)" - expected_branch="$1" - if [[ "$current_branch" != "$expected_branch" ]]; then - log "Current branch '$current_branch' is not '$expected_branch'" - exit 1 - fi -} - -push_release_branch_and_tag() { - git push upstream "$(current_release_branch)" "$(current_version)" -} - -publish() { - dist_tag="$1" - - log "Publishing @openzeppelin/contracts on npm" - cd contracts - npm publish --tag "$dist_tag" --otp "$(prompt_otp)" - cd .. - - if [[ "$dist_tag" == "latest" ]]; then - npm dist-tag rm --otp "$(prompt_otp)" @openzeppelin/contracts next - fi -} - -push_and_publish() { - dist_tag="$1" - - log "Pushing release branch and tags to upstream" - push_release_branch_and_tag - - publish "$dist_tag" -} - -prompt_otp() { - log -n "Enter npm 2FA token: " - read -r otp - echo "$otp" -} - -environment_check() { - if ! git remote get-url upstream &> /dev/null; then - log "No 'upstream' remote found" - exit 1 - fi - - if npm whoami &> /dev/null; then - log "Will publish as '$(npm whoami)'" - else - log "Not logged in into npm, run 'npm login' first" - exit 1 - fi -} - -environment_check - -if [[ "$*" == "push" ]]; then - push_and_publish next - -elif [[ "$*" == "start minor" ]]; then - log "Creating new minor pre-release" - - assert_current_branch master - - # Create temporary release branch - git checkout -b release-temp - - # This bumps minor and adds prerelease suffix, commits the changes, and tags the commit - npm version preminor --preid="$PRERELEASE_SUFFIX" - - # Rename the release branch - git branch --move "$(current_release_branch)" - - push_and_publish next - -elif [[ "$*" == "start major" ]]; then - log "Creating new major pre-release" - - assert_current_branch master - - # Create temporary release branch - git checkout -b release-temp - - # This bumps major and adds prerelease suffix, commits the changes, and tags the commit - npm version premajor --preid="$PRERELEASE_SUFFIX" - - # Rename the release branch - git branch --move "$(current_release_branch)" - - push_and_publish next - -elif [[ "$*" == "rc" ]]; then - log "Bumping pre-release" - - assert_current_branch "$(current_release_branch)" - - # Bumps prerelease number, commits and tags - npm version prerelease - - push_and_publish next - -elif [[ "$*" == "final" ]]; then - # Update changelog release date, remove prerelease suffix, tag, push to git, publish in npm, remove next dist-tag - log "Creating final release" - - assert_current_branch "$(current_release_branch)" - - # This will remove the prerelease suffix from the version - npm version patch - - push_release_branch_and_tag - - push_and_publish latest - - log "Remember to merge the release branch into master and push upstream" - -else - log "Unknown command: '$*'" - exit 1 -fi diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js deleted file mode 100755 index 15915a1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node - -// Synchronizes the version in contracts/package.json with the one in package.json. -// This is run automatically when npm version is run. - -const fs = require('fs'); -const cp = require('child_process'); - -setVersion('contracts/package.json'); - -function setVersion (file) { - const json = JSON.parse(fs.readFileSync(file)); - json.version = process.env.npm_package_version; - fs.writeFileSync(file, JSON.stringify(json, null, 2) + '\n'); - cp.execFileSync('git', ['add', file]); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/update-changelog-release-date.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/update-changelog-release-date.js deleted file mode 100755 index c368eb7..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/update-changelog-release-date.js +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env node - -// Sets the release date of the current release in the changelog. -// This is run automatically when npm version is run. - -const fs = require('fs'); -const cp = require('child_process'); - -const suffix = process.env.PRERELEASE_SUFFIX || 'rc'; - -const changelog = fs.readFileSync('CHANGELOG.md', 'utf8'); - -// The changelog entry to be updated looks like this: -// ## Unreleased -// We need to add the version and release date in a YYYY-MM-DD format, so that it looks like this: -// ## 2.5.3 (2019-04-25) - -const pkg = require('../../package.json'); -const version = pkg.version.replace(new RegExp('-' + suffix + '\\..*'), ''); - -const header = new RegExp(`^## (Unreleased|${version})$`, 'm'); - -if (!header.test(changelog)) { - console.error('Missing changelog entry'); - process.exit(1); -} - -const newHeader = pkg.version.indexOf(suffix) === -1 - ? `## ${version} (${new Date().toISOString().split('T')[0]})` - : `## ${version}`; - -fs.writeFileSync('CHANGELOG.md', changelog.replace(header, newHeader)); - -cp.execSync('git add CHANGELOG.md', { stdio: 'inherit' }); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/update-comment.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/update-comment.js deleted file mode 100755 index 0767234..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/update-comment.js +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env node -const fs = require('fs'); -const proc = require('child_process'); -const semver = require('semver'); -const run = (cmd, ...args) => proc.execFileSync(cmd, args, { encoding: 'utf8' }).trim(); - -const gitStatus = run('git', 'status', '--porcelain', '-uno', 'contracts/**/*.sol'); -if (gitStatus.length > 0) { - console.error('Contracts directory is not clean'); - process.exit(1); -} - -const { version } = require('../../package.json'); - -// Get latest tag according to semver. -const [ tag ] = run('git', 'tag') - .split(/\r?\n/) - .filter(semver.coerce) // check version can be processed - .filter(v => semver.lt(semver.coerce(v), version)) // only consider older tags, ignore current prereleases - .sort(semver.rcompare); - -// Ordering tag → HEAD is important here. -const files = run('git', 'diff', tag, 'HEAD', '--name-only', 'contracts/**/*.sol') - .split(/\r?\n/) - .filter(file => file && !file.match(/mock/i)); - -for (const file of files) { - const current = fs.readFileSync(file, 'utf8'); - const updated = current.replace( - /(\/\/ SPDX-License-Identifier:.*)$(\n\/\/ OpenZeppelin Contracts .*$)?/m, - `$1\n// OpenZeppelin Contracts (last updated v${version}) (${file.replace('contracts/', '')})`, - ); - fs.writeFileSync(file, updated); -} - -run('git', 'add', '--update', 'contracts'); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/version.sh b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/version.sh deleted file mode 100755 index 73d3026..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/release/version.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit - -scripts/release/update-changelog-release-date.js -scripts/release/synchronize-versions.js -scripts/release/update-comment.js - -oz-docs update-version diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js deleted file mode 100644 index 2ef2788..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node - -// This script removes the build artifacts of ignored contracts. - -const fs = require('fs'); -const path = require('path'); -const match = require('micromatch'); - -function readJSON (path) { - return JSON.parse(fs.readFileSync(path)); -} - -const pkgFiles = readJSON('package.json').files; - -// Get only negated patterns. -const ignorePatterns = pkgFiles - .filter(pat => pat.startsWith('!')) -// Remove the negation part. Makes micromatch usage more intuitive. - .map(pat => pat.slice(1)); - -const ignorePatternsSubtrees = ignorePatterns -// Add **/* to ignore all files contained in the directories. - .concat(ignorePatterns.map(pat => path.join(pat, '**/*'))) - .map(p => p.replace(/^\//, '')); - -const artifactsDir = 'build/contracts'; -const buildinfo = 'artifacts/build-info'; -const filenames = fs.readdirSync(buildinfo); - -let n = 0; - -for (const filename of filenames) { - const solcOutput = readJSON(path.join(buildinfo, filename)).output; - for (const sourcePath in solcOutput.contracts) { - const ignore = match.any(sourcePath, ignorePatternsSubtrees); - if (ignore) { - for (const contract in solcOutput.contracts[sourcePath]) { - fs.unlinkSync(path.join(artifactsDir, contract + '.json')); - n += 1; - } - } - } -} - -console.error(`Removed ${n} mock artifacts`); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/update-docs-branch.js b/lib/morpho-utils/lib/openzeppelin-contracts/scripts/update-docs-branch.js deleted file mode 100644 index 82bb7e0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/scripts/update-docs-branch.js +++ /dev/null @@ -1,55 +0,0 @@ -const proc = require('child_process'); -const read = cmd => proc.execSync(cmd, { encoding: 'utf8' }).trim(); -const run = cmd => { proc.execSync(cmd, { stdio: 'inherit' }); }; -const tryRead = cmd => { try { return read(cmd); } catch (e) { return undefined; } }; - -const releaseBranchRegex = /^release-v(?(?\d+)\.(?\d+)(?:\.(?\d+))?)$/; - -const currentBranch = read('git rev-parse --abbrev-ref HEAD'); -const match = currentBranch.match(releaseBranchRegex); - -if (!match) { - console.error('Not currently on a release branch'); - process.exit(1); -} - -if (/-.*$/.test(require('../package.json').version)) { - console.error('Refusing to update docs: prerelease detected'); - process.exit(0); -} - -const current = match.groups; -const docsBranch = `docs-v${current.major}.x`; - -// Fetch remotes and find the docs branch if it exists -run('git fetch --all --no-tags'); -const matchingDocsBranches = tryRead(`git rev-parse --glob='*/${docsBranch}'`); - -if (!matchingDocsBranches) { - // Create the branch - run(`git checkout --orphan ${docsBranch}`); -} else { - const [publishedRef, ...others] = new Set(matchingDocsBranches.split('\n')); - if (others.length > 0) { - console.error( - `Found conflicting ${docsBranch} branches.\n` + - 'Either local branch is outdated or there are multiple matching remote branches.', - ); - process.exit(1); - } - const publishedVersion = JSON.parse(read(`git show ${publishedRef}:package.json`)).version; - const publishedMinor = publishedVersion.match(/\d+\.(?\d+)\.\d+/).groups.minor; - if (current.minor < publishedMinor) { - console.error('Refusing to update docs: newer version is published'); - process.exit(0); - } - - run('git checkout --quiet --detach'); - run(`git reset --soft ${publishedRef}`); - run(`git checkout ${docsBranch}`); -} - -run('npm run prepare-docs'); -run('git add -f docs'); // --force needed because generated docs files are gitignored -run('git commit -m "Update docs"'); -run(`git checkout ${currentBranch}`); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/slither.config.json b/lib/morpho-utils/lib/openzeppelin-contracts/slither.config.json deleted file mode 100644 index e52e3f5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/slither.config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "detectors_to_run": "reentrancy-eth,reentrancy-no-eth,reentrancy-unlimited-gas", - "filter_paths": "contracts/mocks" -} \ No newline at end of file diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/TESTING.md b/lib/morpho-utils/lib/openzeppelin-contracts/test/TESTING.md deleted file mode 100644 index a5ee932..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/TESTING.md +++ /dev/null @@ -1,3 +0,0 @@ -## Testing - -Unit test are critical to OpenZeppelin Contracts. They help ensure code quality and mitigate against security vulnerabilities. The directory structure within the `/test` directory corresponds to the `/contracts` directory. diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControl.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControl.behavior.js deleted file mode 100644 index 53dfa3d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControl.behavior.js +++ /dev/null @@ -1,216 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); - -const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; -const ROLE = web3.utils.soliditySha3('ROLE'); -const OTHER_ROLE = web3.utils.soliditySha3('OTHER_ROLE'); - -function shouldBehaveLikeAccessControl (errorPrefix, admin, authorized, other, otherAdmin, otherAuthorized) { - shouldSupportInterfaces(['AccessControl']); - - describe('default admin', function () { - it('deployer has default admin role', async function () { - expect(await this.accessControl.hasRole(DEFAULT_ADMIN_ROLE, admin)).to.equal(true); - }); - - it('other roles\'s admin is the default admin role', async function () { - expect(await this.accessControl.getRoleAdmin(ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - it('default admin role\'s admin is itself', async function () { - expect(await this.accessControl.getRoleAdmin(DEFAULT_ADMIN_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - }); - - describe('granting', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - }); - - it('non-admin cannot grant role to other accounts', async function () { - await expectRevert( - this.accessControl.grantRole(ROLE, authorized, { from: other }), - `${errorPrefix}: account ${other.toLowerCase()} is missing role ${DEFAULT_ADMIN_ROLE}`, - ); - }); - - it('accounts can be granted a role multiple times', async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - const receipt = await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - expectEvent.notEmitted(receipt, 'RoleGranted'); - }); - }); - - describe('revoking', function () { - it('roles that are not had can be revoked', async function () { - expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false); - - const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin }); - expectEvent.notEmitted(receipt, 'RoleRevoked'); - }); - - context('with granted role', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - }); - - it('admin can revoke role', async function () { - const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin }); - expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: admin }); - - expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false); - }); - - it('non-admin cannot revoke role', async function () { - await expectRevert( - this.accessControl.revokeRole(ROLE, authorized, { from: other }), - `${errorPrefix}: account ${other.toLowerCase()} is missing role ${DEFAULT_ADMIN_ROLE}`, - ); - }); - - it('a role can be revoked multiple times', async function () { - await this.accessControl.revokeRole(ROLE, authorized, { from: admin }); - - const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin }); - expectEvent.notEmitted(receipt, 'RoleRevoked'); - }); - }); - }); - - describe('renouncing', function () { - it('roles that are not had can be renounced', async function () { - const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized }); - expectEvent.notEmitted(receipt, 'RoleRevoked'); - }); - - context('with granted role', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - }); - - it('bearer can renounce role', async function () { - const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized }); - expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: authorized }); - - expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false); - }); - - it('only the sender can renounce their roles', async function () { - await expectRevert( - this.accessControl.renounceRole(ROLE, authorized, { from: admin }), - `${errorPrefix}: can only renounce roles for self`, - ); - }); - - it('a role can be renounced multiple times', async function () { - await this.accessControl.renounceRole(ROLE, authorized, { from: authorized }); - - const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized }); - expectEvent.notEmitted(receipt, 'RoleRevoked'); - }); - }); - }); - - describe('setting role admin', function () { - beforeEach(async function () { - const receipt = await this.accessControl.setRoleAdmin(ROLE, OTHER_ROLE); - expectEvent(receipt, 'RoleAdminChanged', { - role: ROLE, - previousAdminRole: DEFAULT_ADMIN_ROLE, - newAdminRole: OTHER_ROLE, - }); - - await this.accessControl.grantRole(OTHER_ROLE, otherAdmin, { from: admin }); - }); - - it('a role\'s admin role can be changed', async function () { - expect(await this.accessControl.getRoleAdmin(ROLE)).to.equal(OTHER_ROLE); - }); - - it('the new admin can grant roles', async function () { - const receipt = await this.accessControl.grantRole(ROLE, authorized, { from: otherAdmin }); - expectEvent(receipt, 'RoleGranted', { account: authorized, role: ROLE, sender: otherAdmin }); - }); - - it('the new admin can revoke roles', async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: otherAdmin }); - const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: otherAdmin }); - expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: otherAdmin }); - }); - - it('a role\'s previous admins no longer grant roles', async function () { - await expectRevert( - this.accessControl.grantRole(ROLE, authorized, { from: admin }), - `${errorPrefix}: account ${admin.toLowerCase()} is missing role ${OTHER_ROLE}`, - ); - }); - - it('a role\'s previous admins no longer revoke roles', async function () { - await expectRevert( - this.accessControl.revokeRole(ROLE, authorized, { from: admin }), - `${errorPrefix}: account ${admin.toLowerCase()} is missing role ${OTHER_ROLE}`, - ); - }); - }); - - describe('onlyRole modifier', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - }); - - it('do not revert if sender has role', async function () { - await this.accessControl.senderProtected(ROLE, { from: authorized }); - }); - - it('revert if sender doesn\'t have role #1', async function () { - await expectRevert( - this.accessControl.senderProtected(ROLE, { from: other }), - `${errorPrefix}: account ${other.toLowerCase()} is missing role ${ROLE}`, - ); - }); - - it('revert if sender doesn\'t have role #2', async function () { - await expectRevert( - this.accessControl.senderProtected(OTHER_ROLE, { from: authorized }), - `${errorPrefix}: account ${authorized.toLowerCase()} is missing role ${OTHER_ROLE}`, - ); - }); - }); -} - -function shouldBehaveLikeAccessControlEnumerable (errorPrefix, admin, authorized, other, otherAdmin, otherAuthorized) { - shouldSupportInterfaces(['AccessControlEnumerable']); - - describe('enumerating', function () { - it('role bearers can be enumerated', async function () { - await this.accessControl.grantRole(ROLE, authorized, { from: admin }); - await this.accessControl.grantRole(ROLE, other, { from: admin }); - await this.accessControl.grantRole(ROLE, otherAuthorized, { from: admin }); - await this.accessControl.revokeRole(ROLE, other, { from: admin }); - - const memberCount = await this.accessControl.getRoleMemberCount(ROLE); - expect(memberCount).to.bignumber.equal('2'); - - const bearers = []; - for (let i = 0; i < memberCount; ++i) { - bearers.push(await this.accessControl.getRoleMember(ROLE, i)); - } - - expect(bearers).to.have.members([authorized, otherAuthorized]); - }); - it('role enumeration should be in sync after renounceRole call', async function () { - expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('0'); - await this.accessControl.grantRole(ROLE, admin, { from: admin }); - expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('1'); - await this.accessControl.renounceRole(ROLE, admin, { from: admin }); - expect(await this.accessControl.getRoleMemberCount(ROLE)).to.bignumber.equal('0'); - }); - }); -} - -module.exports = { - shouldBehaveLikeAccessControl, - shouldBehaveLikeAccessControlEnumerable, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControl.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControl.test.js deleted file mode 100644 index cd9912a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControl.test.js +++ /dev/null @@ -1,13 +0,0 @@ -const { - shouldBehaveLikeAccessControl, -} = require('./AccessControl.behavior.js'); - -const AccessControlMock = artifacts.require('AccessControlMock'); - -contract('AccessControl', function (accounts) { - beforeEach(async function () { - this.accessControl = await AccessControlMock.new({ from: accounts[0] }); - }); - - shouldBehaveLikeAccessControl('AccessControl', ...accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControlCrossChain.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControlCrossChain.test.js deleted file mode 100644 index cb4f362..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControlCrossChain.test.js +++ /dev/null @@ -1,59 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { BridgeHelper } = require('../helpers/crosschain'); - -const { - shouldBehaveLikeAccessControl, -} = require('./AccessControl.behavior.js'); - -const crossChainRoleAlias = (role) => web3.utils.leftPad( - web3.utils.toHex(web3.utils.toBN(role).xor(web3.utils.toBN(web3.utils.soliditySha3('CROSSCHAIN_ALIAS')))), - 64, -); - -const AccessControlCrossChainMock = artifacts.require('AccessControlCrossChainMock'); - -const ROLE = web3.utils.soliditySha3('ROLE'); - -contract('AccessControl', function (accounts) { - before(async function () { - this.bridge = await BridgeHelper.deploy(); - }); - - beforeEach(async function () { - this.accessControl = await AccessControlCrossChainMock.new({ from: accounts[0] }); - }); - - shouldBehaveLikeAccessControl('AccessControl', ...accounts); - - describe('CrossChain enabled', function () { - beforeEach(async function () { - await this.accessControl.grantRole(ROLE, accounts[0], { from: accounts[0] }); - await this.accessControl.grantRole(crossChainRoleAlias(ROLE), accounts[1], { from: accounts[0] }); - }); - - it('check alliassing', async function () { - expect(await this.accessControl.crossChainRoleAlias(ROLE)).to.be.bignumber.equal(crossChainRoleAlias(ROLE)); - }); - - it('Crosschain calls not authorized to non-aliased addresses', async function () { - await expectRevert( - this.bridge.call( - accounts[0], - this.accessControl, - 'senderProtected', - [ ROLE ], - ), - `AccessControl: account ${accounts[0].toLowerCase()} is missing role ${crossChainRoleAlias(ROLE)}`, - ); - }); - - it('Crosschain calls not authorized to non-aliased addresses', async function () { - await this.bridge.call( - accounts[1], - this.accessControl, - 'senderProtected', - [ ROLE ], - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControlEnumerable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControlEnumerable.test.js deleted file mode 100644 index fa5b546..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/AccessControlEnumerable.test.js +++ /dev/null @@ -1,15 +0,0 @@ -const { - shouldBehaveLikeAccessControl, - shouldBehaveLikeAccessControlEnumerable, -} = require('./AccessControl.behavior.js'); - -const AccessControlMock = artifacts.require('AccessControlEnumerableMock'); - -contract('AccessControl', function (accounts) { - beforeEach(async function () { - this.accessControl = await AccessControlMock.new({ from: accounts[0] }); - }); - - shouldBehaveLikeAccessControl('AccessControl', ...accounts); - shouldBehaveLikeAccessControlEnumerable('AccessControl', ...accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/Ownable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/access/Ownable.test.js deleted file mode 100644 index 894e77c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/access/Ownable.test.js +++ /dev/null @@ -1,57 +0,0 @@ -const { constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const Ownable = artifacts.require('OwnableMock'); - -contract('Ownable', function (accounts) { - const [ owner, other ] = accounts; - - beforeEach(async function () { - this.ownable = await Ownable.new({ from: owner }); - }); - - it('has an owner', async function () { - expect(await this.ownable.owner()).to.equal(owner); - }); - - describe('transfer ownership', function () { - it('changes owner after transfer', async function () { - const receipt = await this.ownable.transferOwnership(other, { from: owner }); - expectEvent(receipt, 'OwnershipTransferred'); - - expect(await this.ownable.owner()).to.equal(other); - }); - - it('prevents non-owners from transferring', async function () { - await expectRevert( - this.ownable.transferOwnership(other, { from: other }), - 'Ownable: caller is not the owner', - ); - }); - - it('guards ownership against stuck state', async function () { - await expectRevert( - this.ownable.transferOwnership(ZERO_ADDRESS, { from: owner }), - 'Ownable: new owner is the zero address', - ); - }); - }); - - describe('renounce ownership', function () { - it('loses owner after renouncement', async function () { - const receipt = await this.ownable.renounceOwnership({ from: owner }); - expectEvent(receipt, 'OwnershipTransferred'); - - expect(await this.ownable.owner()).to.equal(ZERO_ADDRESS); - }); - - it('prevents non-owners from renouncement', async function () { - await expectRevert( - this.ownable.renounceOwnership({ from: other }), - 'Ownable: caller is not the owner', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/crosschain/CrossChainEnabled.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/crosschain/CrossChainEnabled.test.js deleted file mode 100644 index bff9558..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/crosschain/CrossChainEnabled.test.js +++ /dev/null @@ -1,88 +0,0 @@ -const { BridgeHelper } = require('../helpers/crosschain'); -const { expectRevertCustomError } = require('../helpers/customError'); - -function randomAddress () { - return web3.utils.toChecksumAddress(web3.utils.randomHex(20)); -} - -const CrossChainEnabledAMBMock = artifacts.require('CrossChainEnabledAMBMock'); -const CrossChainEnabledArbitrumL1Mock = artifacts.require('CrossChainEnabledArbitrumL1Mock'); -const CrossChainEnabledArbitrumL2Mock = artifacts.require('CrossChainEnabledArbitrumL2Mock'); -const CrossChainEnabledOptimismMock = artifacts.require('CrossChainEnabledOptimismMock'); -const CrossChainEnabledPolygonChildMock = artifacts.require('CrossChainEnabledPolygonChildMock'); - -function shouldBehaveLikeReceiver (sender = randomAddress()) { - it('should reject same-chain calls', async function () { - await expectRevertCustomError( - this.receiver.crossChainRestricted(), - 'NotCrossChainCall()', - ); - - await expectRevertCustomError( - this.receiver.crossChainOwnerRestricted(), - 'NotCrossChainCall()', - ); - }); - - it('should restrict to cross-chain call from a invalid sender', async function () { - await expectRevertCustomError( - this.bridge.call(sender, this.receiver, 'crossChainOwnerRestricted()'), - `InvalidCrossChainSender("${sender}", "${await this.receiver.owner()}")`, - ); - }); - - it('should grant access to cross-chain call from the owner', async function () { - await this.bridge.call( - await this.receiver.owner(), - this.receiver, - 'crossChainOwnerRestricted()', - ); - }); -} - -contract('CrossChainEnabled', function () { - describe('AMB', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('AMB'); - this.receiver = await CrossChainEnabledAMBMock.new(this.bridge.address); - }); - - shouldBehaveLikeReceiver(); - }); - - describe('Arbitrum-L1', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('Arbitrum-L1'); - this.receiver = await CrossChainEnabledArbitrumL1Mock.new(this.bridge.address); - }); - - shouldBehaveLikeReceiver(); - }); - - describe('Arbitrum-L2', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('Arbitrum-L2'); - this.receiver = await CrossChainEnabledArbitrumL2Mock.new(); - }); - - shouldBehaveLikeReceiver(); - }); - - describe('Optimism', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('Optimism'); - this.receiver = await CrossChainEnabledOptimismMock.new(this.bridge.address); - }); - - shouldBehaveLikeReceiver(); - }); - - describe('Polygon-Child', function () { - beforeEach(async function () { - this.bridge = await BridgeHelper.deploy('Polygon-Child'); - this.receiver = await CrossChainEnabledPolygonChildMock.new(this.bridge.address); - }); - - shouldBehaveLikeReceiver(); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/PaymentSplitter.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/PaymentSplitter.test.js deleted file mode 100644 index 2fa7a26..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/PaymentSplitter.test.js +++ /dev/null @@ -1,217 +0,0 @@ -const { balance, constants, ether, expectEvent, send, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const PaymentSplitter = artifacts.require('PaymentSplitter'); -const Token = artifacts.require('ERC20Mock'); - -contract('PaymentSplitter', function (accounts) { - const [ owner, payee1, payee2, payee3, nonpayee1, payer1 ] = accounts; - - const amount = ether('1'); - - it('rejects an empty set of payees', async function () { - await expectRevert(PaymentSplitter.new([], []), 'PaymentSplitter: no payees'); - }); - - it('rejects more payees than shares', async function () { - await expectRevert(PaymentSplitter.new([payee1, payee2, payee3], [20, 30]), - 'PaymentSplitter: payees and shares length mismatch', - ); - }); - - it('rejects more shares than payees', async function () { - await expectRevert(PaymentSplitter.new([payee1, payee2], [20, 30, 40]), - 'PaymentSplitter: payees and shares length mismatch', - ); - }); - - it('rejects null payees', async function () { - await expectRevert(PaymentSplitter.new([payee1, ZERO_ADDRESS], [20, 30]), - 'PaymentSplitter: account is the zero address', - ); - }); - - it('rejects zero-valued shares', async function () { - await expectRevert(PaymentSplitter.new([payee1, payee2], [20, 0]), - 'PaymentSplitter: shares are 0', - ); - }); - - it('rejects repeated payees', async function () { - await expectRevert(PaymentSplitter.new([payee1, payee1], [20, 30]), - 'PaymentSplitter: account already has shares', - ); - }); - - context('once deployed', function () { - beforeEach(async function () { - this.payees = [payee1, payee2, payee3]; - this.shares = [20, 10, 70]; - - this.contract = await PaymentSplitter.new(this.payees, this.shares); - this.token = await Token.new('MyToken', 'MT', owner, ether('1000')); - }); - - it('has total shares', async function () { - expect(await this.contract.totalShares()).to.be.bignumber.equal('100'); - }); - - it('has payees', async function () { - await Promise.all(this.payees.map(async (payee, index) => { - expect(await this.contract.payee(index)).to.equal(payee); - expect(await this.contract.released(payee)).to.be.bignumber.equal('0'); - expect(await this.contract.releasable(payee)).to.be.bignumber.equal('0'); - })); - }); - - describe('accepts payments', function () { - it('Ether', async function () { - await send.ether(owner, this.contract.address, amount); - - expect(await balance.current(this.contract.address)).to.be.bignumber.equal(amount); - }); - - it('Token', async function () { - await this.token.transfer(this.contract.address, amount, { from: owner }); - - expect(await this.token.balanceOf(this.contract.address)).to.be.bignumber.equal(amount); - }); - }); - - describe('shares', function () { - it('stores shares if address is payee', async function () { - expect(await this.contract.shares(payee1)).to.be.bignumber.not.equal('0'); - }); - - it('does not store shares if address is not payee', async function () { - expect(await this.contract.shares(nonpayee1)).to.be.bignumber.equal('0'); - }); - }); - - describe('release', function () { - describe('Ether', function () { - it('reverts if no funds to claim', async function () { - await expectRevert(this.contract.release(payee1), - 'PaymentSplitter: account is not due payment', - ); - }); - it('reverts if non-payee want to claim', async function () { - await send.ether(payer1, this.contract.address, amount); - await expectRevert(this.contract.release(nonpayee1), - 'PaymentSplitter: account has no shares', - ); - }); - }); - - describe('Token', function () { - it('reverts if no funds to claim', async function () { - await expectRevert(this.contract.release(this.token.address, payee1), - 'PaymentSplitter: account is not due payment', - ); - }); - it('reverts if non-payee want to claim', async function () { - await this.token.transfer(this.contract.address, amount, { from: owner }); - await expectRevert(this.contract.release(this.token.address, nonpayee1), - 'PaymentSplitter: account has no shares', - ); - }); - }); - }); - - describe('tracks releasable and released', function () { - it('Ether', async function () { - await send.ether(payer1, this.contract.address, amount); - const payment = amount.divn(10); - expect(await this.contract.releasable(payee2)).to.be.bignumber.equal(payment); - await this.contract.release(payee2); - expect(await this.contract.releasable(payee2)).to.be.bignumber.equal('0'); - expect(await this.contract.released(payee2)).to.be.bignumber.equal(payment); - }); - - it('Token', async function () { - await this.token.transfer(this.contract.address, amount, { from: owner }); - const payment = amount.divn(10); - expect(await this.contract.releasable(this.token.address, payee2, {})).to.be.bignumber.equal(payment); - await this.contract.release(this.token.address, payee2); - expect(await this.contract.releasable(this.token.address, payee2, {})).to.be.bignumber.equal('0'); - expect(await this.contract.released(this.token.address, payee2)).to.be.bignumber.equal(payment); - }); - }); - - describe('distributes funds to payees', function () { - it('Ether', async function () { - await send.ether(payer1, this.contract.address, amount); - - // receive funds - const initBalance = await balance.current(this.contract.address); - expect(initBalance).to.be.bignumber.equal(amount); - - // distribute to payees - - const tracker1 = await balance.tracker(payee1); - const receipt1 = await this.contract.release(payee1); - const profit1 = await tracker1.delta(); - expect(profit1).to.be.bignumber.equal(ether('0.20')); - expectEvent(receipt1, 'PaymentReleased', { to: payee1, amount: profit1 }); - - const tracker2 = await balance.tracker(payee2); - const receipt2 = await this.contract.release(payee2); - const profit2 = await tracker2.delta(); - expect(profit2).to.be.bignumber.equal(ether('0.10')); - expectEvent(receipt2, 'PaymentReleased', { to: payee2, amount: profit2 }); - - const tracker3 = await balance.tracker(payee3); - const receipt3 = await this.contract.release(payee3); - const profit3 = await tracker3.delta(); - expect(profit3).to.be.bignumber.equal(ether('0.70')); - expectEvent(receipt3, 'PaymentReleased', { to: payee3, amount: profit3 }); - - // end balance should be zero - expect(await balance.current(this.contract.address)).to.be.bignumber.equal('0'); - - // check correct funds released accounting - expect(await this.contract.totalReleased()).to.be.bignumber.equal(initBalance); - }); - - it('Token', async function () { - expect(await this.token.balanceOf(payee1)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOf(payee2)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOf(payee3)).to.be.bignumber.equal('0'); - - await this.token.transfer(this.contract.address, amount, { from: owner }); - - expectEvent( - await this.contract.release(this.token.address, payee1), - 'ERC20PaymentReleased', - { token: this.token.address, to: payee1, amount: ether('0.20') }, - ); - - await this.token.transfer(this.contract.address, amount, { from: owner }); - - expectEvent( - await this.contract.release(this.token.address, payee1), - 'ERC20PaymentReleased', - { token: this.token.address, to: payee1, amount: ether('0.20') }, - ); - - expectEvent( - await this.contract.release(this.token.address, payee2), - 'ERC20PaymentReleased', - { token: this.token.address, to: payee2, amount: ether('0.20') }, - ); - - expectEvent( - await this.contract.release(this.token.address, payee3), - 'ERC20PaymentReleased', - { token: this.token.address, to: payee3, amount: ether('1.40') }, - ); - - expect(await this.token.balanceOf(payee1)).to.be.bignumber.equal(ether('0.40')); - expect(await this.token.balanceOf(payee2)).to.be.bignumber.equal(ether('0.20')); - expect(await this.token.balanceOf(payee3)).to.be.bignumber.equal(ether('1.40')); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js deleted file mode 100644 index 0f07e5f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/VestingWallet.behavior.js +++ /dev/null @@ -1,72 +0,0 @@ -const { expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -function releasedEvent (token, amount) { - return token - ? [ 'ERC20Released', { token: token.address, amount } ] - : [ 'EtherReleased', { amount } ]; -} - -function shouldBehaveLikeVesting (beneficiary) { - it('check vesting schedule', async function () { - const [ method, ...args ] = this.token - ? [ 'vestedAmount(address,uint64)', this.token.address ] - : [ 'vestedAmount(uint64)' ]; - - for (const timestamp of this.schedule) { - expect(await this.mock.methods[method](...args, timestamp)) - .to.be.bignumber.equal(this.vestingFn(timestamp)); - } - }); - - it('execute vesting schedule', async function () { - const [ method, ...args ] = this.token - ? [ 'release(address)', this.token.address ] - : [ 'release()' ]; - - let released = web3.utils.toBN(0); - const before = await this.getBalance(beneficiary); - - { - const receipt = await this.mock.methods[method](...args); - - await expectEvent.inTransaction( - receipt.tx, - this.mock, - ...releasedEvent(this.token, '0'), - ); - - await this.checkRelease(receipt, beneficiary, '0'); - - expect(await this.getBalance(beneficiary)).to.be.bignumber.equal(before); - } - - for (const timestamp of this.schedule) { - const vested = this.vestingFn(timestamp); - - await new Promise(resolve => web3.currentProvider.send({ - method: 'evm_setNextBlockTimestamp', - params: [ timestamp.toNumber() ], - }, resolve)); - - const receipt = await this.mock.methods[method](...args); - - await expectEvent.inTransaction( - receipt.tx, - this.mock, - ...releasedEvent(this.token, vested.sub(released)), - ); - - await this.checkRelease(receipt, beneficiary, vested.sub(released)); - - expect(await this.getBalance(beneficiary)) - .to.be.bignumber.equal(before.add(vested)); - - released = vested; - } - }); -} - -module.exports = { - shouldBehaveLikeVesting, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/VestingWallet.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/VestingWallet.test.js deleted file mode 100644 index 6aa7378..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/finance/VestingWallet.test.js +++ /dev/null @@ -1,67 +0,0 @@ -const { constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { web3 } = require('@openzeppelin/test-helpers/src/setup'); -const { expect } = require('chai'); - -const ERC20Mock = artifacts.require('ERC20Mock'); -const VestingWallet = artifacts.require('VestingWallet'); - -const { shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); - -const min = (...args) => args.slice(1).reduce((x, y) => x.lt(y) ? x : y, args[0]); - -contract('VestingWallet', function (accounts) { - const [ sender, beneficiary ] = accounts; - - const amount = web3.utils.toBN(web3.utils.toWei('100')); - const duration = web3.utils.toBN(4 * 365 * 86400); // 4 years - - beforeEach(async function () { - this.start = (await time.latest()).addn(3600); // in 1 hour - this.mock = await VestingWallet.new(beneficiary, this.start, duration); - }); - - it('rejects zero address for beneficiary', async function () { - await expectRevert( - VestingWallet.new(constants.ZERO_ADDRESS, this.start, duration), - 'VestingWallet: beneficiary is zero address', - ); - }); - - it('check vesting contract', async function () { - expect(await this.mock.beneficiary()).to.be.equal(beneficiary); - expect(await this.mock.start()).to.be.bignumber.equal(this.start); - expect(await this.mock.duration()).to.be.bignumber.equal(duration); - }); - - describe('vesting schedule', function () { - beforeEach(async function () { - this.schedule = Array(64).fill().map((_, i) => web3.utils.toBN(i).mul(duration).divn(60).add(this.start)); - this.vestingFn = timestamp => min(amount, amount.mul(timestamp.sub(this.start)).div(duration)); - }); - - describe('Eth vesting', function () { - beforeEach(async function () { - await web3.eth.sendTransaction({ from: sender, to: this.mock.address, value: amount }); - this.getBalance = account => web3.eth.getBalance(account).then(web3.utils.toBN); - this.checkRelease = () => {}; - }); - - shouldBehaveLikeVesting(beneficiary); - }); - - describe('ERC20 vesting', function () { - beforeEach(async function () { - this.token = await ERC20Mock.new('Name', 'Symbol', this.mock.address, amount); - this.getBalance = (account) => this.token.balanceOf(account); - this.checkRelease = (receipt, to, value) => expectEvent.inTransaction( - receipt.tx, - this.token, - 'Transfer', - { from: this.mock.address, to, value }, - ); - }); - - shouldBehaveLikeVesting(beneficiary); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/Governor.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/Governor.test.js deleted file mode 100644 index bd10dcd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/Governor.test.js +++ /dev/null @@ -1,632 +0,0 @@ -const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; -const { fromRpcSig } = require('ethereumjs-util'); -const Enums = require('../helpers/enums'); -const { EIP712Domain } = require('../helpers/eip712'); -const { GovernorHelper } = require('../helpers/governance'); - -const { - shouldSupportInterfaces, -} = require('../utils/introspection/SupportsInterface.behavior'); - -const Token = artifacts.require('ERC20VotesMock'); -const Governor = artifacts.require('GovernorMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); -const ERC721Mock = artifacts.require('ERC721Mock'); -const ERC1155Mock = artifacts.require('ERC1155Mock'); - -contract('Governor', function (accounts) { - const [ owner, proposer, voter1, voter2, voter3, voter4 ] = accounts; - const empty = web3.utils.toChecksumAddress(web3.utils.randomHex(20)); - - const name = 'OZ-Governor'; - const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.chainId = await web3.eth.getChainId(); - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address, votingDelay, votingPeriod, 10); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - value, - }, - ], ''); - }); - - shouldSupportInterfaces([ - 'ERC165', - 'ERC1155Receiver', - 'Governor', - 'GovernorWithParams', - ]); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - expect(await this.mock.COUNTING_MODE()).to.be.equal('support=bravo&quorum=for,abstain'); - }); - - it('nominal workflow', async function () { - // Before - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(false); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(value); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal('0'); - - // Run proposal - const txPropose = await this.helper.propose({ from: proposer }); - - expectEvent( - txPropose, - 'ProposalCreated', - { - proposalId: this.proposal.id, - proposer, - targets: this.proposal.targets, - // values: this.proposal.values, - signatures: this.proposal.signatures, - calldatas: this.proposal.data, - startBlock: new BN(txPropose.receipt.blockNumber).add(votingDelay), - endBlock: new BN(txPropose.receipt.blockNumber).add(votingDelay).add(votingPeriod), - description: this.proposal.description, - }, - ); - - await this.helper.waitForSnapshot(); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For, reason: 'This is nice' }, { from: voter1 }), - 'VoteCast', - { - voter: voter1, - support: Enums.VoteType.For, - reason: 'This is nice', - weight: web3.utils.toWei('10'), - }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }), - 'VoteCast', - { - voter: voter2, - support: Enums.VoteType.For, - weight: web3.utils.toWei('7'), - }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }), - 'VoteCast', - { - voter: voter3, - support: Enums.VoteType.Against, - weight: web3.utils.toWei('5'), - }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }), - 'VoteCast', - { - voter: voter4, - support: Enums.VoteType.Abstain, - weight: web3.utils.toWei('2'), - }, - ); - - await this.helper.waitForDeadline(); - - const txExecute = await this.helper.execute(); - - expectEvent( - txExecute, - 'ProposalExecuted', - { proposalId: this.proposal.id }, - ); - - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalled', - ); - - // After - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal(value); - }); - - it('vote with signature', async function () { - const voterBySig = Wallet.generate(); - const voterBySigAddress = web3.utils.toChecksumAddress(voterBySig.getAddressString()); - - const signature = async (message) => { - return fromRpcSig(ethSigUtil.signTypedMessage( - voterBySig.getPrivateKey(), - { - data: { - types: { - EIP712Domain, - Ballot: [ - { name: 'proposalId', type: 'uint256' }, - { name: 'support', type: 'uint8' }, - ], - }, - domain: { name, version, chainId: this.chainId, verifyingContract: this.mock.address }, - primaryType: 'Ballot', - message, - }, - }, - )); - }; - - await this.token.delegate(voterBySigAddress, { from: voter1 }); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For, signature }), - 'VoteCast', - { voter: voterBySigAddress, support: Enums.VoteType.For }, - ); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - // After - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voterBySigAddress)).to.be.equal(true); - }); - - it('send ethers', async function () { - this.proposal = this.helper.setProposal([ - { - target: empty, - value, - }, - ], ''); - - // Before - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(value); - expect(await web3.eth.getBalance(empty)).to.be.bignumber.equal('0'); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - // After - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(empty)).to.be.bignumber.equal(value); - }); - - describe('should revert', function () { - describe('on propose', function () { - it('if proposal already exists', async function () { - await this.helper.propose(); - await expectRevert(this.helper.propose(), 'Governor: proposal already exists'); - }); - }); - - describe('on vote', function () { - it('if proposal does not exist', async function () { - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'Governor: unknown proposal id', - ); - }); - - it('if voting has not started', async function () { - await this.helper.propose(); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'Governor: vote not currently active', - ); - }); - - it('if support value is invalid', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await expectRevert( - this.helper.vote({ support: new BN('255') }), - 'GovernorVotingSimple: invalid value for enum VoteType', - ); - }); - - it('if vote was already casted', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'GovernorVotingSimple: vote already cast', - ); - }); - - it('if voting is over', async function () { - await this.helper.propose(); - await this.helper.waitForDeadline(); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'Governor: vote not currently active', - ); - }); - }); - - describe('on execute', function () { - it('if proposal does not exist', async function () { - await expectRevert(this.helper.execute(), 'Governor: unknown proposal id'); - }); - - it('if quorum is not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter3 }); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('if score not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter1 }); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('if voting is not over', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('if receiver revert without reason', async function () { - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - data: this.receiver.contract.methods.mockFunctionRevertsNoReason().encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await expectRevert(this.helper.execute(), 'Governor: call reverted without message'); - }); - - it('if receiver revert with reason', async function () { - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - data: this.receiver.contract.methods.mockFunctionRevertsReason().encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await expectRevert(this.helper.execute(), 'CallReceiverMock: reverting'); - }); - - it('if proposal was already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - }); - }); - - describe('state', function () { - it('Unset', async function () { - await expectRevert(this.mock.state(this.proposal.id), 'Governor: unknown proposal id'); - }); - - it('Pending & Active', async function () { - await this.helper.propose(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Pending); - await this.helper.waitForSnapshot(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Pending); - await this.helper.waitForSnapshot(+1); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - }); - - it('Defeated', async function () { - await this.helper.propose(); - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - await this.helper.waitForDeadline(+1); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Defeated); - }); - - it('Succeeded', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - await this.helper.waitForDeadline(+1); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Succeeded); - }); - - it('Executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Executed); - }); - }); - - describe('cancel', function () { - it('before proposal', async function () { - await expectRevert(this.helper.cancel(), 'Governor: unknown proposal id'); - }); - - it('after proposal', async function () { - await this.helper.propose(); - - await this.helper.cancel(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - - await this.helper.waitForSnapshot(); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'Governor: vote not currently active', - ); - }); - - it('after vote', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - - await this.helper.cancel(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - - await this.helper.waitForDeadline(); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('after deadline', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - await this.helper.cancel(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('after execution', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - await expectRevert(this.helper.cancel(), 'Governor: proposal not active'); - }); - }); - - describe('proposal length', function () { - it('empty', async function () { - this.helper.setProposal([ ], ''); - await expectRevert(this.helper.propose(), 'Governor: empty proposal'); - }); - - it('missmatch #1', async function () { - this.helper.setProposal({ - targets: [ ], - values: [ web3.utils.toWei('0') ], - data: [ this.receiver.contract.methods.mockFunction().encodeABI() ], - }, ''); - await expectRevert(this.helper.propose(), 'Governor: invalid proposal length'); - }); - - it('missmatch #2', async function () { - this.helper.setProposal({ - targets: [ this.receiver.address ], - values: [ ], - data: [ this.receiver.contract.methods.mockFunction().encodeABI() ], - }, ''); - await expectRevert(this.helper.propose(), 'Governor: invalid proposal length'); - }); - - it('missmatch #3', async function () { - this.helper.setProposal({ - targets: [ this.receiver.address ], - values: [ web3.utils.toWei('0') ], - data: [ ], - }, ''); - await expectRevert(this.helper.propose(), 'Governor: invalid proposal length'); - }); - }); - - describe('onlyGovernance updates', function () { - it('setVotingDelay is protected', async function () { - await expectRevert(this.mock.setVotingDelay('0'), 'Governor: onlyGovernance'); - }); - - it('setVotingPeriod is protected', async function () { - await expectRevert(this.mock.setVotingPeriod('32'), 'Governor: onlyGovernance'); - }); - - it('setProposalThreshold is protected', async function () { - await expectRevert(this.mock.setProposalThreshold('1000000000000000000'), 'Governor: onlyGovernance'); - }); - - it('can setVotingDelay through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setVotingDelay('0').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'VotingDelaySet', - { oldVotingDelay: '4', newVotingDelay: '0' }, - ); - - expect(await this.mock.votingDelay()).to.be.bignumber.equal('0'); - }); - - it('can setVotingPeriod through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setVotingPeriod('32').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'VotingPeriodSet', - { oldVotingPeriod: '16', newVotingPeriod: '32' }, - ); - - expect(await this.mock.votingPeriod()).to.be.bignumber.equal('32'); - }); - - it('cannot setVotingPeriod to 0 through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setVotingPeriod('0').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - await expectRevert(this.helper.execute(), 'GovernorSettings: voting period too low'); - }); - - it('can setProposalThreshold to 0 through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setProposalThreshold('1000000000000000000').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'ProposalThresholdSet', - { oldProposalThreshold: '0', newProposalThreshold: '1000000000000000000' }, - ); - - expect(await this.mock.proposalThreshold()).to.be.bignumber.equal('1000000000000000000'); - }); - }); - - describe('safe receive', function () { - describe('ERC721', function () { - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - const tokenId = new BN(1); - - beforeEach(async function () { - this.token = await ERC721Mock.new(name, symbol); - await this.token.mint(owner, tokenId); - }); - - it('can receive an ERC721 safeTransfer', async function () { - await this.token.safeTransferFrom(owner, this.mock.address, tokenId, { from: owner }); - }); - }); - - describe('ERC1155', function () { - const uri = 'https://token-cdn-domain/{id}.json'; - const tokenIds = { - 1: new BN(1000), - 2: new BN(2000), - 3: new BN(3000), - }; - - beforeEach(async function () { - this.token = await ERC1155Mock.new(uri); - await this.token.mintBatch(owner, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - - it('can receive ERC1155 safeTransfer', async function () { - await this.token.safeTransferFrom( - owner, - this.mock.address, - ...Object.entries(tokenIds)[0], // id + amount - '0x', - { from: owner }, - ); - }); - - it('can receive ERC1155 safeBatchTransfer', async function () { - await this.token.safeBatchTransferFrom( - owner, - this.mock.address, - Object.keys(tokenIds), - Object.values(tokenIds), - '0x', - { from: owner }, - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/TimelockController.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/TimelockController.test.js deleted file mode 100644 index 2274bb0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/TimelockController.test.js +++ /dev/null @@ -1,1121 +0,0 @@ -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { ZERO_BYTES32 } = constants; - -const { expect } = require('chai'); - -const { - shouldSupportInterfaces, -} = require('../utils/introspection/SupportsInterface.behavior'); - -const TimelockController = artifacts.require('TimelockController'); -const CallReceiverMock = artifacts.require('CallReceiverMock'); -const Implementation2 = artifacts.require('Implementation2'); -const ERC721Mock = artifacts.require('ERC721Mock'); -const ERC1155Mock = artifacts.require('ERC1155Mock'); - -const MINDELAY = time.duration.days(1); - -const salt = '0x025e7b0be353a74631ad648c667493c0e1cd31caa4cc2d3520fdc171ea0cc726'; // a random value - -function genOperation (target, value, data, predecessor, salt) { - const id = web3.utils.keccak256(web3.eth.abi.encodeParameters([ - 'address', - 'uint256', - 'bytes', - 'uint256', - 'bytes32', - ], [ - target, - value, - data, - predecessor, - salt, - ])); - return { id, target, value, data, predecessor, salt }; -} - -function genOperationBatch (targets, values, payloads, predecessor, salt) { - const id = web3.utils.keccak256(web3.eth.abi.encodeParameters([ - 'address[]', - 'uint256[]', - 'bytes[]', - 'uint256', - 'bytes32', - ], [ - targets, - values, - payloads, - predecessor, - salt, - ])); - return { id, targets, values, payloads, predecessor, salt }; -} - -contract('TimelockController', function (accounts) { - const [ admin, proposer, canceller, executor, other ] = accounts; - - const TIMELOCK_ADMIN_ROLE = web3.utils.soliditySha3('TIMELOCK_ADMIN_ROLE'); - const PROPOSER_ROLE = web3.utils.soliditySha3('PROPOSER_ROLE'); - const EXECUTOR_ROLE = web3.utils.soliditySha3('EXECUTOR_ROLE'); - const CANCELLER_ROLE = web3.utils.soliditySha3('CANCELLER_ROLE'); - - beforeEach(async function () { - // Deploy new timelock - this.mock = await TimelockController.new( - MINDELAY, - [ proposer ], - [ executor ], - { from: admin }, - ); - - expect(await this.mock.hasRole(CANCELLER_ROLE, proposer)).to.be.equal(true); - await this.mock.revokeRole(CANCELLER_ROLE, proposer, { from: admin }); - await this.mock.grantRole(CANCELLER_ROLE, canceller, { from: admin }); - - // Mocks - this.callreceivermock = await CallReceiverMock.new({ from: admin }); - this.implementation2 = await Implementation2.new({ from: admin }); - }); - - shouldSupportInterfaces([ - 'ERC1155Receiver', - ]); - - it('initial state', async function () { - expect(await this.mock.getMinDelay()).to.be.bignumber.equal(MINDELAY); - - expect(await this.mock.TIMELOCK_ADMIN_ROLE()).to.be.equal(TIMELOCK_ADMIN_ROLE); - expect(await this.mock.PROPOSER_ROLE()).to.be.equal(PROPOSER_ROLE); - expect(await this.mock.EXECUTOR_ROLE()).to.be.equal(EXECUTOR_ROLE); - expect(await this.mock.CANCELLER_ROLE()).to.be.equal(CANCELLER_ROLE); - - expect(await Promise.all([ PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE ].map(role => - this.mock.hasRole(role, proposer), - ))).to.be.deep.equal([ true, false, false ]); - - expect(await Promise.all([ PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE ].map(role => - this.mock.hasRole(role, canceller), - ))).to.be.deep.equal([ false, true, false ]); - - expect(await Promise.all([ PROPOSER_ROLE, CANCELLER_ROLE, EXECUTOR_ROLE ].map(role => - this.mock.hasRole(role, executor), - ))).to.be.deep.equal([ false, false, true ]); - }); - - describe('methods', function () { - describe('operation hashing', function () { - it('hashOperation', async function () { - this.operation = genOperation( - '0x29cebefe301c6ce1bb36b58654fea275e1cacc83', - '0xf94fdd6e21da21d2', - '0xa3bc5104', - '0xba41db3be0a9929145cfe480bd0f1f003689104d275ae912099f925df424ef94', - '0x60d9109846ab510ed75c15f979ae366a8a2ace11d34ba9788c13ac296db50e6e', - ); - expect(await this.mock.hashOperation( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - )).to.be.equal(this.operation.id); - }); - - it('hashOperationBatch', async function () { - this.operation = genOperationBatch( - Array(8).fill('0x2d5f21620e56531c1d59c2df9b8e95d129571f71'), - Array(8).fill('0x2b993cfce932ccee'), - Array(8).fill('0xcf51966b'), - '0xce8f45069cc71d25f71ba05062de1a3974f9849b004de64a70998bca9d29c2e7', - '0x8952d74c110f72bfe5accdf828c74d53a7dfb71235dfa8a1e8c75d8576b372ff', - ); - expect(await this.mock.hashOperationBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - )).to.be.equal(this.operation.id); - }); - }); - describe('simple', function () { - describe('schedule', function () { - beforeEach(async function () { - this.operation = genOperation( - '0x31754f590B97fD975Eb86938f18Cc304E264D2F2', - 0, - '0x3bf92ccc', - ZERO_BYTES32, - salt, - ); - }); - - it('proposer can schedule', async function () { - const receipt = await this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ); - expectEvent(receipt, 'CallScheduled', { - id: this.operation.id, - index: web3.utils.toBN(0), - target: this.operation.target, - value: web3.utils.toBN(this.operation.value), - data: this.operation.data, - predecessor: this.operation.predecessor, - delay: MINDELAY, - }); - - const block = await web3.eth.getBlock(receipt.receipt.blockHash); - - expect(await this.mock.getTimestamp(this.operation.id)) - .to.be.bignumber.equal(web3.utils.toBN(block.timestamp).add(MINDELAY)); - }); - - it('prevent overwriting active operation', async function () { - await this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ); - - await expectRevert( - this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ), - 'TimelockController: operation already scheduled', - ); - }); - - it('prevent non-proposer from committing', async function () { - await expectRevert( - this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: other }, - ), - `AccessControl: account ${other.toLowerCase()} is missing role ${PROPOSER_ROLE}`, - ); - }); - - it('enforce minimum delay', async function () { - await expectRevert( - this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY - 1, - { from: proposer }, - ), - 'TimelockController: insufficient delay', - ); - }); - }); - - describe('execute', function () { - beforeEach(async function () { - this.operation = genOperation( - '0xAe22104DCD970750610E6FE15E623468A98b15f7', - 0, - '0x13e414de', - ZERO_BYTES32, - '0xc1059ed2dc130227aa1d1d539ac94c641306905c020436c636e19e3fab56fc7f', - ); - }); - - it('revert if operation is not scheduled', async function () { - await expectRevert( - this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - describe('with scheduled operation', function () { - beforeEach(async function () { - ({ receipt: this.receipt, logs: this.logs } = await this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - )); - }); - - it('revert if execution comes too early 1/2', async function () { - await expectRevert( - this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - it('revert if execution comes too early 2/2', async function () { - const timestamp = await this.mock.getTimestamp(this.operation.id); - await time.increaseTo(timestamp - 5); // -1 is too tight, test sometime fails - - await expectRevert( - this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - describe('on time', function () { - beforeEach(async function () { - const timestamp = await this.mock.getTimestamp(this.operation.id); - await time.increaseTo(timestamp); - }); - - it('executor can reveal', async function () { - const receipt = await this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ); - expectEvent(receipt, 'CallExecuted', { - id: this.operation.id, - index: web3.utils.toBN(0), - target: this.operation.target, - value: web3.utils.toBN(this.operation.value), - data: this.operation.data, - }); - }); - - it('prevent non-executor from revealing', async function () { - await expectRevert( - this.mock.execute( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - { from: other }, - ), - `AccessControl: account ${other.toLowerCase()} is missing role ${EXECUTOR_ROLE}`, - ); - }); - }); - }); - }); - }); - - describe('batch', function () { - describe('schedule', function () { - beforeEach(async function () { - this.operation = genOperationBatch( - Array(8).fill('0xEd912250835c812D4516BBD80BdaEA1bB63a293C'), - Array(8).fill(0), - Array(8).fill('0x2fcb7a88'), - ZERO_BYTES32, - '0x6cf9d042ade5de78bed9ffd075eb4b2a4f6b1736932c2dc8af517d6e066f51f5', - ); - }); - - it('proposer can schedule', async function () { - const receipt = await this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ); - for (const i in this.operation.targets) { - expectEvent(receipt, 'CallScheduled', { - id: this.operation.id, - index: web3.utils.toBN(i), - target: this.operation.targets[i], - value: web3.utils.toBN(this.operation.values[i]), - data: this.operation.payloads[i], - predecessor: this.operation.predecessor, - delay: MINDELAY, - }); - } - - const block = await web3.eth.getBlock(receipt.receipt.blockHash); - - expect(await this.mock.getTimestamp(this.operation.id)) - .to.be.bignumber.equal(web3.utils.toBN(block.timestamp).add(MINDELAY)); - }); - - it('prevent overwriting active operation', async function () { - await this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ); - - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ), - 'TimelockController: operation already scheduled', - ); - }); - - it('length of batch parameter must match #1', async function () { - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - [], - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ), - 'TimelockController: length mismatch', - ); - }); - - it('length of batch parameter must match #1', async function () { - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - [], - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - ), - 'TimelockController: length mismatch', - ); - }); - - it('prevent non-proposer from committing', async function () { - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: other }, - ), - `AccessControl: account ${other.toLowerCase()} is missing role ${PROPOSER_ROLE}`, - ); - }); - - it('enforce minimum delay', async function () { - await expectRevert( - this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY - 1, - { from: proposer }, - ), - 'TimelockController: insufficient delay', - ); - }); - }); - - describe('execute', function () { - beforeEach(async function () { - this.operation = genOperationBatch( - Array(8).fill('0x76E53CcEb05131Ef5248553bEBDb8F70536830b1'), - Array(8).fill(0), - Array(8).fill('0x58a60f63'), - ZERO_BYTES32, - '0x9545eeabc7a7586689191f78a5532443698538e54211b5bd4d7dc0fc0102b5c7', - ); - }); - - it('revert if operation is not scheduled', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - describe('with scheduled operation', function () { - beforeEach(async function () { - ({ receipt: this.receipt, logs: this.logs } = await this.mock.scheduleBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - )); - }); - - it('revert if execution comes too early 1/2', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - it('revert if execution comes too early 2/2', async function () { - const timestamp = await this.mock.getTimestamp(this.operation.id); - await time.increaseTo(timestamp - 5); // -1 is to tight, test sometime fails - - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: operation is not ready', - ); - }); - - describe('on time', function () { - beforeEach(async function () { - const timestamp = await this.mock.getTimestamp(this.operation.id); - await time.increaseTo(timestamp); - }); - - it('executor can reveal', async function () { - const receipt = await this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ); - for (const i in this.operation.targets) { - expectEvent(receipt, 'CallExecuted', { - id: this.operation.id, - index: web3.utils.toBN(i), - target: this.operation.targets[i], - value: web3.utils.toBN(this.operation.values[i]), - data: this.operation.payloads[i], - }); - } - }); - - it('prevent non-executor from revealing', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: other }, - ), - `AccessControl: account ${other.toLowerCase()} is missing role ${EXECUTOR_ROLE}`, - ); - }); - - it('length mismatch #1', async function () { - await expectRevert( - this.mock.executeBatch( - [], - this.operation.values, - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: length mismatch', - ); - }); - - it('length mismatch #2', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - [], - this.operation.payloads, - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: length mismatch', - ); - }); - - it('length mismatch #3', async function () { - await expectRevert( - this.mock.executeBatch( - this.operation.targets, - this.operation.values, - [], - this.operation.predecessor, - this.operation.salt, - { from: executor }, - ), - 'TimelockController: length mismatch', - ); - }); - }); - }); - - it('partial execution', async function () { - const operation = genOperationBatch( - [ - this.callreceivermock.address, - this.callreceivermock.address, - this.callreceivermock.address, - ], - [ - 0, - 0, - 0, - ], - [ - this.callreceivermock.contract.methods.mockFunction().encodeABI(), - this.callreceivermock.contract.methods.mockFunctionThrows().encodeABI(), - this.callreceivermock.contract.methods.mockFunction().encodeABI(), - ], - ZERO_BYTES32, - '0x8ac04aa0d6d66b8812fb41d39638d37af0a9ab11da507afd65c509f8ed079d3e', - ); - - await this.mock.scheduleBatch( - operation.targets, - operation.values, - operation.payloads, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await expectRevert( - this.mock.executeBatch( - operation.targets, - operation.values, - operation.payloads, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - }); - }); - - describe('cancel', function () { - beforeEach(async function () { - this.operation = genOperation( - '0xC6837c44AA376dbe1d2709F13879E040CAb653ca', - 0, - '0x296e58dd', - ZERO_BYTES32, - '0xa2485763600634800df9fc9646fb2c112cf98649c55f63dd1d9c7d13a64399d9', - ); - ({ receipt: this.receipt, logs: this.logs } = await this.mock.schedule( - this.operation.target, - this.operation.value, - this.operation.data, - this.operation.predecessor, - this.operation.salt, - MINDELAY, - { from: proposer }, - )); - }); - - it('canceller can cancel', async function () { - const receipt = await this.mock.cancel(this.operation.id, { from: canceller }); - expectEvent(receipt, 'Cancelled', { id: this.operation.id }); - }); - - it('cannot cancel invalid operation', async function () { - await expectRevert( - this.mock.cancel(constants.ZERO_BYTES32, { from: canceller }), - 'TimelockController: operation cannot be cancelled', - ); - }); - - it('prevent non-canceller from canceling', async function () { - await expectRevert( - this.mock.cancel(this.operation.id, { from: other }), - `AccessControl: account ${other.toLowerCase()} is missing role ${CANCELLER_ROLE}`, - ); - }); - }); - }); - - describe('maintenance', function () { - it('prevent unauthorized maintenance', async function () { - await expectRevert( - this.mock.updateDelay(0, { from: other }), - 'TimelockController: caller must be timelock', - ); - }); - - it('timelock scheduled maintenance', async function () { - const newDelay = time.duration.hours(6); - const operation = genOperation( - this.mock.address, - 0, - this.mock.contract.methods.updateDelay(newDelay.toString()).encodeABI(), - ZERO_BYTES32, - '0xf8e775b2c5f4d66fb5c7fa800f35ef518c262b6014b3c0aee6ea21bff157f108', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - const receipt = await this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ); - expectEvent(receipt, 'MinDelayChange', { newDuration: newDelay.toString(), oldDuration: MINDELAY }); - - expect(await this.mock.getMinDelay()).to.be.bignumber.equal(newDelay); - }); - }); - - describe('dependency', function () { - beforeEach(async function () { - this.operation1 = genOperation( - '0xdE66bD4c97304200A95aE0AadA32d6d01A867E39', - 0, - '0x01dc731a', - ZERO_BYTES32, - '0x64e932133c7677402ead2926f86205e2ca4686aebecf5a8077627092b9bb2feb', - ); - this.operation2 = genOperation( - '0x3c7944a3F1ee7fc8c5A5134ba7c79D11c3A1FCa3', - 0, - '0x8f531849', - this.operation1.id, - '0x036e1311cac523f9548e6461e29fb1f8f9196b91910a41711ea22f5de48df07d', - ); - await this.mock.schedule( - this.operation1.target, - this.operation1.value, - this.operation1.data, - this.operation1.predecessor, - this.operation1.salt, - MINDELAY, - { from: proposer }, - ); - await this.mock.schedule( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - }); - - it('cannot execute before dependency', async function () { - await expectRevert( - this.mock.execute( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - { from: executor }, - ), - 'TimelockController: missing dependency', - ); - }); - - it('can execute after dependency', async function () { - await this.mock.execute( - this.operation1.target, - this.operation1.value, - this.operation1.data, - this.operation1.predecessor, - this.operation1.salt, - { from: executor }, - ); - await this.mock.execute( - this.operation2.target, - this.operation2.value, - this.operation2.data, - this.operation2.predecessor, - this.operation2.salt, - { from: executor }, - ); - }); - }); - - describe('usage scenario', function () { - this.timeout(10000); - - it('call', async function () { - const operation = genOperation( - this.implementation2.address, - 0, - this.implementation2.contract.methods.setValue(42).encodeABI(), - ZERO_BYTES32, - '0x8043596363daefc89977b25f9d9b4d06c3910959ef0c4d213557a903e1b555e2', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ); - - expect(await this.implementation2.getValue()).to.be.bignumber.equal(web3.utils.toBN(42)); - }); - - it('call reverting', async function () { - const operation = genOperation( - this.callreceivermock.address, - 0, - this.callreceivermock.contract.methods.mockFunctionRevertsNoReason().encodeABI(), - ZERO_BYTES32, - '0xb1b1b276fdf1a28d1e00537ea73b04d56639128b08063c1a2f70a52e38cba693', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - - it('call throw', async function () { - const operation = genOperation( - this.callreceivermock.address, - 0, - this.callreceivermock.contract.methods.mockFunctionThrows().encodeABI(), - ZERO_BYTES32, - '0xe5ca79f295fc8327ee8a765fe19afb58f4a0cbc5053642bfdd7e73bc68e0fc67', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - - it('call out of gas', async function () { - const operation = genOperation( - this.callreceivermock.address, - 0, - this.callreceivermock.contract.methods.mockFunctionOutOfGas().encodeABI(), - ZERO_BYTES32, - '0xf3274ce7c394c5b629d5215723563a744b817e1730cca5587c567099a14578fd', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor, gas: '70000' }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - - it('call payable with eth', async function () { - const operation = genOperation( - this.callreceivermock.address, - 1, - this.callreceivermock.contract.methods.mockFunction().encodeABI(), - ZERO_BYTES32, - '0x5ab73cd33477dcd36c1e05e28362719d0ed59a7b9ff14939de63a43073dc1f44', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - - await this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor, value: 1 }, - ); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(1)); - }); - - it('call nonpayable with eth', async function () { - const operation = genOperation( - this.callreceivermock.address, - 1, - this.callreceivermock.contract.methods.mockFunctionNonPayable().encodeABI(), - ZERO_BYTES32, - '0xb78edbd920c7867f187e5aa6294ae5a656cfbf0dea1ccdca3751b740d0f2bdf8', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - }); - - it('call reverting with eth', async function () { - const operation = genOperation( - this.callreceivermock.address, - 1, - this.callreceivermock.contract.methods.mockFunctionRevertsNoReason().encodeABI(), - ZERO_BYTES32, - '0xdedb4563ef0095db01d81d3f2decf57cf83e4a72aa792af14c43a792b56f4de6', - ); - - await this.mock.schedule( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - MINDELAY, - { from: proposer }, - ); - await time.increase(MINDELAY); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - - await expectRevert( - this.mock.execute( - operation.target, - operation.value, - operation.data, - operation.predecessor, - operation.salt, - { from: executor }, - ), - 'TimelockController: underlying transaction reverted', - ); - - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - expect(await web3.eth.getBalance(this.callreceivermock.address)).to.be.bignumber.equal(web3.utils.toBN(0)); - }); - }); - - describe('safe receive', function () { - describe('ERC721', function () { - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - const tokenId = new BN(1); - - beforeEach(async function () { - this.token = await ERC721Mock.new(name, symbol); - await this.token.mint(other, tokenId); - }); - - it('can receive an ERC721 safeTransfer', async function () { - await this.token.safeTransferFrom(other, this.mock.address, tokenId, { from: other }); - }); - }); - - describe('ERC1155', function () { - const uri = 'https://token-cdn-domain/{id}.json'; - const tokenIds = { - 1: new BN(1000), - 2: new BN(2000), - 3: new BN(3000), - }; - - beforeEach(async function () { - this.token = await ERC1155Mock.new(uri); - await this.token.mintBatch(other, Object.keys(tokenIds), Object.values(tokenIds), '0x'); - }); - - it('can receive ERC1155 safeTransfer', async function () { - await this.token.safeTransferFrom( - other, - this.mock.address, - ...Object.entries(tokenIds)[0], // id + amount - '0x', - { from: other }, - ); - }); - - it('can receive ERC1155 safeBatchTransfer', async function () { - await this.token.safeBatchTransferFrom( - other, - this.mock.address, - Object.keys(tokenIds), - Object.values(tokenIds), - '0x', - { from: other }, - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/compatibility/GovernorCompatibilityBravo.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/compatibility/GovernorCompatibilityBravo.test.js deleted file mode 100644 index 7995047..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/compatibility/GovernorCompatibilityBravo.test.js +++ /dev/null @@ -1,265 +0,0 @@ -const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const RLP = require('rlp'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesCompMock'); -const Timelock = artifacts.require('CompTimelock'); -const Governor = artifacts.require('GovernorCompatibilityBravoMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -function makeContractAddress (creator, nonce) { - return web3.utils.toChecksumAddress(web3.utils.sha3(RLP.encode([creator, nonce])).slice(12).substring(14)); -} - -contract('GovernorCompatibilityBravo', function (accounts) { - const [ owner, proposer, voter1, voter2, voter3, voter4, other ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const proposalThreshold = web3.utils.toWei('10'); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - const [ deployer ] = await web3.eth.getAccounts(); - - this.token = await Token.new(tokenName, tokenSymbol); - - // Need to predict governance address to set it as timelock admin with a delayed transfer - const nonce = await web3.eth.getTransactionCount(deployer); - const predictGovernor = makeContractAddress(deployer, nonce + 1); - - this.timelock = await Timelock.new(predictGovernor, 2 * 86400); - this.mock = await Governor.new( - name, - this.token.address, - votingDelay, - votingPeriod, - proposalThreshold, - this.timelock.address, - ); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.timelock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: proposer, value: proposalThreshold }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - signature: 'mockFunction()', - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - expect(await this.mock.quorumVotes()).to.be.bignumber.equal('0'); - expect(await this.mock.COUNTING_MODE()).to.be.equal('support=bravo&quorum=bravo'); - }); - - it('nominal workflow', async function () { - // Before - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(false); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.timelock.address)).to.be.bignumber.equal(value); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal('0'); - - // Run proposal - const txPropose = await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For, reason: 'This is nice' }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - // After - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.timelock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal(value); - - const proposal = await this.mock.proposals(this.proposal.id); - expect(proposal.id).to.be.bignumber.equal(this.proposal.id); - expect(proposal.proposer).to.be.equal(proposer); - expect(proposal.eta).to.be.bignumber.equal(await this.mock.proposalEta(this.proposal.id)); - expect(proposal.startBlock).to.be.bignumber.equal(await this.mock.proposalSnapshot(this.proposal.id)); - expect(proposal.endBlock).to.be.bignumber.equal(await this.mock.proposalDeadline(this.proposal.id)); - expect(proposal.canceled).to.be.equal(false); - expect(proposal.executed).to.be.equal(true); - - const action = await this.mock.getActions(this.proposal.id); - expect(action.targets).to.be.deep.equal(this.proposal.targets); - // expect(action.values).to.be.deep.equal(this.proposal.values); - expect(action.signatures).to.be.deep.equal(this.proposal.signatures); - expect(action.calldatas).to.be.deep.equal(this.proposal.data); - - const voteReceipt1 = await this.mock.getReceipt(this.proposal.id, voter1); - expect(voteReceipt1.hasVoted).to.be.equal(true); - expect(voteReceipt1.support).to.be.bignumber.equal(Enums.VoteType.For); - expect(voteReceipt1.votes).to.be.bignumber.equal(web3.utils.toWei('10')); - - const voteReceipt2 = await this.mock.getReceipt(this.proposal.id, voter2); - expect(voteReceipt2.hasVoted).to.be.equal(true); - expect(voteReceipt2.support).to.be.bignumber.equal(Enums.VoteType.For); - expect(voteReceipt2.votes).to.be.bignumber.equal(web3.utils.toWei('7')); - - const voteReceipt3 = await this.mock.getReceipt(this.proposal.id, voter3); - expect(voteReceipt3.hasVoted).to.be.equal(true); - expect(voteReceipt3.support).to.be.bignumber.equal(Enums.VoteType.Against); - expect(voteReceipt3.votes).to.be.bignumber.equal(web3.utils.toWei('5')); - - const voteReceipt4 = await this.mock.getReceipt(this.proposal.id, voter4); - expect(voteReceipt4.hasVoted).to.be.equal(true); - expect(voteReceipt4.support).to.be.bignumber.equal(Enums.VoteType.Abstain); - expect(voteReceipt4.votes).to.be.bignumber.equal(web3.utils.toWei('2')); - - expectEvent( - txPropose, - 'ProposalCreated', - { - proposalId: this.proposal.id, - proposer, - targets: this.proposal.targets, - // values: this.proposal.values, - signatures: this.proposal.signatures.map(() => ''), // this event doesn't contain the proposal detail - calldatas: this.proposal.fulldata, - startBlock: new BN(txPropose.receipt.blockNumber).add(votingDelay), - endBlock: new BN(txPropose.receipt.blockNumber).add(votingDelay).add(votingPeriod), - description: this.proposal.description, - }, - ); - expectEvent( - txExecute, - 'ProposalExecuted', - { proposalId: this.proposal.id }, - ); - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalled', - ); - }); - - it('double voting is forbiden', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await expectRevert( - this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'GovernorCompatibilityBravo: vote already cast', - ); - }); - - it('with function selector and arguments', async function () { - const target = this.receiver.address; - this.helper.setProposal([ - { target, data: this.receiver.contract.methods.mockFunction().encodeABI() }, - { target, data: this.receiver.contract.methods.mockFunctionWithArgs(17, 42).encodeABI() }, - { target, signature: 'mockFunctionNonPayable()' }, - { - target, - signature: 'mockFunctionWithArgs(uint256,uint256)', - data: web3.eth.abi.encodeParameters(['uint256', 'uint256'], [18, 43]), - }, - ], ''); - - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For, reason: 'This is nice' }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalled', - ); - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalled', - ); - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalledWithArgs', - { a: '17', b: '42' }, - ); - await expectEvent.inTransaction( - txExecute.tx, - this.receiver, - 'MockFunctionCalledWithArgs', - { a: '18', b: '43' }, - ); - }); - - describe('should revert', function () { - describe('on propose', function () { - it('if proposal does not meet proposalThreshold', async function () { - await expectRevert( - this.helper.propose({ from: other }), - 'Governor: proposer votes below proposal threshold', - ); - }); - }); - - describe('on vote', function () { - it('if vote type is invalide', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await expectRevert( - this.helper.vote({ support: 5 }, { from: voter1 }), - 'GovernorCompatibilityBravo: invalid vote type', - ); - }); - }); - }); - - describe('cancel', function () { - it('proposer can cancel', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.cancel({ from: proposer }); - }); - - it('anyone can cancel if proposer drop below threshold', async function () { - await this.helper.propose({ from: proposer }); - await this.token.transfer(voter1, web3.utils.toWei('1'), { from: proposer }); - await this.helper.cancel(); - }); - - it('cannot cancel is proposer is still above threshold', async function () { - await this.helper.propose({ from: proposer }); - await expectRevert(this.helper.cancel(), 'GovernorBravo: proposer above threshold'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorComp.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorComp.test.js deleted file mode 100644 index 06d2d62..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorComp.test.js +++ /dev/null @@ -1,78 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesCompMock'); -const Governor = artifacts.require('GovernorCompMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorComp', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.owner = owner; - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - }); - - it('voting with comp token', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter3)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter4)).to.be.equal(true); - - await this.mock.proposalVotes(this.proposal.id).then(results => { - expect(results.forVotes).to.be.bignumber.equal(web3.utils.toWei('17')); - expect(results.againstVotes).to.be.bignumber.equal(web3.utils.toWei('5')); - expect(results.abstainVotes).to.be.bignumber.equal(web3.utils.toWei('2')); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js deleted file mode 100644 index 086fca4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorERC721.test.js +++ /dev/null @@ -1,104 +0,0 @@ -const { BN, expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC721VotesMock'); -const Governor = artifacts.require('GovernorVoteMocks'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorERC721Mock', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockNFToken'; - const tokenSymbol = 'MTKN'; - const NFT0 = new BN(0); - const NFT1 = new BN(1); - const NFT2 = new BN(2); - const NFT3 = new BN(3); - const NFT4 = new BN(4); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.owner = owner; - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await Promise.all([ NFT0, NFT1, NFT2, NFT3, NFT4 ].map(tokenId => this.token.mint(owner, tokenId))); - await this.helper.delegate({ token: this.token, to: voter1, tokenId: NFT0 }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, tokenId: NFT1 }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, tokenId: NFT2 }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, tokenId: NFT3 }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, tokenId: NFT4 }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - }); - - it('voting with ERC721 token', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }), - 'VoteCast', - { voter: voter1, support: Enums.VoteType.For, weight: '1' }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }), - 'VoteCast', - { voter: voter2, support: Enums.VoteType.For, weight: '2' }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }), - 'VoteCast', - { voter: voter3, support: Enums.VoteType.Against, weight: '1' }, - ); - - expectEvent( - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }), - 'VoteCast', - { voter: voter4, support: Enums.VoteType.Abstain, weight: '1' }, - ); - - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter3)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter4)).to.be.equal(true); - - await this.mock.proposalVotes(this.proposal.id).then(results => { - expect(results.forVotes).to.be.bignumber.equal('3'); - expect(results.againstVotes).to.be.bignumber.equal('1'); - expect(results.abstainVotes).to.be.bignumber.equal('1'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js deleted file mode 100644 index 6a5d644..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorPreventLateQuorum.test.js +++ /dev/null @@ -1,177 +0,0 @@ -const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesCompMock'); -const Governor = artifacts.require('GovernorPreventLateQuorumMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorPreventLateQuorum', function (accounts) { - const [ owner, proposer, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const lateQuorumVoteExtension = new BN(8); - const quorum = web3.utils.toWei('1'); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.owner = owner; - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new( - name, - this.token.address, - votingDelay, - votingPeriod, - quorum, - lateQuorumVoteExtension, - ); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal(quorum); - expect(await this.mock.lateQuorumVoteExtension()).to.be.bignumber.equal(lateQuorumVoteExtension); - }); - - it('nominal workflow unaffected', async function () { - const txPropose = await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter3)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter4)).to.be.equal(true); - - await this.mock.proposalVotes(this.proposal.id).then(results => { - expect(results.forVotes).to.be.bignumber.equal(web3.utils.toWei('17')); - expect(results.againstVotes).to.be.bignumber.equal(web3.utils.toWei('5')); - expect(results.abstainVotes).to.be.bignumber.equal(web3.utils.toWei('2')); - }); - - const startBlock = new BN(txPropose.receipt.blockNumber).add(votingDelay); - const endBlock = new BN(txPropose.receipt.blockNumber).add(votingDelay).add(votingPeriod); - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(endBlock); - - expectEvent( - txPropose, - 'ProposalCreated', - { - proposalId: this.proposal.id, - proposer, - targets: this.proposal.targets, - // values: this.proposal.values.map(value => new BN(value)), - signatures: this.proposal.signatures, - calldatas: this.proposal.data, - startBlock, - endBlock, - description: this.proposal.description, - }, - ); - }); - - it('Delay is extended to prevent last minute take-over', async function () { - const txPropose = await this.helper.propose({ from: proposer }); - - // compute original schedule - const startBlock = new BN(txPropose.receipt.blockNumber).add(votingDelay); - const endBlock = new BN(txPropose.receipt.blockNumber).add(votingDelay).add(votingPeriod); - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(endBlock); - - // wait for the last minute to vote - await this.helper.waitForDeadline(-1); - const txVote = await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - - // cannot execute yet - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - - // compute new extended schedule - const extendedDeadline = new BN(txVote.receipt.blockNumber).add(lateQuorumVoteExtension); - expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock); - expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(extendedDeadline); - - // still possible to vote - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter1 }); - - await this.helper.waitForDeadline(); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active); - await this.helper.waitForDeadline(+1); - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Defeated); - - // check extension event - expectEvent( - txVote, - 'ProposalExtended', - { proposalId: this.proposal.id, extendedDeadline }, - ); - }); - - describe('onlyGovernance updates', function () { - it('setLateQuorumVoteExtension is protected', async function () { - await expectRevert( - this.mock.setLateQuorumVoteExtension(0), - 'Governor: onlyGovernance', - ); - }); - - it('can setLateQuorumVoteExtension through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.setLateQuorumVoteExtension('0').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'LateQuorumVoteExtensionSet', - { oldVoteExtension: lateQuorumVoteExtension, newVoteExtension: '0' }, - ); - - expect(await this.mock.lateQuorumVoteExtension()).to.be.bignumber.equal('0'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js deleted file mode 100644 index a31df68..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockCompound.test.js +++ /dev/null @@ -1,368 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const RLP = require('rlp'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const { - shouldSupportInterfaces, -} = require('../../utils/introspection/SupportsInterface.behavior'); - -const Token = artifacts.require('ERC20VotesMock'); -const Timelock = artifacts.require('CompTimelock'); -const Governor = artifacts.require('GovernorTimelockCompoundMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -function makeContractAddress (creator, nonce) { - return web3.utils.toChecksumAddress(web3.utils.sha3(RLP.encode([creator, nonce])).slice(12).substring(14)); -} - -contract('GovernorTimelockCompound', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4, other ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - const [ deployer ] = await web3.eth.getAccounts(); - - this.token = await Token.new(tokenName, tokenSymbol); - - // Need to predict governance address to set it as timelock admin with a delayed transfer - const nonce = await web3.eth.getTransactionCount(deployer); - const predictGovernor = makeContractAddress(deployer, nonce + 1); - - this.timelock = await Timelock.new(predictGovernor, 2 * 86400); - this.mock = await Governor.new( - name, - this.token.address, - votingDelay, - votingPeriod, - this.timelock.address, - 0, - ); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.timelock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - shouldSupportInterfaces([ - 'ERC165', - 'Governor', - 'GovernorWithParams', - 'GovernorTimelock', - ]); - - it('doesn\'t accept ether transfers', async function () { - await expectRevert.unspecified(web3.eth.sendTransaction({ from: owner, to: this.mock.address, value: 1 })); - }); - - it('post deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - - expect(await this.mock.timelock()).to.be.equal(this.timelock.address); - expect(await this.timelock.admin()).to.be.equal(this.mock.address); - }); - - it('nominal', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - const txQueue = await this.helper.queue(); - const eta = await this.mock.proposalEta(this.proposal.id); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expectEvent(txQueue, 'ProposalQueued', { proposalId: this.proposal.id }); - await expectEvent.inTransaction(txQueue.tx, this.timelock, 'QueueTransaction', { eta }); - - expectEvent(txExecute, 'ProposalExecuted', { proposalId: this.proposal.id }); - await expectEvent.inTransaction(txExecute.tx, this.timelock, 'ExecuteTransaction', { eta }); - await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalled'); - }); - - describe('should revert', function () { - describe('on queue', function () { - it('if already queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await expectRevert(this.helper.queue(), 'Governor: proposal not successful'); - }); - - it('if proposal contains duplicate calls', async function () { - const action = { - target: this.token.address, - data: this.token.contract.methods.approve(this.receiver.address, constants.MAX_UINT256).encodeABI(), - }; - this.helper.setProposal([ action, action ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await expectRevert( - this.helper.queue(), - 'GovernorTimelockCompound: identical proposal action already queued', - ); - await expectRevert( - this.helper.execute(), - 'GovernorTimelockCompound: proposal not yet queued', - ); - }); - }); - - describe('on execute', function () { - it('if not queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(+1); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Succeeded); - - await expectRevert( - this.helper.execute(), - 'GovernorTimelockCompound: proposal not yet queued', - ); - }); - - it('if too early', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Queued); - - await expectRevert( - this.helper.execute(), - 'Timelock::executeTransaction: Transaction hasn\'t surpassed time lock', - ); - }); - - it('if too late', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(+30 * 86400); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Expired); - - await expectRevert( - this.helper.execute(), - 'Governor: proposal not successful', - ); - }); - - it('if already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - await expectRevert( - this.helper.execute(), - 'Governor: proposal not successful', - ); - }); - }); - }); - - describe('cancel', function () { - it('cancel before queue prevents scheduling', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.cancel(), - 'ProposalCanceled', - { proposalId: this.proposal.id }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - await expectRevert(this.helper.queue(), 'Governor: proposal not successful'); - }); - - it('cancel after queue prevents executing', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expectEvent( - await this.helper.cancel(), - 'ProposalCanceled', - { proposalId: this.proposal.id }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - }); - - describe('onlyGovernance', function () { - describe('relay', function () { - beforeEach(async function () { - await this.token.mint(this.mock.address, 1); - }); - - it('is protected', async function () { - await expectRevert( - this.mock.relay( - this.token.address, - 0, - this.token.contract.methods.transfer(other, 1).encodeABI(), - ), - 'Governor: onlyGovernance', - ); - }); - - it('can be executed through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.relay( - this.token.address, - 0, - this.token.contract.methods.transfer(other, 1).encodeABI(), - ).encodeABI(), - }, - ], ''); - - expect(await this.token.balanceOf(this.mock.address), 1); - expect(await this.token.balanceOf(other), 0); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expect(await this.token.balanceOf(this.mock.address), 0); - expect(await this.token.balanceOf(other), 1); - - expectEvent.inTransaction( - txExecute.tx, - this.token, - 'Transfer', - { from: this.mock.address, to: other, value: '1' }, - ); - }); - }); - - describe('updateTimelock', function () { - beforeEach(async function () { - this.newTimelock = await Timelock.new(this.mock.address, 7 * 86400); - }); - - it('is protected', async function () { - await expectRevert( - this.mock.updateTimelock(this.newTimelock.address), - 'Governor: onlyGovernance', - ); - }); - - it('can be executed through governance to', async function () { - this.helper.setProposal([ - { - target: this.timelock.address, - data: this.timelock.contract.methods.setPendingAdmin(owner).encodeABI(), - }, - { - target: this.mock.address, - data: this.mock.contract.methods.updateTimelock(this.newTimelock.address).encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expectEvent( - txExecute, - 'TimelockChange', - { oldTimelock: this.timelock.address, newTimelock: this.newTimelock.address }, - ); - - expect(await this.mock.timelock()).to.be.bignumber.equal(this.newTimelock.address); - }); - }); - - it('can transfer timelock to new governor', async function () { - const newGovernor = await Governor.new(name, this.token.address, 8, 32, this.timelock.address, 0); - - this.helper.setProposal([ - { - target: this.timelock.address, - data: this.timelock.contract.methods.setPendingAdmin(newGovernor.address).encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - await expectEvent.inTransaction( - txExecute.tx, - this.timelock, - 'NewPendingAdmin', - { newPendingAdmin: newGovernor.address }, - ); - - await newGovernor.__acceptAdmin(); - expect(await this.timelock.admin()).to.be.bignumber.equal(newGovernor.address); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js deleted file mode 100644 index 45e26c9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorTimelockControl.test.js +++ /dev/null @@ -1,382 +0,0 @@ -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const { - shouldSupportInterfaces, -} = require('../../utils/introspection/SupportsInterface.behavior'); - -const Token = artifacts.require('ERC20VotesMock'); -const Timelock = artifacts.require('TimelockController'); -const Governor = artifacts.require('GovernorTimelockControlMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorTimelockControl', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4, other ] = accounts; - - const TIMELOCK_ADMIN_ROLE = web3.utils.soliditySha3('TIMELOCK_ADMIN_ROLE'); - const PROPOSER_ROLE = web3.utils.soliditySha3('PROPOSER_ROLE'); - const EXECUTOR_ROLE = web3.utils.soliditySha3('EXECUTOR_ROLE'); - const CANCELLER_ROLE = web3.utils.soliditySha3('CANCELLER_ROLE'); - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - const [ deployer ] = await web3.eth.getAccounts(); - - this.token = await Token.new(tokenName, tokenSymbol); - this.timelock = await Timelock.new(3600, [], []); - this.mock = await Governor.new( - name, - this.token.address, - votingDelay, - votingPeriod, - this.timelock.address, - 0, - ); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - this.TIMELOCK_ADMIN_ROLE = await this.timelock.TIMELOCK_ADMIN_ROLE(); - this.PROPOSER_ROLE = await this.timelock.PROPOSER_ROLE(); - this.EXECUTOR_ROLE = await this.timelock.EXECUTOR_ROLE(); - this.CANCELLER_ROLE = await this.timelock.CANCELLER_ROLE(); - - await web3.eth.sendTransaction({ from: owner, to: this.timelock.address, value }); - - // normal setup: governor is proposer, everyone is executor, timelock is its own admin - await this.timelock.grantRole(PROPOSER_ROLE, this.mock.address); - await this.timelock.grantRole(PROPOSER_ROLE, owner); - await this.timelock.grantRole(CANCELLER_ROLE, this.mock.address); - await this.timelock.grantRole(CANCELLER_ROLE, owner); - await this.timelock.grantRole(EXECUTOR_ROLE, constants.ZERO_ADDRESS); - await this.timelock.revokeRole(TIMELOCK_ADMIN_ROLE, deployer); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - this.proposal.timelockid = await this.timelock.hashOperationBatch( - ...this.proposal.shortProposal.slice(0, 3), - '0x0', - this.proposal.shortProposal[3], - ); - }); - - shouldSupportInterfaces([ - 'ERC165', - 'Governor', - 'GovernorWithParams', - 'GovernorTimelock', - ]); - - it('doesn\'t accept ether transfers', async function () { - await expectRevert.unspecified(web3.eth.sendTransaction({ from: owner, to: this.mock.address, value: 1 })); - }); - - it('post deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - - expect(await this.mock.timelock()).to.be.equal(this.timelock.address); - }); - - it('nominal', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - const txQueue = await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expectEvent(txQueue, 'ProposalQueued', { proposalId: this.proposal.id }); - await expectEvent.inTransaction(txQueue.tx, this.timelock, 'CallScheduled', { id: this.proposal.timelockid }); - - expectEvent(txExecute, 'ProposalExecuted', { proposalId: this.proposal.id }); - await expectEvent.inTransaction(txExecute.tx, this.timelock, 'CallExecuted', { id: this.proposal.timelockid }); - await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalled'); - }); - - describe('should revert', function () { - describe('on queue', function () { - it('if already queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await expectRevert(this.helper.queue(), 'Governor: proposal not successful'); - }); - }); - - describe('on execute', function () { - it('if not queued', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(+1); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Succeeded); - - await expectRevert(this.helper.execute(), 'TimelockController: operation is not ready'); - }); - - it('if too early', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Queued); - - await expectRevert(this.helper.execute(), 'TimelockController: operation is not ready'); - }); - - it('if already executed', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('if already executed by another proposer', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - - await this.timelock.executeBatch( - ...this.proposal.shortProposal.slice(0, 3), - '0x0', - this.proposal.shortProposal[3], - ); - - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - }); - }); - - describe('cancel', function () { - it('cancel before queue prevents scheduling', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.cancel(), - 'ProposalCanceled', - { proposalId: this.proposal.id }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - await expectRevert(this.helper.queue(), 'Governor: proposal not successful'); - }); - - it('cancel after queue prevents executing', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expectEvent( - await this.helper.cancel(), - 'ProposalCanceled', - { proposalId: this.proposal.id }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - it('cancel on timelock is reflected on governor', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Queued); - - expectEvent( - await this.timelock.cancel(this.proposal.timelockid, { from: owner }), - 'Cancelled', - { id: this.proposal.timelockid }, - ); - - expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Canceled); - }); - }); - - describe('onlyGovernance', function () { - describe('relay', function () { - beforeEach(async function () { - await this.token.mint(this.mock.address, 1); - }); - - it('is protected', async function () { - await expectRevert( - this.mock.relay( - this.token.address, - 0, - this.token.contract.methods.transfer(other, 1).encodeABI(), - ), - 'Governor: onlyGovernance', - ); - }); - - it('can be executed through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.relay( - this.token.address, - 0, - this.token.contract.methods.transfer(other, 1).encodeABI(), - ).encodeABI(), - }, - ], ''); - - expect(await this.token.balanceOf(this.mock.address), 1); - expect(await this.token.balanceOf(other), 0); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expect(await this.token.balanceOf(this.mock.address), 0); - expect(await this.token.balanceOf(other), 1); - - expectEvent.inTransaction( - txExecute.tx, - this.token, - 'Transfer', - { from: this.mock.address, to: other, value: '1' }, - ); - }); - - it('protected against other proposers', async function () { - await this.timelock.schedule( - this.mock.address, - web3.utils.toWei('0'), - this.mock.contract.methods.relay(constants.ZERO_ADDRESS, 0, '0x').encodeABI(), - constants.ZERO_BYTES32, - constants.ZERO_BYTES32, - 3600, - { from: owner }, - ); - - await time.increase(3600); - - await expectRevert( - this.timelock.execute( - this.mock.address, - web3.utils.toWei('0'), - this.mock.contract.methods.relay(constants.ZERO_ADDRESS, 0, '0x').encodeABI(), - constants.ZERO_BYTES32, - constants.ZERO_BYTES32, - { from: owner }, - ), - 'TimelockController: underlying transaction reverted', - ); - }); - }); - - describe('updateTimelock', function () { - beforeEach(async function () { - this.newTimelock = await Timelock.new(3600, [], []); - }); - - it('is protected', async function () { - await expectRevert( - this.mock.updateTimelock(this.newTimelock.address), - 'Governor: onlyGovernance', - ); - }); - - it('can be executed through governance to', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.updateTimelock(this.newTimelock.address).encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - const txExecute = await this.helper.execute(); - - expectEvent( - txExecute, - 'TimelockChange', - { oldTimelock: this.timelock.address, newTimelock: this.newTimelock.address }, - ); - - expect(await this.mock.timelock()).to.be.bignumber.equal(this.newTimelock.address); - }); - }); - }); - - it('clear queue of pending governor calls', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.nonGovernanceFunction().encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.queue(); - await this.helper.waitForEta(); - await this.helper.execute(); - - // This path clears _governanceCall as part of the afterExecute call, - // but we have not way to check that the cleanup actually happened other - // then coverage reports. - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorWeightQuorumFraction.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorWeightQuorumFraction.test.js deleted file mode 100644 index ea2b55e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorWeightQuorumFraction.test.js +++ /dev/null @@ -1,130 +0,0 @@ -const { BN, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const Enums = require('../../helpers/enums'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesMock'); -const Governor = artifacts.require('GovernorMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -contract('GovernorVotesQuorumFraction', function (accounts) { - const [ owner, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - // const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = new BN(web3.utils.toWei('100')); - const ratio = new BN(8); // percents - const newRatio = new BN(6); // percents - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.owner = owner; - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address, votingDelay, votingPeriod, ratio); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - expect(await this.mock.quorum(0)).to.be.bignumber.equal('0'); - expect(await this.mock.quorumNumerator()).to.be.bignumber.equal(ratio); - expect(await this.mock.quorumDenominator()).to.be.bignumber.equal('100'); - expect(await time.latestBlock().then(blockNumber => this.mock.quorum(blockNumber.subn(1)))) - .to.be.bignumber.equal(tokenSupply.mul(ratio).divn(100)); - }); - - it('quroum reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - }); - - it('quroum not reached', async function () { - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.waitForDeadline(); - await expectRevert(this.helper.execute(), 'Governor: proposal not successful'); - }); - - describe('onlyGovernance updates', function () { - it('updateQuorumNumerator is protected', async function () { - await expectRevert( - this.mock.updateQuorumNumerator(newRatio), - 'Governor: onlyGovernance', - ); - }); - - it('can updateQuorumNumerator through governance', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.updateQuorumNumerator(newRatio).encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - expectEvent( - await this.helper.execute(), - 'QuorumNumeratorUpdated', - { oldQuorumNumerator: ratio, newQuorumNumerator: newRatio }, - ); - - expect(await this.mock.quorumNumerator()).to.be.bignumber.equal(newRatio); - expect(await this.mock.quorumDenominator()).to.be.bignumber.equal('100'); - expect(await time.latestBlock().then(blockNumber => this.mock.quorum(blockNumber.subn(1)))) - .to.be.bignumber.equal(tokenSupply.mul(newRatio).divn(100)); - }); - - it('cannot updateQuorumNumerator over the maximum', async function () { - this.helper.setProposal([ - { - target: this.mock.address, - data: this.mock.contract.methods.updateQuorumNumerator('101').encodeABI(), - }, - ], ''); - - await this.helper.propose(); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 }); - await this.helper.waitForDeadline(); - - await expectRevert( - this.helper.execute(), - 'GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js deleted file mode 100644 index 875b705..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/extensions/GovernorWithParams.test.js +++ /dev/null @@ -1,166 +0,0 @@ -const { BN, expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; -const { fromRpcSig } = require('ethereumjs-util'); -const Enums = require('../../helpers/enums'); -const { EIP712Domain } = require('../../helpers/eip712'); -const { GovernorHelper } = require('../../helpers/governance'); - -const Token = artifacts.require('ERC20VotesCompMock'); -const Governor = artifacts.require('GovernorWithParamsMock'); -const CallReceiver = artifacts.require('CallReceiverMock'); - -const rawParams = { - uintParam: new BN('42'), - strParam: 'These are my params', -}; - -const encodedParams = web3.eth.abi.encodeParameters( - [ 'uint256', 'string' ], - Object.values(rawParams), -); - -contract('GovernorWithParams', function (accounts) { - const [ owner, proposer, voter1, voter2, voter3, voter4 ] = accounts; - - const name = 'OZ-Governor'; - const version = '1'; - const tokenName = 'MockToken'; - const tokenSymbol = 'MTKN'; - const tokenSupply = web3.utils.toWei('100'); - const votingDelay = new BN(4); - const votingPeriod = new BN(16); - const value = web3.utils.toWei('1'); - - beforeEach(async function () { - this.chainId = await web3.eth.getChainId(); - this.token = await Token.new(tokenName, tokenSymbol); - this.mock = await Governor.new(name, this.token.address); - this.receiver = await CallReceiver.new(); - - this.helper = new GovernorHelper(this.mock); - - await web3.eth.sendTransaction({ from: owner, to: this.mock.address, value }); - - await this.token.mint(owner, tokenSupply); - await this.helper.delegate({ token: this.token, to: voter1, value: web3.utils.toWei('10') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter2, value: web3.utils.toWei('7') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter3, value: web3.utils.toWei('5') }, { from: owner }); - await this.helper.delegate({ token: this.token, to: voter4, value: web3.utils.toWei('2') }, { from: owner }); - - // default proposal - this.proposal = this.helper.setProposal([ - { - target: this.receiver.address, - value, - data: this.receiver.contract.methods.mockFunction().encodeABI(), - }, - ], ''); - }); - - it('deployment check', async function () { - expect(await this.mock.name()).to.be.equal(name); - expect(await this.mock.token()).to.be.equal(this.token.address); - expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay); - expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod); - }); - - it('nominal is unaffected', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - await this.helper.vote({ support: Enums.VoteType.For, reason: 'This is nice' }, { from: voter1 }); - await this.helper.vote({ support: Enums.VoteType.For }, { from: voter2 }); - await this.helper.vote({ support: Enums.VoteType.Against }, { from: voter3 }); - await this.helper.vote({ support: Enums.VoteType.Abstain }, { from: voter4 }); - await this.helper.waitForDeadline(); - await this.helper.execute(); - - expect(await this.mock.hasVoted(this.proposal.id, owner)).to.be.equal(false); - expect(await this.mock.hasVoted(this.proposal.id, voter1)).to.be.equal(true); - expect(await this.mock.hasVoted(this.proposal.id, voter2)).to.be.equal(true); - expect(await web3.eth.getBalance(this.mock.address)).to.be.bignumber.equal('0'); - expect(await web3.eth.getBalance(this.receiver.address)).to.be.bignumber.equal(value); - }); - - it('Voting with params is properly supported', async function () { - await this.helper.propose({ from: proposer }); - await this.helper.waitForSnapshot(); - - const weight = new BN(web3.utils.toWei('7')).sub(rawParams.uintParam); - - const tx = await this.helper.vote({ - support: Enums.VoteType.For, - reason: 'no particular reason', - params: encodedParams, - }, { from: voter2 }); - - expectEvent(tx, 'CountParams', { ...rawParams }); - expectEvent(tx, 'VoteCastWithParams', { - voter: voter2, - proposalId: this.proposal.id, - support: Enums.VoteType.For, - weight, - reason: 'no particular reason', - params: encodedParams, - }); - - const votes = await this.mock.proposalVotes(this.proposal.id); - expect(votes.forVotes).to.be.bignumber.equal(weight); - }); - - it('Voting with params by signature is properly supported', async function () { - const voterBySig = Wallet.generate(); - const voterBySigAddress = web3.utils.toChecksumAddress(voterBySig.getAddressString()); - - const signature = async (message) => { - return fromRpcSig(ethSigUtil.signTypedMessage( - voterBySig.getPrivateKey(), - { - data: { - types: { - EIP712Domain, - ExtendedBallot: [ - { name: 'proposalId', type: 'uint256' }, - { name: 'support', type: 'uint8' }, - { name: 'reason', type: 'string' }, - { name: 'params', type: 'bytes' }, - ], - }, - domain: { name, version, chainId: this.chainId, verifyingContract: this.mock.address }, - primaryType: 'ExtendedBallot', - message, - }, - }, - )); - }; - - await this.token.delegate(voterBySigAddress, { from: voter2 }); - - // Run proposal - await this.helper.propose(); - await this.helper.waitForSnapshot(); - - const weight = new BN(web3.utils.toWei('7')).sub(rawParams.uintParam); - - const tx = await this.helper.vote({ - support: Enums.VoteType.For, - reason: 'no particular reason', - params: encodedParams, - signature, - }); - - expectEvent(tx, 'CountParams', { ...rawParams }); - expectEvent(tx, 'VoteCastWithParams', { - voter: voterBySigAddress, - proposalId: this.proposal.id, - support: Enums.VoteType.For, - weight, - reason: 'no particular reason', - params: encodedParams, - }); - - const votes = await this.mock.proposalVotes(this.proposal.id); - expect(votes.forVotes).to.be.bignumber.equal(weight); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js deleted file mode 100644 index aee227b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/utils/Votes.behavior.js +++ /dev/null @@ -1,344 +0,0 @@ -const { constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); - -const { MAX_UINT256, ZERO_ADDRESS } = constants; - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const { EIP712Domain, domainSeparator } = require('../../helpers/eip712'); - -const Delegation = [ - { name: 'delegatee', type: 'address' }, - { name: 'nonce', type: 'uint256' }, - { name: 'expiry', type: 'uint256' }, -]; - -const version = '1'; - -function shouldBehaveLikeVotes () { - describe('run votes workflow', function () { - it('initial nonce is 0', async function () { - expect(await this.votes.nonces(this.account1)).to.be.bignumber.equal('0'); - }); - - it('domain separator', async function () { - expect( - await this.votes.DOMAIN_SEPARATOR(), - ).to.equal( - await domainSeparator(this.name, version, this.chainId, this.votes.address), - ); - }); - - describe('delegation with signature', function () { - const delegator = Wallet.generate(); - const delegatorAddress = web3.utils.toChecksumAddress(delegator.getAddressString()); - const nonce = 0; - - const buildData = (chainId, verifyingContract, name, message) => ({ - data: { - primaryType: 'Delegation', - types: { EIP712Domain, Delegation }, - domain: { name, version, chainId, verifyingContract }, - message, - }, - }); - - beforeEach(async function () { - await this.votes.mint(delegatorAddress, this.NFT0); - }); - - it('accept signed delegation', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - expect(await this.votes.delegates(delegatorAddress)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.votes.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - expectEvent(receipt, 'DelegateChanged', { - delegator: delegatorAddress, - fromDelegate: ZERO_ADDRESS, - toDelegate: delegatorAddress, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: delegatorAddress, - previousBalance: '0', - newBalance: '1', - }); - - expect(await this.votes.delegates(delegatorAddress)).to.be.equal(delegatorAddress); - - expect(await this.votes.getVotes(delegatorAddress)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastVotes(delegatorAddress, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.votes.getPastVotes(delegatorAddress, receipt.blockNumber)).to.be.bignumber.equal('1'); - }); - - it('rejects reused signature', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - await this.votes.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - - await expectRevert( - this.votes.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s), - 'Votes: invalid nonce', - ); - }); - - it('rejects bad delegatee', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - const receipt = await this.votes.delegateBySig(this.account1Delegatee, nonce, MAX_UINT256, v, r, s); - const { args } = receipt.logs.find(({ event }) => event === 'DelegateChanged'); - expect(args.delegator).to.not.be.equal(delegatorAddress); - expect(args.fromDelegate).to.be.equal(ZERO_ADDRESS); - expect(args.toDelegate).to.be.equal(this.account1Delegatee); - }); - - it('rejects bad nonce', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - await expectRevert( - this.votes.delegateBySig(delegatorAddress, nonce + 1, MAX_UINT256, v, r, s), - 'Votes: invalid nonce', - ); - }); - - it('rejects expired permit', async function () { - const expiry = (await time.latest()) - time.duration.weeks(1); - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.votes.address, this.name, { - delegatee: delegatorAddress, - nonce, - expiry, - }), - )); - - await expectRevert( - this.votes.delegateBySig(delegatorAddress, nonce, expiry, v, r, s), - 'Votes: signature expired', - ); - }); - }); - - describe('set delegation', function () { - describe('call', function () { - it('delegation with tokens', async function () { - await this.votes.mint(this.account1, this.NFT0); - expect(await this.votes.delegates(this.account1)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.votes.delegate(this.account1, { from: this.account1 }); - expectEvent(receipt, 'DelegateChanged', { - delegator: this.account1, - fromDelegate: ZERO_ADDRESS, - toDelegate: this.account1, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: this.account1, - previousBalance: '0', - newBalance: '1', - }); - - expect(await this.votes.delegates(this.account1)).to.be.equal(this.account1); - - expect(await this.votes.getVotes(this.account1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastVotes(this.account1, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.votes.getPastVotes(this.account1, receipt.blockNumber)).to.be.bignumber.equal('1'); - }); - - it('delegation without tokens', async function () { - expect(await this.votes.delegates(this.account1)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.votes.delegate(this.account1, { from: this.account1 }); - expectEvent(receipt, 'DelegateChanged', { - delegator: this.account1, - fromDelegate: ZERO_ADDRESS, - toDelegate: this.account1, - }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - expect(await this.votes.delegates(this.account1)).to.be.equal(this.account1); - }); - }); - }); - - describe('change delegation', function () { - beforeEach(async function () { - await this.votes.mint(this.account1, this.NFT0); - await this.votes.delegate(this.account1, { from: this.account1 }); - }); - - it('call', async function () { - expect(await this.votes.delegates(this.account1)).to.be.equal(this.account1); - - const { receipt } = await this.votes.delegate(this.account1Delegatee, { from: this.account1 }); - expectEvent(receipt, 'DelegateChanged', { - delegator: this.account1, - fromDelegate: this.account1, - toDelegate: this.account1Delegatee, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: this.account1, - previousBalance: '1', - newBalance: '0', - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: this.account1Delegatee, - previousBalance: '0', - newBalance: '1', - }); - const prevBlock = receipt.blockNumber - 1; - expect(await this.votes.delegates(this.account1)).to.be.equal(this.account1Delegatee); - - expect(await this.votes.getVotes(this.account1)).to.be.bignumber.equal('0'); - expect(await this.votes.getVotes(this.account1Delegatee)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastVotes(this.account1, receipt.blockNumber - 1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastVotes(this.account1Delegatee, prevBlock)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.votes.getPastVotes(this.account1, receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastVotes(this.account1Delegatee, receipt.blockNumber)).to.be.bignumber.equal('1'); - }); - }); - - describe('getPastTotalSupply', function () { - beforeEach(async function () { - await this.votes.delegate(this.account1, { from: this.account1 }); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.votes.getPastTotalSupply(5e10), - 'block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.votes.getPastTotalSupply(0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const t1 = await this.votes.mint(this.account1, this.NFT0); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t2 = await this.votes.mint(this.account1, this.NFT1); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastTotalSupply(t2.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t2.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.votes.mint(this.account1, this.NFT1); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.votes.burn(this.NFT1); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.votes.mint(this.account1, this.NFT2); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.votes.burn(this.NFT2); - await time.advanceBlock(); - await time.advanceBlock(); - const t5 = await this.votes.mint(this.account1, this.NFT3); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t2.receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t2.receipt.blockNumber + 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t3.receipt.blockNumber)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t3.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t4.receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t4.receipt.blockNumber + 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastTotalSupply(t5.receipt.blockNumber)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(t5.receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - }); - }); - - // The following tests are a adaptation of - // https://github.com/compound-finance/compound-protocol/blob/master/tests/Governance/CompTest.js. - describe('Compound test suite', function () { - beforeEach(async function () { - await this.votes.mint(this.account1, this.NFT0); - await this.votes.mint(this.account1, this.NFT1); - await this.votes.mint(this.account1, this.NFT2); - await this.votes.mint(this.account1, this.NFT3); - }); - - describe('getPastVotes', function () { - it('reverts if block number >= current block', async function () { - await expectRevert( - this.votes.getPastVotes(this.account2, 5e10), - 'block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.votes.getPastVotes(this.account2, 0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const t1 = await this.votes.delegate(this.account2, { from: this.account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - const latest = await this.votes.getVotes(this.account2); - const nextBlock = t1.receipt.blockNumber + 1; - expect(await this.votes.getPastVotes(this.account2, t1.receipt.blockNumber)).to.be.bignumber.equal(latest); - expect(await this.votes.getPastVotes(this.account2, nextBlock)).to.be.bignumber.equal(latest); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.votes.delegate(this.account2, { from: this.account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastVotes(this.account2, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - }); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeVotes, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/utils/Votes.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/utils/Votes.test.js deleted file mode 100644 index 32b7d1d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/governance/utils/Votes.test.js +++ /dev/null @@ -1,61 +0,0 @@ -const { expectRevert, BN } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const { - shouldBehaveLikeVotes, -} = require('./Votes.behavior'); - -const Votes = artifacts.require('VotesMock'); - -contract('Votes', function (accounts) { - const [ account1, account2, account3 ] = accounts; - beforeEach(async function () { - this.name = 'My Vote'; - this.votes = await Votes.new(this.name); - }); - - it('starts with zero votes', async function () { - expect(await this.votes.getTotalSupply()).to.be.bignumber.equal('0'); - }); - - describe('performs voting operations', function () { - beforeEach(async function () { - this.tx1 = await this.votes.mint(account1, 1); - this.tx2 = await this.votes.mint(account2, 1); - this.tx3 = await this.votes.mint(account3, 1); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.votes.getPastTotalSupply(this.tx3.receipt.blockNumber + 1), - 'Votes: block not yet mined', - ); - }); - - it('delegates', async function () { - await this.votes.delegate(account3, account2); - - expect(await this.votes.delegates(account3)).to.be.equal(account2); - }); - - it('returns total amount of votes', async function () { - expect(await this.votes.getTotalSupply()).to.be.bignumber.equal('3'); - }); - }); - - describe('performs voting workflow', function () { - beforeEach(async function () { - this.chainId = await this.votes.getChainId(); - this.account1 = account1; - this.account2 = account2; - this.account1Delegatee = account2; - this.NFT0 = new BN('10000000000000000000000000'); - this.NFT1 = new BN('10'); - this.NFT2 = new BN('20'); - this.NFT3 = new BN('30'); - }); - - shouldBehaveLikeVotes(); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/create2.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/create2.js deleted file mode 100644 index 3e57764..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/create2.js +++ /dev/null @@ -1,12 +0,0 @@ -function computeCreate2Address (saltHex, bytecode, deployer) { - return web3.utils.toChecksumAddress(`0x${web3.utils.sha3(`0x${[ - 'ff', - deployer, - saltHex, - web3.utils.soliditySha3(bytecode), - ].map(x => x.replace(/0x/, '')).join('')}`).slice(-40)}`); -} - -module.exports = { - computeCreate2Address, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/crosschain.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/crosschain.js deleted file mode 100644 index d4d25d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/crosschain.js +++ /dev/null @@ -1,63 +0,0 @@ -const { promisify } = require('util'); - -const BridgeAMBMock = artifacts.require('BridgeAMBMock'); -const BridgeArbitrumL1Mock = artifacts.require('BridgeArbitrumL1Mock'); -const BridgeArbitrumL2Mock = artifacts.require('BridgeArbitrumL2Mock'); -const BridgeOptimismMock = artifacts.require('BridgeOptimismMock'); -const BridgePolygonChildMock = artifacts.require('BridgePolygonChildMock'); - -class BridgeHelper { - static async deploy (type) { - return new BridgeHelper(await deployBridge(type)); - } - - constructor (bridge) { - this.bridge = bridge; - this.address = bridge.address; - } - - call (from, target, selector = undefined, args = []) { - return this.bridge.relayAs( - target.address || target, - selector - ? target.contract.methods[selector](...args).encodeABI() - : '0x', - from, - ); - } -} - -async function deployBridge (type = 'Arbitrum-L2') { - switch (type) { - case 'AMB': - return BridgeAMBMock.new(); - - case 'Arbitrum-L1': - return BridgeArbitrumL1Mock.new(); - - case 'Arbitrum-L2': { - const instance = await BridgeArbitrumL2Mock.new(); - const code = await web3.eth.getCode(instance.address); - await promisify(web3.currentProvider.send.bind(web3.currentProvider))({ - jsonrpc: '2.0', - method: 'hardhat_setCode', - params: [ '0x0000000000000000000000000000000000000064', code ], - id: new Date().getTime(), - }); - return BridgeArbitrumL2Mock.at('0x0000000000000000000000000000000000000064'); - } - - case 'Optimism': - return BridgeOptimismMock.new(); - - case 'Polygon-Child': - return BridgePolygonChildMock.new(); - - default: - throw new Error(`CrossChain: ${type} is not supported`); - } -} - -module.exports = { - BridgeHelper, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/customError.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/customError.js deleted file mode 100644 index 8fea434..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/customError.js +++ /dev/null @@ -1,24 +0,0 @@ -const { config } = require('hardhat'); - -const optimizationsEnabled = config.solidity.compilers.some(c => c.settings.optimizer.enabled); - -/** Revert handler that supports custom errors. */ -async function expectRevertCustomError (promise, reason) { - try { - await promise; - expect.fail('Expected promise to throw but it didn\'t'); - } catch (revert) { - if (reason) { - if (optimizationsEnabled) { - // Optimizations currently mess with Hardhat's decoding of custom errors - expect(revert.message).to.include.oneOf([reason, 'unrecognized return data or custom error']); - } else { - expect(revert.message).to.include(reason); - } - } - } -}; - -module.exports = { - expectRevertCustomError, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/eip712.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/eip712.js deleted file mode 100644 index 8a64b8a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/eip712.js +++ /dev/null @@ -1,30 +0,0 @@ -const ethSigUtil = require('eth-sig-util'); - -const EIP712Domain = [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, -]; - -const Permit = [ - { name: 'owner', type: 'address' }, - { name: 'spender', type: 'address' }, - { name: 'value', type: 'uint256' }, - { name: 'nonce', type: 'uint256' }, - { name: 'deadline', type: 'uint256' }, -]; - -async function domainSeparator (name, version, chainId, verifyingContract) { - return '0x' + ethSigUtil.TypedDataUtils.hashStruct( - 'EIP712Domain', - { name, version, chainId, verifyingContract }, - { EIP712Domain }, - ).toString('hex'); -} - -module.exports = { - EIP712Domain, - Permit, - domainSeparator, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/enums.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/enums.js deleted file mode 100644 index 26825de..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/enums.js +++ /dev/null @@ -1,29 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -function Enum (...options) { - return Object.fromEntries(options.map((key, i) => [ key, new BN(i) ])); -} - -module.exports = { - Enum, - ProposalState: Enum( - 'Pending', - 'Active', - 'Canceled', - 'Defeated', - 'Succeeded', - 'Queued', - 'Expired', - 'Executed', - ), - VoteType: Enum( - 'Against', - 'For', - 'Abstain', - ), - Rounding: Enum( - 'Down', - 'Up', - 'Zero', - ), -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/erc1967.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/erc1967.js deleted file mode 100644 index aab0e22..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/erc1967.js +++ /dev/null @@ -1,24 +0,0 @@ -const ImplementationLabel = 'eip1967.proxy.implementation'; -const AdminLabel = 'eip1967.proxy.admin'; -const BeaconLabel = 'eip1967.proxy.beacon'; - -function labelToSlot (label) { - return '0x' + web3.utils.toBN(web3.utils.keccak256(label)).subn(1).toString(16); -} - -function getSlot (address, slot) { - return web3.eth.getStorageAt( - web3.utils.isAddress(address) ? address : address.address, - web3.utils.isHex(slot) ? slot : labelToSlot(slot), - ); -} - -module.exports = { - ImplementationLabel, - AdminLabel, - BeaconLabel, - ImplementationSlot: labelToSlot(ImplementationLabel), - AdminSlot: labelToSlot(AdminLabel), - BeaconSlot: labelToSlot(BeaconLabel), - getSlot, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/governance.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/governance.js deleted file mode 100644 index c56ec4c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/governance.js +++ /dev/null @@ -1,211 +0,0 @@ -const { time } = require('@openzeppelin/test-helpers'); - -function zip (...args) { - return Array(Math.max(...args.map(array => array.length))) - .fill() - .map((_, i) => args.map(array => array[i])); -} - -function concatHex (...args) { - return web3.utils.bytesToHex([].concat(...args.map(h => web3.utils.hexToBytes(h || '0x')))); -} - -function concatOpts (args, opts = null) { - return opts ? args.concat(opts) : args; -} - -class GovernorHelper { - constructor (governor) { - this.governor = governor; - } - - delegate (delegation = {}, opts = null) { - return Promise.all([ - delegation.token.delegate(delegation.to, { from: delegation.to }), - delegation.value && - delegation.token.transfer(...concatOpts([ delegation.to, delegation.value ]), opts), - delegation.tokenId && - delegation.token.ownerOf(delegation.tokenId).then(owner => - delegation.token.transferFrom(...concatOpts([ owner, delegation.to, delegation.tokenId ], opts)), - ), - ]); - } - - propose (opts = null) { - const proposal = this.currentProposal; - - return this.governor.methods[ - proposal.useCompatibilityInterface - ? 'propose(address[],uint256[],string[],bytes[],string)' - : 'propose(address[],uint256[],bytes[],string)' - ](...concatOpts(proposal.fullProposal, opts)); - } - - queue (opts = null) { - const proposal = this.currentProposal; - - return proposal.useCompatibilityInterface - ? this.governor.methods['queue(uint256)'](...concatOpts( - [ proposal.id ], - opts, - )) - : this.governor.methods['queue(address[],uint256[],bytes[],bytes32)'](...concatOpts( - proposal.shortProposal, - opts, - )); - } - - execute (opts = null) { - const proposal = this.currentProposal; - - return proposal.useCompatibilityInterface - ? this.governor.methods['execute(uint256)'](...concatOpts( - [ proposal.id ], - opts, - )) - : this.governor.methods['execute(address[],uint256[],bytes[],bytes32)'](...concatOpts( - proposal.shortProposal, - opts, - )); - } - - cancel (opts = null) { - const proposal = this.currentProposal; - - return proposal.useCompatibilityInterface - ? this.governor.methods['cancel(uint256)'](...concatOpts( - [ proposal.id ], - opts, - )) - : this.governor.methods['cancel(address[],uint256[],bytes[],bytes32)'](...concatOpts( - proposal.shortProposal, - opts, - )); - } - - vote (vote = {}, opts = null) { - const proposal = this.currentProposal; - - return vote.signature - // if signature, and either params or reason → - ? vote.params || vote.reason - ? vote.signature({ - proposalId: proposal.id, - support: vote.support, - reason: vote.reason || '', - params: vote.params || '', - }).then(({ v, r, s }) => this.governor.castVoteWithReasonAndParamsBySig(...concatOpts( - [ proposal.id, vote.support, vote.reason || '', vote.params || '', v, r, s ], - opts, - ))) - : vote.signature({ - proposalId: proposal.id, - support: vote.support, - }).then(({ v, r, s }) => this.governor.castVoteBySig(...concatOpts( - [ proposal.id, vote.support, v, r, s ], - opts, - ))) - : vote.params - // otherwise if params - ? this.governor.castVoteWithReasonAndParams(...concatOpts( - [ proposal.id, vote.support, vote.reason || '', vote.params ], - opts, - )) - : vote.reason - // otherwise if reason - ? this.governor.castVoteWithReason(...concatOpts( - [ proposal.id, vote.support, vote.reason ], - opts, - )) - : this.governor.castVote(...concatOpts( - [ proposal.id, vote.support ], - opts, - )); - } - - waitForSnapshot (offset = 0) { - const proposal = this.currentProposal; - return this.governor.proposalSnapshot(proposal.id) - .then(blockNumber => time.advanceBlockTo(blockNumber.addn(offset))); - } - - waitForDeadline (offset = 0) { - const proposal = this.currentProposal; - return this.governor.proposalDeadline(proposal.id) - .then(blockNumber => time.advanceBlockTo(blockNumber.addn(offset))); - } - - waitForEta (offset = 0) { - const proposal = this.currentProposal; - return this.governor.proposalEta(proposal.id) - .then(timestamp => time.increaseTo(timestamp.addn(offset))); - } - - /** - * Specify a proposal either as - * 1) an array of objects [{ target, value, data, signature? }] - * 2) an object of arrays { targets: [], values: [], data: [], signatures?: [] } - */ - setProposal (actions, description) { - let targets, values, signatures, data, useCompatibilityInterface; - - if (Array.isArray(actions)) { - useCompatibilityInterface = actions.some(a => 'signature' in a); - targets = actions.map(a => a.target); - values = actions.map(a => a.value || '0'); - signatures = actions.map(a => a.signature || ''); - data = actions.map(a => a.data || '0x'); - } else { - useCompatibilityInterface = Array.isArray(actions.signatures); - ({ targets, values, signatures = [], data } = actions); - } - - const fulldata = zip(signatures.map(s => s && web3.eth.abi.encodeFunctionSignature(s)), data) - .map(hexs => concatHex(...hexs)); - - const descriptionHash = web3.utils.keccak256(description); - - // condensed version for queueing end executing - const shortProposal = [ - targets, - values, - fulldata, - descriptionHash, - ]; - - // full version for proposing - const fullProposal = [ - targets, - values, - ...(useCompatibilityInterface ? [ signatures ] : []), - data, - description, - ]; - - // proposal id - const id = web3.utils.toBN(web3.utils.keccak256(web3.eth.abi.encodeParameters( - [ 'address[]', 'uint256[]', 'bytes[]', 'bytes32' ], - shortProposal, - ))); - - this.currentProposal = { - id, - targets, - values, - signatures, - data, - fulldata, - description, - descriptionHash, - shortProposal, - fullProposal, - useCompatibilityInterface, - }; - - return this.currentProposal; - } -} - -module.exports = { - GovernorHelper, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/sign.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/sign.js deleted file mode 100644 index 4c14d1f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/sign.js +++ /dev/null @@ -1,47 +0,0 @@ -function toEthSignedMessageHash (messageHex) { - const messageBuffer = Buffer.from(messageHex.substring(2), 'hex'); - const prefix = Buffer.from(`\u0019Ethereum Signed Message:\n${messageBuffer.length}`); - return web3.utils.sha3(Buffer.concat([prefix, messageBuffer])); -} - -/** - * Create a signer between a contract and a signer for a voucher of method, args, and redeemer - * Note that `method` is the web3 method, not the truffle-contract method - * @param contract TruffleContract - * @param signer address - * @param redeemer address - * @param methodName string - * @param methodArgs any[] - */ -const getSignFor = (contract, signer) => (redeemer, methodName, methodArgs = []) => { - const parts = [ - contract.address, - redeemer, - ]; - - const REAL_SIGNATURE_SIZE = 2 * 65; // 65 bytes in hexadecimal string length - const PADDED_SIGNATURE_SIZE = 2 * 96; // 96 bytes in hexadecimal string length - const DUMMY_SIGNATURE = `0x${web3.utils.padLeft('', REAL_SIGNATURE_SIZE)}`; - - // if we have a method, add it to the parts that we're signing - if (methodName) { - if (methodArgs.length > 0) { - parts.push( - contract.contract.methods[methodName](...methodArgs.concat([DUMMY_SIGNATURE])).encodeABI() - .slice(0, -1 * PADDED_SIGNATURE_SIZE), - ); - } else { - const abi = contract.abi.find(abi => abi.name === methodName); - parts.push(abi.signature); - } - } - - // return the signature of the "Ethereum Signed Message" hash of the hash of `parts` - const messageHex = web3.utils.soliditySha3(...parts); - return web3.eth.sign(messageHex, signer); -}; - -module.exports = { - toEthSignedMessageHash, - getSignFor, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/txpool.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/txpool.js deleted file mode 100644 index 895246b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/helpers/txpool.js +++ /dev/null @@ -1,40 +0,0 @@ -const { network } = require('hardhat'); -const { promisify } = require('util'); - -const queue = promisify(setImmediate); - -async function countPendingTransactions () { - return parseInt( - await network.provider.send('eth_getBlockTransactionCountByNumber', ['pending']), - ); -} - -async function batchInBlock (txs) { - try { - // disable auto-mining - await network.provider.send('evm_setAutomine', [false]); - // send all transactions - const promises = txs.map(fn => fn()); - // wait for node to have all pending transactions - while (txs.length > await countPendingTransactions()) { - await queue(); - } - // mine one block - await network.provider.send('evm_mine'); - // fetch receipts - const receipts = await Promise.all(promises); - // Sanity check, all tx should be in the same block - const minedBlocks = new Set(receipts.map(({ receipt }) => receipt.blockNumber)); - expect(minedBlocks.size).to.equal(1); - - return receipts; - } finally { - // enable auto-mining - await network.provider.send('evm_setAutomine', [true]); - } -} - -module.exports = { - countPendingTransactions, - batchInBlock, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js deleted file mode 100644 index 8db92ab..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/metatx/ERC2771Context.test.js +++ /dev/null @@ -1,109 +0,0 @@ -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; -const { EIP712Domain } = require('../helpers/eip712'); - -const { expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const ERC2771ContextMock = artifacts.require('ERC2771ContextMock'); -const MinimalForwarder = artifacts.require('MinimalForwarder'); -const ContextMockCaller = artifacts.require('ContextMockCaller'); - -const { shouldBehaveLikeRegularContext } = require('../utils/Context.behavior'); - -const name = 'MinimalForwarder'; -const version = '0.0.1'; - -contract('ERC2771Context', function (accounts) { - beforeEach(async function () { - this.forwarder = await MinimalForwarder.new(); - this.recipient = await ERC2771ContextMock.new(this.forwarder.address); - - this.domain = { - name, - version, - chainId: await web3.eth.getChainId(), - verifyingContract: this.forwarder.address, - }; - this.types = { - EIP712Domain, - ForwardRequest: [ - { name: 'from', type: 'address' }, - { name: 'to', type: 'address' }, - { name: 'value', type: 'uint256' }, - { name: 'gas', type: 'uint256' }, - { name: 'nonce', type: 'uint256' }, - { name: 'data', type: 'bytes' }, - ], - }; - }); - - it('recognize trusted forwarder', async function () { - expect(await this.recipient.isTrustedForwarder(this.forwarder.address)); - }); - - context('when called directly', function () { - beforeEach(async function () { - this.context = this.recipient; // The Context behavior expects the contract in this.context - this.caller = await ContextMockCaller.new(); - }); - - shouldBehaveLikeRegularContext(...accounts); - }); - - context('when receiving a relayed call', function () { - beforeEach(async function () { - this.wallet = Wallet.generate(); - this.sender = web3.utils.toChecksumAddress(this.wallet.getAddressString()); - this.data = { - types: this.types, - domain: this.domain, - primaryType: 'ForwardRequest', - }; - }); - - describe('msgSender', function () { - it('returns the relayed transaction original sender', async function () { - const data = this.recipient.contract.methods.msgSender().encodeABI(); - - const req = { - from: this.sender, - to: this.recipient.address, - value: '0', - gas: '100000', - nonce: (await this.forwarder.getNonce(this.sender)).toString(), - data, - }; - - const sign = ethSigUtil.signTypedMessage(this.wallet.getPrivateKey(), { data: { ...this.data, message: req } }); - expect(await this.forwarder.verify(req, sign)).to.equal(true); - - const { tx } = await this.forwarder.execute(req, sign); - await expectEvent.inTransaction(tx, ERC2771ContextMock, 'Sender', { sender: this.sender }); - }); - }); - - describe('msgData', function () { - it('returns the relayed transaction original data', async function () { - const integerValue = '42'; - const stringValue = 'OpenZeppelin'; - const data = this.recipient.contract.methods.msgData(integerValue, stringValue).encodeABI(); - - const req = { - from: this.sender, - to: this.recipient.address, - value: '0', - gas: '100000', - nonce: (await this.forwarder.getNonce(this.sender)).toString(), - data, - }; - - const sign = ethSigUtil.signTypedMessage(this.wallet.getPrivateKey(), { data: { ...this.data, message: req } }); - expect(await this.forwarder.verify(req, sign)).to.equal(true); - - const { tx } = await this.forwarder.execute(req, sign); - await expectEvent.inTransaction(tx, ERC2771ContextMock, 'Data', { data, integerValue, stringValue }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/metatx/MinimalForwarder.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/metatx/MinimalForwarder.test.js deleted file mode 100644 index b8984e4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/metatx/MinimalForwarder.test.js +++ /dev/null @@ -1,184 +0,0 @@ -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; -const { EIP712Domain } = require('../helpers/eip712'); - -const { expectRevert, constants } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const MinimalForwarder = artifacts.require('MinimalForwarder'); -const CallReceiverMock = artifacts.require('CallReceiverMock'); - -const name = 'MinimalForwarder'; -const version = '0.0.1'; - -contract('MinimalForwarder', function (accounts) { - beforeEach(async function () { - this.forwarder = await MinimalForwarder.new(); - this.domain = { - name, - version, - chainId: await web3.eth.getChainId(), - verifyingContract: this.forwarder.address, - }; - this.types = { - EIP712Domain, - ForwardRequest: [ - { name: 'from', type: 'address' }, - { name: 'to', type: 'address' }, - { name: 'value', type: 'uint256' }, - { name: 'gas', type: 'uint256' }, - { name: 'nonce', type: 'uint256' }, - { name: 'data', type: 'bytes' }, - ], - }; - }); - - context('with message', function () { - beforeEach(async function () { - this.wallet = Wallet.generate(); - this.sender = web3.utils.toChecksumAddress(this.wallet.getAddressString()); - this.req = { - from: this.sender, - to: constants.ZERO_ADDRESS, - value: '0', - gas: '100000', - nonce: Number(await this.forwarder.getNonce(this.sender)), - data: '0x', - }; - this.sign = () => ethSigUtil.signTypedMessage( - this.wallet.getPrivateKey(), - { - data: { - types: this.types, - domain: this.domain, - primaryType: 'ForwardRequest', - message: this.req, - }, - }, - ); - }); - - context('verify', function () { - context('valid signature', function () { - beforeEach(async function () { - expect(await this.forwarder.getNonce(this.req.from)) - .to.be.bignumber.equal(web3.utils.toBN(this.req.nonce)); - }); - - it('success', async function () { - expect(await this.forwarder.verify(this.req, this.sign())).to.be.equal(true); - }); - - afterEach(async function () { - expect(await this.forwarder.getNonce(this.req.from)) - .to.be.bignumber.equal(web3.utils.toBN(this.req.nonce)); - }); - }); - - context('invalid signature', function () { - it('tampered from', async function () { - expect(await this.forwarder.verify({ ...this.req, from: accounts[0] }, this.sign())) - .to.be.equal(false); - }); - it('tampered to', async function () { - expect(await this.forwarder.verify({ ...this.req, to: accounts[0] }, this.sign())) - .to.be.equal(false); - }); - it('tampered value', async function () { - expect(await this.forwarder.verify({ ...this.req, value: web3.utils.toWei('1') }, this.sign())) - .to.be.equal(false); - }); - it('tampered nonce', async function () { - expect(await this.forwarder.verify({ ...this.req, nonce: this.req.nonce + 1 }, this.sign())) - .to.be.equal(false); - }); - it('tampered data', async function () { - expect(await this.forwarder.verify({ ...this.req, data: '0x1742' }, this.sign())) - .to.be.equal(false); - }); - it('tampered signature', async function () { - const tamperedsign = web3.utils.hexToBytes(this.sign()); - tamperedsign[42] ^= 0xff; - expect(await this.forwarder.verify(this.req, web3.utils.bytesToHex(tamperedsign))) - .to.be.equal(false); - }); - }); - }); - - context('execute', function () { - context('valid signature', function () { - beforeEach(async function () { - expect(await this.forwarder.getNonce(this.req.from)) - .to.be.bignumber.equal(web3.utils.toBN(this.req.nonce)); - }); - - it('success', async function () { - await this.forwarder.execute(this.req, this.sign()); // expect to not revert - }); - - afterEach(async function () { - expect(await this.forwarder.getNonce(this.req.from)) - .to.be.bignumber.equal(web3.utils.toBN(this.req.nonce + 1)); - }); - }); - - context('invalid signature', function () { - it('tampered from', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, from: accounts[0] }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered to', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, to: accounts[0] }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered value', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, value: web3.utils.toWei('1') }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered nonce', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, nonce: this.req.nonce + 1 }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered data', async function () { - await expectRevert( - this.forwarder.execute({ ...this.req, data: '0x1742' }, this.sign()), - 'MinimalForwarder: signature does not match request', - ); - }); - it('tampered signature', async function () { - const tamperedsign = web3.utils.hexToBytes(this.sign()); - tamperedsign[42] ^= 0xff; - await expectRevert( - this.forwarder.execute(this.req, web3.utils.bytesToHex(tamperedsign)), - 'MinimalForwarder: signature does not match request', - ); - }); - }); - - it('bubble out of gas', async function () { - const receiver = await CallReceiverMock.new(); - const gasAvailable = 100000; - this.req.to = receiver.address; - this.req.data = receiver.contract.methods.mockFunctionOutOfGas().encodeABI(); - this.req.gas = 1000000; - - await expectRevert.assertion( - this.forwarder.execute(this.req, this.sign(), { gas: gasAvailable }), - ); - - const { transactions } = await web3.eth.getBlock('latest'); - const { gasUsed } = await web3.eth.getTransactionReceipt(transactions[0]); - - expect(gasUsed).to.be.equal(gasAvailable); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/migrate-imports.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/migrate-imports.test.js deleted file mode 100644 index 639767c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/migrate-imports.test.js +++ /dev/null @@ -1,29 +0,0 @@ -const path = require('path'); -const { promises: fs, constants: { F_OK } } = require('fs'); -const { expect } = require('chai'); - -const { pathUpdates, updateImportPaths, getUpgradeablePath } = require('../scripts/migrate-imports.js'); - -describe('migrate-imports.js', function () { - it('every new path exists', async function () { - for (const p of Object.values(pathUpdates)) { - try { - await fs.access(path.join('contracts', p), F_OK); - } catch (e) { - await fs.access(path.join('contracts', getUpgradeablePath(p)), F_OK); - } - } - }); - - it('replaces import paths in a file', async function () { - const source = ` -import '@openzeppelin/contracts/math/Math.sol'; -import '@openzeppelin/contracts-upgradeable/math/MathUpgradeable.sol'; - `; - const expected = ` -import '@openzeppelin/contracts/utils/math/Math.sol'; -import '@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol'; - `; - expect(updateImportPaths(source)).to.equal(expected); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js deleted file mode 100644 index 81c5ee3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Clones.behaviour.js +++ /dev/null @@ -1,150 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const DummyImplementation = artifacts.require('DummyImplementation'); - -module.exports = function shouldBehaveLikeClone (createClone) { - before('deploy implementation', async function () { - this.implementation = web3.utils.toChecksumAddress((await DummyImplementation.new()).address); - }); - - const assertProxyInitialization = function ({ value, balance }) { - it('initializes the proxy', async function () { - const dummy = new DummyImplementation(this.proxy); - expect(await dummy.value()).to.be.bignumber.equal(value.toString()); - }); - - it('has expected balance', async function () { - expect(await web3.eth.getBalance(this.proxy)).to.be.bignumber.equal(balance.toString()); - }); - }; - - describe('initialization without parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10; - const initializeData = new DummyImplementation('').contract.methods['initializeNonPayable()']().encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expectRevert.unspecified( - createClone(this.implementation, initializeData, { value }), - ); - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 100; - const initializeData = new DummyImplementation('').contract.methods['initializePayable()']().encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData, { value }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); - - describe('initialization with parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10; - const initializeData = new DummyImplementation('').contract - .methods.initializeNonPayableWithValue(expectedInitializedValue).encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expectRevert.unspecified( - createClone(this.implementation, initializeData, { value }), - ); - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 42; - const initializeData = new DummyImplementation('').contract - .methods.initializePayableWithValue(expectedInitializedValue).encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createClone(this.implementation, initializeData, { value }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Clones.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Clones.test.js deleted file mode 100644 index 65e5ac1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Clones.test.js +++ /dev/null @@ -1,69 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { computeCreate2Address } = require('../helpers/create2'); -const { expect } = require('chai'); - -const shouldBehaveLikeClone = require('./Clones.behaviour'); - -const ClonesMock = artifacts.require('ClonesMock'); - -contract('Clones', function (accounts) { - describe('clone', function () { - shouldBehaveLikeClone(async (implementation, initData, opts = {}) => { - const factory = await ClonesMock.new(); - const receipt = await factory.clone(implementation, initData, { value: opts.value }); - const address = receipt.logs.find(({ event }) => event === 'NewInstance').args.instance; - return { address }; - }); - }); - - describe('cloneDeterministic', function () { - shouldBehaveLikeClone(async (implementation, initData, opts = {}) => { - const salt = web3.utils.randomHex(32); - const factory = await ClonesMock.new(); - const receipt = await factory.cloneDeterministic(implementation, salt, initData, { value: opts.value }); - const address = receipt.logs.find(({ event }) => event === 'NewInstance').args.instance; - return { address }; - }); - - it('address already used', async function () { - const implementation = web3.utils.randomHex(20); - const salt = web3.utils.randomHex(32); - const factory = await ClonesMock.new(); - // deploy once - expectEvent( - await factory.cloneDeterministic(implementation, salt, '0x'), - 'NewInstance', - ); - // deploy twice - await expectRevert( - factory.cloneDeterministic(implementation, salt, '0x'), - 'ERC1167: create2 failed', - ); - }); - - it('address prediction', async function () { - const implementation = web3.utils.randomHex(20); - const salt = web3.utils.randomHex(32); - const factory = await ClonesMock.new(); - const predicted = await factory.predictDeterministicAddress(implementation, salt); - - const creationCode = [ - '0x3d602d80600a3d3981f3363d3d373d3d3d363d73', - implementation.replace(/0x/, '').toLowerCase(), - '5af43d82803e903d91602b57fd5bf3', - ].join(''); - - expect(computeCreate2Address( - salt, - creationCode, - factory.address, - )).to.be.equal(predicted); - - expectEvent( - await factory.cloneDeterministic(implementation, salt, '0x'), - 'NewInstance', - { instance: predicted }, - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js deleted file mode 100644 index 22df960..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/ERC1967/ERC1967Proxy.test.js +++ /dev/null @@ -1,13 +0,0 @@ -const shouldBehaveLikeProxy = require('../Proxy.behaviour'); - -const ERC1967Proxy = artifacts.require('ERC1967Proxy'); - -contract('ERC1967Proxy', function (accounts) { - const [proxyAdminOwner] = accounts; - - const createProxy = async function (implementation, _admin, initData, opts) { - return ERC1967Proxy.new(implementation, initData, opts); - }; - - shouldBehaveLikeProxy(createProxy, undefined, proxyAdminOwner); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js deleted file mode 100644 index 435792f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/Proxy.behaviour.js +++ /dev/null @@ -1,224 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { getSlot, ImplementationSlot } = require('../helpers/erc1967'); - -const { expect } = require('chai'); - -const DummyImplementation = artifacts.require('DummyImplementation'); - -module.exports = function shouldBehaveLikeProxy (createProxy, proxyAdminAddress, proxyCreator) { - it('cannot be initialized with a non-contract address', async function () { - const nonContractAddress = proxyCreator; - const initializeData = Buffer.from(''); - await expectRevert.unspecified( - createProxy(nonContractAddress, proxyAdminAddress, initializeData, { - from: proxyCreator, - }), - ); - }); - - before('deploy implementation', async function () { - this.implementation = web3.utils.toChecksumAddress((await DummyImplementation.new()).address); - }); - - const assertProxyInitialization = function ({ value, balance }) { - it('sets the implementation address', async function () { - const implementationSlot = await getSlot(this.proxy, ImplementationSlot); - const implementationAddress = web3.utils.toChecksumAddress(implementationSlot.substr(-40)); - expect(implementationAddress).to.be.equal(this.implementation); - }); - - it('initializes the proxy', async function () { - const dummy = new DummyImplementation(this.proxy); - expect(await dummy.value()).to.be.bignumber.equal(value.toString()); - }); - - it('has expected balance', async function () { - expect(await web3.eth.getBalance(this.proxy)).to.be.bignumber.equal(balance.toString()); - }); - }; - - describe('without initialization', function () { - const initializeData = Buffer.from(''); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ value: 0, balance: 0 }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - value, - }) - ).address; - }); - - assertProxyInitialization({ value: 0, balance: value }); - }); - }); - - describe('initialization without parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10; - const initializeData = new DummyImplementation('').contract.methods['initializeNonPayable()']().encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expectRevert.unspecified( - createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator, value }), - ); - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 100; - const initializeData = new DummyImplementation('').contract.methods['initializePayable()']().encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - value, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - }); - - describe('initialization with parameters', function () { - describe('non payable', function () { - const expectedInitializedValue = 10; - const initializeData = new DummyImplementation('').contract - .methods.initializeNonPayableWithValue(expectedInitializedValue).encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - it('reverts', async function () { - await expectRevert.unspecified( - createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator, value }), - ); - }); - }); - }); - - describe('payable', function () { - const expectedInitializedValue = 42; - const initializeData = new DummyImplementation('').contract - .methods.initializePayableWithValue(expectedInitializedValue).encodeABI(); - - describe('when not sending balance', function () { - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: 0, - }); - }); - - describe('when sending some balance', function () { - const value = 10e5; - - beforeEach('creating proxy', async function () { - this.proxy = ( - await createProxy(this.implementation, proxyAdminAddress, initializeData, { - from: proxyCreator, - value, - }) - ).address; - }); - - assertProxyInitialization({ - value: expectedInitializedValue, - balance: value, - }); - }); - }); - - describe('reverting initialization', function () { - const initializeData = new DummyImplementation('').contract - .methods.reverts().encodeABI(); - - it('reverts', async function () { - await expectRevert( - createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator }), - 'DummyImplementation reverted', - ); - }); - }); - }); -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js deleted file mode 100644 index 0a4a8d0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/beacon/BeaconProxy.test.js +++ /dev/null @@ -1,156 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { getSlot, BeaconSlot } = require('../../helpers/erc1967'); - -const { expect } = require('chai'); - -const UpgradeableBeacon = artifacts.require('UpgradeableBeacon'); -const BeaconProxy = artifacts.require('BeaconProxy'); -const DummyImplementation = artifacts.require('DummyImplementation'); -const DummyImplementationV2 = artifacts.require('DummyImplementationV2'); -const BadBeaconNoImpl = artifacts.require('BadBeaconNoImpl'); -const BadBeaconNotContract = artifacts.require('BadBeaconNotContract'); - -contract('BeaconProxy', function (accounts) { - const [anotherAccount] = accounts; - - describe('bad beacon is not accepted', async function () { - it('non-contract beacon', async function () { - await expectRevert( - BeaconProxy.new(anotherAccount, '0x'), - 'ERC1967: new beacon is not a contract', - ); - }); - - it('non-compliant beacon', async function () { - const beacon = await BadBeaconNoImpl.new(); - await expectRevert.unspecified( - BeaconProxy.new(beacon.address, '0x'), - ); - }); - - it('non-contract implementation', async function () { - const beacon = await BadBeaconNotContract.new(); - await expectRevert( - BeaconProxy.new(beacon.address, '0x'), - 'ERC1967: beacon implementation is not a contract', - ); - }); - }); - - before('deploy implementation', async function () { - this.implementationV0 = await DummyImplementation.new(); - this.implementationV1 = await DummyImplementationV2.new(); - }); - - describe('initialization', function () { - before(function () { - this.assertInitialized = async ({ value, balance }) => { - const beaconSlot = await getSlot(this.proxy, BeaconSlot); - const beaconAddress = web3.utils.toChecksumAddress(beaconSlot.substr(-40)); - expect(beaconAddress).to.equal(this.beacon.address); - - const dummy = new DummyImplementation(this.proxy.address); - expect(await dummy.value()).to.bignumber.eq(value); - - expect(await web3.eth.getBalance(this.proxy.address)).to.bignumber.eq(balance); - }; - }); - - beforeEach('deploy beacon', async function () { - this.beacon = await UpgradeableBeacon.new(this.implementationV0.address); - }); - - it('no initialization', async function () { - const data = Buffer.from(''); - const balance = '10'; - this.proxy = await BeaconProxy.new(this.beacon.address, data, { value: balance }); - await this.assertInitialized({ value: '0', balance }); - }); - - it('non-payable initialization', async function () { - const value = '55'; - const data = this.implementationV0.contract.methods - .initializeNonPayableWithValue(value) - .encodeABI(); - this.proxy = await BeaconProxy.new(this.beacon.address, data); - await this.assertInitialized({ value, balance: '0' }); - }); - - it('payable initialization', async function () { - const value = '55'; - const data = this.implementationV0.contract.methods - .initializePayableWithValue(value) - .encodeABI(); - const balance = '100'; - this.proxy = await BeaconProxy.new(this.beacon.address, data, { value: balance }); - await this.assertInitialized({ value, balance }); - }); - - it('reverting initialization', async function () { - const data = this.implementationV0.contract.methods.reverts().encodeABI(); - await expectRevert( - BeaconProxy.new(this.beacon.address, data), - 'DummyImplementation reverted', - ); - }); - }); - - it('upgrade a proxy by upgrading its beacon', async function () { - const beacon = await UpgradeableBeacon.new(this.implementationV0.address); - - const value = '10'; - const data = this.implementationV0.contract.methods - .initializeNonPayableWithValue(value) - .encodeABI(); - const proxy = await BeaconProxy.new(beacon.address, data); - - const dummy = new DummyImplementation(proxy.address); - - // test initial values - expect(await dummy.value()).to.bignumber.eq(value); - - // test initial version - expect(await dummy.version()).to.eq('V1'); - - // upgrade beacon - await beacon.upgradeTo(this.implementationV1.address); - - // test upgraded version - expect(await dummy.version()).to.eq('V2'); - }); - - it('upgrade 2 proxies by upgrading shared beacon', async function () { - const value1 = '10'; - const value2 = '42'; - - const beacon = await UpgradeableBeacon.new(this.implementationV0.address); - - const proxy1InitializeData = this.implementationV0.contract.methods - .initializeNonPayableWithValue(value1) - .encodeABI(); - const proxy1 = await BeaconProxy.new(beacon.address, proxy1InitializeData); - - const proxy2InitializeData = this.implementationV0.contract.methods - .initializeNonPayableWithValue(value2) - .encodeABI(); - const proxy2 = await BeaconProxy.new(beacon.address, proxy2InitializeData); - - const dummy1 = new DummyImplementation(proxy1.address); - const dummy2 = new DummyImplementation(proxy2.address); - - // test initial values - expect(await dummy1.value()).to.bignumber.eq(value1); - expect(await dummy2.value()).to.bignumber.eq(value2); - - // test initial version - expect(await dummy1.version()).to.eq('V1'); - expect(await dummy2.version()).to.eq('V1'); - - // upgrade beacon - await beacon.upgradeTo(this.implementationV1.address); - - // test upgraded version - expect(await dummy1.version()).to.eq('V2'); - expect(await dummy2.version()).to.eq('V2'); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js deleted file mode 100644 index 0c49906..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/beacon/UpgradeableBeacon.test.js +++ /dev/null @@ -1,50 +0,0 @@ -const { expectRevert, expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const UpgradeableBeacon = artifacts.require('UpgradeableBeacon'); -const Implementation1 = artifacts.require('Implementation1'); -const Implementation2 = artifacts.require('Implementation2'); - -contract('UpgradeableBeacon', function (accounts) { - const [owner, other] = accounts; - - it('cannot be created with non-contract implementation', async function () { - await expectRevert( - UpgradeableBeacon.new(accounts[0]), - 'UpgradeableBeacon: implementation is not a contract', - ); - }); - - context('once deployed', async function () { - beforeEach('deploying beacon', async function () { - this.v1 = await Implementation1.new(); - this.beacon = await UpgradeableBeacon.new(this.v1.address, { from: owner }); - }); - - it('returns implementation', async function () { - expect(await this.beacon.implementation()).to.equal(this.v1.address); - }); - - it('can be upgraded by the owner', async function () { - const v2 = await Implementation2.new(); - const receipt = await this.beacon.upgradeTo(v2.address, { from: owner }); - expectEvent(receipt, 'Upgraded', { implementation: v2.address }); - expect(await this.beacon.implementation()).to.equal(v2.address); - }); - - it('cannot be upgraded to a non-contract', async function () { - await expectRevert( - this.beacon.upgradeTo(other, { from: owner }), - 'UpgradeableBeacon: implementation is not a contract', - ); - }); - - it('cannot be upgraded by other account', async function () { - const v2 = await Implementation2.new(); - await expectRevert( - this.beacon.upgradeTo(v2.address, { from: other }), - 'Ownable: caller is not the owner', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js deleted file mode 100644 index 07adba6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/ProxyAdmin.test.js +++ /dev/null @@ -1,125 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ImplV1 = artifacts.require('DummyImplementation'); -const ImplV2 = artifacts.require('DummyImplementationV2'); -const ProxyAdmin = artifacts.require('ProxyAdmin'); -const TransparentUpgradeableProxy = artifacts.require('TransparentUpgradeableProxy'); - -contract('ProxyAdmin', function (accounts) { - const [proxyAdminOwner, newAdmin, anotherAccount] = accounts; - - before('set implementations', async function () { - this.implementationV1 = await ImplV1.new(); - this.implementationV2 = await ImplV2.new(); - }); - - beforeEach(async function () { - const initializeData = Buffer.from(''); - this.proxyAdmin = await ProxyAdmin.new({ from: proxyAdminOwner }); - this.proxy = await TransparentUpgradeableProxy.new( - this.implementationV1.address, - this.proxyAdmin.address, - initializeData, - { from: proxyAdminOwner }, - ); - }); - - it('has an owner', async function () { - expect(await this.proxyAdmin.owner()).to.equal(proxyAdminOwner); - }); - - describe('#getProxyAdmin', function () { - it('returns proxyAdmin as admin of the proxy', async function () { - const admin = await this.proxyAdmin.getProxyAdmin(this.proxy.address); - expect(admin).to.be.equal(this.proxyAdmin.address); - }); - - it('call to invalid proxy', async function () { - await expectRevert.unspecified(this.proxyAdmin.getProxyAdmin(this.implementationV1.address)); - }); - }); - - describe('#changeProxyAdmin', function () { - it('fails to change proxy admin if its not the proxy owner', async function () { - await expectRevert( - this.proxyAdmin.changeProxyAdmin(this.proxy.address, newAdmin, { from: anotherAccount }), - 'caller is not the owner', - ); - }); - - it('changes proxy admin', async function () { - await this.proxyAdmin.changeProxyAdmin(this.proxy.address, newAdmin, { from: proxyAdminOwner }); - expect(await this.proxy.admin.call({ from: newAdmin })).to.eq(newAdmin); - }); - }); - - describe('#getProxyImplementation', function () { - it('returns proxy implementation address', async function () { - const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address); - expect(implementationAddress).to.be.equal(this.implementationV1.address); - }); - - it('call to invalid proxy', async function () { - await expectRevert.unspecified(this.proxyAdmin.getProxyImplementation(this.implementationV1.address)); - }); - }); - - describe('#upgrade', function () { - context('with unauthorized account', function () { - it('fails to upgrade', async function () { - await expectRevert( - this.proxyAdmin.upgrade(this.proxy.address, this.implementationV2.address, { from: anotherAccount }), - 'caller is not the owner', - ); - }); - }); - - context('with authorized account', function () { - it('upgrades implementation', async function () { - await this.proxyAdmin.upgrade(this.proxy.address, this.implementationV2.address, { from: proxyAdminOwner }); - const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address); - expect(implementationAddress).to.be.equal(this.implementationV2.address); - }); - }); - }); - - describe('#upgradeAndCall', function () { - context('with unauthorized account', function () { - it('fails to upgrade', async function () { - const callData = new ImplV1('').contract.methods.initializeNonPayableWithValue(1337).encodeABI(); - await expectRevert( - this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData, - { from: anotherAccount }, - ), - 'caller is not the owner', - ); - }); - }); - - context('with authorized account', function () { - context('with invalid callData', function () { - it('fails to upgrade', async function () { - const callData = '0x12345678'; - await expectRevert.unspecified( - this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData, - { from: proxyAdminOwner }, - ), - ); - }); - }); - - context('with valid callData', function () { - it('upgrades implementation', async function () { - const callData = new ImplV1('').contract.methods.initializeNonPayableWithValue(1337).encodeABI(); - await this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData, - { from: proxyAdminOwner }, - ); - const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address); - expect(implementationAddress).to.be.equal(this.implementationV2.address); - }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js deleted file mode 100644 index 33fef6f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js +++ /dev/null @@ -1,431 +0,0 @@ -const { BN, expectRevert, expectEvent, constants } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; -const { getSlot, ImplementationSlot, AdminSlot } = require('../../helpers/erc1967'); - -const { expect } = require('chai'); - -const Proxy = artifacts.require('Proxy'); -const Implementation1 = artifacts.require('Implementation1'); -const Implementation2 = artifacts.require('Implementation2'); -const Implementation3 = artifacts.require('Implementation3'); -const Implementation4 = artifacts.require('Implementation4'); -const MigratableMockV1 = artifacts.require('MigratableMockV1'); -const MigratableMockV2 = artifacts.require('MigratableMockV2'); -const MigratableMockV3 = artifacts.require('MigratableMockV3'); -const InitializableMock = artifacts.require('InitializableMock'); -const DummyImplementation = artifacts.require('DummyImplementation'); -const ClashingImplementation = artifacts.require('ClashingImplementation'); - -module.exports = function shouldBehaveLikeTransparentUpgradeableProxy (createProxy, accounts) { - const [proxyAdminAddress, proxyAdminOwner, anotherAccount] = accounts; - - before(async function () { - this.implementationV0 = (await DummyImplementation.new()).address; - this.implementationV1 = (await DummyImplementation.new()).address; - }); - - beforeEach(async function () { - const initializeData = Buffer.from(''); - this.proxy = await createProxy(this.implementationV0, proxyAdminAddress, initializeData, { - from: proxyAdminOwner, - }); - this.proxyAddress = this.proxy.address; - }); - - describe('implementation', function () { - it('returns the current implementation address', async function () { - const implementation = await this.proxy.implementation.call({ from: proxyAdminAddress }); - - expect(implementation).to.be.equal(this.implementationV0); - }); - - it('delegates to the implementation', async function () { - const dummy = new DummyImplementation(this.proxyAddress); - const value = await dummy.get(); - - expect(value).to.equal(true); - }); - }); - - describe('upgradeTo', function () { - describe('when the sender is the admin', function () { - const from = proxyAdminAddress; - - describe('when the given implementation is different from the current one', function () { - it('upgrades to the requested implementation', async function () { - await this.proxy.upgradeTo(this.implementationV1, { from }); - - const implementation = await this.proxy.implementation.call({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.implementationV1); - }); - - it('emits an event', async function () { - expectEvent( - await this.proxy.upgradeTo(this.implementationV1, { from }), - 'Upgraded', { - implementation: this.implementationV1, - }, - ); - }); - }); - - describe('when the given implementation is the zero address', function () { - it('reverts', async function () { - await expectRevert( - this.proxy.upgradeTo(ZERO_ADDRESS, { from }), - 'ERC1967: new implementation is not a contract', - ); - }); - }); - }); - - describe('when the sender is not the admin', function () { - const from = anotherAccount; - - it('reverts', async function () { - await expectRevert.unspecified( - this.proxy.upgradeTo(this.implementationV1, { from }), - ); - }); - }); - }); - - describe('upgradeToAndCall', function () { - describe('without migrations', function () { - beforeEach(async function () { - this.behavior = await InitializableMock.new(); - }); - - describe('when the call does not fail', function () { - const initializeData = new InitializableMock('').contract.methods['initializeWithX(uint256)'](42).encodeABI(); - - describe('when the sender is the admin', function () { - const from = proxyAdminAddress; - const value = 1e5; - - beforeEach(async function () { - this.receipt = await this.proxy.upgradeToAndCall(this.behavior.address, initializeData, { from, value }); - }); - - it('upgrades to the requested implementation', async function () { - const implementation = await this.proxy.implementation.call({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.behavior.address); - }); - - it('emits an event', function () { - expectEvent(this.receipt, 'Upgraded', { implementation: this.behavior.address }); - }); - - it('calls the initializer function', async function () { - const migratable = new InitializableMock(this.proxyAddress); - const x = await migratable.x(); - expect(x).to.be.bignumber.equal('42'); - }); - - it('sends given value to the proxy', async function () { - const balance = await web3.eth.getBalance(this.proxyAddress); - expect(balance.toString()).to.be.bignumber.equal(value.toString()); - }); - - it.skip('uses the storage of the proxy', async function () { - // storage layout should look as follows: - // - 0: Initializable storage - // - 1-50: Initailizable reserved storage (50 slots) - // - 51: initializerRan - // - 52: x - const storedValue = await Proxy.at(this.proxyAddress).getStorageAt(52); - expect(parseInt(storedValue)).to.eq(42); - }); - }); - - describe('when the sender is not the admin', function () { - it('reverts', async function () { - await expectRevert.unspecified( - this.proxy.upgradeToAndCall(this.behavior.address, initializeData, { from: anotherAccount }), - ); - }); - }); - }); - - describe('when the call does fail', function () { - const initializeData = new InitializableMock('').contract.methods.fail().encodeABI(); - - it('reverts', async function () { - await expectRevert.unspecified( - this.proxy.upgradeToAndCall(this.behavior.address, initializeData, { from: proxyAdminAddress }), - ); - }); - }); - }); - - describe('with migrations', function () { - describe('when the sender is the admin', function () { - const from = proxyAdminAddress; - const value = 1e5; - - describe('when upgrading to V1', function () { - const v1MigrationData = new MigratableMockV1('').contract.methods.initialize(42).encodeABI(); - - beforeEach(async function () { - this.behaviorV1 = await MigratableMockV1.new(); - this.balancePreviousV1 = new BN(await web3.eth.getBalance(this.proxyAddress)); - this.receipt = await this.proxy.upgradeToAndCall(this.behaviorV1.address, v1MigrationData, { from, value }); - }); - - it('upgrades to the requested version and emits an event', async function () { - const implementation = await this.proxy.implementation.call({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.behaviorV1.address); - expectEvent(this.receipt, 'Upgraded', { implementation: this.behaviorV1.address }); - }); - - it('calls the \'initialize\' function and sends given value to the proxy', async function () { - const migratable = new MigratableMockV1(this.proxyAddress); - - const x = await migratable.x(); - expect(x).to.be.bignumber.equal('42'); - - const balance = await web3.eth.getBalance(this.proxyAddress); - expect(new BN(balance)).to.be.bignumber.equal(this.balancePreviousV1.addn(value)); - }); - - describe('when upgrading to V2', function () { - const v2MigrationData = new MigratableMockV2('').contract.methods.migrate(10, 42).encodeABI(); - - beforeEach(async function () { - this.behaviorV2 = await MigratableMockV2.new(); - this.balancePreviousV2 = new BN(await web3.eth.getBalance(this.proxyAddress)); - this.receipt = - await this.proxy.upgradeToAndCall(this.behaviorV2.address, v2MigrationData, { from, value }); - }); - - it('upgrades to the requested version and emits an event', async function () { - const implementation = await this.proxy.implementation.call({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.behaviorV2.address); - expectEvent(this.receipt, 'Upgraded', { implementation: this.behaviorV2.address }); - }); - - it('calls the \'migrate\' function and sends given value to the proxy', async function () { - const migratable = new MigratableMockV2(this.proxyAddress); - - const x = await migratable.x(); - expect(x).to.be.bignumber.equal('10'); - - const y = await migratable.y(); - expect(y).to.be.bignumber.equal('42'); - - const balance = new BN(await web3.eth.getBalance(this.proxyAddress)); - expect(balance).to.be.bignumber.equal(this.balancePreviousV2.addn(value)); - }); - - describe('when upgrading to V3', function () { - const v3MigrationData = new MigratableMockV3('').contract.methods['migrate()']().encodeABI(); - - beforeEach(async function () { - this.behaviorV3 = await MigratableMockV3.new(); - this.balancePreviousV3 = new BN(await web3.eth.getBalance(this.proxyAddress)); - this.receipt = - await this.proxy.upgradeToAndCall(this.behaviorV3.address, v3MigrationData, { from, value }); - }); - - it('upgrades to the requested version and emits an event', async function () { - const implementation = await this.proxy.implementation.call({ from: proxyAdminAddress }); - expect(implementation).to.be.equal(this.behaviorV3.address); - expectEvent(this.receipt, 'Upgraded', { implementation: this.behaviorV3.address }); - }); - - it('calls the \'migrate\' function and sends given value to the proxy', async function () { - const migratable = new MigratableMockV3(this.proxyAddress); - - const x = await migratable.x(); - expect(x).to.be.bignumber.equal('42'); - - const y = await migratable.y(); - expect(y).to.be.bignumber.equal('10'); - - const balance = new BN(await web3.eth.getBalance(this.proxyAddress)); - expect(balance).to.be.bignumber.equal(this.balancePreviousV3.addn(value)); - }); - }); - }); - }); - }); - - describe('when the sender is not the admin', function () { - const from = anotherAccount; - - it('reverts', async function () { - const behaviorV1 = await MigratableMockV1.new(); - const v1MigrationData = new MigratableMockV1('').contract.methods.initialize(42).encodeABI(); - await expectRevert.unspecified( - this.proxy.upgradeToAndCall(behaviorV1.address, v1MigrationData, { from }), - ); - }); - }); - }); - }); - - describe('changeAdmin', function () { - describe('when the new proposed admin is not the zero address', function () { - const newAdmin = anotherAccount; - - describe('when the sender is the admin', function () { - beforeEach('transferring', async function () { - this.receipt = await this.proxy.changeAdmin(newAdmin, { from: proxyAdminAddress }); - }); - - it('assigns new proxy admin', async function () { - const newProxyAdmin = await this.proxy.admin.call({ from: newAdmin }); - expect(newProxyAdmin).to.be.equal(anotherAccount); - }); - - it('emits an event', function () { - expectEvent(this.receipt, 'AdminChanged', { - previousAdmin: proxyAdminAddress, - newAdmin: newAdmin, - }); - }); - }); - - describe('when the sender is not the admin', function () { - it('reverts', async function () { - await expectRevert.unspecified(this.proxy.changeAdmin(newAdmin, { from: anotherAccount })); - }); - }); - }); - - describe('when the new proposed admin is the zero address', function () { - it('reverts', async function () { - await expectRevert( - this.proxy.changeAdmin(ZERO_ADDRESS, { from: proxyAdminAddress }), - 'ERC1967: new admin is the zero address', - ); - }); - }); - }); - - describe('storage', function () { - it('should store the implementation address in specified location', async function () { - const implementationSlot = await getSlot(this.proxy, ImplementationSlot); - const implementationAddress = web3.utils.toChecksumAddress(implementationSlot.substr(-40)); - expect(implementationAddress).to.be.equal(this.implementationV0); - }); - - it('should store the admin proxy in specified location', async function () { - const proxyAdminSlot = await getSlot(this.proxy, AdminSlot); - const proxyAdminAddress = web3.utils.toChecksumAddress(proxyAdminSlot.substr(-40)); - expect(proxyAdminAddress).to.be.equal(proxyAdminAddress); - }); - }); - - describe('transparent proxy', function () { - beforeEach('creating proxy', async function () { - const initializeData = Buffer.from(''); - this.impl = await ClashingImplementation.new(); - this.proxy = await createProxy(this.impl.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - this.clashing = new ClashingImplementation(this.proxy.address); - }); - - it('proxy admin cannot call delegated functions', async function () { - await expectRevert( - this.clashing.delegatedFunction({ from: proxyAdminAddress }), - 'TransparentUpgradeableProxy: admin cannot fallback to proxy target', - ); - }); - - context('when function names clash', function () { - it('when sender is proxy admin should run the proxy function', async function () { - const value = await this.proxy.admin.call({ from: proxyAdminAddress }); - expect(value).to.be.equal(proxyAdminAddress); - }); - - it('when sender is other should delegate to implementation', async function () { - const value = await this.proxy.admin.call({ from: anotherAccount }); - expect(value).to.be.equal('0x0000000000000000000000000000000011111142'); - }); - }); - }); - - describe('regression', () => { - const initializeData = Buffer.from(''); - - it('should add new function', async () => { - const instance1 = await Implementation1.new(); - const proxy = await createProxy(instance1.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const proxyInstance1 = new Implementation1(proxy.address); - await proxyInstance1.setValue(42); - - const instance2 = await Implementation2.new(); - await proxy.upgradeTo(instance2.address, { from: proxyAdminAddress }); - - const proxyInstance2 = new Implementation2(proxy.address); - const res = await proxyInstance2.getValue(); - expect(res.toString()).to.eq('42'); - }); - - it('should remove function', async () => { - const instance2 = await Implementation2.new(); - const proxy = await createProxy(instance2.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const proxyInstance2 = new Implementation2(proxy.address); - await proxyInstance2.setValue(42); - const res = await proxyInstance2.getValue(); - expect(res.toString()).to.eq('42'); - - const instance1 = await Implementation1.new(); - await proxy.upgradeTo(instance1.address, { from: proxyAdminAddress }); - - const proxyInstance1 = new Implementation2(proxy.address); - await expectRevert.unspecified(proxyInstance1.getValue()); - }); - - it('should change function signature', async () => { - const instance1 = await Implementation1.new(); - const proxy = await createProxy(instance1.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const proxyInstance1 = new Implementation1(proxy.address); - await proxyInstance1.setValue(42); - - const instance3 = await Implementation3.new(); - await proxy.upgradeTo(instance3.address, { from: proxyAdminAddress }); - const proxyInstance3 = new Implementation3(proxy.address); - - const res = await proxyInstance3.getValue(8); - expect(res.toString()).to.eq('50'); - }); - - it('should add fallback function', async () => { - const initializeData = Buffer.from(''); - const instance1 = await Implementation1.new(); - const proxy = await createProxy(instance1.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const instance4 = await Implementation4.new(); - await proxy.upgradeTo(instance4.address, { from: proxyAdminAddress }); - const proxyInstance4 = new Implementation4(proxy.address); - - const data = '0x'; - await web3.eth.sendTransaction({ to: proxy.address, from: anotherAccount, data }); - - const res = await proxyInstance4.getValue(); - expect(res.toString()).to.eq('1'); - }); - - it('should remove fallback function', async () => { - const instance4 = await Implementation4.new(); - const proxy = await createProxy(instance4.address, proxyAdminAddress, initializeData, { from: proxyAdminOwner }); - - const instance2 = await Implementation2.new(); - await proxy.upgradeTo(instance2.address, { from: proxyAdminAddress }); - - const data = '0x'; - await expectRevert.unspecified( - web3.eth.sendTransaction({ to: proxy.address, from: anotherAccount, data }), - ); - - const proxyInstance2 = new Implementation2(proxy.address); - const res = await proxyInstance2.getValue(); - expect(res.toString()).to.eq('0'); - }); - }); -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js deleted file mode 100644 index 86dd55d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/transparent/TransparentUpgradeableProxy.test.js +++ /dev/null @@ -1,15 +0,0 @@ -const shouldBehaveLikeProxy = require('../Proxy.behaviour'); -const shouldBehaveLikeTransparentUpgradeableProxy = require('./TransparentUpgradeableProxy.behaviour'); - -const TransparentUpgradeableProxy = artifacts.require('TransparentUpgradeableProxy'); - -contract('TransparentUpgradeableProxy', function (accounts) { - const [proxyAdminAddress, proxyAdminOwner] = accounts; - - const createProxy = async function (logic, admin, initData, opts) { - return TransparentUpgradeableProxy.new(logic, admin, initData, opts); - }; - - shouldBehaveLikeProxy(createProxy, proxyAdminAddress, proxyAdminOwner); - shouldBehaveLikeTransparentUpgradeableProxy(createProxy, accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js deleted file mode 100644 index 664bd89..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/utils/Initializable.test.js +++ /dev/null @@ -1,203 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const InitializableMock = artifacts.require('InitializableMock'); -const ConstructorInitializableMock = artifacts.require('ConstructorInitializableMock'); -const ChildConstructorInitializableMock = artifacts.require('ChildConstructorInitializableMock'); -const ReinitializerMock = artifacts.require('ReinitializerMock'); -const SampleChild = artifacts.require('SampleChild'); -const DisableBad1 = artifacts.require('DisableBad1'); -const DisableBad2 = artifacts.require('DisableBad2'); -const DisableOk = artifacts.require('DisableOk'); - -contract('Initializable', function (accounts) { - describe('basic testing without inheritance', function () { - beforeEach('deploying', async function () { - this.contract = await InitializableMock.new(); - }); - - describe('before initialize', function () { - it('initializer has not run', async function () { - expect(await this.contract.initializerRan()).to.equal(false); - }); - }); - - describe('after initialize', function () { - beforeEach('initializing', async function () { - await this.contract.initialize(); - }); - - it('initializer has run', async function () { - expect(await this.contract.initializerRan()).to.equal(true); - }); - - it('initializer does not run again', async function () { - await expectRevert(this.contract.initialize(), 'Initializable: contract is already initialized'); - }); - }); - - describe('nested under an initializer', function () { - it('initializer modifier reverts', async function () { - await expectRevert(this.contract.initializerNested(), 'Initializable: contract is already initialized'); - }); - - it('onlyInitializing modifier succeeds', async function () { - await this.contract.onlyInitializingNested(); - expect(await this.contract.onlyInitializingRan()).to.equal(true); - }); - }); - - it('cannot call onlyInitializable function outside the scope of an initializable function', async function () { - await expectRevert(this.contract.initializeOnlyInitializing(), 'Initializable: contract is not initializing'); - }); - }); - - it('nested initializer can run during construction', async function () { - const contract2 = await ConstructorInitializableMock.new(); - expect(await contract2.initializerRan()).to.equal(true); - expect(await contract2.onlyInitializingRan()).to.equal(true); - }); - - it('multiple constructor levels can be initializers', async function () { - const contract2 = await ChildConstructorInitializableMock.new(); - expect(await contract2.initializerRan()).to.equal(true); - expect(await contract2.childInitializerRan()).to.equal(true); - expect(await contract2.onlyInitializingRan()).to.equal(true); - }); - - describe('reinitialization', function () { - beforeEach('deploying', async function () { - this.contract = await ReinitializerMock.new(); - }); - - it('can reinitialize', async function () { - expect(await this.contract.counter()).to.be.bignumber.equal('0'); - await this.contract.initialize(); - expect(await this.contract.counter()).to.be.bignumber.equal('1'); - await this.contract.reinitialize(2); - expect(await this.contract.counter()).to.be.bignumber.equal('2'); - await this.contract.reinitialize(3); - expect(await this.contract.counter()).to.be.bignumber.equal('3'); - }); - - it('can jump multiple steps', async function () { - expect(await this.contract.counter()).to.be.bignumber.equal('0'); - await this.contract.initialize(); - expect(await this.contract.counter()).to.be.bignumber.equal('1'); - await this.contract.reinitialize(128); - expect(await this.contract.counter()).to.be.bignumber.equal('2'); - }); - - it('cannot nest reinitializers', async function () { - expect(await this.contract.counter()).to.be.bignumber.equal('0'); - await expectRevert(this.contract.nestedReinitialize(2, 2), 'Initializable: contract is already initialized'); - await expectRevert(this.contract.nestedReinitialize(2, 3), 'Initializable: contract is already initialized'); - await expectRevert(this.contract.nestedReinitialize(3, 2), 'Initializable: contract is already initialized'); - }); - - it('can chain reinitializers', async function () { - expect(await this.contract.counter()).to.be.bignumber.equal('0'); - await this.contract.chainReinitialize(2, 3); - expect(await this.contract.counter()).to.be.bignumber.equal('2'); - }); - - describe('contract locking', function () { - it('prevents initialization', async function () { - await this.contract.disableInitializers(); - await expectRevert(this.contract.initialize(), 'Initializable: contract is already initialized'); - }); - - it('prevents re-initialization', async function () { - await this.contract.disableInitializers(); - await expectRevert(this.contract.reinitialize(255), 'Initializable: contract is already initialized'); - }); - - it('can lock contract after initialization', async function () { - await this.contract.initialize(); - await this.contract.disableInitializers(); - await expectRevert(this.contract.reinitialize(255), 'Initializable: contract is already initialized'); - }); - }); - }); - - describe('events', function () { - it('constructor initialization emits event', async function () { - const contract = await ConstructorInitializableMock.new(); - - await expectEvent.inTransaction(contract.transactionHash, contract, 'Initialized', { version: '1' }); - }); - - it('initialization emits event', async function () { - const contract = await ReinitializerMock.new(); - - const { receipt } = await contract.initialize(); - expect(receipt.logs.filter(({ event }) => event === 'Initialized').length).to.be.equal(1); - expectEvent(receipt, 'Initialized', { version: '1' }); - }); - - it('reinitialization emits event', async function () { - const contract = await ReinitializerMock.new(); - - const { receipt } = await contract.reinitialize(128); - expect(receipt.logs.filter(({ event }) => event === 'Initialized').length).to.be.equal(1); - expectEvent(receipt, 'Initialized', { version: '128' }); - }); - - it('chained reinitialization emits multiple events', async function () { - const contract = await ReinitializerMock.new(); - - const { receipt } = await contract.chainReinitialize(2, 3); - expect(receipt.logs.filter(({ event }) => event === 'Initialized').length).to.be.equal(2); - expectEvent(receipt, 'Initialized', { version: '2' }); - expectEvent(receipt, 'Initialized', { version: '3' }); - }); - }); - - describe('complex testing with inheritance', function () { - const mother = '12'; - const gramps = '56'; - const father = '34'; - const child = '78'; - - beforeEach('deploying', async function () { - this.contract = await SampleChild.new(); - }); - - beforeEach('initializing', async function () { - await this.contract.initialize(mother, gramps, father, child); - }); - - it('initializes human', async function () { - expect(await this.contract.isHuman()).to.be.equal(true); - }); - - it('initializes mother', async function () { - expect(await this.contract.mother()).to.be.bignumber.equal(mother); - }); - - it('initializes gramps', async function () { - expect(await this.contract.gramps()).to.be.bignumber.equal(gramps); - }); - - it('initializes father', async function () { - expect(await this.contract.father()).to.be.bignumber.equal(father); - }); - - it('initializes child', async function () { - expect(await this.contract.child()).to.be.bignumber.equal(child); - }); - }); - - describe('disabling initialization', function () { - it('old and new patterns in bad sequence', async function () { - await expectRevert(DisableBad1.new(), 'Initializable: contract is already initialized'); - await expectRevert(DisableBad2.new(), 'Initializable: contract is initializing'); - }); - - it('old and new patterns in good sequence', async function () { - const ok = await DisableOk.new(); - await expectEvent.inConstruction(ok, 'Initialized', { version: '1' }); - await expectEvent.inConstruction(ok, 'Initialized', { version: '255' }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js deleted file mode 100644 index 466081d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/proxy/utils/UUPSUpgradeable.test.js +++ /dev/null @@ -1,85 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { web3 } = require('@openzeppelin/test-helpers/src/setup'); -const { getSlot, ImplementationSlot } = require('../../helpers/erc1967'); - -const ERC1967Proxy = artifacts.require('ERC1967Proxy'); -const UUPSUpgradeableMock = artifacts.require('UUPSUpgradeableMock'); -const UUPSUpgradeableUnsafeMock = artifacts.require('UUPSUpgradeableUnsafeMock'); -const UUPSUpgradeableLegacyMock = artifacts.require('UUPSUpgradeableLegacyMock'); -const CountersImpl = artifacts.require('CountersImpl'); - -contract('UUPSUpgradeable', function (accounts) { - before(async function () { - this.implInitial = await UUPSUpgradeableMock.new(); - this.implUpgradeOk = await UUPSUpgradeableMock.new(); - this.implUpgradeUnsafe = await UUPSUpgradeableUnsafeMock.new(); - this.implUpgradeNonUUPS = await CountersImpl.new(); - }); - - beforeEach(async function () { - const { address } = await ERC1967Proxy.new(this.implInitial.address, '0x'); - this.instance = await UUPSUpgradeableMock.at(address); - }); - - it('upgrade to upgradeable implementation', async function () { - const { receipt } = await this.instance.upgradeTo(this.implUpgradeOk.address); - expect(receipt.logs.filter(({ event }) => event === 'Upgraded').length).to.be.equal(1); - expectEvent(receipt, 'Upgraded', { implementation: this.implUpgradeOk.address }); - }); - - it('upgrade to upgradeable implementation with call', async function () { - expect(await this.instance.current()).to.be.bignumber.equal('0'); - - const { receipt } = await this.instance.upgradeToAndCall( - this.implUpgradeOk.address, - this.implUpgradeOk.contract.methods.increment().encodeABI(), - ); - expect(receipt.logs.filter(({ event }) => event === 'Upgraded').length).to.be.equal(1); - expectEvent(receipt, 'Upgraded', { implementation: this.implUpgradeOk.address }); - - expect(await this.instance.current()).to.be.bignumber.equal('1'); - }); - - it('upgrade to and unsafe upgradeable implementation', async function () { - const { receipt } = await this.instance.upgradeTo(this.implUpgradeUnsafe.address); - expectEvent(receipt, 'Upgraded', { implementation: this.implUpgradeUnsafe.address }); - }); - - // delegate to a non existing upgradeTo function causes a low level revert - it('reject upgrade to non uups implementation', async function () { - await expectRevert( - this.instance.upgradeTo(this.implUpgradeNonUUPS.address), - 'ERC1967Upgrade: new implementation is not UUPS', - ); - }); - - it('reject proxy address as implementation', async function () { - const { address } = await ERC1967Proxy.new(this.implInitial.address, '0x'); - const otherInstance = await UUPSUpgradeableMock.at(address); - - await expectRevert( - this.instance.upgradeTo(otherInstance.address), - 'ERC1967Upgrade: new implementation is not UUPS', - ); - }); - - it('can upgrade from legacy implementations', async function () { - const legacyImpl = await UUPSUpgradeableLegacyMock.new(); - const legacyInstance = await ERC1967Proxy.new(legacyImpl.address, '0x') - .then(({ address }) => UUPSUpgradeableLegacyMock.at(address)); - - const receipt = await legacyInstance.upgradeTo(this.implInitial.address); - - const UpgradedEvents = receipt.logs.filter(({ address, event }) => - address === legacyInstance.address && - event === 'Upgraded', - ); - expect(UpgradedEvents.length).to.be.equal(1); - - expectEvent(receipt, 'Upgraded', { implementation: this.implInitial.address }); - - const implementationSlot = await getSlot(legacyInstance, ImplementationSlot); - const implementationAddress = web3.utils.toChecksumAddress(implementationSlot.substr(-40)); - expect(implementationAddress).to.be.equal(this.implInitial.address); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/security/Pausable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/security/Pausable.test.js deleted file mode 100644 index 86701bc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/security/Pausable.test.js +++ /dev/null @@ -1,89 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const PausableMock = artifacts.require('PausableMock'); - -contract('Pausable', function (accounts) { - const [ pauser ] = accounts; - - beforeEach(async function () { - this.pausable = await PausableMock.new(); - }); - - context('when unpaused', function () { - beforeEach(async function () { - expect(await this.pausable.paused()).to.equal(false); - }); - - it('can perform normal process in non-pause', async function () { - expect(await this.pausable.count()).to.be.bignumber.equal('0'); - - await this.pausable.normalProcess(); - expect(await this.pausable.count()).to.be.bignumber.equal('1'); - }); - - it('cannot take drastic measure in non-pause', async function () { - await expectRevert(this.pausable.drasticMeasure(), - 'Pausable: not paused', - ); - expect(await this.pausable.drasticMeasureTaken()).to.equal(false); - }); - - context('when paused', function () { - beforeEach(async function () { - (this.receipt = await this.pausable.pause({ from: pauser })); - }); - - it('emits a Paused event', function () { - expectEvent(this.receipt, 'Paused', { account: pauser }); - }); - - it('cannot perform normal process in pause', async function () { - await expectRevert(this.pausable.normalProcess(), 'Pausable: paused'); - }); - - it('can take a drastic measure in a pause', async function () { - await this.pausable.drasticMeasure(); - expect(await this.pausable.drasticMeasureTaken()).to.equal(true); - }); - - it('reverts when re-pausing', async function () { - await expectRevert(this.pausable.pause(), 'Pausable: paused'); - }); - - describe('unpausing', function () { - it('is unpausable by the pauser', async function () { - await this.pausable.unpause(); - expect(await this.pausable.paused()).to.equal(false); - }); - - context('when unpaused', function () { - beforeEach(async function () { - (this.receipt = await this.pausable.unpause({ from: pauser })); - }); - - it('emits an Unpaused event', function () { - expectEvent(this.receipt, 'Unpaused', { account: pauser }); - }); - - it('should resume allowing normal process', async function () { - expect(await this.pausable.count()).to.be.bignumber.equal('0'); - await this.pausable.normalProcess(); - expect(await this.pausable.count()).to.be.bignumber.equal('1'); - }); - - it('should prevent drastic measure', async function () { - await expectRevert(this.pausable.drasticMeasure(), - 'Pausable: not paused', - ); - }); - - it('reverts when re-unpausing', async function () { - await expectRevert(this.pausable.unpause(), 'Pausable: not paused'); - }); - }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/security/PullPayment.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/security/PullPayment.test.js deleted file mode 100644 index 1552ed9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/security/PullPayment.test.js +++ /dev/null @@ -1,51 +0,0 @@ -const { balance, ether } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const PullPaymentMock = artifacts.require('PullPaymentMock'); - -contract('PullPayment', function (accounts) { - const [ payer, payee1, payee2 ] = accounts; - - const amount = ether('17'); - - beforeEach(async function () { - this.contract = await PullPaymentMock.new({ value: amount }); - }); - - describe('payments', function () { - it('can record an async payment correctly', async function () { - await this.contract.callTransfer(payee1, 100, { from: payer }); - expect(await this.contract.payments(payee1)).to.be.bignumber.equal('100'); - }); - - it('can add multiple balances on one account', async function () { - await this.contract.callTransfer(payee1, 200, { from: payer }); - await this.contract.callTransfer(payee1, 300, { from: payer }); - expect(await this.contract.payments(payee1)).to.be.bignumber.equal('500'); - }); - - it('can add balances on multiple accounts', async function () { - await this.contract.callTransfer(payee1, 200, { from: payer }); - await this.contract.callTransfer(payee2, 300, { from: payer }); - - expect(await this.contract.payments(payee1)).to.be.bignumber.equal('200'); - - expect(await this.contract.payments(payee2)).to.be.bignumber.equal('300'); - }); - }); - - describe('withdrawPayments', function () { - it('can withdraw payment', async function () { - const balanceTracker = await balance.tracker(payee1); - - await this.contract.callTransfer(payee1, amount, { from: payer }); - expect(await this.contract.payments(payee1)).to.be.bignumber.equal(amount); - - await this.contract.withdrawPayments(payee1); - - expect(await balanceTracker.delta()).to.be.bignumber.equal(amount); - expect(await this.contract.payments(payee1)).to.be.bignumber.equal('0'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/security/ReentrancyGuard.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/security/ReentrancyGuard.test.js deleted file mode 100644 index c0116d5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/security/ReentrancyGuard.test.js +++ /dev/null @@ -1,40 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ReentrancyMock = artifacts.require('ReentrancyMock'); -const ReentrancyAttack = artifacts.require('ReentrancyAttack'); - -contract('ReentrancyGuard', function (accounts) { - beforeEach(async function () { - this.reentrancyMock = await ReentrancyMock.new(); - expect(await this.reentrancyMock.counter()).to.be.bignumber.equal('0'); - }); - - it('nonReentrant function can be called', async function () { - expect(await this.reentrancyMock.counter()).to.be.bignumber.equal('0'); - await this.reentrancyMock.callback(); - expect(await this.reentrancyMock.counter()).to.be.bignumber.equal('1'); - }); - - it('does not allow remote callback', async function () { - const attacker = await ReentrancyAttack.new(); - await expectRevert( - this.reentrancyMock.countAndCall(attacker.address), 'ReentrancyAttack: failed call'); - }); - - // The following are more side-effects than intended behavior: - // I put them here as documentation, and to monitor any changes - // in the side-effects. - it('does not allow local recursion', async function () { - await expectRevert( - this.reentrancyMock.countLocalRecursive(10), 'ReentrancyGuard: reentrant call', - ); - }); - - it('does not allow indirect local recursion', async function () { - await expectRevert( - this.reentrancyMock.countThisRecursive(10), 'ReentrancyMock: failed call', - ); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js deleted file mode 100644 index 3ac4c34..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.behavior.js +++ /dev/null @@ -1,774 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -const ERC1155ReceiverMock = artifacts.require('ERC1155ReceiverMock'); - -function shouldBehaveLikeERC1155 ([minter, firstTokenHolder, secondTokenHolder, multiTokenHolder, recipient, proxy]) { - const firstTokenId = new BN(1); - const secondTokenId = new BN(2); - const unknownTokenId = new BN(3); - - const firstAmount = new BN(1000); - const secondAmount = new BN(2000); - - const RECEIVER_SINGLE_MAGIC_VALUE = '0xf23a6e61'; - const RECEIVER_BATCH_MAGIC_VALUE = '0xbc197c81'; - - describe('like an ERC1155', function () { - describe('balanceOf', function () { - it('reverts when queried about the zero address', async function () { - await expectRevert( - this.token.balanceOf(ZERO_ADDRESS, firstTokenId), - 'ERC1155: address zero is not a valid owner', - ); - }); - - context('when accounts don\'t own tokens', function () { - it('returns zero for given addresses', async function () { - expect(await this.token.balanceOf( - firstTokenHolder, - firstTokenId, - )).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOf( - secondTokenHolder, - secondTokenId, - )).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOf( - firstTokenHolder, - unknownTokenId, - )).to.be.bignumber.equal('0'); - }); - }); - - context('when accounts own some tokens', function () { - beforeEach(async function () { - await this.token.mint(firstTokenHolder, firstTokenId, firstAmount, '0x', { - from: minter, - }); - await this.token.mint( - secondTokenHolder, - secondTokenId, - secondAmount, - '0x', - { - from: minter, - }, - ); - }); - - it('returns the amount of tokens owned by the given addresses', async function () { - expect(await this.token.balanceOf( - firstTokenHolder, - firstTokenId, - )).to.be.bignumber.equal(firstAmount); - - expect(await this.token.balanceOf( - secondTokenHolder, - secondTokenId, - )).to.be.bignumber.equal(secondAmount); - - expect(await this.token.balanceOf( - firstTokenHolder, - unknownTokenId, - )).to.be.bignumber.equal('0'); - }); - }); - }); - - describe('balanceOfBatch', function () { - it('reverts when input arrays don\'t match up', async function () { - await expectRevert( - this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder, firstTokenHolder, secondTokenHolder], - [firstTokenId, secondTokenId, unknownTokenId], - ), - 'ERC1155: accounts and ids length mismatch', - ); - - await expectRevert( - this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder], - [firstTokenId, secondTokenId, unknownTokenId], - ), - 'ERC1155: accounts and ids length mismatch', - ); - }); - - it('reverts when one of the addresses is the zero address', async function () { - await expectRevert( - this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder, ZERO_ADDRESS], - [firstTokenId, secondTokenId, unknownTokenId], - ), - 'ERC1155: address zero is not a valid owner', - ); - }); - - context('when accounts don\'t own tokens', function () { - it('returns zeros for each account', async function () { - const result = await this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder, firstTokenHolder], - [firstTokenId, secondTokenId, unknownTokenId], - ); - expect(result).to.be.an('array'); - expect(result[0]).to.be.a.bignumber.equal('0'); - expect(result[1]).to.be.a.bignumber.equal('0'); - expect(result[2]).to.be.a.bignumber.equal('0'); - }); - }); - - context('when accounts own some tokens', function () { - beforeEach(async function () { - await this.token.mint(firstTokenHolder, firstTokenId, firstAmount, '0x', { - from: minter, - }); - await this.token.mint( - secondTokenHolder, - secondTokenId, - secondAmount, - '0x', - { - from: minter, - }, - ); - }); - - it('returns amounts owned by each account in order passed', async function () { - const result = await this.token.balanceOfBatch( - [secondTokenHolder, firstTokenHolder, firstTokenHolder], - [secondTokenId, firstTokenId, unknownTokenId], - ); - expect(result).to.be.an('array'); - expect(result[0]).to.be.a.bignumber.equal(secondAmount); - expect(result[1]).to.be.a.bignumber.equal(firstAmount); - expect(result[2]).to.be.a.bignumber.equal('0'); - }); - - it('returns multiple times the balance of the same address when asked', async function () { - const result = await this.token.balanceOfBatch( - [firstTokenHolder, secondTokenHolder, firstTokenHolder], - [firstTokenId, secondTokenId, firstTokenId], - ); - expect(result).to.be.an('array'); - expect(result[0]).to.be.a.bignumber.equal(result[2]); - expect(result[0]).to.be.a.bignumber.equal(firstAmount); - expect(result[1]).to.be.a.bignumber.equal(secondAmount); - expect(result[2]).to.be.a.bignumber.equal(firstAmount); - }); - }); - }); - - describe('setApprovalForAll', function () { - let receipt; - beforeEach(async function () { - (receipt = await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder })); - }); - - it('sets approval status which can be queried via isApprovedForAll', async function () { - expect(await this.token.isApprovedForAll(multiTokenHolder, proxy)).to.be.equal(true); - }); - - it('emits an ApprovalForAll log', function () { - expectEvent(receipt, 'ApprovalForAll', { account: multiTokenHolder, operator: proxy, approved: true }); - }); - - it('can unset approval for an operator', async function () { - await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder }); - expect(await this.token.isApprovedForAll(multiTokenHolder, proxy)).to.be.equal(false); - }); - - it('reverts if attempting to approve self as an operator', async function () { - await expectRevert( - this.token.setApprovalForAll(multiTokenHolder, true, { from: multiTokenHolder }), - 'ERC1155: setting approval status for self', - ); - }); - }); - - describe('safeTransferFrom', function () { - beforeEach(async function () { - await this.token.mint(multiTokenHolder, firstTokenId, firstAmount, '0x', { - from: minter, - }); - await this.token.mint( - multiTokenHolder, - secondTokenId, - secondAmount, - '0x', - { - from: minter, - }, - ); - }); - - it('reverts when transferring more than balance', async function () { - await expectRevert( - this.token.safeTransferFrom( - multiTokenHolder, - recipient, - firstTokenId, - firstAmount.addn(1), - '0x', - { from: multiTokenHolder }, - ), - 'ERC1155: insufficient balance for transfer', - ); - }); - - it('reverts when transferring to zero address', async function () { - await expectRevert( - this.token.safeTransferFrom( - multiTokenHolder, - ZERO_ADDRESS, - firstTokenId, - firstAmount, - '0x', - { from: multiTokenHolder }, - ), - 'ERC1155: transfer to the zero address', - ); - }); - - function transferWasSuccessful ({ operator, from, id, value }) { - it('debits transferred balance from sender', async function () { - const newBalance = await this.token.balanceOf(from, id); - expect(newBalance).to.be.a.bignumber.equal('0'); - }); - - it('credits transferred balance to receiver', async function () { - const newBalance = await this.token.balanceOf(this.toWhom, id); - expect(newBalance).to.be.a.bignumber.equal(value); - }); - - it('emits a TransferSingle log', function () { - expectEvent(this.transferLogs, 'TransferSingle', { - operator, - from, - to: this.toWhom, - id, - value, - }); - }); - } - - context('when called by the multiTokenHolder', async function () { - beforeEach(async function () { - this.toWhom = recipient; - (this.transferLogs = - await this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', { - from: multiTokenHolder, - })); - }); - - transferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - }); - - it('preserves existing balances which are not transferred by multiTokenHolder', async function () { - const balance1 = await this.token.balanceOf(multiTokenHolder, secondTokenId); - expect(balance1).to.be.a.bignumber.equal(secondAmount); - - const balance2 = await this.token.balanceOf(recipient, secondTokenId); - expect(balance2).to.be.a.bignumber.equal('0'); - }); - }); - - context('when called by an operator on behalf of the multiTokenHolder', function () { - context('when operator is not approved by multiTokenHolder', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder }); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', { - from: proxy, - }), - 'ERC1155: caller is not token owner nor approved', - ); - }); - }); - - context('when operator is approved by multiTokenHolder', function () { - beforeEach(async function () { - this.toWhom = recipient; - await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder }); - (this.transferLogs = - await this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', { - from: proxy, - })); - }); - - transferWasSuccessful.call(this, { - operator: proxy, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - }); - - it('preserves operator\'s balances not involved in the transfer', async function () { - const balance1 = await this.token.balanceOf(proxy, firstTokenId); - expect(balance1).to.be.a.bignumber.equal('0'); - - const balance2 = await this.token.balanceOf(proxy, secondTokenId); - expect(balance2).to.be.a.bignumber.equal('0'); - }); - }); - }); - - context('when sending to a valid receiver', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, false, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - }); - - context('without data', function () { - beforeEach(async function () { - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeTransferFrom( - multiTokenHolder, - this.receiver.address, - firstTokenId, - firstAmount, - '0x', - { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - transferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - }); - - it('calls onERC1155Received', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'Received', { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - data: null, - }); - }); - }); - - context('with data', function () { - const data = '0xf00dd00d'; - beforeEach(async function () { - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeTransferFrom( - multiTokenHolder, - this.receiver.address, - firstTokenId, - firstAmount, - data, - { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - transferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - }); - - it('calls onERC1155Received', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'Received', { - operator: multiTokenHolder, - from: multiTokenHolder, - id: firstTokenId, - value: firstAmount, - data, - }); - }); - }); - }); - - context('to a receiver contract returning unexpected value', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - '0x00c0ffee', false, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', { - from: multiTokenHolder, - }), - 'ERC1155: ERC1155Receiver rejected tokens', - ); - }); - }); - - context('to a receiver contract that reverts', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, true, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', { - from: multiTokenHolder, - }), - 'ERC1155ReceiverMock: reverting on receive', - ); - }); - }); - - context('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const invalidReceiver = this.token; - await expectRevert.unspecified( - this.token.safeTransferFrom(multiTokenHolder, invalidReceiver.address, firstTokenId, firstAmount, '0x', { - from: multiTokenHolder, - }), - ); - }); - }); - }); - - describe('safeBatchTransferFrom', function () { - beforeEach(async function () { - await this.token.mint(multiTokenHolder, firstTokenId, firstAmount, '0x', { - from: minter, - }); - await this.token.mint( - multiTokenHolder, - secondTokenId, - secondAmount, - '0x', - { - from: minter, - }, - ); - }); - - it('reverts when transferring amount more than any of balances', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount.addn(1)], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: insufficient balance for transfer', - ); - }); - - it('reverts when ids array length doesn\'t match amounts array length', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: ids and amounts length mismatch', - ); - - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: ids and amounts length mismatch', - ); - }); - - it('reverts when transferring to zero address', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, ZERO_ADDRESS, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: transfer to the zero address', - ); - }); - - function batchTransferWasSuccessful ({ operator, from, ids, values }) { - it('debits transferred balances from sender', async function () { - const newBalances = await this.token.balanceOfBatch(new Array(ids.length).fill(from), ids); - for (const newBalance of newBalances) { - expect(newBalance).to.be.a.bignumber.equal('0'); - } - }); - - it('credits transferred balances to receiver', async function () { - const newBalances = await this.token.balanceOfBatch(new Array(ids.length).fill(this.toWhom), ids); - for (let i = 0; i < newBalances.length; i++) { - expect(newBalances[i]).to.be.a.bignumber.equal(values[i]); - } - }); - - it('emits a TransferBatch log', function () { - expectEvent(this.transferLogs, 'TransferBatch', { - operator, - from, - to: this.toWhom, - // ids, - // values, - }); - }); - } - - context('when called by the multiTokenHolder', async function () { - beforeEach(async function () { - this.toWhom = recipient; - (this.transferLogs = - await this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - )); - }); - - batchTransferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - }); - - context('when called by an operator on behalf of the multiTokenHolder', function () { - context('when operator is not approved by multiTokenHolder', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder }); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: proxy }, - ), - 'ERC1155: caller is not token owner nor approved', - ); - }); - }); - - context('when operator is approved by multiTokenHolder', function () { - beforeEach(async function () { - this.toWhom = recipient; - await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder }); - (this.transferLogs = - await this.token.safeBatchTransferFrom( - multiTokenHolder, recipient, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: proxy }, - )); - }); - - batchTransferWasSuccessful.call(this, { - operator: proxy, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - - it('preserves operator\'s balances not involved in the transfer', async function () { - const balance1 = await this.token.balanceOf(proxy, firstTokenId); - expect(balance1).to.be.a.bignumber.equal('0'); - const balance2 = await this.token.balanceOf(proxy, secondTokenId); - expect(balance2).to.be.a.bignumber.equal('0'); - }); - }); - }); - - context('when sending to a valid receiver', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, false, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - }); - - context('without data', function () { - beforeEach(async function () { - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - batchTransferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - - it('calls onERC1155BatchReceived', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', { - operator: multiTokenHolder, - from: multiTokenHolder, - // ids: [firstTokenId, secondTokenId], - // values: [firstAmount, secondAmount], - data: null, - }); - }); - }); - - context('with data', function () { - const data = '0xf00dd00d'; - beforeEach(async function () { - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - data, { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - batchTransferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - - it('calls onERC1155Received', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', { - operator: multiTokenHolder, - from: multiTokenHolder, - // ids: [firstTokenId, secondTokenId], - // values: [firstAmount, secondAmount], - data, - }); - }); - }); - }); - - context('to a receiver contract returning unexpected value', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, false, - RECEIVER_SINGLE_MAGIC_VALUE, false, - ); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155: ERC1155Receiver rejected tokens', - ); - }); - }); - - context('to a receiver contract that reverts', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, false, - RECEIVER_BATCH_MAGIC_VALUE, true, - ); - }); - - it('reverts', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - 'ERC1155ReceiverMock: reverting on batch receive', - ); - }); - }); - - context('to a receiver contract that reverts only on single transfers', function () { - beforeEach(async function () { - this.receiver = await ERC1155ReceiverMock.new( - RECEIVER_SINGLE_MAGIC_VALUE, true, - RECEIVER_BATCH_MAGIC_VALUE, false, - ); - - this.toWhom = this.receiver.address; - this.transferReceipt = await this.token.safeBatchTransferFrom( - multiTokenHolder, this.receiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ); - (this.transferLogs = this.transferReceipt); - }); - - batchTransferWasSuccessful.call(this, { - operator: multiTokenHolder, - from: multiTokenHolder, - ids: [firstTokenId, secondTokenId], - values: [firstAmount, secondAmount], - }); - - it('calls onERC1155BatchReceived', async function () { - await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', { - operator: multiTokenHolder, - from: multiTokenHolder, - // ids: [firstTokenId, secondTokenId], - // values: [firstAmount, secondAmount], - data: null, - }); - }); - }); - - context('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const invalidReceiver = this.token; - await expectRevert.unspecified( - this.token.safeBatchTransferFrom( - multiTokenHolder, invalidReceiver.address, - [firstTokenId, secondTokenId], - [firstAmount, secondAmount], - '0x', { from: multiTokenHolder }, - ), - ); - }); - }); - }); - - shouldSupportInterfaces(['ERC165', 'ERC1155']); - }); -} - -module.exports = { - shouldBehaveLikeERC1155, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js deleted file mode 100644 index a0a8cf3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/ERC1155.test.js +++ /dev/null @@ -1,264 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const { shouldBehaveLikeERC1155 } = require('./ERC1155.behavior'); -const ERC1155Mock = artifacts.require('ERC1155Mock'); - -contract('ERC1155', function (accounts) { - const [operator, tokenHolder, tokenBatchHolder, ...otherAccounts] = accounts; - - const initialURI = 'https://token-cdn-domain/{id}.json'; - - beforeEach(async function () { - this.token = await ERC1155Mock.new(initialURI); - }); - - shouldBehaveLikeERC1155(otherAccounts); - - describe('internal functions', function () { - const tokenId = new BN(1990); - const mintAmount = new BN(9001); - const burnAmount = new BN(3000); - - const tokenBatchIds = [new BN(2000), new BN(2010), new BN(2020)]; - const mintAmounts = [new BN(5000), new BN(10000), new BN(42195)]; - const burnAmounts = [new BN(5000), new BN(9001), new BN(195)]; - - const data = '0x12345678'; - - describe('_mint', function () { - it('reverts with a zero destination address', async function () { - await expectRevert( - this.token.mint(ZERO_ADDRESS, tokenId, mintAmount, data), - 'ERC1155: mint to the zero address', - ); - }); - - context('with minted tokens', function () { - beforeEach(async function () { - (this.receipt = await this.token.mint(tokenHolder, tokenId, mintAmount, data, { from: operator })); - }); - - it('emits a TransferSingle event', function () { - expectEvent(this.receipt, 'TransferSingle', { - operator, - from: ZERO_ADDRESS, - to: tokenHolder, - id: tokenId, - value: mintAmount, - }); - }); - - it('credits the minted amount of tokens', async function () { - expect(await this.token.balanceOf(tokenHolder, tokenId)).to.be.bignumber.equal(mintAmount); - }); - }); - }); - - describe('_mintBatch', function () { - it('reverts with a zero destination address', async function () { - await expectRevert( - this.token.mintBatch(ZERO_ADDRESS, tokenBatchIds, mintAmounts, data), - 'ERC1155: mint to the zero address', - ); - }); - - it('reverts if length of inputs do not match', async function () { - await expectRevert( - this.token.mintBatch(tokenBatchHolder, tokenBatchIds, mintAmounts.slice(1), data), - 'ERC1155: ids and amounts length mismatch', - ); - - await expectRevert( - this.token.mintBatch(tokenBatchHolder, tokenBatchIds.slice(1), mintAmounts, data), - 'ERC1155: ids and amounts length mismatch', - ); - }); - - context('with minted batch of tokens', function () { - beforeEach(async function () { - (this.receipt = await this.token.mintBatch( - tokenBatchHolder, - tokenBatchIds, - mintAmounts, - data, - { from: operator }, - )); - }); - - it('emits a TransferBatch event', function () { - expectEvent(this.receipt, 'TransferBatch', { - operator, - from: ZERO_ADDRESS, - to: tokenBatchHolder, - }); - }); - - it('credits the minted batch of tokens', async function () { - const holderBatchBalances = await this.token.balanceOfBatch( - new Array(tokenBatchIds.length).fill(tokenBatchHolder), - tokenBatchIds, - ); - - for (let i = 0; i < holderBatchBalances.length; i++) { - expect(holderBatchBalances[i]).to.be.bignumber.equal(mintAmounts[i]); - } - }); - }); - }); - - describe('_burn', function () { - it('reverts when burning the zero account\'s tokens', async function () { - await expectRevert( - this.token.burn(ZERO_ADDRESS, tokenId, mintAmount), - 'ERC1155: burn from the zero address', - ); - }); - - it('reverts when burning a non-existent token id', async function () { - await expectRevert( - this.token.burn(tokenHolder, tokenId, mintAmount), - 'ERC1155: burn amount exceeds balance', - ); - }); - - it('reverts when burning more than available tokens', async function () { - await this.token.mint( - tokenHolder, - tokenId, - mintAmount, - data, - { from: operator }, - ); - - await expectRevert( - this.token.burn(tokenHolder, tokenId, mintAmount.addn(1)), - 'ERC1155: burn amount exceeds balance', - ); - }); - - context('with minted-then-burnt tokens', function () { - beforeEach(async function () { - await this.token.mint(tokenHolder, tokenId, mintAmount, data); - (this.receipt = await this.token.burn( - tokenHolder, - tokenId, - burnAmount, - { from: operator }, - )); - }); - - it('emits a TransferSingle event', function () { - expectEvent(this.receipt, 'TransferSingle', { - operator, - from: tokenHolder, - to: ZERO_ADDRESS, - id: tokenId, - value: burnAmount, - }); - }); - - it('accounts for both minting and burning', async function () { - expect(await this.token.balanceOf( - tokenHolder, - tokenId, - )).to.be.bignumber.equal(mintAmount.sub(burnAmount)); - }); - }); - }); - - describe('_burnBatch', function () { - it('reverts when burning the zero account\'s tokens', async function () { - await expectRevert( - this.token.burnBatch(ZERO_ADDRESS, tokenBatchIds, burnAmounts), - 'ERC1155: burn from the zero address', - ); - }); - - it('reverts if length of inputs do not match', async function () { - await expectRevert( - this.token.burnBatch(tokenBatchHolder, tokenBatchIds, burnAmounts.slice(1)), - 'ERC1155: ids and amounts length mismatch', - ); - - await expectRevert( - this.token.burnBatch(tokenBatchHolder, tokenBatchIds.slice(1), burnAmounts), - 'ERC1155: ids and amounts length mismatch', - ); - }); - - it('reverts when burning a non-existent token id', async function () { - await expectRevert( - this.token.burnBatch(tokenBatchHolder, tokenBatchIds, burnAmounts), - 'ERC1155: burn amount exceeds balance', - ); - }); - - context('with minted-then-burnt tokens', function () { - beforeEach(async function () { - await this.token.mintBatch(tokenBatchHolder, tokenBatchIds, mintAmounts, data); - (this.receipt = await this.token.burnBatch( - tokenBatchHolder, - tokenBatchIds, - burnAmounts, - { from: operator }, - )); - }); - - it('emits a TransferBatch event', function () { - expectEvent(this.receipt, 'TransferBatch', { - operator, - from: tokenBatchHolder, - to: ZERO_ADDRESS, - // ids: tokenBatchIds, - // values: burnAmounts, - }); - }); - - it('accounts for both minting and burning', async function () { - const holderBatchBalances = await this.token.balanceOfBatch( - new Array(tokenBatchIds.length).fill(tokenBatchHolder), - tokenBatchIds, - ); - - for (let i = 0; i < holderBatchBalances.length; i++) { - expect(holderBatchBalances[i]).to.be.bignumber.equal(mintAmounts[i].sub(burnAmounts[i])); - } - }); - }); - }); - }); - - describe('ERC1155MetadataURI', function () { - const firstTokenID = new BN('42'); - const secondTokenID = new BN('1337'); - - it('emits no URI event in constructor', async function () { - await expectEvent.notEmitted.inConstruction(this.token, 'URI'); - }); - - it('sets the initial URI for all token types', async function () { - expect(await this.token.uri(firstTokenID)).to.be.equal(initialURI); - expect(await this.token.uri(secondTokenID)).to.be.equal(initialURI); - }); - - describe('_setURI', function () { - const newURI = 'https://token-cdn-domain/{locale}/{id}.json'; - - it('emits no URI event', async function () { - const receipt = await this.token.setURI(newURI); - - expectEvent.notEmitted(receipt, 'URI'); - }); - - it('sets the new URI for all token types', async function () { - await this.token.setURI(newURI); - - expect(await this.token.uri(firstTokenID)).to.be.equal(newURI); - expect(await this.token.uri(secondTokenID)).to.be.equal(newURI); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js deleted file mode 100644 index caa4d16..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Burnable.test.js +++ /dev/null @@ -1,67 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC1155BurnableMock = artifacts.require('ERC1155BurnableMock'); - -contract('ERC1155Burnable', function (accounts) { - const [ holder, operator, other ] = accounts; - - const uri = 'https://token.com'; - - const tokenIds = [new BN('42'), new BN('1137')]; - const amounts = [new BN('3000'), new BN('9902')]; - - beforeEach(async function () { - this.token = await ERC1155BurnableMock.new(uri); - - await this.token.mint(holder, tokenIds[0], amounts[0], '0x'); - await this.token.mint(holder, tokenIds[1], amounts[1], '0x'); - }); - - describe('burn', function () { - it('holder can burn their tokens', async function () { - await this.token.burn(holder, tokenIds[0], amounts[0].subn(1), { from: holder }); - - expect(await this.token.balanceOf(holder, tokenIds[0])).to.be.bignumber.equal('1'); - }); - - it('approved operators can burn the holder\'s tokens', async function () { - await this.token.setApprovalForAll(operator, true, { from: holder }); - await this.token.burn(holder, tokenIds[0], amounts[0].subn(1), { from: operator }); - - expect(await this.token.balanceOf(holder, tokenIds[0])).to.be.bignumber.equal('1'); - }); - - it('unapproved accounts cannot burn the holder\'s tokens', async function () { - await expectRevert( - this.token.burn(holder, tokenIds[0], amounts[0].subn(1), { from: other }), - 'ERC1155: caller is not token owner nor approved', - ); - }); - }); - - describe('burnBatch', function () { - it('holder can burn their tokens', async function () { - await this.token.burnBatch(holder, tokenIds, [ amounts[0].subn(1), amounts[1].subn(2) ], { from: holder }); - - expect(await this.token.balanceOf(holder, tokenIds[0])).to.be.bignumber.equal('1'); - expect(await this.token.balanceOf(holder, tokenIds[1])).to.be.bignumber.equal('2'); - }); - - it('approved operators can burn the holder\'s tokens', async function () { - await this.token.setApprovalForAll(operator, true, { from: holder }); - await this.token.burnBatch(holder, tokenIds, [ amounts[0].subn(1), amounts[1].subn(2) ], { from: operator }); - - expect(await this.token.balanceOf(holder, tokenIds[0])).to.be.bignumber.equal('1'); - expect(await this.token.balanceOf(holder, tokenIds[1])).to.be.bignumber.equal('2'); - }); - - it('unapproved accounts cannot burn the holder\'s tokens', async function () { - await expectRevert( - this.token.burnBatch(holder, tokenIds, [ amounts[0].subn(1), amounts[1].subn(2) ], { from: other }), - 'ERC1155: caller is not token owner nor approved', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js deleted file mode 100644 index f7c4052..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Pausable.test.js +++ /dev/null @@ -1,108 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC1155PausableMock = artifacts.require('ERC1155PausableMock'); - -contract('ERC1155Pausable', function (accounts) { - const [ holder, operator, receiver, other ] = accounts; - - const uri = 'https://token.com'; - - beforeEach(async function () { - this.token = await ERC1155PausableMock.new(uri); - }); - - context('when token is paused', function () { - const firstTokenId = new BN('37'); - const firstTokenAmount = new BN('42'); - - const secondTokenId = new BN('19842'); - const secondTokenAmount = new BN('23'); - - beforeEach(async function () { - await this.token.setApprovalForAll(operator, true, { from: holder }); - await this.token.mint(holder, firstTokenId, firstTokenAmount, '0x'); - - await this.token.pause(); - }); - - it('reverts when trying to safeTransferFrom from holder', async function () { - await expectRevert( - this.token.safeTransferFrom(holder, receiver, firstTokenId, firstTokenAmount, '0x', { from: holder }), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeTransferFrom from operator', async function () { - await expectRevert( - this.token.safeTransferFrom(holder, receiver, firstTokenId, firstTokenAmount, '0x', { from: operator }), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeBatchTransferFrom from holder', async function () { - await expectRevert( - this.token.safeBatchTransferFrom(holder, receiver, [firstTokenId], [firstTokenAmount], '0x', { from: holder }), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeBatchTransferFrom from operator', async function () { - await expectRevert( - this.token.safeBatchTransferFrom( - holder, receiver, [firstTokenId], [firstTokenAmount], '0x', { from: operator }, - ), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to mint', async function () { - await expectRevert( - this.token.mint(holder, secondTokenId, secondTokenAmount, '0x'), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to mintBatch', async function () { - await expectRevert( - this.token.mintBatch(holder, [secondTokenId], [secondTokenAmount], '0x'), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to burn', async function () { - await expectRevert( - this.token.burn(holder, firstTokenId, firstTokenAmount), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to burnBatch', async function () { - await expectRevert( - this.token.burnBatch(holder, [firstTokenId], [firstTokenAmount]), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - describe('setApprovalForAll', function () { - it('approves an operator', async function () { - await this.token.setApprovalForAll(other, true, { from: holder }); - expect(await this.token.isApprovedForAll(holder, other)).to.equal(true); - }); - }); - - describe('balanceOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - const balance = await this.token.balanceOf(holder, firstTokenId); - expect(balance).to.be.bignumber.equal(firstTokenAmount); - }); - }); - - describe('isApprovedForAll', function () { - it('returns the approval of the operator', async function () { - expect(await this.token.isApprovedForAll(holder, operator)).to.equal(true); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js deleted file mode 100644 index 1a63260..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Supply.test.js +++ /dev/null @@ -1,111 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC1155SupplyMock = artifacts.require('ERC1155SupplyMock'); - -contract('ERC1155Supply', function (accounts) { - const [ holder ] = accounts; - - const uri = 'https://token.com'; - - const firstTokenId = new BN('37'); - const firstTokenAmount = new BN('42'); - - const secondTokenId = new BN('19842'); - const secondTokenAmount = new BN('23'); - - beforeEach(async function () { - this.token = await ERC1155SupplyMock.new(uri); - }); - - context('before mint', function () { - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(false); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal('0'); - }); - }); - - context('after mint', function () { - context('single', function () { - beforeEach(async function () { - await this.token.mint(holder, firstTokenId, firstTokenAmount, '0x'); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(true); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal(firstTokenAmount); - }); - }); - - context('batch', function () { - beforeEach(async function () { - await this.token.mintBatch( - holder, - [ firstTokenId, secondTokenId ], - [ firstTokenAmount, secondTokenAmount ], - '0x', - ); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(true); - expect(await this.token.exists(secondTokenId)).to.be.equal(true); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal(firstTokenAmount); - expect(await this.token.totalSupply(secondTokenId)).to.be.bignumber.equal(secondTokenAmount); - }); - }); - }); - - context('after burn', function () { - context('single', function () { - beforeEach(async function () { - await this.token.mint(holder, firstTokenId, firstTokenAmount, '0x'); - await this.token.burn(holder, firstTokenId, firstTokenAmount); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(false); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal('0'); - }); - }); - - context('batch', function () { - beforeEach(async function () { - await this.token.mintBatch( - holder, - [ firstTokenId, secondTokenId ], - [ firstTokenAmount, secondTokenAmount ], - '0x', - ); - await this.token.burnBatch( - holder, - [ firstTokenId, secondTokenId ], - [ firstTokenAmount, secondTokenAmount ], - ); - }); - - it('exist', async function () { - expect(await this.token.exists(firstTokenId)).to.be.equal(false); - expect(await this.token.exists(secondTokenId)).to.be.equal(false); - }); - - it('totalSupply', async function () { - expect(await this.token.totalSupply(firstTokenId)).to.be.bignumber.equal('0'); - expect(await this.token.totalSupply(secondTokenId)).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js deleted file mode 100644 index 7ba7e56..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155URIStorage.test.js +++ /dev/null @@ -1,66 +0,0 @@ -const { BN, expectEvent } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); -const { artifacts } = require('hardhat'); - -const ERC1155URIStorageMock = artifacts.require('ERC1155URIStorageMock'); - -contract(['ERC1155URIStorage'], function (accounts) { - const [ holder ] = accounts; - - const erc1155Uri = 'https://token.com/nfts/'; - const baseUri = 'https://token.com/'; - - const tokenId = new BN('1'); - const amount = new BN('3000'); - - describe('with base uri set', function () { - beforeEach(async function () { - this.token = await ERC1155URIStorageMock.new(erc1155Uri); - this.token.setBaseURI(baseUri); - - await this.token.mint(holder, tokenId, amount, '0x'); - }); - - it('can request the token uri, returning the erc1155 uri if no token uri was set', async function () { - const receivedTokenUri = await this.token.uri(tokenId); - - expect(receivedTokenUri).to.be.equal(erc1155Uri); - }); - - it('can request the token uri, returning the concatenated uri if a token uri was set', async function () { - const tokenUri = '1234/'; - const receipt = await this.token.setURI(tokenId, tokenUri); - - const receivedTokenUri = await this.token.uri(tokenId); - - const expectedUri = `${baseUri}${tokenUri}`; - expect(receivedTokenUri).to.be.equal(expectedUri); - expectEvent(receipt, 'URI', { value: expectedUri, id: tokenId }); - }); - }); - - describe('with base uri set to the empty string', function () { - beforeEach(async function () { - this.token = await ERC1155URIStorageMock.new(''); - - await this.token.mint(holder, tokenId, amount, '0x'); - }); - - it('can request the token uri, returning an empty string if no token uri was set', async function () { - const receivedTokenUri = await this.token.uri(tokenId); - - expect(receivedTokenUri).to.be.equal(''); - }); - - it('can request the token uri, returning the token uri if a token uri was set', async function () { - const tokenUri = 'ipfs://1234/'; - const receipt = await this.token.setURI(tokenId, tokenUri); - - const receivedTokenUri = await this.token.uri(tokenId); - - expect(receivedTokenUri).to.be.equal(tokenUri); - expectEvent(receipt, 'URI', { value: tokenUri, id: tokenId }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/presets/ERC1155PresetMinterPauser.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/presets/ERC1155PresetMinterPauser.test.js deleted file mode 100644 index a8d83d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/presets/ERC1155PresetMinterPauser.test.js +++ /dev/null @@ -1,146 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); - -const { expect } = require('chai'); - -const ERC1155PresetMinterPauser = artifacts.require('ERC1155PresetMinterPauser'); - -contract('ERC1155PresetMinterPauser', function (accounts) { - const [ deployer, other ] = accounts; - - const firstTokenId = new BN('845'); - const firstTokenIdAmount = new BN('5000'); - - const secondTokenId = new BN('48324'); - const secondTokenIdAmount = new BN('77875'); - - const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const MINTER_ROLE = web3.utils.soliditySha3('MINTER_ROLE'); - const PAUSER_ROLE = web3.utils.soliditySha3('PAUSER_ROLE'); - - const uri = 'https://token.com'; - - beforeEach(async function () { - this.token = await ERC1155PresetMinterPauser.new(uri, { from: deployer }); - }); - - shouldSupportInterfaces(['ERC1155', 'AccessControl', 'AccessControlEnumerable']); - - it('deployer has the default admin role', async function () { - expect(await this.token.getRoleMemberCount(DEFAULT_ADMIN_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(DEFAULT_ADMIN_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the minter role', async function () { - expect(await this.token.getRoleMemberCount(MINTER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(MINTER_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the pauser role', async function () { - expect(await this.token.getRoleMemberCount(PAUSER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(PAUSER_ROLE, 0)).to.equal(deployer); - }); - - it('minter and pauser role admin is the default admin', async function () { - expect(await this.token.getRoleAdmin(MINTER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - expect(await this.token.getRoleAdmin(PAUSER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - describe('minting', function () { - it('deployer can mint tokens', async function () { - const receipt = await this.token.mint(other, firstTokenId, firstTokenIdAmount, '0x', { from: deployer }); - expectEvent(receipt, 'TransferSingle', - { operator: deployer, from: ZERO_ADDRESS, to: other, value: firstTokenIdAmount, id: firstTokenId }, - ); - - expect(await this.token.balanceOf(other, firstTokenId)).to.be.bignumber.equal(firstTokenIdAmount); - }); - - it('other accounts cannot mint tokens', async function () { - await expectRevert( - this.token.mint(other, firstTokenId, firstTokenIdAmount, '0x', { from: other }), - 'ERC1155PresetMinterPauser: must have minter role to mint', - ); - }); - }); - - describe('batched minting', function () { - it('deployer can batch mint tokens', async function () { - const receipt = await this.token.mintBatch( - other, [firstTokenId, secondTokenId], [firstTokenIdAmount, secondTokenIdAmount], '0x', { from: deployer }, - ); - - expectEvent(receipt, 'TransferBatch', - { operator: deployer, from: ZERO_ADDRESS, to: other }, - ); - - expect(await this.token.balanceOf(other, firstTokenId)).to.be.bignumber.equal(firstTokenIdAmount); - }); - - it('other accounts cannot batch mint tokens', async function () { - await expectRevert( - this.token.mintBatch( - other, [firstTokenId, secondTokenId], [firstTokenIdAmount, secondTokenIdAmount], '0x', { from: other }, - ), - 'ERC1155PresetMinterPauser: must have minter role to mint', - ); - }); - }); - - describe('pausing', function () { - it('deployer can pause', async function () { - const receipt = await this.token.pause({ from: deployer }); - expectEvent(receipt, 'Paused', { account: deployer }); - - expect(await this.token.paused()).to.equal(true); - }); - - it('deployer can unpause', async function () { - await this.token.pause({ from: deployer }); - - const receipt = await this.token.unpause({ from: deployer }); - expectEvent(receipt, 'Unpaused', { account: deployer }); - - expect(await this.token.paused()).to.equal(false); - }); - - it('cannot mint while paused', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.mint(other, firstTokenId, firstTokenIdAmount, '0x', { from: deployer }), - 'ERC1155Pausable: token transfer while paused', - ); - }); - - it('other accounts cannot pause', async function () { - await expectRevert( - this.token.pause({ from: other }), - 'ERC1155PresetMinterPauser: must have pauser role to pause', - ); - }); - - it('other accounts cannot unpause', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.unpause({ from: other }), - 'ERC1155PresetMinterPauser: must have pauser role to unpause', - ); - }); - }); - - describe('burning', function () { - it('holders can burn their tokens', async function () { - await this.token.mint(other, firstTokenId, firstTokenIdAmount, '0x', { from: deployer }); - - const receipt = await this.token.burn(other, firstTokenId, firstTokenIdAmount.subn(1), { from: other }); - expectEvent(receipt, 'TransferSingle', - { operator: other, from: other, to: ZERO_ADDRESS, value: firstTokenIdAmount.subn(1), id: firstTokenId }, - ); - - expect(await this.token.balanceOf(other, firstTokenId)).to.be.bignumber.equal('1'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js deleted file mode 100644 index 41225c2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC1155/utils/ERC1155Holder.test.js +++ /dev/null @@ -1,62 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const ERC1155Holder = artifacts.require('ERC1155Holder'); -const ERC1155Mock = artifacts.require('ERC1155Mock'); - -const { expect } = require('chai'); - -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); - -contract('ERC1155Holder', function (accounts) { - const [creator] = accounts; - const uri = 'https://token-cdn-domain/{id}.json'; - const multiTokenIds = [new BN(1), new BN(2), new BN(3)]; - const multiTokenAmounts = [new BN(1000), new BN(2000), new BN(3000)]; - const transferData = '0x12345678'; - - beforeEach(async function () { - this.multiToken = await ERC1155Mock.new(uri, { from: creator }); - this.holder = await ERC1155Holder.new(); - await this.multiToken.mintBatch(creator, multiTokenIds, multiTokenAmounts, '0x', { from: creator }); - }); - - shouldSupportInterfaces(['ERC165', 'ERC1155Receiver']); - - it('receives ERC1155 tokens from a single ID', async function () { - await this.multiToken.safeTransferFrom( - creator, - this.holder.address, - multiTokenIds[0], - multiTokenAmounts[0], - transferData, - { from: creator }, - ); - - expect(await this.multiToken.balanceOf(this.holder.address, multiTokenIds[0])) - .to.be.bignumber.equal(multiTokenAmounts[0]); - - for (let i = 1; i < multiTokenIds.length; i++) { - expect(await this.multiToken.balanceOf(this.holder.address, multiTokenIds[i])).to.be.bignumber.equal(new BN(0)); - } - }); - - it('receives ERC1155 tokens from a multiple IDs', async function () { - for (let i = 0; i < multiTokenIds.length; i++) { - expect(await this.multiToken.balanceOf(this.holder.address, multiTokenIds[i])).to.be.bignumber.equal(new BN(0)); - }; - - await this.multiToken.safeBatchTransferFrom( - creator, - this.holder.address, - multiTokenIds, - multiTokenAmounts, - transferData, - { from: creator }, - ); - - for (let i = 0; i < multiTokenIds.length; i++) { - expect(await this.multiToken.balanceOf(this.holder.address, multiTokenIds[i])) - .to.be.bignumber.equal(multiTokenAmounts[i]); - } - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js deleted file mode 100644 index 8bc5476..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/ERC20.behavior.js +++ /dev/null @@ -1,333 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS, MAX_UINT256 } = constants; - -function shouldBehaveLikeERC20 (errorPrefix, initialSupply, initialHolder, recipient, anotherAccount) { - describe('total supply', function () { - it('returns the total amount of tokens', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - }); - }); - - describe('balanceOf', function () { - describe('when the requested account has no tokens', function () { - it('returns zero', async function () { - expect(await this.token.balanceOf(anotherAccount)).to.be.bignumber.equal('0'); - }); - }); - - describe('when the requested account has some tokens', function () { - it('returns the total amount of tokens', async function () { - expect(await this.token.balanceOf(initialHolder)).to.be.bignumber.equal(initialSupply); - }); - }); - }); - - describe('transfer', function () { - shouldBehaveLikeERC20Transfer(errorPrefix, initialHolder, recipient, initialSupply, - function (from, to, value) { - return this.token.transfer(to, value, { from }); - }, - ); - }); - - describe('transfer from', function () { - const spender = recipient; - - describe('when the token owner is not the zero address', function () { - const tokenOwner = initialHolder; - - describe('when the recipient is not the zero address', function () { - const to = anotherAccount; - - describe('when the spender has enough allowance', function () { - beforeEach(async function () { - await this.token.approve(spender, initialSupply, { from: initialHolder }); - }); - - describe('when the token owner has enough balance', function () { - const amount = initialSupply; - - it('transfers the requested amount', async function () { - await this.token.transferFrom(tokenOwner, to, amount, { from: spender }); - - expect(await this.token.balanceOf(tokenOwner)).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOf(to)).to.be.bignumber.equal(amount); - }); - - it('decreases the spender allowance', async function () { - await this.token.transferFrom(tokenOwner, to, amount, { from: spender }); - - expect(await this.token.allowance(tokenOwner, spender)).to.be.bignumber.equal('0'); - }); - - it('emits a transfer event', async function () { - expectEvent( - await this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - 'Transfer', - { from: tokenOwner, to: to, value: amount }, - ); - }); - - it('emits an approval event', async function () { - expectEvent( - await this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - 'Approval', - { owner: tokenOwner, spender: spender, value: await this.token.allowance(tokenOwner, spender) }, - ); - }); - }); - - describe('when the token owner does not have enough balance', function () { - const amount = initialSupply; - - beforeEach('reducing balance', async function () { - await this.token.transfer(to, 1, { from: tokenOwner }); - }); - - it('reverts', async function () { - await expectRevert( - this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - `${errorPrefix}: transfer amount exceeds balance`, - ); - }); - }); - }); - - describe('when the spender does not have enough allowance', function () { - const allowance = initialSupply.subn(1); - - beforeEach(async function () { - await this.token.approve(spender, allowance, { from: tokenOwner }); - }); - - describe('when the token owner has enough balance', function () { - const amount = initialSupply; - - it('reverts', async function () { - await expectRevert( - this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - `${errorPrefix}: insufficient allowance`, - ); - }); - }); - - describe('when the token owner does not have enough balance', function () { - const amount = allowance; - - beforeEach('reducing balance', async function () { - await this.token.transfer(to, 2, { from: tokenOwner }); - }); - - it('reverts', async function () { - await expectRevert( - this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - `${errorPrefix}: transfer amount exceeds balance`, - ); - }); - }); - }); - - describe('when the spender has unlimited allowance', function () { - beforeEach(async function () { - await this.token.approve(spender, MAX_UINT256, { from: initialHolder }); - }); - - it('does not decrease the spender allowance', async function () { - await this.token.transferFrom(tokenOwner, to, 1, { from: spender }); - - expect(await this.token.allowance(tokenOwner, spender)).to.be.bignumber.equal(MAX_UINT256); - }); - - it('does not emit an approval event', async function () { - expectEvent.notEmitted( - await this.token.transferFrom(tokenOwner, to, 1, { from: spender }), - 'Approval', - ); - }); - }); - }); - - describe('when the recipient is the zero address', function () { - const amount = initialSupply; - const to = ZERO_ADDRESS; - - beforeEach(async function () { - await this.token.approve(spender, amount, { from: tokenOwner }); - }); - - it('reverts', async function () { - await expectRevert(this.token.transferFrom( - tokenOwner, to, amount, { from: spender }), `${errorPrefix}: transfer to the zero address`, - ); - }); - }); - }); - - describe('when the token owner is the zero address', function () { - const amount = 0; - const tokenOwner = ZERO_ADDRESS; - const to = recipient; - - it('reverts', async function () { - await expectRevert( - this.token.transferFrom(tokenOwner, to, amount, { from: spender }), - 'from the zero address', - ); - }); - }); - }); - - describe('approve', function () { - shouldBehaveLikeERC20Approve(errorPrefix, initialHolder, recipient, initialSupply, - function (owner, spender, amount) { - return this.token.approve(spender, amount, { from: owner }); - }, - ); - }); -} - -function shouldBehaveLikeERC20Transfer (errorPrefix, from, to, balance, transfer) { - describe('when the recipient is not the zero address', function () { - describe('when the sender does not have enough balance', function () { - const amount = balance.addn(1); - - it('reverts', async function () { - await expectRevert(transfer.call(this, from, to, amount), - `${errorPrefix}: transfer amount exceeds balance`, - ); - }); - }); - - describe('when the sender transfers all balance', function () { - const amount = balance; - - it('transfers the requested amount', async function () { - await transfer.call(this, from, to, amount); - - expect(await this.token.balanceOf(from)).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOf(to)).to.be.bignumber.equal(amount); - }); - - it('emits a transfer event', async function () { - expectEvent( - await transfer.call(this, from, to, amount), - 'Transfer', - { from, to, value: amount }, - ); - }); - }); - - describe('when the sender transfers zero tokens', function () { - const amount = new BN('0'); - - it('transfers the requested amount', async function () { - await transfer.call(this, from, to, amount); - - expect(await this.token.balanceOf(from)).to.be.bignumber.equal(balance); - - expect(await this.token.balanceOf(to)).to.be.bignumber.equal('0'); - }); - - it('emits a transfer event', async function () { - expectEvent( - await transfer.call(this, from, to, amount), - 'Transfer', - { from, to, value: amount }, - ); - }); - }); - }); - - describe('when the recipient is the zero address', function () { - it('reverts', async function () { - await expectRevert(transfer.call(this, from, ZERO_ADDRESS, balance), - `${errorPrefix}: transfer to the zero address`, - ); - }); - }); -} - -function shouldBehaveLikeERC20Approve (errorPrefix, owner, spender, supply, approve) { - describe('when the spender is not the zero address', function () { - describe('when the sender has enough balance', function () { - const amount = supply; - - it('emits an approval event', async function () { - expectEvent( - await approve.call(this, owner, spender, amount), - 'Approval', - { owner: owner, spender: spender, value: amount }, - ); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await approve.call(this, owner, spender, amount); - - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await approve.call(this, owner, spender, new BN(1)); - }); - - it('approves the requested amount and replaces the previous one', async function () { - await approve.call(this, owner, spender, amount); - - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(amount); - }); - }); - }); - - describe('when the sender does not have enough balance', function () { - const amount = supply.addn(1); - - it('emits an approval event', async function () { - expectEvent( - await approve.call(this, owner, spender, amount), - 'Approval', - { owner: owner, spender: spender, value: amount }, - ); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await approve.call(this, owner, spender, amount); - - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await approve.call(this, owner, spender, new BN(1)); - }); - - it('approves the requested amount and replaces the previous one', async function () { - await approve.call(this, owner, spender, amount); - - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(amount); - }); - }); - }); - }); - - describe('when the spender is the zero address', function () { - it('reverts', async function () { - await expectRevert(approve.call(this, owner, ZERO_ADDRESS, supply), - `${errorPrefix}: approve to the zero address`, - ); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js deleted file mode 100644 index 992edf9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/ERC20.test.js +++ /dev/null @@ -1,309 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS } = constants; - -const { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -} = require('./ERC20.behavior'); - -const ERC20Mock = artifacts.require('ERC20Mock'); -const ERC20DecimalsMock = artifacts.require('ERC20DecimalsMock'); - -contract('ERC20', function (accounts) { - const [ initialHolder, recipient, anotherAccount ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - const initialSupply = new BN(100); - - beforeEach(async function () { - this.token = await ERC20Mock.new(name, symbol, initialHolder, initialSupply); - }); - - it('has a name', async function () { - expect(await this.token.name()).to.equal(name); - }); - - it('has a symbol', async function () { - expect(await this.token.symbol()).to.equal(symbol); - }); - - it('has 18 decimals', async function () { - expect(await this.token.decimals()).to.be.bignumber.equal('18'); - }); - - describe('set decimals', function () { - const decimals = new BN(6); - - it('can set decimals during construction', async function () { - const token = await ERC20DecimalsMock.new(name, symbol, decimals); - expect(await token.decimals()).to.be.bignumber.equal(decimals); - }); - }); - - shouldBehaveLikeERC20('ERC20', initialSupply, initialHolder, recipient, anotherAccount); - - describe('decrease allowance', function () { - describe('when the spender is not the zero address', function () { - const spender = recipient; - - function shouldDecreaseApproval (amount) { - describe('when there was no approved amount before', function () { - it('reverts', async function () { - await expectRevert(this.token.decreaseAllowance( - spender, amount, { from: initialHolder }), 'ERC20: decreased allowance below zero', - ); - }); - }); - - describe('when the spender had an approved amount', function () { - const approvedAmount = amount; - - beforeEach(async function () { - await this.token.approve(spender, approvedAmount, { from: initialHolder }); - }); - - it('emits an approval event', async function () { - expectEvent( - await this.token.decreaseAllowance(spender, approvedAmount, { from: initialHolder }), - 'Approval', - { owner: initialHolder, spender: spender, value: new BN(0) }, - ); - }); - - it('decreases the spender allowance subtracting the requested amount', async function () { - await this.token.decreaseAllowance(spender, approvedAmount.subn(1), { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal('1'); - }); - - it('sets the allowance to zero when all allowance is removed', async function () { - await this.token.decreaseAllowance(spender, approvedAmount, { from: initialHolder }); - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal('0'); - }); - - it('reverts when more than the full allowance is removed', async function () { - await expectRevert( - this.token.decreaseAllowance(spender, approvedAmount.addn(1), { from: initialHolder }), - 'ERC20: decreased allowance below zero', - ); - }); - }); - } - - describe('when the sender has enough balance', function () { - const amount = initialSupply; - - shouldDecreaseApproval(amount); - }); - - describe('when the sender does not have enough balance', function () { - const amount = initialSupply.addn(1); - - shouldDecreaseApproval(amount); - }); - }); - - describe('when the spender is the zero address', function () { - const amount = initialSupply; - const spender = ZERO_ADDRESS; - - it('reverts', async function () { - await expectRevert(this.token.decreaseAllowance( - spender, amount, { from: initialHolder }), 'ERC20: decreased allowance below zero', - ); - }); - }); - }); - - describe('increase allowance', function () { - const amount = initialSupply; - - describe('when the spender is not the zero address', function () { - const spender = recipient; - - describe('when the sender has enough balance', function () { - it('emits an approval event', async function () { - expectEvent( - await this.token.increaseAllowance(spender, amount, { from: initialHolder }), - 'Approval', - { owner: initialHolder, spender: spender, value: amount }, - ); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await this.token.increaseAllowance(spender, amount, { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await this.token.approve(spender, new BN(1), { from: initialHolder }); - }); - - it('increases the spender allowance adding the requested amount', async function () { - await this.token.increaseAllowance(spender, amount, { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal(amount.addn(1)); - }); - }); - }); - - describe('when the sender does not have enough balance', function () { - const amount = initialSupply.addn(1); - - it('emits an approval event', async function () { - expectEvent( - await this.token.increaseAllowance(spender, amount, { from: initialHolder }), - 'Approval', - { owner: initialHolder, spender: spender, value: amount }, - ); - }); - - describe('when there was no approved amount before', function () { - it('approves the requested amount', async function () { - await this.token.increaseAllowance(spender, amount, { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal(amount); - }); - }); - - describe('when the spender had an approved amount', function () { - beforeEach(async function () { - await this.token.approve(spender, new BN(1), { from: initialHolder }); - }); - - it('increases the spender allowance adding the requested amount', async function () { - await this.token.increaseAllowance(spender, amount, { from: initialHolder }); - - expect(await this.token.allowance(initialHolder, spender)).to.be.bignumber.equal(amount.addn(1)); - }); - }); - }); - }); - - describe('when the spender is the zero address', function () { - const spender = ZERO_ADDRESS; - - it('reverts', async function () { - await expectRevert( - this.token.increaseAllowance(spender, amount, { from: initialHolder }), 'ERC20: approve to the zero address', - ); - }); - }); - }); - - describe('_mint', function () { - const amount = new BN(50); - it('rejects a null account', async function () { - await expectRevert( - this.token.mint(ZERO_ADDRESS, amount), 'ERC20: mint to the zero address', - ); - }); - - describe('for a non zero account', function () { - beforeEach('minting', async function () { - this.receipt = await this.token.mint(recipient, amount); - }); - - it('increments totalSupply', async function () { - const expectedSupply = initialSupply.add(amount); - expect(await this.token.totalSupply()).to.be.bignumber.equal(expectedSupply); - }); - - it('increments recipient balance', async function () { - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(amount); - }); - - it('emits Transfer event', async function () { - const event = expectEvent( - this.receipt, - 'Transfer', - { from: ZERO_ADDRESS, to: recipient }, - ); - - expect(event.args.value).to.be.bignumber.equal(amount); - }); - }); - }); - - describe('_burn', function () { - it('rejects a null account', async function () { - await expectRevert(this.token.burn(ZERO_ADDRESS, new BN(1)), - 'ERC20: burn from the zero address'); - }); - - describe('for a non zero account', function () { - it('rejects burning more than balance', async function () { - await expectRevert(this.token.burn( - initialHolder, initialSupply.addn(1)), 'ERC20: burn amount exceeds balance', - ); - }); - - const describeBurn = function (description, amount) { - describe(description, function () { - beforeEach('burning', async function () { - this.receipt = await this.token.burn(initialHolder, amount); - }); - - it('decrements totalSupply', async function () { - const expectedSupply = initialSupply.sub(amount); - expect(await this.token.totalSupply()).to.be.bignumber.equal(expectedSupply); - }); - - it('decrements initialHolder balance', async function () { - const expectedBalance = initialSupply.sub(amount); - expect(await this.token.balanceOf(initialHolder)).to.be.bignumber.equal(expectedBalance); - }); - - it('emits Transfer event', async function () { - const event = expectEvent( - this.receipt, - 'Transfer', - { from: initialHolder, to: ZERO_ADDRESS }, - ); - - expect(event.args.value).to.be.bignumber.equal(amount); - }); - }); - }; - - describeBurn('for entire balance', initialSupply); - describeBurn('for less amount than balance', initialSupply.subn(1)); - }); - }); - - describe('_transfer', function () { - shouldBehaveLikeERC20Transfer('ERC20', initialHolder, recipient, initialSupply, function (from, to, amount) { - return this.token.transferInternal(from, to, amount); - }); - - describe('when the sender is the zero address', function () { - it('reverts', async function () { - await expectRevert(this.token.transferInternal(ZERO_ADDRESS, recipient, initialSupply), - 'ERC20: transfer from the zero address', - ); - }); - }); - }); - - describe('_approve', function () { - shouldBehaveLikeERC20Approve('ERC20', initialHolder, recipient, initialSupply, function (owner, spender, amount) { - return this.token.approveInternal(owner, spender, amount); - }); - - describe('when the owner is the zero address', function () { - it('reverts', async function () { - await expectRevert(this.token.approveInternal(ZERO_ADDRESS, recipient, initialSupply), - 'ERC20: approve from the zero address', - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.behavior.js deleted file mode 100644 index a931bf6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.behavior.js +++ /dev/null @@ -1,109 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) { - describe('burn', function () { - describe('when the given amount is not greater than balance of the sender', function () { - context('for a zero amount', function () { - shouldBurn(new BN(0)); - }); - - context('for a non-zero amount', function () { - shouldBurn(new BN(100)); - }); - - function shouldBurn (amount) { - beforeEach(async function () { - (this.receipt = await this.token.burn(amount, { from: owner })); - }); - - it('burns the requested amount', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialBalance.sub(amount)); - }); - - it('emits a transfer event', async function () { - expectEvent(this.receipt, 'Transfer', { - from: owner, - to: ZERO_ADDRESS, - value: amount, - }); - }); - } - }); - - describe('when the given amount is greater than the balance of the sender', function () { - const amount = initialBalance.addn(1); - - it('reverts', async function () { - await expectRevert(this.token.burn(amount, { from: owner }), - 'ERC20: burn amount exceeds balance', - ); - }); - }); - }); - - describe('burnFrom', function () { - describe('on success', function () { - context('for a zero amount', function () { - shouldBurnFrom(new BN(0)); - }); - - context('for a non-zero amount', function () { - shouldBurnFrom(new BN(100)); - }); - - function shouldBurnFrom (amount) { - const originalAllowance = amount.muln(3); - - beforeEach(async function () { - await this.token.approve(burner, originalAllowance, { from: owner }); - this.receipt = await this.token.burnFrom(owner, amount, { from: burner }); - }); - - it('burns the requested amount', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialBalance.sub(amount)); - }); - - it('decrements allowance', async function () { - expect(await this.token.allowance(owner, burner)).to.be.bignumber.equal(originalAllowance.sub(amount)); - }); - - it('emits a transfer event', async function () { - expectEvent(this.receipt, 'Transfer', { - from: owner, - to: ZERO_ADDRESS, - value: amount, - }); - }); - } - }); - - describe('when the given amount is greater than the balance of the sender', function () { - const amount = initialBalance.addn(1); - - it('reverts', async function () { - await this.token.approve(burner, amount, { from: owner }); - await expectRevert(this.token.burnFrom(owner, amount, { from: burner }), - 'ERC20: burn amount exceeds balance', - ); - }); - }); - - describe('when the given amount is greater than the allowance', function () { - const allowance = new BN(100); - - it('reverts', async function () { - await this.token.approve(burner, allowance, { from: owner }); - await expectRevert(this.token.burnFrom(owner, allowance.addn(1), { from: burner }), - 'ERC20: insufficient allowance', - ); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC20Burnable, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js deleted file mode 100644 index 8aa4fb6..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Burnable.test.js +++ /dev/null @@ -1,19 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const { shouldBehaveLikeERC20Burnable } = require('./ERC20Burnable.behavior'); -const ERC20BurnableMock = artifacts.require('ERC20BurnableMock'); - -contract('ERC20Burnable', function (accounts) { - const [ owner, ...otherAccounts ] = accounts; - - const initialBalance = new BN(1000); - - const name = 'My Token'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.token = await ERC20BurnableMock.new(name, symbol, owner, initialBalance, { from: owner }); - }); - - shouldBehaveLikeERC20Burnable(owner, initialBalance, otherAccounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.behavior.js deleted file mode 100644 index 4692f99..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.behavior.js +++ /dev/null @@ -1,32 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -function shouldBehaveLikeERC20Capped (minter, [other], cap) { - describe('capped token', function () { - const from = minter; - - it('starts with the correct cap', async function () { - expect(await this.token.cap()).to.be.bignumber.equal(cap); - }); - - it('mints when amount is less than cap', async function () { - await this.token.mint(other, cap.subn(1), { from }); - expect(await this.token.totalSupply()).to.be.bignumber.equal(cap.subn(1)); - }); - - it('fails to mint if the amount exceeds the cap', async function () { - await this.token.mint(other, cap.subn(1), { from }); - await expectRevert(this.token.mint(other, 2, { from }), 'ERC20Capped: cap exceeded'); - }); - - it('fails to mint after cap is reached', async function () { - await this.token.mint(other, cap, { from }); - await expectRevert(this.token.mint(other, 1, { from }), 'ERC20Capped: cap exceeded'); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC20Capped, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js deleted file mode 100644 index 76532ce..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Capped.test.js +++ /dev/null @@ -1,27 +0,0 @@ -const { BN, ether, expectRevert } = require('@openzeppelin/test-helpers'); -const { shouldBehaveLikeERC20Capped } = require('./ERC20Capped.behavior'); - -const ERC20Capped = artifacts.require('ERC20CappedMock'); - -contract('ERC20Capped', function (accounts) { - const [ minter, ...otherAccounts ] = accounts; - - const cap = ether('1000'); - - const name = 'My Token'; - const symbol = 'MTKN'; - - it('requires a non-zero cap', async function () { - await expectRevert( - ERC20Capped.new(name, symbol, new BN(0), { from: minter }), 'ERC20Capped: cap is 0', - ); - }); - - context('once deployed', async function () { - beforeEach(async function () { - this.token = await ERC20Capped.new(name, symbol, cap, { from: minter }); - }); - - shouldBehaveLikeERC20Capped(minter, otherAccounts, cap); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js deleted file mode 100644 index 01c08db..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20FlashMint.test.js +++ /dev/null @@ -1,144 +0,0 @@ -/* eslint-disable */ - -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256, ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const ERC20FlashMintMock = artifacts.require('ERC20FlashMintMock'); -const ERC3156FlashBorrowerMock = artifacts.require('ERC3156FlashBorrowerMock'); - -contract('ERC20FlashMint', function (accounts) { - const [ initialHolder, other, anotherAccount ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - const initialSupply = new BN(100); - const loanAmount = new BN(10000000000000); - - beforeEach(async function () { - this.token = await ERC20FlashMintMock.new(name, symbol, initialHolder, initialSupply); - }); - - describe('maxFlashLoan', function () { - it('token match', async function () { - expect(await this.token.maxFlashLoan(this.token.address)).to.be.bignumber.equal(MAX_UINT256.sub(initialSupply)); - }); - - it('token mismatch', async function () { - expect(await this.token.maxFlashLoan(ZERO_ADDRESS)).to.be.bignumber.equal('0'); - }); - }); - - describe('flashFee', function () { - it('token match', async function () { - expect(await this.token.flashFee(this.token.address, loanAmount)).to.be.bignumber.equal('0'); - }); - - it('token mismatch', async function () { - await expectRevert(this.token.flashFee(ZERO_ADDRESS, loanAmount), 'ERC20FlashMint: wrong token'); - }); - }); - - describe('flashFeeReceiver', function () { - it('default receiver', async function () { - expect(await this.token.flashFeeReceiver()).to.be.eq(ZERO_ADDRESS); - }); - }); - - describe('flashLoan', function () { - it('success', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(true, true); - const { tx } = await this.token.flashLoan(receiver.address, this.token.address, loanAmount, '0x'); - - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: ZERO_ADDRESS, to: receiver.address, value: loanAmount }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: receiver.address, to: ZERO_ADDRESS, value: loanAmount }); - await expectEvent.inTransaction(tx, receiver, 'BalanceOf', { token: this.token.address, account: receiver.address, value: loanAmount }); - await expectEvent.inTransaction(tx, receiver, 'TotalSupply', { token: this.token.address, value: initialSupply.add(loanAmount) }); - - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOf(receiver.address)).to.be.bignumber.equal('0'); - expect(await this.token.allowance(receiver.address, this.token.address)).to.be.bignumber.equal('0'); - }); - - it ('missing return value', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(false, true); - await expectRevert( - this.token.flashLoan(receiver.address, this.token.address, loanAmount, '0x'), - 'ERC20FlashMint: invalid return value', - ); - }); - - it ('missing approval', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(true, false); - await expectRevert( - this.token.flashLoan(receiver.address, this.token.address, loanAmount, '0x'), - 'ERC20: insufficient allowance', - ); - }); - - it ('unavailable funds', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(true, true); - const data = this.token.contract.methods.transfer(other, 10).encodeABI(); - await expectRevert( - this.token.flashLoan(receiver.address, this.token.address, loanAmount, data), - 'ERC20: burn amount exceeds balance', - ); - }); - - it ('more than maxFlashLoan', async function () { - const receiver = await ERC3156FlashBorrowerMock.new(true, true); - const data = this.token.contract.methods.transfer(other, 10).encodeABI(); - // _mint overflow reverts using a panic code. No reason string. - await expectRevert.unspecified(this.token.flashLoan(receiver.address, this.token.address, MAX_UINT256, data)); - }); - - describe('custom flash fee & custom fee receiver', function () { - const receiverInitialBalance = new BN(200000); - const flashFee = new BN(5000); - - beforeEach('init reciever balance & set flash fee',async function () { - this.receiver = await ERC3156FlashBorrowerMock.new(true, true); - const receipt = await this.token.mint(this.receiver.address, receiverInitialBalance); - await expectEvent(receipt, 'Transfer', { from: ZERO_ADDRESS, to: this.receiver.address, value: receiverInitialBalance }); - expect(await this.token.balanceOf(this.receiver.address)).to.be.bignumber.equal(receiverInitialBalance); - - await this.token.setFlashFee(flashFee); - expect(await this.token.flashFee(this.token.address, loanAmount)).to.be.bignumber.equal(flashFee); - }); - - it('default flash fee receiver', async function () { - const { tx } = await this.token.flashLoan(this.receiver.address, this.token.address, loanAmount, '0x'); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: ZERO_ADDRESS, to: this.receiver.address, value: loanAmount }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: this.receiver.address, to: ZERO_ADDRESS, value: loanAmount.add (flashFee)}); - await expectEvent.inTransaction(tx, this.receiver, 'BalanceOf', { token: this.token.address, account: this.receiver.address, value: receiverInitialBalance.add(loanAmount) }); - await expectEvent.inTransaction(tx, this.receiver, 'TotalSupply', { token: this.token.address, value: initialSupply.add (receiverInitialBalance).add(loanAmount) }); - - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply.add(receiverInitialBalance).sub(flashFee)); - expect(await this.token.balanceOf(this.receiver.address)).to.be.bignumber.equal(receiverInitialBalance.sub(flashFee)); - expect(await this.token.balanceOf(await this.token.flashFeeReceiver())).to.be.bignumber.equal('0'); - expect(await this.token.allowance(this.receiver.address, this.token.address)).to.be.bignumber.equal('0'); - }); - - it('custom flash fee receiver', async function () { - const flashFeeReceiverAddress = anotherAccount; - await this.token.setFlashFeeReceiver(flashFeeReceiverAddress); - expect(await this.token.flashFeeReceiver()).to.be.eq(flashFeeReceiverAddress); - - expect(await this.token.balanceOf(flashFeeReceiverAddress)).to.be.bignumber.equal('0'); - - const { tx } = await this.token.flashLoan(this.receiver.address, this.token.address, loanAmount, '0x'); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: ZERO_ADDRESS, to: this.receiver.address, value: loanAmount }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: this.receiver.address, to: ZERO_ADDRESS, value: loanAmount }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { from: this.receiver.address, to: flashFeeReceiverAddress, value: flashFee }); - await expectEvent.inTransaction(tx, this.receiver, 'BalanceOf', { token: this.token.address, account: this.receiver.address, value: receiverInitialBalance.add(loanAmount) }); - await expectEvent.inTransaction(tx, this.receiver, 'TotalSupply', { token: this.token.address, value: initialSupply.add (receiverInitialBalance).add(loanAmount) }); - - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply.add(receiverInitialBalance)); - expect(await this.token.balanceOf(this.receiver.address)).to.be.bignumber.equal(receiverInitialBalance.sub(flashFee)); - expect(await this.token.balanceOf(flashFeeReceiverAddress)).to.be.bignumber.equal(flashFee); - expect(await this.token.allowance(this.receiver.address, flashFeeReceiverAddress)).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js deleted file mode 100644 index 8670e2f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Pausable.test.js +++ /dev/null @@ -1,134 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC20PausableMock = artifacts.require('ERC20PausableMock'); - -contract('ERC20Pausable', function (accounts) { - const [ holder, recipient, anotherAccount ] = accounts; - - const initialSupply = new BN(100); - - const name = 'My Token'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.token = await ERC20PausableMock.new(name, symbol, holder, initialSupply); - }); - - describe('pausable token', function () { - describe('transfer', function () { - it('allows to transfer when unpaused', async function () { - await this.token.transfer(recipient, initialSupply, { from: holder }); - - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(initialSupply); - }); - - it('allows to transfer when paused and then unpaused', async function () { - await this.token.pause(); - await this.token.unpause(); - - await this.token.transfer(recipient, initialSupply, { from: holder }); - - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(initialSupply); - }); - - it('reverts when trying to transfer when paused', async function () { - await this.token.pause(); - - await expectRevert(this.token.transfer(recipient, initialSupply, { from: holder }), - 'ERC20Pausable: token transfer while paused', - ); - }); - }); - - describe('transfer from', function () { - const allowance = new BN(40); - - beforeEach(async function () { - await this.token.approve(anotherAccount, allowance, { from: holder }); - }); - - it('allows to transfer from when unpaused', async function () { - await this.token.transferFrom(holder, recipient, allowance, { from: anotherAccount }); - - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(allowance); - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(allowance)); - }); - - it('allows to transfer when paused and then unpaused', async function () { - await this.token.pause(); - await this.token.unpause(); - - await this.token.transferFrom(holder, recipient, allowance, { from: anotherAccount }); - - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(allowance); - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(allowance)); - }); - - it('reverts when trying to transfer from when paused', async function () { - await this.token.pause(); - - await expectRevert(this.token.transferFrom( - holder, recipient, allowance, { from: anotherAccount }), 'ERC20Pausable: token transfer while paused', - ); - }); - }); - - describe('mint', function () { - const amount = new BN('42'); - - it('allows to mint when unpaused', async function () { - await this.token.mint(recipient, amount); - - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(amount); - }); - - it('allows to mint when paused and then unpaused', async function () { - await this.token.pause(); - await this.token.unpause(); - - await this.token.mint(recipient, amount); - - expect(await this.token.balanceOf(recipient)).to.be.bignumber.equal(amount); - }); - - it('reverts when trying to mint when paused', async function () { - await this.token.pause(); - - await expectRevert(this.token.mint(recipient, amount), - 'ERC20Pausable: token transfer while paused', - ); - }); - }); - - describe('burn', function () { - const amount = new BN('42'); - - it('allows to burn when unpaused', async function () { - await this.token.burn(holder, amount); - - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(amount)); - }); - - it('allows to burn when paused and then unpaused', async function () { - await this.token.pause(); - await this.token.unpause(); - - await this.token.burn(holder, amount); - - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply.sub(amount)); - }); - - it('reverts when trying to burn when paused', async function () { - await this.token.pause(); - - await expectRevert(this.token.burn(holder, amount), - 'ERC20Pausable: token transfer while paused', - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Snapshot.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Snapshot.test.js deleted file mode 100644 index 64d9227..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Snapshot.test.js +++ /dev/null @@ -1,204 +0,0 @@ -const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const ERC20SnapshotMock = artifacts.require('ERC20SnapshotMock'); - -const { expect } = require('chai'); - -contract('ERC20Snapshot', function (accounts) { - const [ initialHolder, recipient, other ] = accounts; - - const initialSupply = new BN(100); - - const name = 'My Token'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.token = await ERC20SnapshotMock.new(name, symbol, initialHolder, initialSupply); - }); - - describe('snapshot', function () { - it('emits a snapshot event', async function () { - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot'); - }); - - it('creates increasing snapshots ids, starting from 1', async function () { - for (const id of ['1', '2', '3', '4', '5']) { - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id }); - } - }); - }); - - describe('totalSupplyAt', function () { - it('reverts with a snapshot id of 0', async function () { - await expectRevert(this.token.totalSupplyAt(0), 'ERC20Snapshot: id is 0'); - }); - - it('reverts with a not-yet-created snapshot id', async function () { - await expectRevert(this.token.totalSupplyAt(1), 'ERC20Snapshot: nonexistent id'); - }); - - context('with initial snapshot', function () { - beforeEach(async function () { - this.initialSnapshotId = new BN('1'); - - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id: this.initialSnapshotId }); - }); - - context('with no supply changes after the snapshot', function () { - it('returns the current total supply', async function () { - expect(await this.token.totalSupplyAt(this.initialSnapshotId)).to.be.bignumber.equal(initialSupply); - }); - }); - - context('with supply changes after the snapshot', function () { - beforeEach(async function () { - await this.token.mint(other, new BN('50')); - await this.token.burn(initialHolder, new BN('20')); - }); - - it('returns the total supply before the changes', async function () { - expect(await this.token.totalSupplyAt(this.initialSnapshotId)).to.be.bignumber.equal(initialSupply); - }); - - context('with a second snapshot after supply changes', function () { - beforeEach(async function () { - this.secondSnapshotId = new BN('2'); - - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id: this.secondSnapshotId }); - }); - - it('snapshots return the supply before and after the changes', async function () { - expect(await this.token.totalSupplyAt(this.initialSnapshotId)).to.be.bignumber.equal(initialSupply); - - expect(await this.token.totalSupplyAt(this.secondSnapshotId)).to.be.bignumber.equal( - await this.token.totalSupply(), - ); - }); - }); - - context('with multiple snapshots after supply changes', function () { - beforeEach(async function () { - this.secondSnapshotIds = ['2', '3', '4']; - - for (const id of this.secondSnapshotIds) { - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id }); - } - }); - - it('all posterior snapshots return the supply after the changes', async function () { - expect(await this.token.totalSupplyAt(this.initialSnapshotId)).to.be.bignumber.equal(initialSupply); - - const currentSupply = await this.token.totalSupply(); - - for (const id of this.secondSnapshotIds) { - expect(await this.token.totalSupplyAt(id)).to.be.bignumber.equal(currentSupply); - } - }); - }); - }); - }); - }); - - describe('balanceOfAt', function () { - it('reverts with a snapshot id of 0', async function () { - await expectRevert(this.token.balanceOfAt(other, 0), 'ERC20Snapshot: id is 0'); - }); - - it('reverts with a not-yet-created snapshot id', async function () { - await expectRevert(this.token.balanceOfAt(other, 1), 'ERC20Snapshot: nonexistent id'); - }); - - context('with initial snapshot', function () { - beforeEach(async function () { - this.initialSnapshotId = new BN('1'); - - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id: this.initialSnapshotId }); - }); - - context('with no balance changes after the snapshot', function () { - it('returns the current balance for all accounts', async function () { - expect(await this.token.balanceOfAt(initialHolder, this.initialSnapshotId)) - .to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOfAt(recipient, this.initialSnapshotId)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOfAt(other, this.initialSnapshotId)).to.be.bignumber.equal('0'); - }); - }); - - context('with balance changes after the snapshot', function () { - beforeEach(async function () { - await this.token.transfer(recipient, new BN('10'), { from: initialHolder }); - await this.token.mint(other, new BN('50')); - await this.token.burn(initialHolder, new BN('20')); - }); - - it('returns the balances before the changes', async function () { - expect(await this.token.balanceOfAt(initialHolder, this.initialSnapshotId)) - .to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOfAt(recipient, this.initialSnapshotId)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOfAt(other, this.initialSnapshotId)).to.be.bignumber.equal('0'); - }); - - context('with a second snapshot after supply changes', function () { - beforeEach(async function () { - this.secondSnapshotId = new BN('2'); - - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id: this.secondSnapshotId }); - }); - - it('snapshots return the balances before and after the changes', async function () { - expect(await this.token.balanceOfAt(initialHolder, this.initialSnapshotId)) - .to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOfAt(recipient, this.initialSnapshotId)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOfAt(other, this.initialSnapshotId)).to.be.bignumber.equal('0'); - - expect(await this.token.balanceOfAt(initialHolder, this.secondSnapshotId)).to.be.bignumber.equal( - await this.token.balanceOf(initialHolder), - ); - expect(await this.token.balanceOfAt(recipient, this.secondSnapshotId)).to.be.bignumber.equal( - await this.token.balanceOf(recipient), - ); - expect(await this.token.balanceOfAt(other, this.secondSnapshotId)).to.be.bignumber.equal( - await this.token.balanceOf(other), - ); - }); - }); - - context('with multiple snapshots after supply changes', function () { - beforeEach(async function () { - this.secondSnapshotIds = ['2', '3', '4']; - - for (const id of this.secondSnapshotIds) { - const receipt = await this.token.snapshot(); - expectEvent(receipt, 'Snapshot', { id }); - } - }); - - it('all posterior snapshots return the supply after the changes', async function () { - expect(await this.token.balanceOfAt(initialHolder, this.initialSnapshotId)) - .to.be.bignumber.equal(initialSupply); - expect(await this.token.balanceOfAt(recipient, this.initialSnapshotId)).to.be.bignumber.equal('0'); - expect(await this.token.balanceOfAt(other, this.initialSnapshotId)).to.be.bignumber.equal('0'); - - for (const id of this.secondSnapshotIds) { - expect(await this.token.balanceOfAt(initialHolder, id)).to.be.bignumber.equal( - await this.token.balanceOf(initialHolder), - ); - expect(await this.token.balanceOfAt(recipient, id)).to.be.bignumber.equal( - await this.token.balanceOf(recipient), - ); - expect(await this.token.balanceOfAt(other, id)).to.be.bignumber.equal( - await this.token.balanceOf(other), - ); - } - }); - }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js deleted file mode 100644 index be28f66..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Votes.test.js +++ /dev/null @@ -1,505 +0,0 @@ -/* eslint-disable */ - -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256, ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const ERC20VotesMock = artifacts.require('ERC20VotesMock'); - -const { batchInBlock } = require('../../../helpers/txpool'); -const { EIP712Domain, domainSeparator } = require('../../../helpers/eip712'); - -const Delegation = [ - { name: 'delegatee', type: 'address' }, - { name: 'nonce', type: 'uint256' }, - { name: 'expiry', type: 'uint256' }, -]; - -contract('ERC20Votes', function (accounts) { - const [ holder, recipient, holderDelegatee, recipientDelegatee, other1, other2 ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - const version = '1'; - const supply = new BN('10000000000000000000000000'); - - beforeEach(async function () { - this.token = await ERC20VotesMock.new(name, symbol); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.token.getChainId(); - }); - - it('initial nonce is 0', async function () { - expect(await this.token.nonces(holder)).to.be.bignumber.equal('0'); - }); - - it('domain separator', async function () { - expect( - await this.token.DOMAIN_SEPARATOR(), - ).to.equal( - await domainSeparator(name, version, this.chainId, this.token.address), - ); - }); - - it('minting restriction', async function () { - const amount = new BN('2').pow(new BN('224')); - await expectRevert( - this.token.mint(holder, amount), - 'ERC20Votes: total supply risks overflowing votes', - ); - }); - - describe('set delegation', function () { - describe('call', function () { - it('delegation with balance', async function () { - await this.token.mint(holder, supply); - expect(await this.token.delegates(holder)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegate(holder, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: ZERO_ADDRESS, - toDelegate: holder, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holder, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(holder)).to.be.equal(holder); - - expect(await this.token.getVotes(holder)).to.be.bignumber.equal(supply); - expect(await this.token.getPastVotes(holder, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPastVotes(holder, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - - it('delegation without balance', async function () { - expect(await this.token.delegates(holder)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegate(holder, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: ZERO_ADDRESS, - toDelegate: holder, - }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - expect(await this.token.delegates(holder)).to.be.equal(holder); - }); - }); - - describe('with signature', function () { - const delegator = Wallet.generate(); - const delegatorAddress = web3.utils.toChecksumAddress(delegator.getAddressString()); - const nonce = 0; - - const buildData = (chainId, verifyingContract, message) => ({ data: { - primaryType: 'Delegation', - types: { EIP712Domain, Delegation }, - domain: { name, version, chainId, verifyingContract }, - message, - }}); - - beforeEach(async function () { - await this.token.mint(delegatorAddress, supply); - }); - - it('accept signed delegation', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - expect(await this.token.delegates(delegatorAddress)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - expectEvent(receipt, 'DelegateChanged', { - delegator: delegatorAddress, - fromDelegate: ZERO_ADDRESS, - toDelegate: delegatorAddress, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: delegatorAddress, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(delegatorAddress)).to.be.equal(delegatorAddress); - - expect(await this.token.getVotes(delegatorAddress)).to.be.bignumber.equal(supply); - expect(await this.token.getPastVotes(delegatorAddress, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPastVotes(delegatorAddress, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - - it('rejects reused signature', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - await this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s), - 'ERC20Votes: invalid nonce', - ); - }); - - it('rejects bad delegatee', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - const receipt = await this.token.delegateBySig(holderDelegatee, nonce, MAX_UINT256, v, r, s); - const { args } = receipt.logs.find(({ event }) => event == 'DelegateChanged'); - expect(args.delegator).to.not.be.equal(delegatorAddress); - expect(args.fromDelegate).to.be.equal(ZERO_ADDRESS); - expect(args.toDelegate).to.be.equal(holderDelegatee); - }); - - it('rejects bad nonce', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce + 1, MAX_UINT256, v, r, s), - 'ERC20Votes: invalid nonce', - ); - }); - - it('rejects expired permit', async function () { - const expiry = (await time.latest()) - time.duration.weeks(1); - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry, - }), - )); - - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce, expiry, v, r, s), - 'ERC20Votes: signature expired', - ); - }); - }); - }); - - describe('change delegation', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - await this.token.delegate(holder, { from: holder }); - }); - - it('call', async function () { - expect(await this.token.delegates(holder)).to.be.equal(holder); - - const { receipt } = await this.token.delegate(holderDelegatee, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: holder, - toDelegate: holderDelegatee, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holder, - previousBalance: supply, - newBalance: '0', - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holderDelegatee, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(holder)).to.be.equal(holderDelegatee); - - expect(await this.token.getVotes(holder)).to.be.bignumber.equal('0'); - expect(await this.token.getVotes(holderDelegatee)).to.be.bignumber.equal(supply); - expect(await this.token.getPastVotes(holder, receipt.blockNumber - 1)).to.be.bignumber.equal(supply); - expect(await this.token.getPastVotes(holderDelegatee, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPastVotes(holder, receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.token.getPastVotes(holderDelegatee, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - }); - - describe('transfers', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - }); - - it('no delegation', async function () { - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - this.holderVotes = '0'; - this.recipientVotes = '0'; - }); - - it('sender delegation', async function () { - await this.token.delegate(holder, { from: holder }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.holderVotes = supply.subn(1); - this.recipientVotes = '0'; - }); - - it('receiver delegation', async function () { - await this.token.delegate(recipient, { from: recipient }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.holderVotes = '0'; - this.recipientVotes = '1'; - }); - - it('full delegation', async function () { - await this.token.delegate(holder, { from: holder }); - await this.token.delegate(recipient, { from: recipient }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.holderVotes = supply.subn(1); - this.recipientVotes = '1'; - }); - - afterEach(async function () { - expect(await this.token.getVotes(holder)).to.be.bignumber.equal(this.holderVotes); - expect(await this.token.getVotes(recipient)).to.be.bignumber.equal(this.recipientVotes); - - // need to advance 2 blocks to see the effect of a transfer on "getPastVotes" - const blockNumber = await time.latestBlock(); - await time.advanceBlock(); - expect(await this.token.getPastVotes(holder, blockNumber)).to.be.bignumber.equal(this.holderVotes); - expect(await this.token.getPastVotes(recipient, blockNumber)).to.be.bignumber.equal(this.recipientVotes); - }); - }); - - // The following tests are a adaptation of https://github.com/compound-finance/compound-protocol/blob/master/tests/Governance/CompTest.js. - describe('Compound test suite', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - }); - - describe('balanceOf', function () { - it('grants to initial account', async function () { - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); - - describe('numCheckpoints', function () { - it('returns the number of checkpoints for a delegate', async function () { - await this.token.transfer(recipient, '100', { from: holder }); //give an account a few tokens for readability - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('0'); - - const t1 = await this.token.delegate(other1, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('1'); - - const t2 = await this.token.transfer(other2, 10, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('2'); - - const t3 = await this.token.transfer(other2, 10, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('3'); - - const t4 = await this.token.transfer(recipient, 20, { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('4'); - - expect(await this.token.checkpoints(other1, 0)).to.be.deep.equal([ t1.receipt.blockNumber.toString(), '100' ]); - expect(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ t2.receipt.blockNumber.toString(), '90' ]); - expect(await this.token.checkpoints(other1, 2)).to.be.deep.equal([ t3.receipt.blockNumber.toString(), '80' ]); - expect(await this.token.checkpoints(other1, 3)).to.be.deep.equal([ t4.receipt.blockNumber.toString(), '100' ]); - - await time.advanceBlock(); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('100'); - expect(await this.token.getPastVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('90'); - expect(await this.token.getPastVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('80'); - expect(await this.token.getPastVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('100'); - }); - - it('does not add more than one checkpoint in a block', async function () { - await this.token.transfer(recipient, '100', { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('0'); - - const [ t1, t2, t3 ] = await batchInBlock([ - () => this.token.delegate(other1, { from: recipient, gas: 100000 }), - () => this.token.transfer(other2, 10, { from: recipient, gas: 100000 }), - () => this.token.transfer(other2, 10, { from: recipient, gas: 100000 }), - ]); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('1'); - expect(await this.token.checkpoints(other1, 0)).to.be.deep.equal([ t1.receipt.blockNumber.toString(), '80' ]); - // expectReve(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ '0', '0' ]); // Reverts due to array overflow check - // expect(await this.token.checkpoints(other1, 2)).to.be.deep.equal([ '0', '0' ]); // Reverts due to array overflow check - - const t4 = await this.token.transfer(recipient, 20, { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('2'); - expect(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ t4.receipt.blockNumber.toString(), '100' ]); - }); - }); - - describe('getPastVotes', function () { - it('reverts if block number >= current block', async function () { - await expectRevert( - this.token.getPastVotes(other1, 5e10), - 'ERC20Votes: block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPastVotes(other1, 0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.token.transfer(other2, 10, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.token.transfer(other2, 10, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.token.transfer(holder, 20, { from: other2 }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastVotes(other1, t2.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastVotes(other1, t3.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastVotes(other1, t4.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); - }); - - describe('getPastTotalSupply', function () { - beforeEach(async function () { - await this.token.delegate(holder, { from: holder }); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.token.getPastTotalSupply(5e10), - 'ERC20Votes: block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPastTotalSupply(0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - t1 = await this.token.mint(holder, supply); - - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal(supply); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal(supply); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.token.mint(holder, supply); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.mint(holder, supply); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.token.burn(holder, 10); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.token.burn(holder, 10); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.token.mint(holder, 20); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t2.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastTotalSupply(t2.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastTotalSupply(t3.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastTotalSupply(t3.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastTotalSupply(t4.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t4.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20VotesComp.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20VotesComp.test.js deleted file mode 100644 index b70c6d1..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20VotesComp.test.js +++ /dev/null @@ -1,496 +0,0 @@ -/* eslint-disable */ - -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256, ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const ERC20VotesCompMock = artifacts.require('ERC20VotesCompMock'); - -const { batchInBlock } = require('../../../helpers/txpool'); -const { EIP712Domain, domainSeparator } = require('../../../helpers/eip712'); - -const Delegation = [ - { name: 'delegatee', type: 'address' }, - { name: 'nonce', type: 'uint256' }, - { name: 'expiry', type: 'uint256' }, -]; - -contract('ERC20VotesComp', function (accounts) { - const [ holder, recipient, holderDelegatee, recipientDelegatee, other1, other2 ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - const version = '1'; - const supply = new BN('10000000000000000000000000'); - - beforeEach(async function () { - this.token = await ERC20VotesCompMock.new(name, symbol); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.token.getChainId(); - }); - - it('initial nonce is 0', async function () { - expect(await this.token.nonces(holder)).to.be.bignumber.equal('0'); - }); - - it('domain separator', async function () { - expect( - await this.token.DOMAIN_SEPARATOR(), - ).to.equal( - await domainSeparator(name, version, this.chainId, this.token.address), - ); - }); - - it('minting restriction', async function () { - const amount = new BN('2').pow(new BN('96')); - await expectRevert( - this.token.mint(holder, amount), - 'ERC20Votes: total supply risks overflowing votes', - ); - }); - - describe('set delegation', function () { - describe('call', function () { - it('delegation with balance', async function () { - await this.token.mint(holder, supply); - expect(await this.token.delegates(holder)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegate(holder, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: ZERO_ADDRESS, - toDelegate: holder, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holder, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(holder)).to.be.equal(holder); - - expect(await this.token.getCurrentVotes(holder)).to.be.bignumber.equal(supply); - expect(await this.token.getPriorVotes(holder, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPriorVotes(holder, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - - it('delegation without balance', async function () { - expect(await this.token.delegates(holder)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegate(holder, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: ZERO_ADDRESS, - toDelegate: holder, - }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - expect(await this.token.delegates(holder)).to.be.equal(holder); - }); - }); - - describe('with signature', function () { - const delegator = Wallet.generate(); - const delegatorAddress = web3.utils.toChecksumAddress(delegator.getAddressString()); - const nonce = 0; - - const buildData = (chainId, verifyingContract, message) => ({ data: { - primaryType: 'Delegation', - types: { EIP712Domain, Delegation }, - domain: { name, version, chainId, verifyingContract }, - message, - }}); - - beforeEach(async function () { - await this.token.mint(delegatorAddress, supply); - }); - - it('accept signed delegation', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - expect(await this.token.delegates(delegatorAddress)).to.be.equal(ZERO_ADDRESS); - - const { receipt } = await this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - expectEvent(receipt, 'DelegateChanged', { - delegator: delegatorAddress, - fromDelegate: ZERO_ADDRESS, - toDelegate: delegatorAddress, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: delegatorAddress, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(delegatorAddress)).to.be.equal(delegatorAddress); - - expect(await this.token.getCurrentVotes(delegatorAddress)).to.be.bignumber.equal(supply); - expect(await this.token.getPriorVotes(delegatorAddress, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPriorVotes(delegatorAddress, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - - it('rejects reused signature', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - await this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s); - - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce, MAX_UINT256, v, r, s), - 'ERC20Votes: invalid nonce', - ); - }); - - it('rejects bad delegatee', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - - const receipt = await this.token.delegateBySig(holderDelegatee, nonce, MAX_UINT256, v, r, s); - const { args } = receipt.logs.find(({ event }) => event == 'DelegateChanged'); - expect(args.delegator).to.not.be.equal(delegatorAddress); - expect(args.fromDelegate).to.be.equal(ZERO_ADDRESS); - expect(args.toDelegate).to.be.equal(holderDelegatee); - }); - - it('rejects bad nonce', async function () { - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry: MAX_UINT256, - }), - )); - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce + 1, MAX_UINT256, v, r, s), - 'ERC20Votes: invalid nonce', - ); - }); - - it('rejects expired permit', async function () { - const expiry = (await time.latest()) - time.duration.weeks(1); - const { v, r, s } = fromRpcSig(ethSigUtil.signTypedMessage( - delegator.getPrivateKey(), - buildData(this.chainId, this.token.address, { - delegatee: delegatorAddress, - nonce, - expiry, - }), - )); - - await expectRevert( - this.token.delegateBySig(delegatorAddress, nonce, expiry, v, r, s), - 'ERC20Votes: signature expired', - ); - }); - }); - }); - - describe('change delegation', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - await this.token.delegate(holder, { from: holder }); - }); - - it('call', async function () { - expect(await this.token.delegates(holder)).to.be.equal(holder); - - const { receipt } = await this.token.delegate(holderDelegatee, { from: holder }); - expectEvent(receipt, 'DelegateChanged', { - delegator: holder, - fromDelegate: holder, - toDelegate: holderDelegatee, - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holder, - previousBalance: supply, - newBalance: '0', - }); - expectEvent(receipt, 'DelegateVotesChanged', { - delegate: holderDelegatee, - previousBalance: '0', - newBalance: supply, - }); - - expect(await this.token.delegates(holder)).to.be.equal(holderDelegatee); - - expect(await this.token.getCurrentVotes(holder)).to.be.bignumber.equal('0'); - expect(await this.token.getCurrentVotes(holderDelegatee)).to.be.bignumber.equal(supply); - expect(await this.token.getPriorVotes(holder, receipt.blockNumber - 1)).to.be.bignumber.equal(supply); - expect(await this.token.getPriorVotes(holderDelegatee, receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - await time.advanceBlock(); - expect(await this.token.getPriorVotes(holder, receipt.blockNumber)).to.be.bignumber.equal('0'); - expect(await this.token.getPriorVotes(holderDelegatee, receipt.blockNumber)).to.be.bignumber.equal(supply); - }); - }); - - describe('transfers', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - }); - - it('no delegation', async function () { - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - this.holderVotes = '0'; - this.recipientVotes = '0'; - }); - - it('sender delegation', async function () { - await this.token.delegate(holder, { from: holder }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); - - this.holderVotes = supply.subn(1); - this.recipientVotes = '0'; - }); - - it('receiver delegation', async function () { - await this.token.delegate(recipient, { from: recipient }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); - - this.holderVotes = '0'; - this.recipientVotes = '1'; - }); - - it('full delegation', async function () { - await this.token.delegate(holder, { from: holder }); - await this.token.delegate(recipient, { from: recipient }); - - const { receipt } = await this.token.transfer(recipient, 1, { from: holder }); - expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); - - this.holderVotes = supply.subn(1); - this.recipientVotes = '1'; - }); - - afterEach(async function () { - expect(await this.token.getCurrentVotes(holder)).to.be.bignumber.equal(this.holderVotes); - expect(await this.token.getCurrentVotes(recipient)).to.be.bignumber.equal(this.recipientVotes); - - // need to advance 2 blocks to see the effect of a transfer on "getPriorVotes" - const blockNumber = await time.latestBlock(); - await time.advanceBlock(); - expect(await this.token.getPriorVotes(holder, blockNumber)).to.be.bignumber.equal(this.holderVotes); - expect(await this.token.getPriorVotes(recipient, blockNumber)).to.be.bignumber.equal(this.recipientVotes); - }); - }); - - // The following tests are a adaptation of https://github.com/compound-finance/compound-protocol/blob/master/tests/Governance/CompTest.js. - describe('Compound test suite', function () { - beforeEach(async function () { - await this.token.mint(holder, supply); - }); - - describe('balanceOf', function () { - it('grants to initial account', async function () { - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); - - describe('numCheckpoints', function () { - it('returns the number of checkpoints for a delegate', async function () { - await this.token.transfer(recipient, '100', { from: holder }); //give an account a few tokens for readability - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('0'); - - const t1 = await this.token.delegate(other1, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('1'); - - const t2 = await this.token.transfer(other2, 10, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('2'); - - const t3 = await this.token.transfer(other2, 10, { from: recipient }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('3'); - - const t4 = await this.token.transfer(recipient, 20, { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('4'); - - expect(await this.token.checkpoints(other1, 0)).to.be.deep.equal([ t1.receipt.blockNumber.toString(), '100' ]); - expect(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ t2.receipt.blockNumber.toString(), '90' ]); - expect(await this.token.checkpoints(other1, 2)).to.be.deep.equal([ t3.receipt.blockNumber.toString(), '80' ]); - expect(await this.token.checkpoints(other1, 3)).to.be.deep.equal([ t4.receipt.blockNumber.toString(), '100' ]); - - await time.advanceBlock(); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('100'); - expect(await this.token.getPriorVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('90'); - expect(await this.token.getPriorVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('80'); - expect(await this.token.getPriorVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('100'); - }); - - it('does not add more than one checkpoint in a block', async function () { - await this.token.transfer(recipient, '100', { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('0'); - - const [ t1, t2, t3 ] = await batchInBlock([ - () => this.token.delegate(other1, { from: recipient, gas: 100000 }), - () => this.token.transfer(other2, 10, { from: recipient, gas: 100000 }), - () => this.token.transfer(other2, 10, { from: recipient, gas: 100000 }), - ]); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('1'); - expect(await this.token.checkpoints(other1, 0)).to.be.deep.equal([ t1.receipt.blockNumber.toString(), '80' ]); - // expectReve(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ '0', '0' ]); // Reverts due to array overflow check - // expect(await this.token.checkpoints(other1, 2)).to.be.deep.equal([ '0', '0' ]); // Reverts due to array overflow check - - const t4 = await this.token.transfer(recipient, 20, { from: holder }); - expect(await this.token.numCheckpoints(other1)).to.be.bignumber.equal('2'); - expect(await this.token.checkpoints(other1, 1)).to.be.deep.equal([ t4.receipt.blockNumber.toString(), '100' ]); - }); - }); - - describe('getPriorVotes', function () { - it('reverts if block number >= current block', async function () { - await expectRevert( - this.token.getPriorVotes(other1, 5e10), - 'ERC20Votes: block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPriorVotes(other1, 0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.delegate(other1, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.token.transfer(other2, 10, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.token.transfer(other2, 10, { from: holder }); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.token.transfer(holder, 20, { from: other2 }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPriorVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPriorVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPriorVotes(other1, t2.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPriorVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPriorVotes(other1, t3.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPriorVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPriorVotes(other1, t4.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); - }); - - describe('getPastTotalSupply', function () { - beforeEach(async function () { - await this.token.delegate(holder, { from: holder }); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.token.getPastTotalSupply(5e10), - 'ERC20Votes: block not yet mined', - ); - }); - - it('returns 0 if there are no checkpoints', async function () { - expect(await this.token.getPastTotalSupply(0)).to.be.bignumber.equal('0'); - }); - - it('returns the latest block if >= last checkpoint block', async function () { - t1 = await this.token.mint(holder, supply); - - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal(supply); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal(supply); - }); - - it('returns zero if < first checkpoint block', async function () { - await time.advanceBlock(); - const t1 = await this.token.mint(holder, supply); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - const t1 = await this.token.mint(holder, supply); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.token.burn(holder, 10); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.token.burn(holder, 10); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.token.mint(holder, 20); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t1.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t2.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastTotalSupply(t2.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999990'); - expect(await this.token.getPastTotalSupply(t3.receipt.blockNumber)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastTotalSupply(t3.receipt.blockNumber + 1)).to.be.bignumber.equal('9999999999999999999999980'); - expect(await this.token.getPastTotalSupply(t4.receipt.blockNumber)).to.be.bignumber.equal('10000000000000000000000000'); - expect(await this.token.getPastTotalSupply(t4.receipt.blockNumber + 1)).to.be.bignumber.equal('10000000000000000000000000'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js deleted file mode 100644 index ceb813e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC20Wrapper.test.js +++ /dev/null @@ -1,190 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS, MAX_UINT256 } = constants; - -const { shouldBehaveLikeERC20 } = require('../ERC20.behavior'); - -const NotAnERC20 = artifacts.require('CallReceiverMock'); -const ERC20Mock = artifacts.require('ERC20DecimalsMock'); -const ERC20WrapperMock = artifacts.require('ERC20WrapperMock'); - -contract('ERC20', function (accounts) { - const [ initialHolder, recipient, anotherAccount ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - const initialSupply = new BN(100); - - beforeEach(async function () { - this.underlying = await ERC20Mock.new(name, symbol, 9); - this.token = await ERC20WrapperMock.new(this.underlying.address, `Wrapped ${name}`, `W${symbol}`); - - await this.underlying.mint(initialHolder, initialSupply); - }); - - afterEach(async function () { - expect(await this.underlying.balanceOf(this.token.address)).to.be.bignumber.equal(await this.token.totalSupply()); - }); - - it('has a name', async function () { - expect(await this.token.name()).to.equal(`Wrapped ${name}`); - }); - - it('has a symbol', async function () { - expect(await this.token.symbol()).to.equal(`W${symbol}`); - }); - - it('has the same decimals as the underlying token', async function () { - expect(await this.token.decimals()).to.be.bignumber.equal('9'); - }); - - it('decimals default back to 18 if token has no metadata', async function () { - const noDecimals = await NotAnERC20.new(); - const otherToken = await ERC20WrapperMock.new(noDecimals.address, `Wrapped ${name}`, `W${symbol}`); - expect(await otherToken.decimals()).to.be.bignumber.equal('18'); - }); - - it('has underlying', async function () { - expect(await this.token.underlying()).to.be.bignumber.equal(this.underlying.address); - }); - - describe('deposit', function () { - it('valid', async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - const { tx } = await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: initialHolder, - to: this.token.address, - value: initialSupply, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: ZERO_ADDRESS, - to: initialHolder, - value: initialSupply, - }); - }); - - it('missing approval', async function () { - await expectRevert( - this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }), - 'ERC20: insufficient allowance', - ); - }); - - it('missing balance', async function () { - await this.underlying.approve(this.token.address, MAX_UINT256, { from: initialHolder }); - await expectRevert( - this.token.depositFor(initialHolder, MAX_UINT256, { from: initialHolder }), - 'ERC20: transfer amount exceeds balance', - ); - }); - - it('to other account', async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - const { tx } = await this.token.depositFor(anotherAccount, initialSupply, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: initialHolder, - to: this.token.address, - value: initialSupply, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: ZERO_ADDRESS, - to: anotherAccount, - value: initialSupply, - }); - }); - }); - - describe('withdraw', function () { - beforeEach(async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }); - }); - - it('missing balance', async function () { - await expectRevert( - this.token.withdrawTo(initialHolder, MAX_UINT256, { from: initialHolder }), - 'ERC20: burn amount exceeds balance', - ); - }); - - it('valid', async function () { - const value = new BN(42); - - const { tx } = await this.token.withdrawTo(initialHolder, value, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: this.token.address, - to: initialHolder, - value: value, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: initialHolder, - to: ZERO_ADDRESS, - value: value, - }); - }); - - it('entire balance', async function () { - const { tx } = await this.token.withdrawTo(initialHolder, initialSupply, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: this.token.address, - to: initialHolder, - value: initialSupply, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: initialHolder, - to: ZERO_ADDRESS, - value: initialSupply, - }); - }); - - it('to other account', async function () { - const { tx } = await this.token.withdrawTo(anotherAccount, initialSupply, { from: initialHolder }); - await expectEvent.inTransaction(tx, this.underlying, 'Transfer', { - from: this.token.address, - to: anotherAccount, - value: initialSupply, - }); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: initialHolder, - to: ZERO_ADDRESS, - value: initialSupply, - }); - }); - }); - - describe('recover', function () { - it('nothing to recover', async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }); - - const { tx } = await this.token.recover(anotherAccount); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: ZERO_ADDRESS, - to: anotherAccount, - value: '0', - }); - }); - - it('something to recover', async function () { - await this.underlying.transfer(this.token.address, initialSupply, { from: initialHolder }); - - const { tx } = await this.token.recover(anotherAccount); - await expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: ZERO_ADDRESS, - to: anotherAccount, - value: initialSupply, - }); - }); - }); - - describe('erc20 behaviour', function () { - beforeEach(async function () { - await this.underlying.approve(this.token.address, initialSupply, { from: initialHolder }); - await this.token.depositFor(initialHolder, initialSupply, { from: initialHolder }); - }); - - shouldBehaveLikeERC20('ERC20', initialSupply, initialHolder, recipient, anotherAccount); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js deleted file mode 100644 index 6f3d665..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/ERC4626.test.js +++ /dev/null @@ -1,612 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const ERC20DecimalsMock = artifacts.require('ERC20DecimalsMock'); -const ERC4626Mock = artifacts.require('ERC4626Mock'); - -const parseToken = (token) => (new BN(token)).mul(new BN('1000000000000')); -const parseShare = (share) => (new BN(share)).mul(new BN('1000000000000000000')); - -contract('ERC4626', function (accounts) { - const [ holder, recipient, spender, other, user1, user2 ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.token = await ERC20DecimalsMock.new(name, symbol, 12); - this.vault = await ERC4626Mock.new(this.token.address, name + ' Vault', symbol + 'V'); - - await this.token.mint(holder, web3.utils.toWei('100')); - await this.token.approve(this.vault.address, constants.MAX_UINT256, { from: holder }); - await this.vault.approve(spender, constants.MAX_UINT256, { from: holder }); - }); - - it('metadata', async function () { - expect(await this.vault.name()).to.be.equal(name + ' Vault'); - expect(await this.vault.symbol()).to.be.equal(symbol + 'V'); - expect(await this.vault.asset()).to.be.equal(this.token.address); - }); - - describe('empty vault: no assets & no shares', function () { - it('status', async function () { - expect(await this.vault.totalAssets()).to.be.bignumber.equal('0'); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewDeposit(parseToken(1))).to.be.bignumber.equal(parseShare(1)); - - const { tx } = await this.vault.deposit(parseToken(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewMint(parseShare(1))).to.be.bignumber.equal(parseToken(1)); - - const { tx } = await this.vault.mint(parseShare(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewWithdraw('0')).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.withdraw('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewRedeem('0')).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.redeem('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - }); - - describe('partially empty vault: assets & no shares', function () { - beforeEach(async function () { - await this.token.mint(this.vault.address, parseToken(1)); // 1 token - }); - - it('status', async function () { - expect(await this.vault.totalAssets()).to.be.bignumber.equal(parseToken(1)); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewDeposit(parseToken(1))).to.be.bignumber.equal(parseShare(1)); - - const { tx } = await this.vault.deposit(parseToken(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewMint(parseShare(1))).to.be.bignumber.equal(parseToken(1)); - - const { tx } = await this.vault.mint(parseShare(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewWithdraw('0')).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.withdraw('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewRedeem('0')).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.redeem('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - }); - - describe('partially empty vault: shares & no assets', function () { - beforeEach(async function () { - await this.vault.mockMint(holder, parseShare(1)); // 1 share - }); - - it('status', async function () { - expect(await this.vault.totalAssets()).to.be.bignumber.equal('0'); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(holder)).to.be.bignumber.equal('0'); - - // Can deposit 0 (max deposit) - const { tx } = await this.vault.deposit(0, recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: 0, - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: 0, - }); - - // Cannot deposit more than 0 - await expectRevert.unspecified(this.vault.previewDeposit(parseToken(1))); - await expectRevert( - this.vault.deposit(parseToken(1), recipient, { from: holder }), - 'ERC4626: deposit more than max', - ); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewMint(parseShare(1))).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.mint(parseShare(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(holder)).to.be.bignumber.equal('0'); - expect(await this.vault.previewWithdraw('0')).to.be.bignumber.equal('0'); - await expectRevert.unspecified(this.vault.previewWithdraw('1')); - - const { tx } = await this.vault.withdraw('0', recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: '0', - }); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(holder)).to.be.bignumber.equal(parseShare(1)); - expect(await this.vault.previewRedeem(parseShare(1))).to.be.bignumber.equal('0'); - - const { tx } = await this.vault.redeem(parseShare(1), recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: '0', - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: parseShare(1), - }); - }); - }); - - describe('full vault: assets & shares', function () { - beforeEach(async function () { - await this.token.mint(this.vault.address, parseToken(1)); // 1 tokens - await this.vault.mockMint(holder, parseShare(100)); // 100 share - }); - - it('status', async function () { - expect(await this.vault.totalAssets()).to.be.bignumber.equal(parseToken(1)); - }); - - it('deposit', async function () { - expect(await this.vault.maxDeposit(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewDeposit(parseToken(1))).to.be.bignumber.equal(parseShare(100)); - - const { tx } = await this.vault.deposit(parseToken(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(100), - }); - }); - - it('mint', async function () { - expect(await this.vault.maxMint(holder)).to.be.bignumber.equal(constants.MAX_UINT256); - expect(await this.vault.previewMint(parseShare(1))).to.be.bignumber.equal(parseToken(1).divn(100)); - - const { tx } = await this.vault.mint(parseShare(1), recipient, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: holder, - to: this.vault.address, - value: parseToken(1).divn(100), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: recipient, - value: parseShare(1), - }); - }); - - it('withdraw', async function () { - expect(await this.vault.maxWithdraw(holder)).to.be.bignumber.equal(parseToken(1)); - expect(await this.vault.previewWithdraw(parseToken(1))).to.be.bignumber.equal(parseShare(100)); - - const { tx } = await this.vault.withdraw(parseToken(1), recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: parseShare(100), - }); - }); - - it('withdraw with approval', async function () { - await expectRevert( - this.vault.withdraw(parseToken(1), recipient, holder, { from: other }), - 'ERC20: insufficient allowance', - ); - - await this.vault.withdraw(parseToken(1), recipient, holder, { from: spender }); - }); - - it('redeem', async function () { - expect(await this.vault.maxRedeem(holder)).to.be.bignumber.equal(parseShare(100)); - expect(await this.vault.previewRedeem(parseShare(100))).to.be.bignumber.equal(parseToken(1)); - - const { tx } = await this.vault.redeem(parseShare(100), recipient, holder, { from: holder }); - - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: recipient, - value: parseToken(1), - }); - - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: holder, - to: constants.ZERO_ADDRESS, - value: parseShare(100), - }); - }); - - it('redeem with approval', async function () { - await expectRevert( - this.vault.redeem(parseShare(100), recipient, holder, { from: other }), - 'ERC20: insufficient allowance', - ); - - await this.vault.redeem(parseShare(100), recipient, holder, { from: spender }); - }); - }); - - /// Scenario inspired by solmate ERC4626 tests: - /// https://github.com/transmissions11/solmate/blob/main/src/test/ERC4626.t.sol - it('multiple mint, deposit, redeem & withdrawal', async function () { - // test designed with both asset using similar decimals - this.token = await ERC20DecimalsMock.new(name, symbol, 18); - this.vault = await ERC4626Mock.new(this.token.address, name + ' Vault', symbol + 'V'); - - await this.token.mint(user1, 4000); - await this.token.mint(user2, 7001); - await this.token.approve(this.vault.address, 4000, { from: user1 }); - await this.token.approve(this.vault.address, 7001, { from: user2 }); - - // 1. Alice mints 2000 shares (costs 2000 tokens) - { - const { tx } = await this.vault.mint(2000, user1, { from: user1 }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: user1, - to: this.vault.address, - value: '2000', - }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: user1, - value: '2000', - }); - - expect(await this.vault.previewDeposit(2000)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('0'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('2000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('0'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('2000'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('2000'); - } - - // 2. Bob deposits 4000 tokens (mints 4000 shares) - { - const { tx } = await this.vault.mint(4000, user2, { from: user2 }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: user2, - to: this.vault.address, - value: '4000', - }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: user2, - value: '4000', - }); - - expect(await this.vault.previewDeposit(4000)).to.be.bignumber.equal('4000'); - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('2000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('4000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('6000'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('6000'); - } - - // 3. Vault mutates by +3000 tokens (simulated yield returned from strategy) - await this.token.mint(this.vault.address, 3000); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('3000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('6000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('6000'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('9000'); - - // 4. Alice deposits 2000 tokens (mints 1333 shares) - { - const { tx } = await this.vault.deposit(2000, user1, { from: user1 }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: user1, - to: this.vault.address, - value: '2000', - }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: user1, - value: '1333', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('3333'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('4999'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('6000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('7333'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('11000'); - } - - // 5. Bob mints 2000 shares (costs 3001 assets) - // NOTE: Bob's assets spent got rounded up - // NOTE: Alices's vault assets got rounded up - { - const { tx } = await this.vault.mint(2000, user2, { from: user2 }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: user2, - to: this.vault.address, - value: '3001', - }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: constants.ZERO_ADDRESS, - to: user2, - value: '2000', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('3333'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('6000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('5000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('9000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('9333'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('14001'); - } - - // 6. Vault mutates by +3000 tokens - // NOTE: Vault holds 17001 tokens, but sum of assetsOf() is 17000. - await this.token.mint(this.vault.address, 3000); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('3333'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('6000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('6071'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('10929'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('9333'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('17001'); - - // 7. Alice redeem 1333 shares (2428 assets) - { - const { tx } = await this.vault.redeem(1333, user1, user1, { from: user1 }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: user1, - to: constants.ZERO_ADDRESS, - value: '1333', - }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: user1, - value: '2428', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('6000'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('3643'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('10929'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('8000'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('14573'); - } - - // 8. Bob withdraws 2929 assets (1608 shares) - { - const { tx } = await this.vault.withdraw(2929, user2, user2, { from: user2 }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: user2, - to: constants.ZERO_ADDRESS, - value: '1608', - }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: user2, - value: '2929', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('2000'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4392'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('3643'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('8000'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('6392'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('11644'); - } - - // 9. Alice withdraws 3643 assets (2000 shares) - // NOTE: Bob's assets have been rounded back up - { - const { tx } = await this.vault.withdraw(3643, user1, user1, { from: user1 }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: user1, - to: constants.ZERO_ADDRESS, - value: '2000', - }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: user1, - value: '3643', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('0'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('4392'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('0'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('8001'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('4392'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('8001'); - } - - // 10. Bob redeem 4392 shares (8001 tokens) - { - const { tx } = await this.vault.redeem(4392, user2, user2, { from: user2 }); - expectEvent.inTransaction(tx, this.vault, 'Transfer', { - from: user2, - to: constants.ZERO_ADDRESS, - value: '4392', - }); - expectEvent.inTransaction(tx, this.token, 'Transfer', { - from: this.vault.address, - to: user2, - value: '8001', - }); - - expect(await this.vault.balanceOf(user1)).to.be.bignumber.equal('0'); - expect(await this.vault.balanceOf(user2)).to.be.bignumber.equal('0'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user1))).to.be.bignumber.equal('0'); - expect(await this.vault.convertToAssets(await this.vault.balanceOf(user2))).to.be.bignumber.equal('0'); - expect(await this.vault.totalSupply()).to.be.bignumber.equal('0'); - expect(await this.vault.totalAssets()).to.be.bignumber.equal('0'); - } - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/draft-ERC20Permit.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/draft-ERC20Permit.test.js deleted file mode 100644 index fb60a6c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/extensions/draft-ERC20Permit.test.js +++ /dev/null @@ -1,109 +0,0 @@ -/* eslint-disable */ - -const { BN, constants, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256, ZERO_ADDRESS, ZERO_BYTES32 } = constants; - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const ERC20PermitMock = artifacts.require('ERC20PermitMock'); - -const { EIP712Domain, Permit, domainSeparator } = require('../../../helpers/eip712'); - -contract('ERC20Permit', function (accounts) { - const [ initialHolder, spender, recipient, other ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - const version = '1'; - - const initialSupply = new BN(100); - - beforeEach(async function () { - this.token = await ERC20PermitMock.new(name, symbol, initialHolder, initialSupply); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.token.getChainId(); - }); - - it('initial nonce is 0', async function () { - expect(await this.token.nonces(initialHolder)).to.be.bignumber.equal('0'); - }); - - it('domain separator', async function () { - expect( - await this.token.DOMAIN_SEPARATOR(), - ).to.equal( - await domainSeparator(name, version, this.chainId, this.token.address), - ); - }); - - describe('permit', function () { - const wallet = Wallet.generate(); - - const owner = wallet.getAddressString(); - const value = new BN(42); - const nonce = 0; - const maxDeadline = MAX_UINT256; - - const buildData = (chainId, verifyingContract, deadline = maxDeadline) => ({ - primaryType: 'Permit', - types: { EIP712Domain, Permit }, - domain: { name, version, chainId, verifyingContract }, - message: { owner, spender, value, nonce, deadline }, - }); - - it('accepts owner signature', async function () { - const data = buildData(this.chainId, this.token.address); - const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data }); - const { v, r, s } = fromRpcSig(signature); - - const receipt = await this.token.permit(owner, spender, value, maxDeadline, v, r, s); - - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(value); - }); - - it('rejects reused signature', async function () { - const data = buildData(this.chainId, this.token.address); - const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data }); - const { v, r, s } = fromRpcSig(signature); - - await this.token.permit(owner, spender, value, maxDeadline, v, r, s); - - await expectRevert( - this.token.permit(owner, spender, value, maxDeadline, v, r, s), - 'ERC20Permit: invalid signature', - ); - }); - - it('rejects other signature', async function () { - const otherWallet = Wallet.generate(); - const data = buildData(this.chainId, this.token.address); - const signature = ethSigUtil.signTypedMessage(otherWallet.getPrivateKey(), { data }); - const { v, r, s } = fromRpcSig(signature); - - await expectRevert( - this.token.permit(owner, spender, value, maxDeadline, v, r, s), - 'ERC20Permit: invalid signature', - ); - }); - - it('rejects expired permit', async function () { - const deadline = (await time.latest()) - time.duration.weeks(1); - - const data = buildData(this.chainId, this.token.address, deadline); - const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data }); - const { v, r, s } = fromRpcSig(signature); - - await expectRevert( - this.token.permit(owner, spender, value, deadline, v, r, s), - 'ERC20Permit: expired deadline', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/presets/ERC20PresetFixedSupply.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/presets/ERC20PresetFixedSupply.test.js deleted file mode 100644 index f1d0b53..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/presets/ERC20PresetFixedSupply.test.js +++ /dev/null @@ -1,42 +0,0 @@ -const { BN, constants, expectEvent } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC20PresetFixedSupply = artifacts.require('ERC20PresetFixedSupply'); - -contract('ERC20PresetFixedSupply', function (accounts) { - const [deployer, owner] = accounts; - - const name = 'PresetFixedSupply'; - const symbol = 'PFS'; - - const initialSupply = new BN('50000'); - const amount = new BN('10000'); - - before(async function () { - this.token = await ERC20PresetFixedSupply.new(name, symbol, initialSupply, owner, { from: deployer }); - }); - - it('deployer has the balance equal to initial supply', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialSupply); - }); - - it('total supply is equal to initial supply', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - }); - - describe('burning', function () { - it('holders can burn their tokens', async function () { - const remainingBalance = initialSupply.sub(amount); - const receipt = await this.token.burn(amount, { from: owner }); - expectEvent(receipt, 'Transfer', { from: owner, to: ZERO_ADDRESS, value: amount }); - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(remainingBalance); - }); - - it('decrements totalSupply', async function () { - const expectedSupply = initialSupply.sub(amount); - expect(await this.token.totalSupply()).to.be.bignumber.equal(expectedSupply); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/presets/ERC20PresetMinterPauser.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/presets/ERC20PresetMinterPauser.test.js deleted file mode 100644 index c143790..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/presets/ERC20PresetMinterPauser.test.js +++ /dev/null @@ -1,113 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC20PresetMinterPauser = artifacts.require('ERC20PresetMinterPauser'); - -contract('ERC20PresetMinterPauser', function (accounts) { - const [ deployer, other ] = accounts; - - const name = 'MinterPauserToken'; - const symbol = 'DRT'; - - const amount = new BN('5000'); - - const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const MINTER_ROLE = web3.utils.soliditySha3('MINTER_ROLE'); - const PAUSER_ROLE = web3.utils.soliditySha3('PAUSER_ROLE'); - - beforeEach(async function () { - this.token = await ERC20PresetMinterPauser.new(name, symbol, { from: deployer }); - }); - - it('deployer has the default admin role', async function () { - expect(await this.token.getRoleMemberCount(DEFAULT_ADMIN_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(DEFAULT_ADMIN_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the minter role', async function () { - expect(await this.token.getRoleMemberCount(MINTER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(MINTER_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the pauser role', async function () { - expect(await this.token.getRoleMemberCount(PAUSER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(PAUSER_ROLE, 0)).to.equal(deployer); - }); - - it('minter and pauser role admin is the default admin', async function () { - expect(await this.token.getRoleAdmin(MINTER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - expect(await this.token.getRoleAdmin(PAUSER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - describe('minting', function () { - it('deployer can mint tokens', async function () { - const receipt = await this.token.mint(other, amount, { from: deployer }); - expectEvent(receipt, 'Transfer', { from: ZERO_ADDRESS, to: other, value: amount }); - - expect(await this.token.balanceOf(other)).to.be.bignumber.equal(amount); - }); - - it('other accounts cannot mint tokens', async function () { - await expectRevert( - this.token.mint(other, amount, { from: other }), - 'ERC20PresetMinterPauser: must have minter role to mint', - ); - }); - }); - - describe('pausing', function () { - it('deployer can pause', async function () { - const receipt = await this.token.pause({ from: deployer }); - expectEvent(receipt, 'Paused', { account: deployer }); - - expect(await this.token.paused()).to.equal(true); - }); - - it('deployer can unpause', async function () { - await this.token.pause({ from: deployer }); - - const receipt = await this.token.unpause({ from: deployer }); - expectEvent(receipt, 'Unpaused', { account: deployer }); - - expect(await this.token.paused()).to.equal(false); - }); - - it('cannot mint while paused', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.mint(other, amount, { from: deployer }), - 'ERC20Pausable: token transfer while paused', - ); - }); - - it('other accounts cannot pause', async function () { - await expectRevert( - this.token.pause({ from: other }), - 'ERC20PresetMinterPauser: must have pauser role to pause', - ); - }); - - it('other accounts cannot unpause', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.unpause({ from: other }), - 'ERC20PresetMinterPauser: must have pauser role to unpause', - ); - }); - }); - - describe('burning', function () { - it('holders can burn their tokens', async function () { - await this.token.mint(other, amount, { from: deployer }); - - const receipt = await this.token.burn(amount.subn(1), { from: other }); - expectEvent(receipt, 'Transfer', { from: other, to: ZERO_ADDRESS, value: amount.subn(1) }); - - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('1'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js deleted file mode 100644 index 4c54c58..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/utils/SafeERC20.test.js +++ /dev/null @@ -1,255 +0,0 @@ -const { constants, expectRevert } = require('@openzeppelin/test-helpers'); - -const ERC20ReturnFalseMock = artifacts.require('ERC20ReturnFalseMock'); -const ERC20ReturnTrueMock = artifacts.require('ERC20ReturnTrueMock'); -const ERC20NoReturnMock = artifacts.require('ERC20NoReturnMock'); -const ERC20PermitNoRevertMock = artifacts.require('ERC20PermitNoRevertMock'); -const SafeERC20Wrapper = artifacts.require('SafeERC20Wrapper'); - -const { EIP712Domain, Permit } = require('../../../helpers/eip712'); - -const { fromRpcSig } = require('ethereumjs-util'); -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -contract('SafeERC20', function (accounts) { - const [ hasNoCode ] = accounts; - - describe('with address that has no contract code', function () { - beforeEach(async function () { - this.wrapper = await SafeERC20Wrapper.new(hasNoCode); - }); - - shouldRevertOnAllCalls('Address: call to non-contract'); - }); - - describe('with token that returns false on all calls', function () { - beforeEach(async function () { - this.wrapper = await SafeERC20Wrapper.new((await ERC20ReturnFalseMock.new()).address); - }); - - shouldRevertOnAllCalls('SafeERC20: ERC20 operation did not succeed'); - }); - - describe('with token that returns true on all calls', function () { - beforeEach(async function () { - this.wrapper = await SafeERC20Wrapper.new((await ERC20ReturnTrueMock.new()).address); - }); - - shouldOnlyRevertOnErrors(); - }); - - describe('with token that returns no boolean values', function () { - beforeEach(async function () { - this.wrapper = await SafeERC20Wrapper.new((await ERC20NoReturnMock.new()).address); - }); - - shouldOnlyRevertOnErrors(); - }); - - describe('with token that doesn\'t revert on invalid permit', function () { - const wallet = Wallet.generate(); - const owner = wallet.getAddressString(); - const spender = hasNoCode; - - beforeEach(async function () { - this.token = await ERC20PermitNoRevertMock.new(); - this.wrapper = await SafeERC20Wrapper.new(this.token.address); - - const chainId = await this.token.getChainId(); - - this.data = { - primaryType: 'Permit', - types: { EIP712Domain, Permit }, - domain: { name: 'ERC20PermitNoRevertMock', version: '1', chainId, verifyingContract: this.token.address }, - message: { owner, spender, value: '42', nonce: '0', deadline: constants.MAX_UINT256 }, - }; - this.signature = fromRpcSig(ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data: this.data })); - }); - - it('accepts owner signature', async function () { - expect(await this.token.nonces(owner)).to.be.bignumber.equal('0'); - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal('0'); - - await this.wrapper.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - this.signature.v, - this.signature.r, - this.signature.s, - ); - - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - expect(await this.token.allowance(owner, spender)).to.be.bignumber.equal(this.data.message.value); - }); - - it('revert on reused signature', async function () { - expect(await this.token.nonces(owner)).to.be.bignumber.equal('0'); - // use valid signature and consume nounce - await this.wrapper.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - this.signature.v, - this.signature.r, - this.signature.s, - ); - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - // invalid call does not revert for this token implementation - await this.token.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - this.signature.v, - this.signature.r, - this.signature.s, - ); - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - // invalid call revert when called through the SafeERC20 library - await expectRevert( - this.wrapper.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - this.signature.v, - this.signature.r, - this.signature.s, - ), - 'SafeERC20: permit did not succeed', - ); - expect(await this.token.nonces(owner)).to.be.bignumber.equal('1'); - }); - - it('revert on invalid signature', async function () { - // signature that is not valid for owner - const invalidSignature = { - v: 27, - r: '0x71753dc5ecb5b4bfc0e3bc530d79ce5988760ed3f3a234c86a5546491f540775', - s: '0x0049cedee5aed990aabed5ad6a9f6e3c565b63379894b5fa8b512eb2b79e485d', - }; - - // invalid call does not revert for this token implementation - await this.token.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - invalidSignature.v, - invalidSignature.r, - invalidSignature.s, - ); - - // invalid call revert when called through the SafeERC20 library - await expectRevert( - this.wrapper.permit( - this.data.message.owner, - this.data.message.spender, - this.data.message.value, - this.data.message.deadline, - invalidSignature.v, - invalidSignature.r, - invalidSignature.s, - ), - 'SafeERC20: permit did not succeed', - ); - }); - }); -}); - -function shouldRevertOnAllCalls (reason) { - it('reverts on transfer', async function () { - await expectRevert(this.wrapper.transfer(), reason); - }); - - it('reverts on transferFrom', async function () { - await expectRevert(this.wrapper.transferFrom(), reason); - }); - - it('reverts on approve', async function () { - await expectRevert(this.wrapper.approve(0), reason); - }); - - it('reverts on increaseAllowance', async function () { - // [TODO] make sure it's reverting for the right reason - await expectRevert.unspecified(this.wrapper.increaseAllowance(0)); - }); - - it('reverts on decreaseAllowance', async function () { - // [TODO] make sure it's reverting for the right reason - await expectRevert.unspecified(this.wrapper.decreaseAllowance(0)); - }); -} - -function shouldOnlyRevertOnErrors () { - it('doesn\'t revert on transfer', async function () { - await this.wrapper.transfer(); - }); - - it('doesn\'t revert on transferFrom', async function () { - await this.wrapper.transferFrom(); - }); - - describe('approvals', function () { - context('with zero allowance', function () { - beforeEach(async function () { - await this.wrapper.setAllowance(0); - }); - - it('doesn\'t revert when approving a non-zero allowance', async function () { - await this.wrapper.approve(100); - }); - - it('doesn\'t revert when approving a zero allowance', async function () { - await this.wrapper.approve(0); - }); - - it('doesn\'t revert when increasing the allowance', async function () { - await this.wrapper.increaseAllowance(10); - }); - - it('reverts when decreasing the allowance', async function () { - await expectRevert( - this.wrapper.decreaseAllowance(10), - 'SafeERC20: decreased allowance below zero', - ); - }); - }); - - context('with non-zero allowance', function () { - beforeEach(async function () { - await this.wrapper.setAllowance(100); - }); - - it('reverts when approving a non-zero allowance', async function () { - await expectRevert( - this.wrapper.approve(20), - 'SafeERC20: approve from non-zero to non-zero allowance', - ); - }); - - it('doesn\'t revert when approving a zero allowance', async function () { - await this.wrapper.approve(0); - }); - - it('doesn\'t revert when increasing the allowance', async function () { - await this.wrapper.increaseAllowance(10); - }); - - it('doesn\'t revert when decreasing the allowance to a positive value', async function () { - await this.wrapper.decreaseAllowance(50); - }); - - it('reverts when decreasing the allowance to a negative value', async function () { - await expectRevert( - this.wrapper.decreaseAllowance(200), - 'SafeERC20: decreased allowance below zero', - ); - }); - }); - }); -} diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/utils/TokenTimelock.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/utils/TokenTimelock.test.js deleted file mode 100644 index e546b34..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC20/utils/TokenTimelock.test.js +++ /dev/null @@ -1,71 +0,0 @@ -const { BN, expectRevert, time } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC20Mock = artifacts.require('ERC20Mock'); -const TokenTimelock = artifacts.require('TokenTimelock'); - -contract('TokenTimelock', function (accounts) { - const [ beneficiary ] = accounts; - - const name = 'My Token'; - const symbol = 'MTKN'; - - const amount = new BN(100); - - context('with token', function () { - beforeEach(async function () { - this.token = await ERC20Mock.new(name, symbol, beneficiary, 0); // We're not using the preminted tokens - }); - - it('rejects a release time in the past', async function () { - const pastReleaseTime = (await time.latest()).sub(time.duration.years(1)); - await expectRevert( - TokenTimelock.new(this.token.address, beneficiary, pastReleaseTime), - 'TokenTimelock: release time is before current time', - ); - }); - - context('once deployed', function () { - beforeEach(async function () { - this.releaseTime = (await time.latest()).add(time.duration.years(1)); - this.timelock = await TokenTimelock.new(this.token.address, beneficiary, this.releaseTime); - await this.token.mint(this.timelock.address, amount); - }); - - it('can get state', async function () { - expect(await this.timelock.token()).to.equal(this.token.address); - expect(await this.timelock.beneficiary()).to.equal(beneficiary); - expect(await this.timelock.releaseTime()).to.be.bignumber.equal(this.releaseTime); - }); - - it('cannot be released before time limit', async function () { - await expectRevert(this.timelock.release(), 'TokenTimelock: current time is before release time'); - }); - - it('cannot be released just before time limit', async function () { - await time.increaseTo(this.releaseTime.sub(time.duration.seconds(3))); - await expectRevert(this.timelock.release(), 'TokenTimelock: current time is before release time'); - }); - - it('can be released just after limit', async function () { - await time.increaseTo(this.releaseTime.add(time.duration.seconds(1))); - await this.timelock.release(); - expect(await this.token.balanceOf(beneficiary)).to.be.bignumber.equal(amount); - }); - - it('can be released after time limit', async function () { - await time.increaseTo(this.releaseTime.add(time.duration.years(1))); - await this.timelock.release(); - expect(await this.token.balanceOf(beneficiary)).to.be.bignumber.equal(amount); - }); - - it('cannot be released twice', async function () { - await time.increaseTo(this.releaseTime.add(time.duration.years(1))); - await this.timelock.release(); - await expectRevert(this.timelock.release(), 'TokenTimelock: no tokens to release'); - expect(await this.token.balanceOf(beneficiary)).to.be.bignumber.equal(amount); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js deleted file mode 100644 index c13bc1e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721.behavior.js +++ /dev/null @@ -1,937 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS } = constants; - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -const ERC721ReceiverMock = artifacts.require('ERC721ReceiverMock'); - -const Error = [ 'None', 'RevertWithMessage', 'RevertWithoutMessage', 'Panic' ] - .reduce((acc, entry, idx) => Object.assign({ [entry]: idx }, acc), {}); - -const firstTokenId = new BN('5042'); -const secondTokenId = new BN('79217'); -const nonExistentTokenId = new BN('13'); -const fourthTokenId = new BN(4); -const baseURI = 'https://api.example.com/v1/'; - -const RECEIVER_MAGIC_VALUE = '0x150b7a02'; - -function shouldBehaveLikeERC721 (errorPrefix, owner, newOwner, approved, anotherApproved, operator, other) { - shouldSupportInterfaces([ - 'ERC165', - 'ERC721', - ]); - - context('with minted tokens', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - this.toWhom = other; // default to other for toWhom in context-dependent tests - }); - - describe('balanceOf', function () { - context('when the given address owns some tokens', function () { - it('returns the amount of tokens owned by the given address', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('2'); - }); - }); - - context('when the given address does not own any tokens', function () { - it('returns 0', async function () { - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('0'); - }); - }); - - context('when querying the zero address', function () { - it('throws', async function () { - await expectRevert( - this.token.balanceOf(ZERO_ADDRESS), 'ERC721: address zero is not a valid owner', - ); - }); - }); - }); - - describe('ownerOf', function () { - context('when the given token ID was tracked by this token', function () { - const tokenId = firstTokenId; - - it('returns the owner of the given token ID', async function () { - expect(await this.token.ownerOf(tokenId)).to.be.equal(owner); - }); - }); - - context('when the given token ID was not tracked by this token', function () { - const tokenId = nonExistentTokenId; - - it('reverts', async function () { - await expectRevert( - this.token.ownerOf(tokenId), 'ERC721: invalid token ID', - ); - }); - }); - }); - - describe('transfers', function () { - const tokenId = firstTokenId; - const data = '0x42'; - - let receipt = null; - - beforeEach(async function () { - await this.token.approve(approved, tokenId, { from: owner }); - await this.token.setApprovalForAll(operator, true, { from: owner }); - }); - - const transferWasSuccessful = function ({ owner, tokenId, approved }) { - it('transfers the ownership of the given token ID to the given address', async function () { - expect(await this.token.ownerOf(tokenId)).to.be.equal(this.toWhom); - }); - - it('emits a Transfer event', async function () { - expectEvent(receipt, 'Transfer', { from: owner, to: this.toWhom, tokenId: tokenId }); - }); - - it('clears the approval for the token ID', async function () { - expect(await this.token.getApproved(tokenId)).to.be.equal(ZERO_ADDRESS); - }); - - it('adjusts owners balances', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1'); - }); - - it('adjusts owners tokens by index', async function () { - if (!this.token.tokenOfOwnerByIndex) return; - - expect(await this.token.tokenOfOwnerByIndex(this.toWhom, 0)).to.be.bignumber.equal(tokenId); - - expect(await this.token.tokenOfOwnerByIndex(owner, 0)).to.be.bignumber.not.equal(tokenId); - }); - }; - - const shouldTransferTokensByUsers = function (transferFunction) { - context('when called by the owner', function () { - beforeEach(async function () { - (receipt = await transferFunction.call(this, owner, this.toWhom, tokenId, { from: owner })); - }); - transferWasSuccessful({ owner, tokenId, approved }); - }); - - context('when called by the approved individual', function () { - beforeEach(async function () { - (receipt = await transferFunction.call(this, owner, this.toWhom, tokenId, { from: approved })); - }); - transferWasSuccessful({ owner, tokenId, approved }); - }); - - context('when called by the operator', function () { - beforeEach(async function () { - (receipt = await transferFunction.call(this, owner, this.toWhom, tokenId, { from: operator })); - }); - transferWasSuccessful({ owner, tokenId, approved }); - }); - - context('when called by the owner without an approved user', function () { - beforeEach(async function () { - await this.token.approve(ZERO_ADDRESS, tokenId, { from: owner }); - (receipt = await transferFunction.call(this, owner, this.toWhom, tokenId, { from: operator })); - }); - transferWasSuccessful({ owner, tokenId, approved: null }); - }); - - context('when sent to the owner', function () { - beforeEach(async function () { - (receipt = await transferFunction.call(this, owner, owner, tokenId, { from: owner })); - }); - - it('keeps ownership of the token', async function () { - expect(await this.token.ownerOf(tokenId)).to.be.equal(owner); - }); - - it('clears the approval for the token ID', async function () { - expect(await this.token.getApproved(tokenId)).to.be.equal(ZERO_ADDRESS); - }); - - it('emits only a transfer event', async function () { - expectEvent(receipt, 'Transfer', { - from: owner, - to: owner, - tokenId: tokenId, - }); - }); - - it('keeps the owner balance', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('2'); - }); - - it('keeps same tokens by index', async function () { - if (!this.token.tokenOfOwnerByIndex) return; - const tokensListed = await Promise.all( - [0, 1].map(i => this.token.tokenOfOwnerByIndex(owner, i)), - ); - expect(tokensListed.map(t => t.toNumber())).to.have.members( - [firstTokenId.toNumber(), secondTokenId.toNumber()], - ); - }); - }); - - context('when the address of the previous owner is incorrect', function () { - it('reverts', async function () { - await expectRevert( - transferFunction.call(this, other, other, tokenId, { from: owner }), - 'ERC721: transfer from incorrect owner', - ); - }); - }); - - context('when the sender is not authorized for the token id', function () { - it('reverts', async function () { - await expectRevert( - transferFunction.call(this, owner, other, tokenId, { from: other }), - 'ERC721: caller is not token owner nor approved', - ); - }); - }); - - context('when the given token ID does not exist', function () { - it('reverts', async function () { - await expectRevert( - transferFunction.call(this, owner, other, nonExistentTokenId, { from: owner }), - 'ERC721: invalid token ID', - ); - }); - }); - - context('when the address to transfer the token to is the zero address', function () { - it('reverts', async function () { - await expectRevert( - transferFunction.call(this, owner, ZERO_ADDRESS, tokenId, { from: owner }), - 'ERC721: transfer to the zero address', - ); - }); - }); - }; - - describe('via transferFrom', function () { - shouldTransferTokensByUsers(function (from, to, tokenId, opts) { - return this.token.transferFrom(from, to, tokenId, opts); - }); - }); - - describe('via safeTransferFrom', function () { - const safeTransferFromWithData = function (from, to, tokenId, opts) { - return this.token.methods['safeTransferFrom(address,address,uint256,bytes)'](from, to, tokenId, data, opts); - }; - - const safeTransferFromWithoutData = function (from, to, tokenId, opts) { - return this.token.methods['safeTransferFrom(address,address,uint256)'](from, to, tokenId, opts); - }; - - const shouldTransferSafely = function (transferFun, data) { - describe('to a user account', function () { - shouldTransferTokensByUsers(transferFun); - }); - - describe('to a valid receiver contract', function () { - beforeEach(async function () { - this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None); - this.toWhom = this.receiver.address; - }); - - shouldTransferTokensByUsers(transferFun); - - it('calls onERC721Received', async function () { - const receipt = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: owner }); - - await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { - operator: owner, - from: owner, - tokenId: tokenId, - data: data, - }); - }); - - it('calls onERC721Received from approved', async function () { - const receipt = await transferFun.call(this, owner, this.receiver.address, tokenId, { from: approved }); - - await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { - operator: approved, - from: owner, - tokenId: tokenId, - data: data, - }); - }); - - describe('with an invalid token id', function () { - it('reverts', async function () { - await expectRevert( - transferFun.call( - this, - owner, - this.receiver.address, - nonExistentTokenId, - { from: owner }, - ), - 'ERC721: invalid token ID', - ); - }); - }); - }); - }; - - describe('with data', function () { - shouldTransferSafely(safeTransferFromWithData, data); - }); - - describe('without data', function () { - shouldTransferSafely(safeTransferFromWithoutData, null); - }); - - describe('to a receiver contract returning unexpected value', function () { - it('reverts', async function () { - const invalidReceiver = await ERC721ReceiverMock.new('0x42', Error.None); - await expectRevert( - this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - - describe('to a receiver contract that reverts with message', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithMessage); - await expectRevert( - this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }), - 'ERC721ReceiverMock: reverting', - ); - }); - }); - - describe('to a receiver contract that reverts without message', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithoutMessage); - await expectRevert( - this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - - describe('to a receiver contract that panics', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.Panic); - await expectRevert.unspecified( - this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }), - ); - }); - }); - - describe('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const nonReceiver = this.token; - await expectRevert( - this.token.safeTransferFrom(owner, nonReceiver.address, tokenId, { from: owner }), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - }); - }); - - describe('safe mint', function () { - const tokenId = fourthTokenId; - const data = '0x42'; - - describe('via safeMint', function () { // regular minting is tested in ERC721Mintable.test.js and others - it('calls onERC721Received — with data', async function () { - this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None); - const receipt = await this.token.safeMint(this.receiver.address, tokenId, data); - - await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { - from: ZERO_ADDRESS, - tokenId: tokenId, - data: data, - }); - }); - - it('calls onERC721Received — without data', async function () { - this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None); - const receipt = await this.token.safeMint(this.receiver.address, tokenId); - - await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { - from: ZERO_ADDRESS, - tokenId: tokenId, - }); - }); - - context('to a receiver contract returning unexpected value', function () { - it('reverts', async function () { - const invalidReceiver = await ERC721ReceiverMock.new('0x42', Error.None); - await expectRevert( - this.token.safeMint(invalidReceiver.address, tokenId), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - - context('to a receiver contract that reverts with message', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithMessage); - await expectRevert( - this.token.safeMint(revertingReceiver.address, tokenId), - 'ERC721ReceiverMock: reverting', - ); - }); - }); - - context('to a receiver contract that reverts without message', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithoutMessage); - await expectRevert( - this.token.safeMint(revertingReceiver.address, tokenId), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - - context('to a receiver contract that panics', function () { - it('reverts', async function () { - const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.Panic); - await expectRevert.unspecified( - this.token.safeMint(revertingReceiver.address, tokenId), - ); - }); - }); - - context('to a contract that does not implement the required function', function () { - it('reverts', async function () { - const nonReceiver = this.token; - await expectRevert( - this.token.safeMint(nonReceiver.address, tokenId), - 'ERC721: transfer to non ERC721Receiver implementer', - ); - }); - }); - }); - }); - - describe('approve', function () { - const tokenId = firstTokenId; - - let receipt = null; - - const itClearsApproval = function () { - it('clears approval for the token', async function () { - expect(await this.token.getApproved(tokenId)).to.be.equal(ZERO_ADDRESS); - }); - }; - - const itApproves = function (address) { - it('sets the approval for the target address', async function () { - expect(await this.token.getApproved(tokenId)).to.be.equal(address); - }); - }; - - const itEmitsApprovalEvent = function (address) { - it('emits an approval event', async function () { - expectEvent(receipt, 'Approval', { - owner: owner, - approved: address, - tokenId: tokenId, - }); - }); - }; - - context('when clearing approval', function () { - context('when there was no prior approval', function () { - beforeEach(async function () { - (receipt = await this.token.approve(ZERO_ADDRESS, tokenId, { from: owner })); - }); - - itClearsApproval(); - itEmitsApprovalEvent(ZERO_ADDRESS); - }); - - context('when there was a prior approval', function () { - beforeEach(async function () { - await this.token.approve(approved, tokenId, { from: owner }); - (receipt = await this.token.approve(ZERO_ADDRESS, tokenId, { from: owner })); - }); - - itClearsApproval(); - itEmitsApprovalEvent(ZERO_ADDRESS); - }); - }); - - context('when approving a non-zero address', function () { - context('when there was no prior approval', function () { - beforeEach(async function () { - (receipt = await this.token.approve(approved, tokenId, { from: owner })); - }); - - itApproves(approved); - itEmitsApprovalEvent(approved); - }); - - context('when there was a prior approval to the same address', function () { - beforeEach(async function () { - await this.token.approve(approved, tokenId, { from: owner }); - (receipt = await this.token.approve(approved, tokenId, { from: owner })); - }); - - itApproves(approved); - itEmitsApprovalEvent(approved); - }); - - context('when there was a prior approval to a different address', function () { - beforeEach(async function () { - await this.token.approve(anotherApproved, tokenId, { from: owner }); - (receipt = await this.token.approve(anotherApproved, tokenId, { from: owner })); - }); - - itApproves(anotherApproved); - itEmitsApprovalEvent(anotherApproved); - }); - }); - - context('when the address that receives the approval is the owner', function () { - it('reverts', async function () { - await expectRevert( - this.token.approve(owner, tokenId, { from: owner }), 'ERC721: approval to current owner', - ); - }); - }); - - context('when the sender does not own the given token ID', function () { - it('reverts', async function () { - await expectRevert(this.token.approve(approved, tokenId, { from: other }), - 'ERC721: approve caller is not token owner nor approved'); - }); - }); - - context('when the sender is approved for the given token ID', function () { - it('reverts', async function () { - await this.token.approve(approved, tokenId, { from: owner }); - await expectRevert(this.token.approve(anotherApproved, tokenId, { from: approved }), - 'ERC721: approve caller is not token owner nor approved for all'); - }); - }); - - context('when the sender is an operator', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - (receipt = await this.token.approve(approved, tokenId, { from: operator })); - }); - - itApproves(approved); - itEmitsApprovalEvent(approved); - }); - - context('when the given token ID does not exist', function () { - it('reverts', async function () { - await expectRevert(this.token.approve(approved, nonExistentTokenId, { from: operator }), - 'ERC721: invalid token ID'); - }); - }); - }); - - describe('setApprovalForAll', function () { - context('when the operator willing to approve is not the owner', function () { - context('when there is no operator approval set by the sender', function () { - it('approves the operator', async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(true); - }); - - it('emits an approval event', async function () { - const receipt = await this.token.setApprovalForAll(operator, true, { from: owner }); - - expectEvent(receipt, 'ApprovalForAll', { - owner: owner, - operator: operator, - approved: true, - }); - }); - }); - - context('when the operator was set as not approved', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(operator, false, { from: owner }); - }); - - it('approves the operator', async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(true); - }); - - it('emits an approval event', async function () { - const receipt = await this.token.setApprovalForAll(operator, true, { from: owner }); - - expectEvent(receipt, 'ApprovalForAll', { - owner: owner, - operator: operator, - approved: true, - }); - }); - - it('can unset the operator approval', async function () { - await this.token.setApprovalForAll(operator, false, { from: owner }); - - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(false); - }); - }); - - context('when the operator was already approved', function () { - beforeEach(async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - }); - - it('keeps the approval to the given address', async function () { - await this.token.setApprovalForAll(operator, true, { from: owner }); - - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(true); - }); - - it('emits an approval event', async function () { - const receipt = await this.token.setApprovalForAll(operator, true, { from: owner }); - - expectEvent(receipt, 'ApprovalForAll', { - owner: owner, - operator: operator, - approved: true, - }); - }); - }); - }); - - context('when the operator is the owner', function () { - it('reverts', async function () { - await expectRevert(this.token.setApprovalForAll(owner, true, { from: owner }), - 'ERC721: approve to caller'); - }); - }); - }); - - describe('getApproved', async function () { - context('when token is not minted', async function () { - it('reverts', async function () { - await expectRevert( - this.token.getApproved(nonExistentTokenId), - 'ERC721: invalid token ID', - ); - }); - }); - - context('when token has been minted ', async function () { - it('should return the zero address', async function () { - expect(await this.token.getApproved(firstTokenId)).to.be.equal( - ZERO_ADDRESS, - ); - }); - - context('when account has been approved', async function () { - beforeEach(async function () { - await this.token.approve(approved, firstTokenId, { from: owner }); - }); - - it('returns approved account', async function () { - expect(await this.token.getApproved(firstTokenId)).to.be.equal(approved); - }); - }); - }); - }); - }); - - describe('_mint(address, uint256)', function () { - it('reverts with a null destination address', async function () { - await expectRevert( - this.token.mint(ZERO_ADDRESS, firstTokenId), 'ERC721: mint to the zero address', - ); - }); - - context('with minted token', async function () { - beforeEach(async function () { - (this.receipt = await this.token.mint(owner, firstTokenId)); - }); - - it('emits a Transfer event', function () { - expectEvent(this.receipt, 'Transfer', { from: ZERO_ADDRESS, to: owner, tokenId: firstTokenId }); - }); - - it('creates the token', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1'); - expect(await this.token.ownerOf(firstTokenId)).to.equal(owner); - }); - - it('reverts when adding a token id that already exists', async function () { - await expectRevert(this.token.mint(owner, firstTokenId), 'ERC721: token already minted'); - }); - }); - }); - - describe('_burn', function () { - it('reverts when burning a non-existent token id', async function () { - await expectRevert( - this.token.burn(nonExistentTokenId), 'ERC721: invalid token ID', - ); - }); - - context('with minted tokens', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - }); - - context('with burnt token', function () { - beforeEach(async function () { - (this.receipt = await this.token.burn(firstTokenId)); - }); - - it('emits a Transfer event', function () { - expectEvent(this.receipt, 'Transfer', { from: owner, to: ZERO_ADDRESS, tokenId: firstTokenId }); - }); - - it('deletes the token', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1'); - await expectRevert( - this.token.ownerOf(firstTokenId), 'ERC721: invalid token ID', - ); - }); - - it('reverts when burning a token id that has been deleted', async function () { - await expectRevert( - this.token.burn(firstTokenId), 'ERC721: invalid token ID', - ); - }); - }); - }); - }); -} - -function shouldBehaveLikeERC721Enumerable (errorPrefix, owner, newOwner, approved, anotherApproved, operator, other) { - shouldSupportInterfaces([ - 'ERC721Enumerable', - ]); - - context('with minted tokens', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - this.toWhom = other; // default to other for toWhom in context-dependent tests - }); - - describe('totalSupply', function () { - it('returns total token supply', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal('2'); - }); - }); - - describe('tokenOfOwnerByIndex', function () { - describe('when the given index is lower than the amount of tokens owned by the given address', function () { - it('returns the token ID placed at the given index', async function () { - expect(await this.token.tokenOfOwnerByIndex(owner, 0)).to.be.bignumber.equal(firstTokenId); - }); - }); - - describe('when the index is greater than or equal to the total tokens owned by the given address', function () { - it('reverts', async function () { - await expectRevert( - this.token.tokenOfOwnerByIndex(owner, 2), 'ERC721Enumerable: owner index out of bounds', - ); - }); - }); - - describe('when the given address does not own any token', function () { - it('reverts', async function () { - await expectRevert( - this.token.tokenOfOwnerByIndex(other, 0), 'ERC721Enumerable: owner index out of bounds', - ); - }); - }); - - describe('after transferring all tokens to another user', function () { - beforeEach(async function () { - await this.token.transferFrom(owner, other, firstTokenId, { from: owner }); - await this.token.transferFrom(owner, other, secondTokenId, { from: owner }); - }); - - it('returns correct token IDs for target', async function () { - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('2'); - const tokensListed = await Promise.all( - [0, 1].map(i => this.token.tokenOfOwnerByIndex(other, i)), - ); - expect(tokensListed.map(t => t.toNumber())).to.have.members([firstTokenId.toNumber(), - secondTokenId.toNumber()]); - }); - - it('returns empty collection for original owner', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('0'); - await expectRevert( - this.token.tokenOfOwnerByIndex(owner, 0), 'ERC721Enumerable: owner index out of bounds', - ); - }); - }); - }); - - describe('tokenByIndex', function () { - it('returns all tokens', async function () { - const tokensListed = await Promise.all( - [0, 1].map(i => this.token.tokenByIndex(i)), - ); - expect(tokensListed.map(t => t.toNumber())).to.have.members([firstTokenId.toNumber(), - secondTokenId.toNumber()]); - }); - - it('reverts if index is greater than supply', async function () { - await expectRevert( - this.token.tokenByIndex(2), 'ERC721Enumerable: global index out of bounds', - ); - }); - - [firstTokenId, secondTokenId].forEach(function (tokenId) { - it(`returns all tokens after burning token ${tokenId} and minting new tokens`, async function () { - const newTokenId = new BN(300); - const anotherNewTokenId = new BN(400); - - await this.token.burn(tokenId); - await this.token.mint(newOwner, newTokenId); - await this.token.mint(newOwner, anotherNewTokenId); - - expect(await this.token.totalSupply()).to.be.bignumber.equal('3'); - - const tokensListed = await Promise.all( - [0, 1, 2].map(i => this.token.tokenByIndex(i)), - ); - const expectedTokens = [firstTokenId, secondTokenId, newTokenId, anotherNewTokenId].filter( - x => (x !== tokenId), - ); - expect(tokensListed.map(t => t.toNumber())).to.have.members(expectedTokens.map(t => t.toNumber())); - }); - }); - }); - }); - - describe('_mint(address, uint256)', function () { - it('reverts with a null destination address', async function () { - await expectRevert( - this.token.mint(ZERO_ADDRESS, firstTokenId), 'ERC721: mint to the zero address', - ); - }); - - context('with minted token', async function () { - beforeEach(async function () { - (this.receipt = await this.token.mint(owner, firstTokenId)); - }); - - it('adjusts owner tokens by index', async function () { - expect(await this.token.tokenOfOwnerByIndex(owner, 0)).to.be.bignumber.equal(firstTokenId); - }); - - it('adjusts all tokens list', async function () { - expect(await this.token.tokenByIndex(0)).to.be.bignumber.equal(firstTokenId); - }); - }); - }); - - describe('_burn', function () { - it('reverts when burning a non-existent token id', async function () { - await expectRevert( - this.token.burn(firstTokenId), 'ERC721: invalid token ID', - ); - }); - - context('with minted tokens', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - }); - - context('with burnt token', function () { - beforeEach(async function () { - (this.receipt = await this.token.burn(firstTokenId)); - }); - - it('removes that token from the token list of the owner', async function () { - expect(await this.token.tokenOfOwnerByIndex(owner, 0)).to.be.bignumber.equal(secondTokenId); - }); - - it('adjusts all tokens list', async function () { - expect(await this.token.tokenByIndex(0)).to.be.bignumber.equal(secondTokenId); - }); - - it('burns all tokens', async function () { - await this.token.burn(secondTokenId, { from: owner }); - expect(await this.token.totalSupply()).to.be.bignumber.equal('0'); - await expectRevert( - this.token.tokenByIndex(0), 'ERC721Enumerable: global index out of bounds', - ); - }); - }); - }); - }); -} - -function shouldBehaveLikeERC721Metadata (errorPrefix, name, symbol, owner) { - shouldSupportInterfaces([ - 'ERC721Metadata', - ]); - - describe('metadata', function () { - it('has a name', async function () { - expect(await this.token.name()).to.be.equal(name); - }); - - it('has a symbol', async function () { - expect(await this.token.symbol()).to.be.equal(symbol); - }); - - describe('token URI', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - }); - - it('return empty string by default', async function () { - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(''); - }); - - it('reverts when queried for non existent token id', async function () { - await expectRevert( - this.token.tokenURI(nonExistentTokenId), 'ERC721: invalid token ID', - ); - }); - - describe('base URI', function () { - beforeEach(function () { - if (this.token.setBaseURI === undefined) { - this.skip(); - } - }); - - it('base URI can be set', async function () { - await this.token.setBaseURI(baseURI); - expect(await this.token.baseURI()).to.equal(baseURI); - }); - - it('base URI is added as a prefix to the token URI', async function () { - await this.token.setBaseURI(baseURI); - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(baseURI + firstTokenId.toString()); - }); - - it('token URI can be changed by changing the base URI', async function () { - await this.token.setBaseURI(baseURI); - const newBaseURI = 'https://api.example.com/v2/'; - await this.token.setBaseURI(newBaseURI); - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(newBaseURI + firstTokenId.toString()); - }); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Enumerable, - shouldBehaveLikeERC721Metadata, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js deleted file mode 100644 index 1abbd66..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Metadata, -} = require('./ERC721.behavior'); - -const ERC721Mock = artifacts.require('ERC721Mock'); - -contract('ERC721', function (accounts) { - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - beforeEach(async function () { - this.token = await ERC721Mock.new(name, symbol); - }); - - shouldBehaveLikeERC721('ERC721', ...accounts); - shouldBehaveLikeERC721Metadata('ERC721', name, symbol, ...accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js deleted file mode 100644 index 2c13621..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/ERC721Enumerable.test.js +++ /dev/null @@ -1,20 +0,0 @@ -const { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Metadata, - shouldBehaveLikeERC721Enumerable, -} = require('./ERC721.behavior'); - -const ERC721Mock = artifacts.require('ERC721EnumerableMock'); - -contract('ERC721Enumerable', function (accounts) { - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - beforeEach(async function () { - this.token = await ERC721Mock.new(name, symbol); - }); - - shouldBehaveLikeERC721('ERC721', ...accounts); - shouldBehaveLikeERC721Metadata('ERC721', name, symbol, ...accounts); - shouldBehaveLikeERC721Enumerable('ERC721', ...accounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js deleted file mode 100644 index e8fc334..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Burnable.test.js +++ /dev/null @@ -1,78 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC721BurnableMock = artifacts.require('ERC721BurnableMock'); - -contract('ERC721Burnable', function (accounts) { - const [owner, approved] = accounts; - - const firstTokenId = new BN(1); - const secondTokenId = new BN(2); - const unknownTokenId = new BN(3); - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - beforeEach(async function () { - this.token = await ERC721BurnableMock.new(name, symbol); - }); - - describe('like a burnable ERC721', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - await this.token.mint(owner, secondTokenId); - }); - - describe('burn', function () { - const tokenId = firstTokenId; - let receipt = null; - - describe('when successful', function () { - beforeEach(async function () { - receipt = await this.token.burn(tokenId, { from: owner }); - }); - - it('burns the given token ID and adjusts the balance of the owner', async function () { - await expectRevert( - this.token.ownerOf(tokenId), - 'ERC721: invalid token ID', - ); - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal('1'); - }); - - it('emits a burn event', async function () { - expectEvent(receipt, 'Transfer', { - from: owner, - to: ZERO_ADDRESS, - tokenId: tokenId, - }); - }); - }); - - describe('when there is a previous approval burned', function () { - beforeEach(async function () { - await this.token.approve(approved, tokenId, { from: owner }); - receipt = await this.token.burn(tokenId, { from: owner }); - }); - - context('getApproved', function () { - it('reverts', async function () { - await expectRevert( - this.token.getApproved(tokenId), 'ERC721: invalid token ID', - ); - }); - }); - }); - - describe('when the given token ID was not tracked by this contract', function () { - it('reverts', async function () { - await expectRevert( - this.token.burn(unknownTokenId, { from: owner }), 'ERC721: invalid token ID', - ); - }); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js deleted file mode 100644 index 16847dc..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Pausable.test.js +++ /dev/null @@ -1,98 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC721PausableMock = artifacts.require('ERC721PausableMock'); - -contract('ERC721Pausable', function (accounts) { - const [ owner, receiver, operator ] = accounts; - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - beforeEach(async function () { - this.token = await ERC721PausableMock.new(name, symbol); - }); - - context('when token is paused', function () { - const firstTokenId = new BN(1); - const secondTokenId = new BN(1337); - - const mockData = '0x42'; - - beforeEach(async function () { - await this.token.mint(owner, firstTokenId, { from: owner }); - await this.token.pause(); - }); - - it('reverts when trying to transferFrom', async function () { - await expectRevert( - this.token.transferFrom(owner, receiver, firstTokenId, { from: owner }), - 'ERC721Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeTransferFrom', async function () { - await expectRevert( - this.token.safeTransferFrom(owner, receiver, firstTokenId, { from: owner }), - 'ERC721Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to safeTransferFrom with data', async function () { - await expectRevert( - this.token.methods['safeTransferFrom(address,address,uint256,bytes)']( - owner, receiver, firstTokenId, mockData, { from: owner }, - ), 'ERC721Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to mint', async function () { - await expectRevert( - this.token.mint(receiver, secondTokenId), - 'ERC721Pausable: token transfer while paused', - ); - }); - - it('reverts when trying to burn', async function () { - await expectRevert( - this.token.burn(firstTokenId), - 'ERC721Pausable: token transfer while paused', - ); - }); - - describe('getApproved', function () { - it('returns approved address', async function () { - const approvedAccount = await this.token.getApproved(firstTokenId); - expect(approvedAccount).to.equal(ZERO_ADDRESS); - }); - }); - - describe('balanceOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - const balance = await this.token.balanceOf(owner); - expect(balance).to.be.bignumber.equal('1'); - }); - }); - - describe('ownerOf', function () { - it('returns the amount of tokens owned by the given address', async function () { - const ownerOfToken = await this.token.ownerOf(firstTokenId); - expect(ownerOfToken).to.equal(owner); - }); - }); - - describe('exists', function () { - it('returns token existence', async function () { - expect(await this.token.exists(firstTokenId)).to.equal(true); - }); - }); - - describe('isApprovedForAll', function () { - it('returns the approval of the operator', async function () { - expect(await this.token.isApprovedForAll(owner, operator)).to.equal(false); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js deleted file mode 100644 index 29b28dd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Royalty.test.js +++ /dev/null @@ -1,40 +0,0 @@ -const { BN, constants } = require('@openzeppelin/test-helpers'); -const ERC721RoyaltyMock = artifacts.require('ERC721RoyaltyMock'); -const { ZERO_ADDRESS } = constants; - -const { shouldBehaveLikeERC2981 } = require('../../common/ERC2981.behavior'); - -contract('ERC721Royalty', function (accounts) { - const [ account1, account2 ] = accounts; - const tokenId1 = new BN('1'); - const tokenId2 = new BN('2'); - const royalty = new BN('200'); - const salePrice = new BN('1000'); - - beforeEach(async function () { - this.token = await ERC721RoyaltyMock.new('My Token', 'TKN'); - - await this.token.mint(account1, tokenId1); - await this.token.mint(account1, tokenId2); - this.account1 = account1; - this.account2 = account2; - this.tokenId1 = tokenId1; - this.tokenId2 = tokenId2; - this.salePrice = salePrice; - }); - - describe('token specific functions', function () { - beforeEach(async function () { - await this.token.setTokenRoyalty(tokenId1, account1, royalty); - }); - - it('removes royalty information after burn', async function () { - await this.token.burn(tokenId1); - const tokenInfo = await this.token.royaltyInfo(tokenId1, salePrice); - - expect(tokenInfo[0]).to.be.equal(ZERO_ADDRESS); - expect(tokenInfo[1]).to.be.bignumber.equal(new BN('0')); - }); - }); - shouldBehaveLikeERC2981(); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js deleted file mode 100644 index eeacf5e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721URIStorage.test.js +++ /dev/null @@ -1,96 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC721URIStorageMock = artifacts.require('ERC721URIStorageMock'); - -contract('ERC721URIStorage', function (accounts) { - const [ owner ] = accounts; - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - const firstTokenId = new BN('5042'); - const nonExistentTokenId = new BN('13'); - - beforeEach(async function () { - this.token = await ERC721URIStorageMock.new(name, symbol); - }); - - describe('token URI', function () { - beforeEach(async function () { - await this.token.mint(owner, firstTokenId); - }); - - const baseURI = 'https://api.example.com/v1/'; - const sampleUri = 'mock://mytoken'; - - it('it is empty by default', async function () { - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(''); - }); - - it('reverts when queried for non existent token id', async function () { - await expectRevert( - this.token.tokenURI(nonExistentTokenId), 'ERC721: invalid token ID', - ); - }); - - it('can be set for a token id', async function () { - await this.token.setTokenURI(firstTokenId, sampleUri); - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(sampleUri); - }); - - it('reverts when setting for non existent token id', async function () { - await expectRevert( - this.token.setTokenURI(nonExistentTokenId, sampleUri), 'ERC721URIStorage: URI set of nonexistent token', - ); - }); - - it('base URI can be set', async function () { - await this.token.setBaseURI(baseURI); - expect(await this.token.baseURI()).to.equal(baseURI); - }); - - it('base URI is added as a prefix to the token URI', async function () { - await this.token.setBaseURI(baseURI); - await this.token.setTokenURI(firstTokenId, sampleUri); - - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(baseURI + sampleUri); - }); - - it('token URI can be changed by changing the base URI', async function () { - await this.token.setBaseURI(baseURI); - await this.token.setTokenURI(firstTokenId, sampleUri); - - const newBaseURI = 'https://api.example.com/v2/'; - await this.token.setBaseURI(newBaseURI); - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(newBaseURI + sampleUri); - }); - - it('tokenId is appended to base URI for tokens with no URI', async function () { - await this.token.setBaseURI(baseURI); - - expect(await this.token.tokenURI(firstTokenId)).to.be.equal(baseURI + firstTokenId); - }); - - it('tokens without URI can be burnt ', async function () { - await this.token.burn(firstTokenId, { from: owner }); - - expect(await this.token.exists(firstTokenId)).to.equal(false); - await expectRevert( - this.token.tokenURI(firstTokenId), 'ERC721: invalid token ID', - ); - }); - - it('tokens with URI can be burnt ', async function () { - await this.token.setTokenURI(firstTokenId, sampleUri); - - await this.token.burn(firstTokenId, { from: owner }); - - expect(await this.token.exists(firstTokenId)).to.equal(false); - await expectRevert( - this.token.tokenURI(firstTokenId), 'ERC721: invalid token ID', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js deleted file mode 100644 index 6f001f2..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/extensions/ERC721Votes.test.js +++ /dev/null @@ -1,174 +0,0 @@ -/* eslint-disable */ - -const { BN, expectEvent, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const { promisify } = require('util'); -const queue = promisify(setImmediate); - -const ERC721VotesMock = artifacts.require('ERC721VotesMock'); - -const { shouldBehaveLikeVotes } = require('../../../governance/utils/Votes.behavior'); - -contract('ERC721Votes', function (accounts) { - const [ account1, account2, account1Delegatee, other1, other2 ] = accounts; - this.name = 'My Vote'; - const symbol = 'MTKN'; - - beforeEach(async function () { - this.votes = await ERC721VotesMock.new(name, symbol); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.votes.getChainId(); - - this.NFT0 = new BN('10000000000000000000000000'); - this.NFT1 = new BN('10'); - this.NFT2 = new BN('20'); - this.NFT3 = new BN('30'); - }); - - describe('balanceOf', function () { - beforeEach(async function () { - await this.votes.mint(account1, this.NFT0); - await this.votes.mint(account1, this.NFT1); - await this.votes.mint(account1, this.NFT2); - await this.votes.mint(account1, this.NFT3); - }); - - it('grants to initial account', async function () { - expect(await this.votes.balanceOf(account1)).to.be.bignumber.equal('4'); - }); - }); - - describe('transfers', function () { - beforeEach(async function () { - await this.votes.mint(account1, this.NFT0); - }); - - it('no delegation', async function () { - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - expectEvent(receipt, 'Transfer', { from: account1, to: account2, tokenId: this.NFT0 }); - expectEvent.notEmitted(receipt, 'DelegateVotesChanged'); - - this.account1Votes = '0'; - this.account2Votes = '0'; - }); - - it('sender delegation', async function () { - await this.votes.delegate(account1, { from: account1 }); - - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - expectEvent(receipt, 'Transfer', { from: account1, to: account2, tokenId: this.NFT0 }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: account1, previousBalance: '1', newBalance: '0' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.account1Votes = '0'; - this.account2Votes = '0'; - }); - - it('receiver delegation', async function () { - await this.votes.delegate(account2, { from: account2 }); - - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - expectEvent(receipt, 'Transfer', { from: account1, to: account2, tokenId: this.NFT0 }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: account2, previousBalance: '0', newBalance: '1' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.account1Votes = '0'; - this.account2Votes = '1'; - }); - - it('full delegation', async function () { - await this.votes.delegate(account1, { from: account1 }); - await this.votes.delegate(account2, { from: account2 }); - - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - expectEvent(receipt, 'Transfer', { from: account1, to: account2, tokenId: this.NFT0 }); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: account1, previousBalance: '1', newBalance: '0'}); - expectEvent(receipt, 'DelegateVotesChanged', { delegate: account2, previousBalance: '0', newBalance: '1' }); - - const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer'); - expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true); - - this.account1Votes = '0'; - this.account2Votes = '1'; - }); - - it('returns the same total supply on transfers', async function () { - await this.votes.delegate(account1, { from: account1 }); - - const { receipt } = await this.votes.transferFrom(account1, account2, this.NFT0, { from: account1 }); - - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastTotalSupply(receipt.blockNumber - 1)).to.be.bignumber.equal('1'); - expect(await this.votes.getPastTotalSupply(receipt.blockNumber + 1)).to.be.bignumber.equal('1'); - - this.account1Votes = '0'; - this.account2Votes = '0'; - }); - - it('generally returns the voting balance at the appropriate checkpoint', async function () { - await this.votes.mint(account1, this.NFT1); - await this.votes.mint(account1, this.NFT2); - await this.votes.mint(account1, this.NFT3); - - const total = await this.votes.balanceOf(account1); - - const t1 = await this.votes.delegate(other1, { from: account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - const t2 = await this.votes.transferFrom(account1, other2, this.NFT0, { from: account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - const t3 = await this.votes.transferFrom(account1, other2, this.NFT2, { from: account1 }); - await time.advanceBlock(); - await time.advanceBlock(); - const t4 = await this.votes.transferFrom(other2, account1, this.NFT2, { from: other2 }); - await time.advanceBlock(); - await time.advanceBlock(); - - expect(await this.votes.getPastVotes(other1, t1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.votes.getPastVotes(other1, t1.receipt.blockNumber)).to.be.bignumber.equal(total); - expect(await this.votes.getPastVotes(other1, t1.receipt.blockNumber + 1)).to.be.bignumber.equal(total); - expect(await this.votes.getPastVotes(other1, t2.receipt.blockNumber)).to.be.bignumber.equal('3'); - expect(await this.votes.getPastVotes(other1, t2.receipt.blockNumber + 1)).to.be.bignumber.equal('3'); - expect(await this.votes.getPastVotes(other1, t3.receipt.blockNumber)).to.be.bignumber.equal('2'); - expect(await this.votes.getPastVotes(other1, t3.receipt.blockNumber + 1)).to.be.bignumber.equal('2'); - expect(await this.votes.getPastVotes(other1, t4.receipt.blockNumber)).to.be.bignumber.equal('3'); - expect(await this.votes.getPastVotes(other1, t4.receipt.blockNumber + 1)).to.be.bignumber.equal('3'); - - this.account1Votes = '0'; - this.account2Votes = '0'; - }); - - afterEach(async function () { - expect(await this.votes.getVotes(account1)).to.be.bignumber.equal(this.account1Votes); - expect(await this.votes.getVotes(account2)).to.be.bignumber.equal(this.account2Votes); - - // need to advance 2 blocks to see the effect of a transfer on "getPastVotes" - const blockNumber = await time.latestBlock(); - await time.advanceBlock(); - expect(await this.votes.getPastVotes(account1, blockNumber)).to.be.bignumber.equal(this.account1Votes); - expect(await this.votes.getPastVotes(account2, blockNumber)).to.be.bignumber.equal(this.account2Votes); - }); - }); - - describe('Voting workflow', function () { - beforeEach(async function () { - this.account1 = account1; - this.account1Delegatee = account1Delegatee; - this.account2 = account2; - this.name = 'My Vote'; - }); - - shouldBehaveLikeVotes(); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/presets/ERC721PresetMinterPauserAutoId.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/presets/ERC721PresetMinterPauserAutoId.test.js deleted file mode 100644 index 4ad7355..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/presets/ERC721PresetMinterPauserAutoId.test.js +++ /dev/null @@ -1,125 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); - -const { expect } = require('chai'); - -const ERC721PresetMinterPauserAutoId = artifacts.require('ERC721PresetMinterPauserAutoId'); - -contract('ERC721PresetMinterPauserAutoId', function (accounts) { - const [ deployer, other ] = accounts; - - const name = 'MinterAutoIDToken'; - const symbol = 'MAIT'; - const baseURI = 'my.app/'; - - const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; - const MINTER_ROLE = web3.utils.soliditySha3('MINTER_ROLE'); - - beforeEach(async function () { - this.token = await ERC721PresetMinterPauserAutoId.new(name, symbol, baseURI, { from: deployer }); - }); - - shouldSupportInterfaces(['ERC721', 'ERC721Enumerable', 'AccessControl', 'AccessControlEnumerable']); - - it('token has correct name', async function () { - expect(await this.token.name()).to.equal(name); - }); - - it('token has correct symbol', async function () { - expect(await this.token.symbol()).to.equal(symbol); - }); - - it('deployer has the default admin role', async function () { - expect(await this.token.getRoleMemberCount(DEFAULT_ADMIN_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(DEFAULT_ADMIN_ROLE, 0)).to.equal(deployer); - }); - - it('deployer has the minter role', async function () { - expect(await this.token.getRoleMemberCount(MINTER_ROLE)).to.be.bignumber.equal('1'); - expect(await this.token.getRoleMember(MINTER_ROLE, 0)).to.equal(deployer); - }); - - it('minter role admin is the default admin', async function () { - expect(await this.token.getRoleAdmin(MINTER_ROLE)).to.equal(DEFAULT_ADMIN_ROLE); - }); - - describe('minting', function () { - it('deployer can mint tokens', async function () { - const tokenId = new BN('0'); - - const receipt = await this.token.mint(other, { from: deployer }); - expectEvent(receipt, 'Transfer', { from: ZERO_ADDRESS, to: other, tokenId }); - - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('1'); - expect(await this.token.ownerOf(tokenId)).to.equal(other); - - expect(await this.token.tokenURI(tokenId)).to.equal(baseURI + tokenId); - }); - - it('other accounts cannot mint tokens', async function () { - await expectRevert( - this.token.mint(other, { from: other }), - 'ERC721PresetMinterPauserAutoId: must have minter role to mint', - ); - }); - }); - - describe('pausing', function () { - it('deployer can pause', async function () { - const receipt = await this.token.pause({ from: deployer }); - expectEvent(receipt, 'Paused', { account: deployer }); - - expect(await this.token.paused()).to.equal(true); - }); - - it('deployer can unpause', async function () { - await this.token.pause({ from: deployer }); - - const receipt = await this.token.unpause({ from: deployer }); - expectEvent(receipt, 'Unpaused', { account: deployer }); - - expect(await this.token.paused()).to.equal(false); - }); - - it('cannot mint while paused', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.mint(other, { from: deployer }), - 'ERC721Pausable: token transfer while paused', - ); - }); - - it('other accounts cannot pause', async function () { - await expectRevert( - this.token.pause({ from: other }), - 'ERC721PresetMinterPauserAutoId: must have pauser role to pause', - ); - }); - - it('other accounts cannot unpause', async function () { - await this.token.pause({ from: deployer }); - - await expectRevert( - this.token.unpause({ from: other }), - 'ERC721PresetMinterPauserAutoId: must have pauser role to unpause', - ); - }); - }); - - describe('burning', function () { - it('holders can burn their tokens', async function () { - const tokenId = new BN('0'); - - await this.token.mint(other, { from: deployer }); - - const receipt = await this.token.burn(tokenId, { from: other }); - - expectEvent(receipt, 'Transfer', { from: other, to: ZERO_ADDRESS, tokenId }); - - expect(await this.token.balanceOf(other)).to.be.bignumber.equal('0'); - expect(await this.token.totalSupply()).to.be.bignumber.equal('0'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js deleted file mode 100644 index 2431e66..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC721/utils/ERC721Holder.test.js +++ /dev/null @@ -1,24 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC721Holder = artifacts.require('ERC721Holder'); -const ERC721Mock = artifacts.require('ERC721Mock'); - -contract('ERC721Holder', function (accounts) { - const [ owner ] = accounts; - - const name = 'Non Fungible Token'; - const symbol = 'NFT'; - - it('receives an ERC721 token', async function () { - const token = await ERC721Mock.new(name, symbol); - const tokenId = new BN(1); - await token.mint(owner, tokenId); - - const receiver = await ERC721Holder.new(); - await token.safeTransferFrom(owner, receiver.address, tokenId, { from: owner }); - - expect(await token.ownerOf(tokenId)).to.be.equal(receiver.address); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/ERC777.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/ERC777.behavior.js deleted file mode 100644 index f6af942..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/ERC777.behavior.js +++ /dev/null @@ -1,555 +0,0 @@ -const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const ERC777SenderRecipientMock = artifacts.require('ERC777SenderRecipientMock'); - -function shouldBehaveLikeERC777DirectSendBurn (holder, recipient, data) { - shouldBehaveLikeERC777DirectSend(holder, recipient, data); - shouldBehaveLikeERC777DirectBurn(holder, data); -} - -function shouldBehaveLikeERC777OperatorSendBurn (holder, recipient, operator, data, operatorData) { - shouldBehaveLikeERC777OperatorSend(holder, recipient, operator, data, operatorData); - shouldBehaveLikeERC777OperatorBurn(holder, operator, data, operatorData); -} - -function shouldBehaveLikeERC777UnauthorizedOperatorSendBurn (holder, recipient, operator, data, operatorData) { - shouldBehaveLikeERC777UnauthorizedOperatorSend(holder, recipient, operator, data, operatorData); - shouldBehaveLikeERC777UnauthorizedOperatorBurn(holder, operator, data, operatorData); -} - -function shouldBehaveLikeERC777DirectSend (holder, recipient, data) { - describe('direct send', function () { - context('when the sender has tokens', function () { - shouldDirectSendTokens(holder, recipient, new BN('0'), data); - shouldDirectSendTokens(holder, recipient, new BN('1'), data); - - it('reverts when sending more than the balance', async function () { - const balance = await this.token.balanceOf(holder); - await expectRevert.unspecified(this.token.send(recipient, balance.addn(1), data, { from: holder })); - }); - - it('reverts when sending to the zero address', async function () { - await expectRevert.unspecified(this.token.send(ZERO_ADDRESS, new BN('1'), data, { from: holder })); - }); - }); - - context('when the sender has no tokens', function () { - removeBalance(holder); - - shouldDirectSendTokens(holder, recipient, new BN('0'), data); - - it('reverts when sending a non-zero amount', async function () { - await expectRevert.unspecified(this.token.send(recipient, new BN('1'), data, { from: holder })); - }); - }); - }); -} - -function shouldBehaveLikeERC777OperatorSend (holder, recipient, operator, data, operatorData) { - describe('operator send', function () { - context('when the sender has tokens', async function () { - shouldOperatorSendTokens(holder, operator, recipient, new BN('0'), data, operatorData); - shouldOperatorSendTokens(holder, operator, recipient, new BN('1'), data, operatorData); - - it('reverts when sending more than the balance', async function () { - const balance = await this.token.balanceOf(holder); - await expectRevert.unspecified( - this.token.operatorSend(holder, recipient, balance.addn(1), data, operatorData, { from: operator }), - ); - }); - - it('reverts when sending to the zero address', async function () { - await expectRevert.unspecified( - this.token.operatorSend( - holder, ZERO_ADDRESS, new BN('1'), data, operatorData, { from: operator }, - ), - ); - }); - }); - - context('when the sender has no tokens', function () { - removeBalance(holder); - - shouldOperatorSendTokens(holder, operator, recipient, new BN('0'), data, operatorData); - - it('reverts when sending a non-zero amount', async function () { - await expectRevert.unspecified( - this.token.operatorSend(holder, recipient, new BN('1'), data, operatorData, { from: operator }), - ); - }); - - it('reverts when sending from the zero address', async function () { - // This is not yet reflected in the spec - await expectRevert.unspecified( - this.token.operatorSend( - ZERO_ADDRESS, recipient, new BN('0'), data, operatorData, { from: operator }, - ), - ); - }); - }); - }); -} - -function shouldBehaveLikeERC777UnauthorizedOperatorSend (holder, recipient, operator, data, operatorData) { - describe('operator send', function () { - it('reverts', async function () { - await expectRevert.unspecified(this.token.operatorSend(holder, recipient, new BN('0'), data, operatorData)); - }); - }); -} - -function shouldBehaveLikeERC777DirectBurn (holder, data) { - describe('direct burn', function () { - context('when the sender has tokens', function () { - shouldDirectBurnTokens(holder, new BN('0'), data); - shouldDirectBurnTokens(holder, new BN('1'), data); - - it('reverts when burning more than the balance', async function () { - const balance = await this.token.balanceOf(holder); - await expectRevert.unspecified(this.token.burn(balance.addn(1), data, { from: holder })); - }); - }); - - context('when the sender has no tokens', function () { - removeBalance(holder); - - shouldDirectBurnTokens(holder, new BN('0'), data); - - it('reverts when burning a non-zero amount', async function () { - await expectRevert.unspecified(this.token.burn(new BN('1'), data, { from: holder })); - }); - }); - }); -} - -function shouldBehaveLikeERC777OperatorBurn (holder, operator, data, operatorData) { - describe('operator burn', function () { - context('when the sender has tokens', async function () { - shouldOperatorBurnTokens(holder, operator, new BN('0'), data, operatorData); - shouldOperatorBurnTokens(holder, operator, new BN('1'), data, operatorData); - - it('reverts when burning more than the balance', async function () { - const balance = await this.token.balanceOf(holder); - await expectRevert.unspecified( - this.token.operatorBurn(holder, balance.addn(1), data, operatorData, { from: operator }), - ); - }); - }); - - context('when the sender has no tokens', function () { - removeBalance(holder); - - shouldOperatorBurnTokens(holder, operator, new BN('0'), data, operatorData); - - it('reverts when burning a non-zero amount', async function () { - await expectRevert.unspecified( - this.token.operatorBurn(holder, new BN('1'), data, operatorData, { from: operator }), - ); - }); - - it('reverts when burning from the zero address', async function () { - // This is not yet reflected in the spec - await expectRevert.unspecified( - this.token.operatorBurn( - ZERO_ADDRESS, new BN('0'), data, operatorData, { from: operator }, - ), - ); - }); - }); - }); -} - -function shouldBehaveLikeERC777UnauthorizedOperatorBurn (holder, operator, data, operatorData) { - describe('operator burn', function () { - it('reverts', async function () { - await expectRevert.unspecified(this.token.operatorBurn(holder, new BN('0'), data, operatorData)); - }); - }); -} - -function shouldDirectSendTokens (from, to, amount, data) { - shouldSendTokens(from, null, to, amount, data, null); -} - -function shouldOperatorSendTokens (from, operator, to, amount, data, operatorData) { - shouldSendTokens(from, operator, to, amount, data, operatorData); -} - -function shouldSendTokens (from, operator, to, amount, data, operatorData) { - const operatorCall = operator !== null; - - it(`${operatorCall ? 'operator ' : ''}can send an amount of ${amount}`, async function () { - const initialTotalSupply = await this.token.totalSupply(); - const initialFromBalance = await this.token.balanceOf(from); - const initialToBalance = await this.token.balanceOf(to); - - let receipt; - if (!operatorCall) { - (receipt = await this.token.send(to, amount, data, { from })); - expectEvent(receipt, 'Sent', { - operator: from, - from, - to, - amount, - data, - operatorData: null, - }); - } else { - (receipt = await this.token.operatorSend(from, to, amount, data, operatorData, { from: operator })); - expectEvent(receipt, 'Sent', { - operator, - from, - to, - amount, - data, - operatorData, - }); - } - - expectEvent(receipt, 'Transfer', { - from, - to, - value: amount, - }); - - const finalTotalSupply = await this.token.totalSupply(); - const finalFromBalance = await this.token.balanceOf(from); - const finalToBalance = await this.token.balanceOf(to); - - expect(finalTotalSupply).to.be.bignumber.equal(initialTotalSupply); - expect(finalToBalance.sub(initialToBalance)).to.be.bignumber.equal(amount); - expect(finalFromBalance.sub(initialFromBalance)).to.be.bignumber.equal(amount.neg()); - }); -} - -function shouldDirectBurnTokens (from, amount, data) { - shouldBurnTokens(from, null, amount, data, null); -} - -function shouldOperatorBurnTokens (from, operator, amount, data, operatorData) { - shouldBurnTokens(from, operator, amount, data, operatorData); -} - -function shouldBurnTokens (from, operator, amount, data, operatorData) { - const operatorCall = operator !== null; - - it(`${operatorCall ? 'operator ' : ''}can burn an amount of ${amount}`, async function () { - const initialTotalSupply = await this.token.totalSupply(); - const initialFromBalance = await this.token.balanceOf(from); - - let receipt; - if (!operatorCall) { - (receipt = await this.token.burn(amount, data, { from })); - expectEvent(receipt, 'Burned', { - operator: from, - from, - amount, - data, - operatorData: null, - }); - } else { - (receipt = await this.token.operatorBurn(from, amount, data, operatorData, { from: operator })); - expectEvent(receipt, 'Burned', { - operator, - from, - amount, - data, - operatorData, - }); - } - - expectEvent(receipt, 'Transfer', { - from, - to: ZERO_ADDRESS, - value: amount, - }); - - const finalTotalSupply = await this.token.totalSupply(); - const finalFromBalance = await this.token.balanceOf(from); - - expect(finalTotalSupply.sub(initialTotalSupply)).to.be.bignumber.equal(amount.neg()); - expect(finalFromBalance.sub(initialFromBalance)).to.be.bignumber.equal(amount.neg()); - }); -} - -function shouldBehaveLikeERC777InternalMint (recipient, operator, amount, data, operatorData) { - shouldInternalMintTokens(operator, recipient, new BN('0'), data, operatorData); - shouldInternalMintTokens(operator, recipient, amount, data, operatorData); - - it('reverts when minting tokens for the zero address', async function () { - await expectRevert.unspecified( - this.token.mintInternal(ZERO_ADDRESS, amount, data, operatorData, { from: operator }), - ); - }); -} - -function shouldInternalMintTokens (operator, to, amount, data, operatorData) { - it(`can (internal) mint an amount of ${amount}`, async function () { - const initialTotalSupply = await this.token.totalSupply(); - const initialToBalance = await this.token.balanceOf(to); - - const receipt = await this.token.mintInternal(to, amount, data, operatorData, { from: operator }); - - expectEvent(receipt, 'Minted', { - operator, - to, - amount, - data, - operatorData, - }); - - expectEvent(receipt, 'Transfer', { - from: ZERO_ADDRESS, - to, - value: amount, - }); - - const finalTotalSupply = await this.token.totalSupply(); - const finalToBalance = await this.token.balanceOf(to); - - expect(finalTotalSupply.sub(initialTotalSupply)).to.be.bignumber.equal(amount); - expect(finalToBalance.sub(initialToBalance)).to.be.bignumber.equal(amount); - }); -} - -function shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook (operator, amount, data, operatorData) { - context('when TokensRecipient reverts', function () { - beforeEach(async function () { - await this.tokensRecipientImplementer.setShouldRevertReceive(true); - }); - - it('send reverts', async function () { - await expectRevert.unspecified(sendFromHolder(this.token, this.sender, this.recipient, amount, data)); - }); - - it('operatorSend reverts', async function () { - await expectRevert.unspecified( - this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }), - ); - }); - - it('mint (internal) reverts', async function () { - await expectRevert.unspecified( - this.token.mintInternal(this.recipient, amount, data, operatorData, { from: operator }), - ); - }); - }); - - context('when TokensRecipient does not revert', function () { - beforeEach(async function () { - await this.tokensRecipientImplementer.setShouldRevertSend(false); - }); - - it('TokensRecipient receives send data and is called after state mutation', async function () { - const { tx } = await sendFromHolder(this.token, this.sender, this.recipient, amount, data); - - const postSenderBalance = await this.token.balanceOf(this.sender); - const postRecipientBalance = await this.token.balanceOf(this.recipient); - - await assertTokensReceivedCalled( - this.token, - tx, - this.sender, - this.sender, - this.recipient, - amount, - data, - null, - postSenderBalance, - postRecipientBalance, - ); - }); - - it('TokensRecipient receives operatorSend data and is called after state mutation', async function () { - const { tx } = await this.token.operatorSend( - this.sender, this.recipient, amount, data, operatorData, - { from: operator }, - ); - - const postSenderBalance = await this.token.balanceOf(this.sender); - const postRecipientBalance = await this.token.balanceOf(this.recipient); - - await assertTokensReceivedCalled( - this.token, - tx, - operator, - this.sender, - this.recipient, - amount, - data, - operatorData, - postSenderBalance, - postRecipientBalance, - ); - }); - - it('TokensRecipient receives mint (internal) data and is called after state mutation', async function () { - const { tx } = await this.token.mintInternal( - this.recipient, amount, data, operatorData, { from: operator }, - ); - - const postRecipientBalance = await this.token.balanceOf(this.recipient); - - await assertTokensReceivedCalled( - this.token, - tx, - operator, - ZERO_ADDRESS, - this.recipient, - amount, - data, - operatorData, - new BN('0'), - postRecipientBalance, - ); - }); - }); -} - -function shouldBehaveLikeERC777SendBurnWithSendHook (operator, amount, data, operatorData) { - context('when TokensSender reverts', function () { - beforeEach(async function () { - await this.tokensSenderImplementer.setShouldRevertSend(true); - }); - - it('send reverts', async function () { - await expectRevert.unspecified(sendFromHolder(this.token, this.sender, this.recipient, amount, data)); - }); - - it('operatorSend reverts', async function () { - await expectRevert.unspecified( - this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }), - ); - }); - - it('burn reverts', async function () { - await expectRevert.unspecified(burnFromHolder(this.token, this.sender, amount, data)); - }); - - it('operatorBurn reverts', async function () { - await expectRevert.unspecified( - this.token.operatorBurn(this.sender, amount, data, operatorData, { from: operator }), - ); - }); - }); - - context('when TokensSender does not revert', function () { - beforeEach(async function () { - await this.tokensSenderImplementer.setShouldRevertSend(false); - }); - - it('TokensSender receives send data and is called before state mutation', async function () { - const preSenderBalance = await this.token.balanceOf(this.sender); - const preRecipientBalance = await this.token.balanceOf(this.recipient); - - const { tx } = await sendFromHolder(this.token, this.sender, this.recipient, amount, data); - - await assertTokensToSendCalled( - this.token, - tx, - this.sender, - this.sender, - this.recipient, - amount, - data, - null, - preSenderBalance, - preRecipientBalance, - ); - }); - - it('TokensSender receives operatorSend data and is called before state mutation', async function () { - const preSenderBalance = await this.token.balanceOf(this.sender); - const preRecipientBalance = await this.token.balanceOf(this.recipient); - - const { tx } = await this.token.operatorSend( - this.sender, this.recipient, amount, data, operatorData, - { from: operator }, - ); - - await assertTokensToSendCalled( - this.token, - tx, - operator, - this.sender, - this.recipient, - amount, - data, - operatorData, - preSenderBalance, - preRecipientBalance, - ); - }); - - it('TokensSender receives burn data and is called before state mutation', async function () { - const preSenderBalance = await this.token.balanceOf(this.sender); - - const { tx } = await burnFromHolder(this.token, this.sender, amount, data, { from: this.sender }); - - await assertTokensToSendCalled( - this.token, tx, this.sender, this.sender, ZERO_ADDRESS, amount, data, null, preSenderBalance, - ); - }); - - it('TokensSender receives operatorBurn data and is called before state mutation', async function () { - const preSenderBalance = await this.token.balanceOf(this.sender); - - const { tx } = await this.token.operatorBurn(this.sender, amount, data, operatorData, { from: operator }); - - await assertTokensToSendCalled( - this.token, tx, operator, this.sender, ZERO_ADDRESS, amount, data, operatorData, preSenderBalance, - ); - }); - }); -} - -function removeBalance (holder) { - beforeEach(async function () { - await this.token.burn(await this.token.balanceOf(holder), '0x', { from: holder }); - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal('0'); - }); -} - -async function assertTokensReceivedCalled (token, txHash, operator, from, to, amount, data, operatorData, fromBalance, - toBalance = '0') { - await expectEvent.inTransaction(txHash, ERC777SenderRecipientMock, 'TokensReceivedCalled', { - operator, from, to, amount, data, operatorData, token: token.address, fromBalance, toBalance, - }); -} - -async function assertTokensToSendCalled (token, txHash, operator, from, to, amount, data, operatorData, fromBalance, - toBalance = '0') { - await expectEvent.inTransaction(txHash, ERC777SenderRecipientMock, 'TokensToSendCalled', { - operator, from, to, amount, data, operatorData, token: token.address, fromBalance, toBalance, - }); -} - -async function sendFromHolder (token, holder, to, amount, data) { - if ((await web3.eth.getCode(holder)).length <= '0x'.length) { - return token.send(to, amount, data, { from: holder }); - } else { - // assume holder is ERC777SenderRecipientMock contract - return (await ERC777SenderRecipientMock.at(holder)).send(token.address, to, amount, data); - } -} - -async function burnFromHolder (token, holder, amount, data) { - if ((await web3.eth.getCode(holder)).length <= '0x'.length) { - return token.burn(amount, data, { from: holder }); - } else { - // assume holder is ERC777SenderRecipientMock contract - return (await ERC777SenderRecipientMock.at(holder)).burn(token.address, amount, data); - } -} - -module.exports = { - shouldBehaveLikeERC777DirectSendBurn, - shouldBehaveLikeERC777OperatorSendBurn, - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn, - shouldBehaveLikeERC777InternalMint, - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook, - shouldBehaveLikeERC777SendBurnWithSendHook, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/ERC777.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/ERC777.test.js deleted file mode 100644 index 51da130..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/ERC777.test.js +++ /dev/null @@ -1,610 +0,0 @@ -const { BN, constants, expectEvent, expectRevert, singletons } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const { - shouldBehaveLikeERC777DirectSendBurn, - shouldBehaveLikeERC777OperatorSendBurn, - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn, - shouldBehaveLikeERC777InternalMint, - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook, - shouldBehaveLikeERC777SendBurnWithSendHook, -} = require('./ERC777.behavior'); - -const { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Approve, -} = require('../ERC20/ERC20.behavior'); - -const ERC777 = artifacts.require('ERC777Mock'); -const ERC777SenderRecipientMock = artifacts.require('ERC777SenderRecipientMock'); - -contract('ERC777', function (accounts) { - const [ registryFunder, holder, defaultOperatorA, defaultOperatorB, newOperator, anyone ] = accounts; - - const initialSupply = new BN('10000'); - const name = 'ERC777Test'; - const symbol = '777T'; - const data = web3.utils.sha3('OZ777TestData'); - const operatorData = web3.utils.sha3('OZ777TestOperatorData'); - - const defaultOperators = [defaultOperatorA, defaultOperatorB]; - - beforeEach(async function () { - this.erc1820 = await singletons.ERC1820Registry(registryFunder); - }); - - context('with default operators', function () { - beforeEach(async function () { - this.token = await ERC777.new(holder, initialSupply, name, symbol, defaultOperators); - }); - - describe('as an ERC20 token', function () { - shouldBehaveLikeERC20('ERC777', initialSupply, holder, anyone, defaultOperatorA); - - describe('_approve', function () { - shouldBehaveLikeERC20Approve('ERC777', holder, anyone, initialSupply, function (owner, spender, amount) { - return this.token.approveInternal(owner, spender, amount); - }); - - describe('when the owner is the zero address', function () { - it('reverts', async function () { - await expectRevert(this.token.approveInternal(ZERO_ADDRESS, anyone, initialSupply), - 'ERC777: approve from the zero address', - ); - }); - }); - }); - }); - - it('does not emit AuthorizedOperator events for default operators', async function () { - await expectEvent.notEmitted.inConstruction(this.token, 'AuthorizedOperator'); - }); - - describe('basic information', function () { - it('returns the name', async function () { - expect(await this.token.name()).to.equal(name); - }); - - it('returns the symbol', async function () { - expect(await this.token.symbol()).to.equal(symbol); - }); - - it('returns a granularity of 1', async function () { - expect(await this.token.granularity()).to.be.bignumber.equal('1'); - }); - - it('returns the default operators', async function () { - expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators); - }); - - it('default operators are operators for all accounts', async function () { - for (const operator of defaultOperators) { - expect(await this.token.isOperatorFor(operator, anyone)).to.equal(true); - } - }); - - it('returns the total supply', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - }); - - it('returns 18 when decimals is called', async function () { - expect(await this.token.decimals()).to.be.bignumber.equal('18'); - }); - - it('the ERC777Token interface is registered in the registry', async function () { - expect(await this.erc1820.getInterfaceImplementer(this.token.address, web3.utils.soliditySha3('ERC777Token'))) - .to.equal(this.token.address); - }); - - it('the ERC20Token interface is registered in the registry', async function () { - expect(await this.erc1820.getInterfaceImplementer(this.token.address, web3.utils.soliditySha3('ERC20Token'))) - .to.equal(this.token.address); - }); - }); - - describe('balanceOf', function () { - context('for an account with no tokens', function () { - it('returns zero', async function () { - expect(await this.token.balanceOf(anyone)).to.be.bignumber.equal('0'); - }); - }); - - context('for an account with tokens', function () { - it('returns their balance', async function () { - expect(await this.token.balanceOf(holder)).to.be.bignumber.equal(initialSupply); - }); - }); - }); - - context('with no ERC777TokensSender and no ERC777TokensRecipient implementers', function () { - describe('send/burn', function () { - shouldBehaveLikeERC777DirectSendBurn(holder, anyone, data); - - context('with self operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, holder, data, operatorData); - }); - - context('with first default operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, defaultOperatorA, data, operatorData); - }); - - context('with second default operator', function () { - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, defaultOperatorB, data, operatorData); - }); - - context('before authorizing a new operator', function () { - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn(holder, anyone, newOperator, data, operatorData); - }); - - context('with new authorized operator', function () { - beforeEach(async function () { - await this.token.authorizeOperator(newOperator, { from: holder }); - }); - - shouldBehaveLikeERC777OperatorSendBurn(holder, anyone, newOperator, data, operatorData); - - context('with revoked operator', function () { - beforeEach(async function () { - await this.token.revokeOperator(newOperator, { from: holder }); - }); - - shouldBehaveLikeERC777UnauthorizedOperatorSendBurn(holder, anyone, newOperator, data, operatorData); - }); - }); - }); - - describe('mint (internal)', function () { - const to = anyone; - const amount = new BN('5'); - - context('with default operator', function () { - const operator = defaultOperatorA; - - shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData); - }); - - context('with non operator', function () { - const operator = newOperator; - - shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData); - }); - }); - - describe('mint (internal extended)', function () { - const amount = new BN('5'); - - context('to anyone', function () { - beforeEach(async function () { - this.recipient = anyone; - }); - - context('with default operator', function () { - const operator = defaultOperatorA; - - it('without requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - false, - { from: operator }, - ); - }); - - it('with requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - true, - { from: operator }, - ); - }); - }); - - context('with non operator', function () { - const operator = newOperator; - - it('without requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - false, - { from: operator }, - ); - }); - - it('with requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - true, - { from: operator }, - ); - }); - }); - }); - - context('to non ERC777TokensRecipient implementer', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = this.tokensRecipientImplementer.address; - }); - - context('with default operator', function () { - const operator = defaultOperatorA; - - it('without requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - false, - { from: operator }, - ); - }); - - it('with requireReceptionAck', async function () { - await expectRevert( - this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - true, - { from: operator }, - ), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - }); - - context('with non operator', function () { - const operator = newOperator; - - it('without requireReceptionAck', async function () { - await this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - false, - { from: operator }, - ); - }); - - it('with requireReceptionAck', async function () { - await expectRevert( - this.token.mintInternalExtended( - this.recipient, - amount, - data, - operatorData, - true, - { from: operator }, - ), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - }); - }); - }); - }); - - describe('operator management', function () { - it('accounts are their own operator', async function () { - expect(await this.token.isOperatorFor(holder, holder)).to.equal(true); - }); - - it('reverts when self-authorizing', async function () { - await expectRevert( - this.token.authorizeOperator(holder, { from: holder }), 'ERC777: authorizing self as operator', - ); - }); - - it('reverts when self-revoking', async function () { - await expectRevert( - this.token.revokeOperator(holder, { from: holder }), 'ERC777: revoking self as operator', - ); - }); - - it('non-operators can be revoked', async function () { - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(false); - - const receipt = await this.token.revokeOperator(newOperator, { from: holder }); - expectEvent(receipt, 'RevokedOperator', { operator: newOperator, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(false); - }); - - it('non-operators can be authorized', async function () { - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(false); - - const receipt = await this.token.authorizeOperator(newOperator, { from: holder }); - expectEvent(receipt, 'AuthorizedOperator', { operator: newOperator, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(true); - }); - - describe('new operators', function () { - beforeEach(async function () { - await this.token.authorizeOperator(newOperator, { from: holder }); - }); - - it('are not added to the default operators list', async function () { - expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators); - }); - - it('can be re-authorized', async function () { - const receipt = await this.token.authorizeOperator(newOperator, { from: holder }); - expectEvent(receipt, 'AuthorizedOperator', { operator: newOperator, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(true); - }); - - it('can be revoked', async function () { - const receipt = await this.token.revokeOperator(newOperator, { from: holder }); - expectEvent(receipt, 'RevokedOperator', { operator: newOperator, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(newOperator, holder)).to.equal(false); - }); - }); - - describe('default operators', function () { - it('can be re-authorized', async function () { - const receipt = await this.token.authorizeOperator(defaultOperatorA, { from: holder }); - expectEvent(receipt, 'AuthorizedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(defaultOperatorA, holder)).to.equal(true); - }); - - it('can be revoked', async function () { - const receipt = await this.token.revokeOperator(defaultOperatorA, { from: holder }); - expectEvent(receipt, 'RevokedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(defaultOperatorA, holder)).to.equal(false); - }); - - it('cannot be revoked for themselves', async function () { - await expectRevert( - this.token.revokeOperator(defaultOperatorA, { from: defaultOperatorA }), - 'ERC777: revoking self as operator', - ); - }); - - context('with revoked default operator', function () { - beforeEach(async function () { - await this.token.revokeOperator(defaultOperatorA, { from: holder }); - }); - - it('default operator is not revoked for other holders', async function () { - expect(await this.token.isOperatorFor(defaultOperatorA, anyone)).to.equal(true); - }); - - it('other default operators are not revoked', async function () { - expect(await this.token.isOperatorFor(defaultOperatorB, holder)).to.equal(true); - }); - - it('default operators list is not modified', async function () { - expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators); - }); - - it('revoked default operator can be re-authorized', async function () { - const receipt = await this.token.authorizeOperator(defaultOperatorA, { from: holder }); - expectEvent(receipt, 'AuthorizedOperator', { operator: defaultOperatorA, tokenHolder: holder }); - - expect(await this.token.isOperatorFor(defaultOperatorA, holder)).to.equal(true); - }); - }); - }); - }); - - describe('send and receive hooks', function () { - const amount = new BN('1'); - const operator = defaultOperatorA; - // sender and recipient are stored inside 'this', since in some tests their addresses are determined dynamically - - describe('tokensReceived', function () { - beforeEach(function () { - this.sender = holder; - }); - - context('with no ERC777TokensRecipient implementer', function () { - context('with contract recipient', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = this.tokensRecipientImplementer.address; - - // Note that tokensRecipientImplementer doesn't implement the recipient interface for the recipient - }); - - it('send reverts', async function () { - await expectRevert( - this.token.send(this.recipient, amount, data, { from: holder }), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - - it('operatorSend reverts', async function () { - await expectRevert( - this.token.operatorSend(this.sender, this.recipient, amount, data, operatorData, { from: operator }), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - - it('mint (internal) reverts', async function () { - await expectRevert( - this.token.mintInternal(this.recipient, amount, data, operatorData, { from: operator }), - 'ERC777: token recipient contract has no implementer for ERC777TokensRecipient', - ); - }); - - it('(ERC20) transfer succeeds', async function () { - await this.token.transfer(this.recipient, amount, { from: holder }); - }); - - it('(ERC20) transferFrom succeeds', async function () { - const approved = anyone; - await this.token.approve(approved, amount, { from: this.sender }); - await this.token.transferFrom(this.sender, this.recipient, amount, { from: approved }); - }); - }); - }); - - context('with ERC777TokensRecipient implementer', function () { - context('with contract as implementer for an externally owned account', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = anyone; - - await this.tokensRecipientImplementer.recipientFor(this.recipient); - - await this.erc1820.setInterfaceImplementer( - this.recipient, - web3.utils.soliditySha3('ERC777TokensRecipient'), this.tokensRecipientImplementer.address, - { from: this.recipient }, - ); - }); - - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); - }); - - context('with contract as implementer for another contract', function () { - beforeEach(async function () { - this.recipientContract = await ERC777SenderRecipientMock.new(); - this.recipient = this.recipientContract.address; - - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - await this.tokensRecipientImplementer.recipientFor(this.recipient); - await this.recipientContract.registerRecipient(this.tokensRecipientImplementer.address); - }); - - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); - }); - - context('with contract as implementer for itself', function () { - beforeEach(async function () { - this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new(); - this.recipient = this.tokensRecipientImplementer.address; - - await this.tokensRecipientImplementer.recipientFor(this.recipient); - }); - - shouldBehaveLikeERC777SendBurnMintInternalWithReceiveHook(operator, amount, data, operatorData); - }); - }); - }); - - describe('tokensToSend', function () { - beforeEach(function () { - this.recipient = anyone; - }); - - context('with a contract as implementer for an externally owned account', function () { - beforeEach(async function () { - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - this.sender = holder; - - await this.tokensSenderImplementer.senderFor(this.sender); - - await this.erc1820.setInterfaceImplementer( - this.sender, - web3.utils.soliditySha3('ERC777TokensSender'), this.tokensSenderImplementer.address, - { from: this.sender }, - ); - }); - - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); - }); - - context('with contract as implementer for another contract', function () { - beforeEach(async function () { - this.senderContract = await ERC777SenderRecipientMock.new(); - this.sender = this.senderContract.address; - - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - await this.tokensSenderImplementer.senderFor(this.sender); - await this.senderContract.registerSender(this.tokensSenderImplementer.address); - - // For the contract to be able to receive tokens (that it can later send), it must also implement the - // recipient interface. - - await this.senderContract.recipientFor(this.sender); - await this.token.send(this.sender, amount, data, { from: holder }); - }); - - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); - }); - - context('with a contract as implementer for itself', function () { - beforeEach(async function () { - this.tokensSenderImplementer = await ERC777SenderRecipientMock.new(); - this.sender = this.tokensSenderImplementer.address; - - await this.tokensSenderImplementer.senderFor(this.sender); - - // For the contract to be able to receive tokens (that it can later send), it must also implement the - // recipient interface. - - await this.tokensSenderImplementer.recipientFor(this.sender); - await this.token.send(this.sender, amount, data, { from: holder }); - }); - - shouldBehaveLikeERC777SendBurnWithSendHook(operator, amount, data, operatorData); - }); - }); - }); - }); - - context('with no default operators', function () { - beforeEach(async function () { - this.token = await ERC777.new(holder, initialSupply, name, symbol, []); - }); - - it('default operators list is empty', async function () { - expect(await this.token.defaultOperators()).to.deep.equal([]); - }); - }); - - describe('relative order of hooks', function () { - beforeEach(async function () { - await singletons.ERC1820Registry(registryFunder); - this.sender = await ERC777SenderRecipientMock.new(); - await this.sender.registerRecipient(this.sender.address); - await this.sender.registerSender(this.sender.address); - this.token = await ERC777.new(holder, initialSupply, name, symbol, []); - await this.token.send(this.sender.address, 1, '0x', { from: holder }); - }); - - it('send', async function () { - const { receipt } = await this.sender.send(this.token.address, anyone, 1, '0x'); - - const internalBeforeHook = receipt.logs.findIndex(l => l.event === 'BeforeTokenTransfer'); - expect(internalBeforeHook).to.be.gte(0); - const externalSendHook = receipt.logs.findIndex(l => l.event === 'TokensToSendCalled'); - expect(externalSendHook).to.be.gte(0); - - expect(externalSendHook).to.be.lt(internalBeforeHook); - }); - - it('burn', async function () { - const { receipt } = await this.sender.burn(this.token.address, 1, '0x'); - - const internalBeforeHook = receipt.logs.findIndex(l => l.event === 'BeforeTokenTransfer'); - expect(internalBeforeHook).to.be.gte(0); - const externalSendHook = receipt.logs.findIndex(l => l.event === 'TokensToSendCalled'); - expect(externalSendHook).to.be.gte(0); - - expect(externalSendHook).to.be.lt(internalBeforeHook); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/presets/ERC777PresetFixedSupply.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/presets/ERC777PresetFixedSupply.test.js deleted file mode 100644 index e6a842b..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/ERC777/presets/ERC777PresetFixedSupply.test.js +++ /dev/null @@ -1,49 +0,0 @@ -const { BN, singletons } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC777PresetFixedSupply = artifacts.require('ERC777PresetFixedSupply'); - -contract('ERC777PresetFixedSupply', function (accounts) { - const [registryFunder, owner, defaultOperatorA, defaultOperatorB, anyone] = accounts; - - const initialSupply = new BN('10000'); - const name = 'ERC777Preset'; - const symbol = '777P'; - - const defaultOperators = [defaultOperatorA, defaultOperatorB]; - - before(async function () { - await singletons.ERC1820Registry(registryFunder); - }); - - beforeEach(async function () { - this.token = await ERC777PresetFixedSupply.new(name, symbol, defaultOperators, initialSupply, owner); - }); - - it('returns the name', async function () { - expect(await this.token.name()).to.equal(name); - }); - - it('returns the symbol', async function () { - expect(await this.token.symbol()).to.equal(symbol); - }); - - it('returns the default operators', async function () { - expect(await this.token.defaultOperators()).to.deep.equal(defaultOperators); - }); - - it('default operators are operators for all accounts', async function () { - for (const operator of defaultOperators) { - expect(await this.token.isOperatorFor(operator, anyone)).to.equal(true); - } - }); - - it('returns the total supply equal to initial supply', async function () { - expect(await this.token.totalSupply()).to.be.bignumber.equal(initialSupply); - }); - - it('returns the balance of owner equal to initial supply', async function () { - expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialSupply); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js deleted file mode 100644 index 2fd2747..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/token/common/ERC2981.behavior.js +++ /dev/null @@ -1,160 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { ZERO_ADDRESS } = constants; - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -function shouldBehaveLikeERC2981 () { - const royaltyFraction = new BN('10'); - - shouldSupportInterfaces(['ERC2981']); - - describe('default royalty', function () { - beforeEach(async function () { - await this.token.setDefaultRoyalty(this.account1, royaltyFraction); - }); - - it('checks royalty is set', async function () { - const royalty = new BN((this.salePrice * royaltyFraction) / 10000); - - const initInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - expect(initInfo[0]).to.be.equal(this.account1); - expect(initInfo[1]).to.be.bignumber.equal(royalty); - }); - - it('updates royalty amount', async function () { - const newPercentage = new BN('25'); - - // Updated royalty check - await this.token.setDefaultRoyalty(this.account1, newPercentage); - const royalty = new BN((this.salePrice * newPercentage) / 10000); - const newInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - expect(newInfo[0]).to.be.equal(this.account1); - expect(newInfo[1]).to.be.bignumber.equal(royalty); - }); - - it('holds same royalty value for different tokens', async function () { - const newPercentage = new BN('20'); - await this.token.setDefaultRoyalty(this.account1, newPercentage); - - const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - - expect(token1Info[1]).to.be.bignumber.equal(token2Info[1]); - }); - - it('Remove royalty information', async function () { - const newValue = new BN('0'); - await this.token.deleteDefaultRoyalty(); - - const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - // Test royalty info is still persistent across all tokens - expect(token1Info[0]).to.be.bignumber.equal(token2Info[0]); - expect(token1Info[1]).to.be.bignumber.equal(token2Info[1]); - // Test information was deleted - expect(token1Info[0]).to.be.equal(ZERO_ADDRESS); - expect(token1Info[1]).to.be.bignumber.equal(newValue); - }); - - it('reverts if invalid parameters', async function () { - await expectRevert( - this.token.setDefaultRoyalty(ZERO_ADDRESS, royaltyFraction), - 'ERC2981: invalid receiver', - ); - - await expectRevert( - this.token.setDefaultRoyalty(this.account1, new BN('11000')), - 'ERC2981: royalty fee will exceed salePrice', - ); - }); - }); - - describe('token based royalty', function () { - beforeEach(async function () { - await this.token.setTokenRoyalty(this.tokenId1, this.account1, royaltyFraction); - }); - - it('updates royalty amount', async function () { - const newPercentage = new BN('25'); - let royalty = new BN((this.salePrice * royaltyFraction) / 10000); - // Initial royalty check - const initInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - expect(initInfo[0]).to.be.equal(this.account1); - expect(initInfo[1]).to.be.bignumber.equal(royalty); - - // Updated royalty check - await this.token.setTokenRoyalty(this.tokenId1, this.account1, newPercentage); - royalty = new BN((this.salePrice * newPercentage) / 10000); - const newInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - expect(newInfo[0]).to.be.equal(this.account1); - expect(newInfo[1]).to.be.bignumber.equal(royalty); - }); - - it('holds different values for different tokens', async function () { - const newPercentage = new BN('20'); - await this.token.setTokenRoyalty(this.tokenId2, this.account1, newPercentage); - - const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - - // must be different even at the same this.salePrice - expect(token1Info[1]).to.not.be.equal(token2Info.royaltyFraction); - }); - - it('reverts if invalid parameters', async function () { - await expectRevert( - this.token.setTokenRoyalty(this.tokenId1, ZERO_ADDRESS, royaltyFraction), - 'ERC2981: Invalid parameters', - ); - - await expectRevert( - this.token.setTokenRoyalty(this.tokenId1, this.account1, new BN('11000')), - 'ERC2981: royalty fee will exceed salePrice', - ); - }); - - it('can reset token after setting royalty', async function () { - const newPercentage = new BN('30'); - const royalty = new BN((this.salePrice * newPercentage) / 10000); - await this.token.setTokenRoyalty(this.tokenId1, this.account2, newPercentage); - - const tokenInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - - // Tokens must have own information - expect(tokenInfo[1]).to.be.bignumber.equal(royalty); - expect(tokenInfo[0]).to.be.equal(this.account2); - - await this.token.setTokenRoyalty(this.tokenId2, this.account1, new BN('0')); - const result = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - // Token must not share default information - expect(result[0]).to.be.equal(this.account1); - expect(result[1]).to.be.bignumber.equal(new BN('0')); - }); - - it('can hold default and token royalty information', async function () { - const newPercentage = new BN('30'); - const royalty = new BN((this.salePrice * newPercentage) / 10000); - - await this.token.setTokenRoyalty(this.tokenId2, this.account2, newPercentage); - - const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice); - const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice); - // Tokens must not have same values - expect(token1Info[1]).to.not.be.bignumber.equal(token2Info[1]); - expect(token1Info[0]).to.not.be.equal(token2Info[0]); - - // Updated token must have new values - expect(token2Info[0]).to.be.equal(this.account2); - expect(token2Info[1]).to.be.bignumber.equal(royalty); - }); - }); -} - -module.exports = { - shouldBehaveLikeERC2981, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Address.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Address.test.js deleted file mode 100644 index 1bdfad4..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Address.test.js +++ /dev/null @@ -1,382 +0,0 @@ -const { balance, ether, expectRevert, send, expectEvent } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const AddressImpl = artifacts.require('AddressImpl'); -const EtherReceiver = artifacts.require('EtherReceiverMock'); -const CallReceiverMock = artifacts.require('CallReceiverMock'); - -contract('Address', function (accounts) { - const [ recipient, other ] = accounts; - - beforeEach(async function () { - this.mock = await AddressImpl.new(); - }); - - describe('isContract', function () { - it('returns false for account address', async function () { - expect(await this.mock.isContract(other)).to.equal(false); - }); - - it('returns true for contract address', async function () { - const contract = await AddressImpl.new(); - expect(await this.mock.isContract(contract.address)).to.equal(true); - }); - }); - - describe('sendValue', function () { - beforeEach(async function () { - this.recipientTracker = await balance.tracker(recipient); - }); - - context('when sender contract has no funds', function () { - it('sends 0 wei', async function () { - await this.mock.sendValue(other, 0); - - expect(await this.recipientTracker.delta()).to.be.bignumber.equal('0'); - }); - - it('reverts when sending non-zero amounts', async function () { - await expectRevert(this.mock.sendValue(other, 1), 'Address: insufficient balance'); - }); - }); - - context('when sender contract has funds', function () { - const funds = ether('1'); - beforeEach(async function () { - await send.ether(other, this.mock.address, funds); - }); - - it('sends 0 wei', async function () { - await this.mock.sendValue(recipient, 0); - expect(await this.recipientTracker.delta()).to.be.bignumber.equal('0'); - }); - - it('sends non-zero amounts', async function () { - await this.mock.sendValue(recipient, funds.subn(1)); - expect(await this.recipientTracker.delta()).to.be.bignumber.equal(funds.subn(1)); - }); - - it('sends the whole balance', async function () { - await this.mock.sendValue(recipient, funds); - expect(await this.recipientTracker.delta()).to.be.bignumber.equal(funds); - expect(await balance.current(this.mock.address)).to.be.bignumber.equal('0'); - }); - - it('reverts when sending more than the balance', async function () { - await expectRevert(this.mock.sendValue(recipient, funds.addn(1)), 'Address: insufficient balance'); - }); - - context('with contract recipient', function () { - beforeEach(async function () { - this.contractRecipient = await EtherReceiver.new(); - }); - - it('sends funds', async function () { - const tracker = await balance.tracker(this.contractRecipient.address); - - await this.contractRecipient.setAcceptEther(true); - await this.mock.sendValue(this.contractRecipient.address, funds); - expect(await tracker.delta()).to.be.bignumber.equal(funds); - }); - - it('reverts on recipient revert', async function () { - await this.contractRecipient.setAcceptEther(false); - await expectRevert( - this.mock.sendValue(this.contractRecipient.address, funds), - 'Address: unable to send value, recipient may have reverted', - ); - }); - }); - }); - }); - - describe('functionCall', function () { - beforeEach(async function () { - this.contractRecipient = await CallReceiverMock.new(); - }); - - context('with valid contract receiver', function () { - it('calls the requested function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - const receipt = await this.mock.functionCall(this.contractRecipient.address, abiEncodedCall); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); - }); - - it('reverts when the called function reverts with no reason', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionRevertsNoReason', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), - 'Address: low-level call failed', - ); - }); - - it('reverts when the called function reverts, bubbling up the revert reason', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionRevertsReason', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), - 'CallReceiverMock: reverting', - ); - }); - - it('reverts when the called function runs out of gas', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionOutOfGas', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall, { gas: '120000' }), - 'Address: low-level call failed', - ); - }); - - it('reverts when the called function throws', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionThrows', - type: 'function', - inputs: [], - }, []); - - await expectRevert.unspecified( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), - ); - }); - - it('reverts when function does not exist', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionDoesNotExist', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), - 'Address: low-level call failed', - ); - }); - }); - - context('with non-contract receiver', function () { - it('reverts when address is not a contract', async function () { - const [ recipient ] = accounts; - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - await expectRevert(this.mock.functionCall(recipient, abiEncodedCall), 'Address: call to non-contract'); - }); - }); - }); - - describe('functionCallWithValue', function () { - beforeEach(async function () { - this.contractRecipient = await CallReceiverMock.new(); - }); - - context('with zero value', function () { - it('calls the requested function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - const receipt = await this.mock.functionCallWithValue(this.contractRecipient.address, abiEncodedCall, 0); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); - }); - }); - - context('with non-zero value', function () { - const amount = ether('1.2'); - - it('reverts if insufficient sender balance', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionCallWithValue(this.contractRecipient.address, abiEncodedCall, amount), - 'Address: insufficient balance for call', - ); - }); - - it('calls the requested function with existing value', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - const tracker = await balance.tracker(this.contractRecipient.address); - - await send.ether(other, this.mock.address, amount); - const receipt = await this.mock.functionCallWithValue(this.contractRecipient.address, abiEncodedCall, amount); - - expect(await tracker.delta()).to.be.bignumber.equal(amount); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); - }); - - it('calls the requested function with transaction funds', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - const tracker = await balance.tracker(this.contractRecipient.address); - - expect(await balance.current(this.mock.address)).to.be.bignumber.equal('0'); - const receipt = await this.mock.functionCallWithValue( - this.contractRecipient.address, abiEncodedCall, amount, { from: other, value: amount }, - ); - - expect(await tracker.delta()).to.be.bignumber.equal(amount); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); - }); - - it('reverts when calling non-payable functions', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionNonPayable', - type: 'function', - inputs: [], - }, []); - - await send.ether(other, this.mock.address, amount); - await expectRevert( - this.mock.functionCallWithValue(this.contractRecipient.address, abiEncodedCall, amount), - 'Address: low-level call with value failed', - ); - }); - }); - }); - - describe('functionStaticCall', function () { - beforeEach(async function () { - this.contractRecipient = await CallReceiverMock.new(); - }); - - it('calls the requested function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockStaticFunction', - type: 'function', - inputs: [], - }, []); - - const receipt = await this.mock.functionStaticCall(this.contractRecipient.address, abiEncodedCall); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - }); - - it('reverts on a non-static function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionStaticCall(this.contractRecipient.address, abiEncodedCall), - 'Address: low-level static call failed', - ); - }); - - it('bubbles up revert reason', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionRevertsReason', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionStaticCall(this.contractRecipient.address, abiEncodedCall), - 'CallReceiverMock: reverting', - ); - }); - - it('reverts when address is not a contract', async function () { - const [ recipient ] = accounts; - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - await expectRevert( - this.mock.functionStaticCall(recipient, abiEncodedCall), - 'Address: call to non-contract', - ); - }); - }); - - describe('functionDelegateCall', function () { - beforeEach(async function () { - this.contractRecipient = await CallReceiverMock.new(); - }); - - it('delegate calls the requested function', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionWritesStorage', - type: 'function', - inputs: [], - }, []); - - const receipt = await this.mock.functionDelegateCall(this.contractRecipient.address, abiEncodedCall); - - expectEvent(receipt, 'CallReturnValue', { data: '0x1234' }); - - expect(await this.mock.sharedAnswer()).to.equal('42'); - }); - - it('bubbles up revert reason', async function () { - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunctionRevertsReason', - type: 'function', - inputs: [], - }, []); - - await expectRevert( - this.mock.functionDelegateCall(this.contractRecipient.address, abiEncodedCall), - 'CallReceiverMock: reverting', - ); - }); - - it('reverts when address is not a contract', async function () { - const [ recipient ] = accounts; - const abiEncodedCall = web3.eth.abi.encodeFunctionCall({ - name: 'mockFunction', - type: 'function', - inputs: [], - }, []); - await expectRevert( - this.mock.functionDelegateCall(recipient, abiEncodedCall), - 'Address: call to non-contract', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Arrays.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Arrays.test.js deleted file mode 100644 index 67128fa..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Arrays.test.js +++ /dev/null @@ -1,87 +0,0 @@ -require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ArraysImpl = artifacts.require('ArraysImpl'); - -contract('Arrays', function (accounts) { - describe('findUpperBound', function () { - context('Even number of elements', function () { - const EVEN_ELEMENTS_ARRAY = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; - - beforeEach(async function () { - this.arrays = await ArraysImpl.new(EVEN_ELEMENTS_ARRAY); - }); - - it('returns correct index for the basic case', async function () { - expect(await this.arrays.findUpperBound(16)).to.be.bignumber.equal('5'); - }); - - it('returns 0 for the first element', async function () { - expect(await this.arrays.findUpperBound(11)).to.be.bignumber.equal('0'); - }); - - it('returns index of the last element', async function () { - expect(await this.arrays.findUpperBound(20)).to.be.bignumber.equal('9'); - }); - - it('returns first index after last element if searched value is over the upper boundary', async function () { - expect(await this.arrays.findUpperBound(32)).to.be.bignumber.equal('10'); - }); - - it('returns 0 for the element under the lower boundary', async function () { - expect(await this.arrays.findUpperBound(2)).to.be.bignumber.equal('0'); - }); - }); - - context('Odd number of elements', function () { - const ODD_ELEMENTS_ARRAY = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]; - - beforeEach(async function () { - this.arrays = await ArraysImpl.new(ODD_ELEMENTS_ARRAY); - }); - - it('returns correct index for the basic case', async function () { - expect(await this.arrays.findUpperBound(16)).to.be.bignumber.equal('5'); - }); - - it('returns 0 for the first element', async function () { - expect(await this.arrays.findUpperBound(11)).to.be.bignumber.equal('0'); - }); - - it('returns index of the last element', async function () { - expect(await this.arrays.findUpperBound(21)).to.be.bignumber.equal('10'); - }); - - it('returns first index after last element if searched value is over the upper boundary', async function () { - expect(await this.arrays.findUpperBound(32)).to.be.bignumber.equal('11'); - }); - - it('returns 0 for the element under the lower boundary', async function () { - expect(await this.arrays.findUpperBound(2)).to.be.bignumber.equal('0'); - }); - }); - - context('Array with gap', function () { - const WITH_GAP_ARRAY = [11, 12, 13, 14, 15, 20, 21, 22, 23, 24]; - - beforeEach(async function () { - this.arrays = await ArraysImpl.new(WITH_GAP_ARRAY); - }); - - it('returns index of first element in next filled range', async function () { - expect(await this.arrays.findUpperBound(17)).to.be.bignumber.equal('5'); - }); - }); - - context('Empty array', function () { - beforeEach(async function () { - this.arrays = await ArraysImpl.new([]); - }); - - it('always returns 0 for empty array', async function () { - expect(await this.arrays.findUpperBound(10)).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Base64.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Base64.test.js deleted file mode 100644 index b6ee657..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Base64.test.js +++ /dev/null @@ -1,33 +0,0 @@ -const { expect } = require('chai'); - -const Base64Mock = artifacts.require('Base64Mock'); - -contract('Strings', function () { - beforeEach(async function () { - this.base64 = await Base64Mock.new(); - }); - - describe('from bytes - base64', function () { - it('converts to base64 encoded string with double padding', async function () { - const TEST_MESSAGE = 'test'; - const input = web3.utils.asciiToHex(TEST_MESSAGE); - expect(await this.base64.encode(input)).to.equal('dGVzdA=='); - }); - - it('converts to base64 encoded string with single padding', async function () { - const TEST_MESSAGE = 'test1'; - const input = web3.utils.asciiToHex(TEST_MESSAGE); - expect(await this.base64.encode(input)).to.equal('dGVzdDE='); - }); - - it('converts to base64 encoded string without padding', async function () { - const TEST_MESSAGE = 'test12'; - const input = web3.utils.asciiToHex(TEST_MESSAGE); - expect(await this.base64.encode(input)).to.equal('dGVzdDEy'); - }); - - it('empty bytes', async function () { - expect(await this.base64.encode([])).to.equal(''); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Checkpoints.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Checkpoints.test.js deleted file mode 100644 index 9938dc3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Checkpoints.test.js +++ /dev/null @@ -1,74 +0,0 @@ -const { expectRevert, time } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const { batchInBlock } = require('../helpers/txpool'); - -const CheckpointsImpl = artifacts.require('CheckpointsImpl'); - -contract('Checkpoints', function (accounts) { - beforeEach(async function () { - this.checkpoint = await CheckpointsImpl.new(); - }); - - describe('without checkpoints', function () { - it('returns zero as latest value', async function () { - expect(await this.checkpoint.latest()).to.be.bignumber.equal('0'); - }); - - it('returns zero as past value', async function () { - await time.advanceBlock(); - expect(await this.checkpoint.getAtBlock(await web3.eth.getBlockNumber() - 1)).to.be.bignumber.equal('0'); - }); - }); - - describe('with checkpoints', function () { - beforeEach('pushing checkpoints', async function () { - this.tx1 = await this.checkpoint.push(1); - this.tx2 = await this.checkpoint.push(2); - await time.advanceBlock(); - this.tx3 = await this.checkpoint.push(3); - await time.advanceBlock(); - await time.advanceBlock(); - }); - - it('returns latest value', async function () { - expect(await this.checkpoint.latest()).to.be.bignumber.equal('3'); - }); - - it('returns past values', async function () { - expect(await this.checkpoint.getAtBlock(this.tx1.receipt.blockNumber - 1)).to.be.bignumber.equal('0'); - expect(await this.checkpoint.getAtBlock(this.tx1.receipt.blockNumber)).to.be.bignumber.equal('1'); - expect(await this.checkpoint.getAtBlock(this.tx2.receipt.blockNumber)).to.be.bignumber.equal('2'); - // Block with no new checkpoints - expect(await this.checkpoint.getAtBlock(this.tx2.receipt.blockNumber + 1)).to.be.bignumber.equal('2'); - expect(await this.checkpoint.getAtBlock(this.tx3.receipt.blockNumber)).to.be.bignumber.equal('3'); - expect(await this.checkpoint.getAtBlock(this.tx3.receipt.blockNumber + 1)).to.be.bignumber.equal('3'); - }); - - it('reverts if block number >= current block', async function () { - await expectRevert( - this.checkpoint.getAtBlock(await web3.eth.getBlockNumber()), - 'Checkpoints: block not yet mined', - ); - - await expectRevert( - this.checkpoint.getAtBlock(await web3.eth.getBlockNumber() + 1), - 'Checkpoints: block not yet mined', - ); - }); - - it('multiple checkpoints in the same block', async function () { - const lengthBefore = await this.checkpoint.length(); - await batchInBlock([ - () => this.checkpoint.push(8, { gas: 100000 }), - () => this.checkpoint.push(9, { gas: 100000 }), - () => this.checkpoint.push(10, { gas: 100000 }), - ]); - const lengthAfter = await this.checkpoint.length(); - - expect(lengthAfter.toNumber()).to.be.equal(lengthBefore.toNumber() + 1); - expect(await this.checkpoint.latest()).to.be.bignumber.equal('10'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Context.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Context.behavior.js deleted file mode 100644 index 8728e10..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Context.behavior.js +++ /dev/null @@ -1,42 +0,0 @@ -const { BN, expectEvent } = require('@openzeppelin/test-helpers'); - -const ContextMock = artifacts.require('ContextMock'); - -function shouldBehaveLikeRegularContext (sender) { - describe('msgSender', function () { - it('returns the transaction sender when called from an EOA', async function () { - const receipt = await this.context.msgSender({ from: sender }); - expectEvent(receipt, 'Sender', { sender }); - }); - - it('returns the transaction sender when from another contract', async function () { - const { tx } = await this.caller.callSender(this.context.address, { from: sender }); - await expectEvent.inTransaction(tx, ContextMock, 'Sender', { sender: this.caller.address }); - }); - }); - - describe('msgData', function () { - const integerValue = new BN('42'); - const stringValue = 'OpenZeppelin'; - - let callData; - - beforeEach(async function () { - callData = this.context.contract.methods.msgData(integerValue.toString(), stringValue).encodeABI(); - }); - - it('returns the transaction data when called from an EOA', async function () { - const receipt = await this.context.msgData(integerValue, stringValue); - expectEvent(receipt, 'Data', { data: callData, integerValue, stringValue }); - }); - - it('returns the transaction sender when from another contract', async function () { - const { tx } = await this.caller.callData(this.context.address, integerValue, stringValue); - await expectEvent.inTransaction(tx, ContextMock, 'Data', { data: callData, integerValue, stringValue }); - }); - }); -} - -module.exports = { - shouldBehaveLikeRegularContext, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Context.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Context.test.js deleted file mode 100644 index 709aa87..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Context.test.js +++ /dev/null @@ -1,17 +0,0 @@ -require('@openzeppelin/test-helpers'); - -const ContextMock = artifacts.require('ContextMock'); -const ContextMockCaller = artifacts.require('ContextMockCaller'); - -const { shouldBehaveLikeRegularContext } = require('./Context.behavior'); - -contract('Context', function (accounts) { - const [ sender ] = accounts; - - beforeEach(async function () { - this.context = await ContextMock.new(); - this.caller = await ContextMockCaller.new(); - }); - - shouldBehaveLikeRegularContext(sender); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Counters.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Counters.test.js deleted file mode 100644 index 04be4c0..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Counters.test.js +++ /dev/null @@ -1,84 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const CountersImpl = artifacts.require('CountersImpl'); - -contract('Counters', function (accounts) { - beforeEach(async function () { - this.counter = await CountersImpl.new(); - }); - - it('starts at zero', async function () { - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - - describe('increment', function () { - context('starting from 0', function () { - it('increments the current value by one', async function () { - await this.counter.increment(); - expect(await this.counter.current()).to.be.bignumber.equal('1'); - }); - - it('can be called multiple times', async function () { - await this.counter.increment(); - await this.counter.increment(); - await this.counter.increment(); - - expect(await this.counter.current()).to.be.bignumber.equal('3'); - }); - }); - }); - - describe('decrement', function () { - beforeEach(async function () { - await this.counter.increment(); - expect(await this.counter.current()).to.be.bignumber.equal('1'); - }); - context('starting from 1', function () { - it('decrements the current value by one', async function () { - await this.counter.decrement(); - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - - it('reverts if the current value is 0', async function () { - await this.counter.decrement(); - await expectRevert(this.counter.decrement(), 'Counter: decrement overflow'); - }); - }); - context('after incremented to 3', function () { - it('can be called multiple times', async function () { - await this.counter.increment(); - await this.counter.increment(); - - expect(await this.counter.current()).to.be.bignumber.equal('3'); - - await this.counter.decrement(); - await this.counter.decrement(); - await this.counter.decrement(); - - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - }); - }); - - describe('reset', function () { - context('null counter', function () { - it('does not throw', async function () { - await this.counter.reset(); - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - }); - - context('non null counter', function () { - beforeEach(async function () { - await this.counter.increment(); - expect(await this.counter.current()).to.be.bignumber.equal('1'); - }); - it('reset to 0', async function () { - await this.counter.reset(); - expect(await this.counter.current()).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Create2.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Create2.test.js deleted file mode 100644 index b57e063..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Create2.test.js +++ /dev/null @@ -1,92 +0,0 @@ -const { balance, BN, ether, expectRevert, send } = require('@openzeppelin/test-helpers'); -const { computeCreate2Address } = require('../helpers/create2'); -const { expect } = require('chai'); - -const Create2Impl = artifacts.require('Create2Impl'); -const ERC20Mock = artifacts.require('ERC20Mock'); -const ERC1820Implementer = artifacts.require('ERC1820Implementer'); - -contract('Create2', function (accounts) { - const [deployerAccount] = accounts; - - const salt = 'salt message'; - const saltHex = web3.utils.soliditySha3(salt); - - const encodedParams = web3.eth.abi.encodeParameters( - ['string', 'string', 'address', 'uint256'], - ['MyToken', 'MTKN', deployerAccount, 100], - ).slice(2); - - const constructorByteCode = `${ERC20Mock.bytecode}${encodedParams}`; - - beforeEach(async function () { - this.factory = await Create2Impl.new(); - }); - describe('computeAddress', function () { - it('computes the correct contract address', async function () { - const onChainComputed = await this.factory - .computeAddress(saltHex, web3.utils.keccak256(constructorByteCode)); - const offChainComputed = - computeCreate2Address(saltHex, constructorByteCode, this.factory.address); - expect(onChainComputed).to.equal(offChainComputed); - }); - - it('computes the correct contract address with deployer', async function () { - const onChainComputed = await this.factory - .computeAddressWithDeployer(saltHex, web3.utils.keccak256(constructorByteCode), deployerAccount); - const offChainComputed = - computeCreate2Address(saltHex, constructorByteCode, deployerAccount); - expect(onChainComputed).to.equal(offChainComputed); - }); - }); - - describe('deploy', function () { - it('deploys a ERC1820Implementer from inline assembly code', async function () { - const offChainComputed = - computeCreate2Address(saltHex, ERC1820Implementer.bytecode, this.factory.address); - await this.factory.deployERC1820Implementer(0, saltHex); - expect(ERC1820Implementer.bytecode).to.include((await web3.eth.getCode(offChainComputed)).slice(2)); - }); - - it('deploys a ERC20Mock with correct balances', async function () { - const offChainComputed = computeCreate2Address(saltHex, constructorByteCode, this.factory.address); - - await this.factory.deploy(0, saltHex, constructorByteCode); - - const erc20 = await ERC20Mock.at(offChainComputed); - expect(await erc20.balanceOf(deployerAccount)).to.be.bignumber.equal(new BN(100)); - }); - - it('deploys a contract with funds deposited in the factory', async function () { - const deposit = ether('2'); - await send.ether(deployerAccount, this.factory.address, deposit); - expect(await balance.current(this.factory.address)).to.be.bignumber.equal(deposit); - - const onChainComputed = await this.factory - .computeAddressWithDeployer(saltHex, web3.utils.keccak256(constructorByteCode), this.factory.address); - - await this.factory.deploy(deposit, saltHex, constructorByteCode); - expect(await balance.current(onChainComputed)).to.be.bignumber.equal(deposit); - }); - - it('fails deploying a contract in an existent address', async function () { - await this.factory.deploy(0, saltHex, constructorByteCode, { from: deployerAccount }); - await expectRevert( - this.factory.deploy(0, saltHex, constructorByteCode, { from: deployerAccount }), 'Create2: Failed on deploy', - ); - }); - - it('fails deploying a contract if the bytecode length is zero', async function () { - await expectRevert( - this.factory.deploy(0, saltHex, '0x', { from: deployerAccount }), 'Create2: bytecode length is zero', - ); - }); - - it('fails deploying a contract if factory contract does not have sufficient balance', async function () { - await expectRevert( - this.factory.deploy(1, saltHex, constructorByteCode, { from: deployerAccount }), - 'Create2: insufficient balance', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Multicall.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Multicall.test.js deleted file mode 100644 index c6453bb..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Multicall.test.js +++ /dev/null @@ -1,57 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); -const MulticallTokenMock = artifacts.require('MulticallTokenMock'); - -contract('MulticallToken', function (accounts) { - const [deployer, alice, bob] = accounts; - const amount = 12000; - - beforeEach(async function () { - this.multicallToken = await MulticallTokenMock.new(new BN(amount), { from: deployer }); - }); - - it('batches function calls', async function () { - expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0')); - expect(await this.multicallToken.balanceOf(bob)).to.be.bignumber.equal(new BN('0')); - - await this.multicallToken.multicall([ - this.multicallToken.contract.methods.transfer(alice, amount / 2).encodeABI(), - this.multicallToken.contract.methods.transfer(bob, amount / 3).encodeABI(), - ], { from: deployer }); - - expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN(amount / 2)); - expect(await this.multicallToken.balanceOf(bob)).to.be.bignumber.equal(new BN(amount / 3)); - }); - - it('returns an array with the result of each call', async function () { - const MulticallTest = artifacts.require('MulticallTest'); - const multicallTest = await MulticallTest.new({ from: deployer }); - await this.multicallToken.transfer(multicallTest.address, amount, { from: deployer }); - expect(await this.multicallToken.balanceOf(multicallTest.address)).to.be.bignumber.equal(new BN(amount)); - - const recipients = [alice, bob]; - const amounts = [amount / 2, amount / 3].map(n => new BN(n)); - - await multicallTest.testReturnValues(this.multicallToken.address, recipients, amounts); - }); - - it('reverts previous calls', async function () { - expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0')); - - const call = this.multicallToken.multicall([ - this.multicallToken.contract.methods.transfer(alice, amount).encodeABI(), - this.multicallToken.contract.methods.transfer(bob, amount).encodeABI(), - ], { from: deployer }); - - await expectRevert(call, 'ERC20: transfer amount exceeds balance'); - expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0')); - }); - - it('bubbles up revert reasons', async function () { - const call = this.multicallToken.multicall([ - this.multicallToken.contract.methods.transfer(alice, amount).encodeABI(), - this.multicallToken.contract.methods.transfer(bob, amount).encodeABI(), - ], { from: deployer }); - - await expectRevert(call, 'ERC20: transfer amount exceeds balance'); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/StorageSlot.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/StorageSlot.test.js deleted file mode 100644 index 9d42887..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/StorageSlot.test.js +++ /dev/null @@ -1,110 +0,0 @@ -const { constants, BN } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const StorageSlotMock = artifacts.require('StorageSlotMock'); - -const slot = web3.utils.keccak256('some.storage.slot'); -const otherSlot = web3.utils.keccak256('some.other.storage.slot'); - -contract('StorageSlot', function (accounts) { - beforeEach(async function () { - this.store = await StorageSlotMock.new(); - }); - - describe('boolean storage slot', function () { - beforeEach(async function () { - this.value = true; - }); - - it('set', async function () { - await this.store.setBoolean(slot, this.value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.store.setBoolean(slot, this.value); - }); - - it('from right slot', async function () { - expect(await this.store.getBoolean(slot)).to.be.equal(this.value); - }); - - it('from other slot', async function () { - expect(await this.store.getBoolean(otherSlot)).to.be.equal(false); - }); - }); - }); - - describe('address storage slot', function () { - beforeEach(async function () { - this.value = accounts[1]; - }); - - it('set', async function () { - await this.store.setAddress(slot, this.value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.store.setAddress(slot, this.value); - }); - - it('from right slot', async function () { - expect(await this.store.getAddress(slot)).to.be.equal(this.value); - }); - - it('from other slot', async function () { - expect(await this.store.getAddress(otherSlot)).to.be.equal(constants.ZERO_ADDRESS); - }); - }); - }); - - describe('bytes32 storage slot', function () { - beforeEach(async function () { - this.value = web3.utils.keccak256('some byte32 value'); - }); - - it('set', async function () { - await this.store.setBytes32(slot, this.value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.store.setBytes32(slot, this.value); - }); - - it('from right slot', async function () { - expect(await this.store.getBytes32(slot)).to.be.equal(this.value); - }); - - it('from other slot', async function () { - expect(await this.store.getBytes32(otherSlot)).to.be.equal(constants.ZERO_BYTES32); - }); - }); - }); - - describe('uint256 storage slot', function () { - beforeEach(async function () { - this.value = new BN(1742); - }); - - it('set', async function () { - await this.store.setUint256(slot, this.value); - }); - - describe('get', function () { - beforeEach(async function () { - await this.store.setUint256(slot, this.value); - }); - - it('from right slot', async function () { - expect(await this.store.getUint256(slot)).to.be.bignumber.equal(this.value); - }); - - it('from other slot', async function () { - expect(await this.store.getUint256(otherSlot)).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Strings.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Strings.test.js deleted file mode 100644 index 8dda829..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/Strings.test.js +++ /dev/null @@ -1,71 +0,0 @@ -const { constants, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const StringsMock = artifacts.require('StringsMock'); - -contract('Strings', function (accounts) { - beforeEach(async function () { - this.strings = await StringsMock.new(); - }); - - describe('from uint256 - decimal format', function () { - it('converts 0', async function () { - expect(await this.strings.fromUint256(0)).to.equal('0'); - }); - - it('converts a positive number', async function () { - expect(await this.strings.fromUint256(4132)).to.equal('4132'); - }); - - it('converts MAX_UINT256', async function () { - expect(await this.strings.fromUint256(constants.MAX_UINT256)).to.equal(constants.MAX_UINT256.toString()); - }); - }); - - describe('from uint256 - hex format', function () { - it('converts 0', async function () { - expect(await this.strings.fromUint256Hex(0)).to.equal('0x00'); - }); - - it('converts a positive number', async function () { - expect(await this.strings.fromUint256Hex(0x4132)).to.equal('0x4132'); - }); - - it('converts MAX_UINT256', async function () { - expect(await this.strings.fromUint256Hex(constants.MAX_UINT256)) - .to.equal(web3.utils.toHex(constants.MAX_UINT256)); - }); - }); - - describe('from uint256 - fixed hex format', function () { - it('converts a positive number (long)', async function () { - expect(await this.strings.fromUint256HexFixed(0x4132, 32)) - .to.equal('0x0000000000000000000000000000000000000000000000000000000000004132'); - }); - - it('converts a positive number (short)', async function () { - await expectRevert( - this.strings.fromUint256HexFixed(0x4132, 1), - 'Strings: hex length insufficient', - ); - }); - - it('converts MAX_UINT256', async function () { - expect(await this.strings.fromUint256HexFixed(constants.MAX_UINT256, 32)) - .to.equal(web3.utils.toHex(constants.MAX_UINT256)); - }); - }); - - describe('from address - fixed hex format', function () { - it('converts a random address', async function () { - const addr = '0xa9036907dccae6a1e0033479b12e837e5cf5a02f'; - expect(await this.strings.fromAddressHexFixed(addr)).to.equal(addr); - }); - - it('converts an address with leading zeros', async function () { - const addr = '0x0000e0ca771e21bd00057f54a68c30d400000000'; - expect(await this.strings.fromAddressHexFixed(addr)).to.equal(addr); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/TimersBlockNumberImpl.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/TimersBlockNumberImpl.test.js deleted file mode 100644 index d9f83d9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/TimersBlockNumberImpl.test.js +++ /dev/null @@ -1,55 +0,0 @@ -const { BN, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const TimersBlockNumberImpl = artifacts.require('TimersBlockNumberImpl'); - -contract('TimersBlockNumber', function (accounts) { - beforeEach(async function () { - this.instance = await TimersBlockNumberImpl.new(); - this.now = await web3.eth.getBlock('latest').then(({ number }) => number); - }); - - it('unset', async function () { - expect(await this.instance.getDeadline()).to.be.bignumber.equal('0'); - expect(await this.instance.isUnset()).to.be.equal(true); - expect(await this.instance.isStarted()).to.be.equal(false); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('pending', async function () { - await this.instance.setDeadline(this.now + 3); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(this.now + 3)); - expect(await this.instance.isUnset()).to.be.equal(false); - expect(await this.instance.isStarted()).to.be.equal(true); - expect(await this.instance.isPending()).to.be.equal(true); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('expired', async function () { - await this.instance.setDeadline(this.now - 3); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(this.now - 3)); - expect(await this.instance.isUnset()).to.be.equal(false); - expect(await this.instance.isStarted()).to.be.equal(true); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(true); - }); - - it('reset', async function () { - await this.instance.reset(); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(0)); - expect(await this.instance.isUnset()).to.be.equal(true); - expect(await this.instance.isStarted()).to.be.equal(false); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('fast forward', async function () { - await this.instance.setDeadline(this.now + 3); - expect(await this.instance.isPending()).to.be.equal(true); - expect(await this.instance.isExpired()).to.be.equal(false); - await time.advanceBlockTo(this.now + 3); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(true); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/TimersTimestamp.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/TimersTimestamp.test.js deleted file mode 100644 index b08118d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/TimersTimestamp.test.js +++ /dev/null @@ -1,55 +0,0 @@ -const { BN, time } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const TimersTimestampImpl = artifacts.require('TimersTimestampImpl'); - -contract('TimersTimestamp', function (accounts) { - beforeEach(async function () { - this.instance = await TimersTimestampImpl.new(); - this.now = await web3.eth.getBlock('latest').then(({ timestamp }) => timestamp); - }); - - it('unset', async function () { - expect(await this.instance.getDeadline()).to.be.bignumber.equal('0'); - expect(await this.instance.isUnset()).to.be.equal(true); - expect(await this.instance.isStarted()).to.be.equal(false); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('pending', async function () { - await this.instance.setDeadline(this.now + 100); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(this.now + 100)); - expect(await this.instance.isUnset()).to.be.equal(false); - expect(await this.instance.isStarted()).to.be.equal(true); - expect(await this.instance.isPending()).to.be.equal(true); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('expired', async function () { - await this.instance.setDeadline(this.now - 100); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(this.now - 100)); - expect(await this.instance.isUnset()).to.be.equal(false); - expect(await this.instance.isStarted()).to.be.equal(true); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(true); - }); - - it('reset', async function () { - await this.instance.reset(); - expect(await this.instance.getDeadline()).to.be.bignumber.equal(new BN(0)); - expect(await this.instance.isUnset()).to.be.equal(true); - expect(await this.instance.isStarted()).to.be.equal(false); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(false); - }); - - it('fast forward', async function () { - await this.instance.setDeadline(this.now + 100); - expect(await this.instance.isPending()).to.be.equal(true); - expect(await this.instance.isExpired()).to.be.equal(false); - await time.increaseTo(this.now + 100); - expect(await this.instance.isPending()).to.be.equal(false); - expect(await this.instance.isExpired()).to.be.equal(true); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js deleted file mode 100644 index fff3e2c..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/ECDSA.test.js +++ /dev/null @@ -1,222 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { toEthSignedMessageHash } = require('../../helpers/sign'); - -const { expect } = require('chai'); - -const ECDSAMock = artifacts.require('ECDSAMock'); - -const TEST_MESSAGE = web3.utils.sha3('OpenZeppelin'); -const WRONG_MESSAGE = web3.utils.sha3('Nope'); -const NON_HASH_MESSAGE = '0x' + Buffer.from('abcd').toString('hex'); - -function to2098Format (signature) { - const long = web3.utils.hexToBytes(signature); - if (long.length !== 65) { - throw new Error('invalid signature length (expected long format)'); - } - if (long[32] >> 7 === 1) { - throw new Error('invalid signature \'s\' value'); - } - const short = long.slice(0, 64); - short[32] |= (long[64] % 27) << 7; // set the first bit of the 32nd byte to the v parity bit - return web3.utils.bytesToHex(short); -} - -function from2098Format (signature) { - const short = web3.utils.hexToBytes(signature); - if (short.length !== 64) { - throw new Error('invalid signature length (expected short format)'); - } - short.push((short[32] >> 7) + 27); - short[32] &= (1 << 7) - 1; // zero out the first bit of 1 the 32nd byte - return web3.utils.bytesToHex(short); -} - -function split (signature) { - const raw = web3.utils.hexToBytes(signature); - switch (raw.length) { - case 64: - return [ - web3.utils.bytesToHex(raw.slice(0, 32)), // r - web3.utils.bytesToHex(raw.slice(32, 64)), // vs - ]; - case 65: - return [ - raw[64], // v - web3.utils.bytesToHex(raw.slice(0, 32)), // r - web3.utils.bytesToHex(raw.slice(32, 64)), // s - ]; - default: - expect.fail('Invalid signature length, cannot split'); - } -} - -contract('ECDSA', function (accounts) { - const [ other ] = accounts; - - beforeEach(async function () { - this.ecdsa = await ECDSAMock.new(); - }); - - context('recover with invalid signature', function () { - it('with short signature', async function () { - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, '0x1234'), 'ECDSA: invalid signature length'); - }); - - it('with long signature', async function () { - await expectRevert( - // eslint-disable-next-line max-len - this.ecdsa.recover(TEST_MESSAGE, '0x01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'), - 'ECDSA: invalid signature length', - ); - }); - }); - - context('recover with valid signature', function () { - context('using web3.eth.sign', function () { - it('returns signer address with correct signature', async function () { - // Create the signature - const signature = await web3.eth.sign(TEST_MESSAGE, other); - - // Recover the signer address from the generated message and signature. - expect(await this.ecdsa.recover( - toEthSignedMessageHash(TEST_MESSAGE), - signature, - )).to.equal(other); - }); - - it('returns signer address with correct signature for arbitrary length message', async function () { - // Create the signature - const signature = await web3.eth.sign(NON_HASH_MESSAGE, other); - - // Recover the signer address from the generated message and signature. - expect(await this.ecdsa.recover( - toEthSignedMessageHash(NON_HASH_MESSAGE), - signature, - )).to.equal(other); - }); - - it('returns a different address', async function () { - const signature = await web3.eth.sign(TEST_MESSAGE, other); - expect(await this.ecdsa.recover(WRONG_MESSAGE, signature)).to.not.equal(other); - }); - - it('reverts with invalid signature', async function () { - // eslint-disable-next-line max-len - const signature = '0x332ce75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e01c'; - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, signature), 'ECDSA: invalid signature'); - }); - }); - - context('with v0 signature', function () { - // Signature generated outside ganache with method web3.eth.sign(signer, message) - const signer = '0x2cc1166f6212628A0deEf2B33BEFB2187D35b86c'; - // eslint-disable-next-line max-len - const signatureWithoutVersion = '0x5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be892'; - - it('reverts with 00 as version value', async function () { - const version = '00'; - const signature = signatureWithoutVersion + version; - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, signature), 'ECDSA: invalid signature \'v\' value'); - await expectRevert( - this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature)), - 'ECDSA: invalid signature \'v\' value', - ); - }); - - it('works with 27 as version value', async function () { - const version = '1b'; // 27 = 1b. - const signature = signatureWithoutVersion + version; - expect(await this.ecdsa.recover(TEST_MESSAGE, signature)).to.equal(signer); - expect(await this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature))).to.equal(signer); - expect(await this.ecdsa.recover_r_vs(TEST_MESSAGE, ...split(to2098Format(signature)))).to.equal(signer); - }); - - it('reverts with wrong version', async function () { - // The last two hex digits are the signature version. - // The only valid values are 0, 1, 27 and 28. - const version = '02'; - const signature = signatureWithoutVersion + version; - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, signature), 'ECDSA: invalid signature \'v\' value'); - await expectRevert( - this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature)), - 'ECDSA: invalid signature \'v\' value', - ); - }); - - it('works with short EIP2098 format', async function () { - const version = '1b'; // 27 = 1b. - const signature = signatureWithoutVersion + version; - expect(await this.ecdsa.recover(TEST_MESSAGE, to2098Format(signature))).to.equal(signer); - expect(await this.ecdsa.recover(TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.equal(signer); - }); - }); - - context('with v1 signature', function () { - const signer = '0x1E318623aB09Fe6de3C9b8672098464Aeda9100E'; - // eslint-disable-next-line max-len - const signatureWithoutVersion = '0x331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e0'; - - it('reverts with 01 as version value', async function () { - const version = '01'; - const signature = signatureWithoutVersion + version; - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, signature), 'ECDSA: invalid signature \'v\' value'); - await expectRevert( - this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature)), - 'ECDSA: invalid signature \'v\' value', - ); - }); - - it('works with 28 as version value', async function () { - const version = '1c'; // 28 = 1c. - const signature = signatureWithoutVersion + version; - expect(await this.ecdsa.recover(TEST_MESSAGE, signature)).to.equal(signer); - expect(await this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature))).to.equal(signer); - expect(await this.ecdsa.recover_r_vs(TEST_MESSAGE, ...split(to2098Format(signature)))).to.equal(signer); - }); - - it('reverts with wrong version', async function () { - // The last two hex digits are the signature version. - // The only valid values are 0, 1, 27 and 28. - const version = '02'; - const signature = signatureWithoutVersion + version; - await expectRevert(this.ecdsa.recover(TEST_MESSAGE, signature), 'ECDSA: invalid signature \'v\' value'); - await expectRevert( - this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(signature)), - 'ECDSA: invalid signature \'v\' value', - ); - }); - - it('works with short EIP2098 format', async function () { - const version = '1c'; // 27 = 1b. - const signature = signatureWithoutVersion + version; - expect(await this.ecdsa.recover(TEST_MESSAGE, to2098Format(signature))).to.equal(signer); - expect(await this.ecdsa.recover(TEST_MESSAGE, from2098Format(to2098Format(signature)))).to.equal(signer); - }); - }); - - it('reverts with high-s value signature', async function () { - const message = '0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'; - // eslint-disable-next-line max-len - const highSSignature = '0xe742ff452d41413616a5bf43fe15dd88294e983d3d36206c2712f39083d638bde0a0fc89be718fbc1033e1d30d78be1c68081562ed2e97af876f286f3453231d1b'; - await expectRevert(this.ecdsa.recover(message, highSSignature), 'ECDSA: invalid signature \'s\' value'); - await expectRevert( - this.ecdsa.recover_v_r_s(TEST_MESSAGE, ...split(highSSignature)), - 'ECDSA: invalid signature \'s\' value', - ); - expect(() => to2098Format(highSSignature)).to.throw('invalid signature \'s\' value'); - }); - }); - - context('toEthSignedMessageHash', function () { - it('prefixes bytes32 data correctly', async function () { - expect(await this.ecdsa.methods['toEthSignedMessageHash(bytes32)'](TEST_MESSAGE)) - .to.equal(toEthSignedMessageHash(TEST_MESSAGE)); - }); - - it('prefixes dynamic length data correctly', async function () { - expect(await this.ecdsa.methods['toEthSignedMessageHash(bytes)'](NON_HASH_MESSAGE)) - .to.equal(toEthSignedMessageHash(NON_HASH_MESSAGE)); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js deleted file mode 100644 index 2d4aacd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/MerkleProof.test.js +++ /dev/null @@ -1,179 +0,0 @@ -require('@openzeppelin/test-helpers'); - -const { expectRevert } = require('@openzeppelin/test-helpers'); -const { MerkleTree } = require('merkletreejs'); -const keccak256 = require('keccak256'); - -const { expect } = require('chai'); - -const MerkleProofWrapper = artifacts.require('MerkleProofWrapper'); - -contract('MerkleProof', function (accounts) { - beforeEach(async function () { - this.merkleProof = await MerkleProofWrapper.new(); - }); - - describe('verify', function () { - it('returns true for a valid Merkle proof', async function () { - const elements = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''); - const merkleTree = new MerkleTree(elements, keccak256, { hashLeaves: true, sortPairs: true }); - - const root = merkleTree.getHexRoot(); - - const leaf = keccak256(elements[0]); - - const proof = merkleTree.getHexProof(leaf); - - expect(await this.merkleProof.verify(proof, root, leaf)).to.equal(true); - expect(await this.merkleProof.verifyCalldata(proof, root, leaf)).to.equal(true); - - // For demonstration, it is also possible to create valid proofs for certain 64-byte values *not* in elements: - const noSuchLeaf = keccak256( - Buffer.concat([keccak256(elements[0]), keccak256(elements[1])].sort(Buffer.compare)), - ); - expect(await this.merkleProof.verify(proof.slice(1), root, noSuchLeaf)).to.equal(true); - expect(await this.merkleProof.verifyCalldata(proof.slice(1), root, noSuchLeaf)).to.equal(true); - }); - - it('returns false for an invalid Merkle proof', async function () { - const correctElements = ['a', 'b', 'c']; - const correctMerkleTree = new MerkleTree(correctElements, keccak256, { hashLeaves: true, sortPairs: true }); - - const correctRoot = correctMerkleTree.getHexRoot(); - - const correctLeaf = keccak256(correctElements[0]); - - const badElements = ['d', 'e', 'f']; - const badMerkleTree = new MerkleTree(badElements); - - const badProof = badMerkleTree.getHexProof(badElements[0]); - - expect(await this.merkleProof.verify(badProof, correctRoot, correctLeaf)).to.equal(false); - expect(await this.merkleProof.verifyCalldata(badProof, correctRoot, correctLeaf)).to.equal(false); - }); - - it('returns false for a Merkle proof of invalid length', async function () { - const elements = ['a', 'b', 'c']; - const merkleTree = new MerkleTree(elements, keccak256, { hashLeaves: true, sortPairs: true }); - - const root = merkleTree.getHexRoot(); - - const leaf = keccak256(elements[0]); - - const proof = merkleTree.getHexProof(leaf); - const badProof = proof.slice(0, proof.length - 5); - - expect(await this.merkleProof.verify(badProof, root, leaf)).to.equal(false); - expect(await this.merkleProof.verifyCalldata(badProof, root, leaf)).to.equal(false); - }); - }); - - describe('multiProofVerify', function () { - it('returns true for a valid Merkle multi proof', async function () { - const leaves = ['a', 'b', 'c', 'd', 'e', 'f'].map(keccak256).sort(Buffer.compare); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - const proofLeaves = ['b', 'f', 'd'].map(keccak256).sort(Buffer.compare); - const proof = merkleTree.getMultiProof(proofLeaves); - const proofFlags = merkleTree.getProofFlags(proofLeaves, proof); - - expect(await this.merkleProof.multiProofVerify(proof, proofFlags, root, proofLeaves)).to.equal(true); - expect(await this.merkleProof.multiProofVerifyCalldata(proof, proofFlags, root, proofLeaves)).to.equal(true); - }); - - it('returns false for an invalid Merkle multi proof', async function () { - const leaves = ['a', 'b', 'c', 'd', 'e', 'f'].map(keccak256).sort(Buffer.compare); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - const badProofLeaves = ['g', 'h', 'i'].map(keccak256).sort(Buffer.compare); - const badMerkleTree = new MerkleTree(badProofLeaves); - const badProof = badMerkleTree.getMultiProof(badProofLeaves); - const badProofFlags = badMerkleTree.getProofFlags(badProofLeaves, badProof); - - expect(await this.merkleProof.multiProofVerify(badProof, badProofFlags, root, badProofLeaves)) - .to.equal(false); - expect(await this.merkleProof.multiProofVerifyCalldata(badProof, badProofFlags, root, badProofLeaves)) - .to.equal(false); - }); - - it('revert with invalid multi proof #1', async function () { - const fill = Buffer.alloc(32); // This could be anything, we are reconstructing a fake branch - const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare); - const badLeaf = keccak256('e'); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - - await expectRevert( - this.merkleProof.multiProofVerify( - [ leaves[1], fill, merkleTree.layers[1][1] ], - [ false, false, false ], - root, - [ leaves[0], badLeaf ], // A, E - ), - 'MerkleProof: invalid multiproof', - ); - await expectRevert( - this.merkleProof.multiProofVerifyCalldata( - [ leaves[1], fill, merkleTree.layers[1][1] ], - [ false, false, false ], - root, - [ leaves[0], badLeaf ], // A, E - ), - 'MerkleProof: invalid multiproof', - ); - }); - - it('revert with invalid multi proof #2', async function () { - const fill = Buffer.alloc(32); // This could be anything, we are reconstructing a fake branch - const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare); - const badLeaf = keccak256('e'); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - - await expectRevert( - this.merkleProof.multiProofVerify( - [ leaves[1], fill, merkleTree.layers[1][1] ], - [ false, false, false, false ], - root, - [ badLeaf, leaves[0] ], // A, E - ), - 'reverted with panic code 0x32', - ); - await expectRevert( - this.merkleProof.multiProofVerifyCalldata( - [ leaves[1], fill, merkleTree.layers[1][1] ], - [ false, false, false, false ], - root, - [ badLeaf, leaves[0] ], // A, E - ), - 'reverted with panic code 0x32', - ); - }); - - it('limit case: works for tree containing a single leaf', async function () { - const leaves = ['a'].map(keccak256).sort(Buffer.compare); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - const proofLeaves = ['a'].map(keccak256).sort(Buffer.compare); - const proof = merkleTree.getMultiProof(proofLeaves); - const proofFlags = merkleTree.getProofFlags(proofLeaves, proof); - - expect(await this.merkleProof.multiProofVerify(proof, proofFlags, root, proofLeaves)).to.equal(true); - expect(await this.merkleProof.multiProofVerifyCalldata(proof, proofFlags, root, proofLeaves)).to.equal(true); - }); - - it('limit case: can prove empty leaves', async function () { - const leaves = ['a', 'b', 'c', 'd'].map(keccak256).sort(Buffer.compare); - const merkleTree = new MerkleTree(leaves, keccak256, { sort: true }); - - const root = merkleTree.getRoot(); - expect(await this.merkleProof.multiProofVerify([ root ], [], root, [])).to.equal(true); - expect(await this.merkleProof.multiProofVerifyCalldata([ root ], [], root, [])).to.equal(true); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js deleted file mode 100644 index 801377a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/SignatureChecker.test.js +++ /dev/null @@ -1,81 +0,0 @@ -const { toEthSignedMessageHash } = require('../../helpers/sign'); - -const { expect } = require('chai'); - -const SignatureCheckerMock = artifacts.require('SignatureCheckerMock'); -const ERC1271WalletMock = artifacts.require('ERC1271WalletMock'); -const ERC1271MaliciousMock = artifacts.require('ERC1271MaliciousMock'); - -const TEST_MESSAGE = web3.utils.sha3('OpenZeppelin'); -const WRONG_MESSAGE = web3.utils.sha3('Nope'); - -contract('SignatureChecker (ERC1271)', function (accounts) { - const [signer, other] = accounts; - - before('deploying', async function () { - this.signaturechecker = await SignatureCheckerMock.new(); - this.wallet = await ERC1271WalletMock.new(signer); - this.malicious = await ERC1271MaliciousMock.new(); - this.signature = await web3.eth.sign(TEST_MESSAGE, signer); - }); - - context('EOA account', function () { - it('with matching signer and signature', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - signer, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(true); - }); - - it('with invalid signer', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - other, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(false); - }); - - it('with invalid signature', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - signer, - toEthSignedMessageHash(WRONG_MESSAGE), - this.signature, - )).to.equal(false); - }); - }); - - context('ERC1271 wallet', function () { - it('with matching signer and signature', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - this.wallet.address, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(true); - }); - - it('with invalid signer', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - this.signaturechecker.address, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(false); - }); - - it('with invalid signature', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - this.wallet.address, - toEthSignedMessageHash(WRONG_MESSAGE), - this.signature, - )).to.equal(false); - }); - - it('with malicious wallet', async function () { - expect(await this.signaturechecker.isValidSignatureNow( - this.malicious.address, - toEthSignedMessageHash(TEST_MESSAGE), - this.signature, - )).to.equal(false); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/draft-EIP712.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/draft-EIP712.test.js deleted file mode 100644 index 9e26a87..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/cryptography/draft-EIP712.test.js +++ /dev/null @@ -1,57 +0,0 @@ -const ethSigUtil = require('eth-sig-util'); -const Wallet = require('ethereumjs-wallet').default; - -const { EIP712Domain, domainSeparator } = require('../../helpers/eip712'); - -const EIP712 = artifacts.require('EIP712External'); - -contract('EIP712', function (accounts) { - const [mailTo] = accounts; - - const name = 'A Name'; - const version = '1'; - - beforeEach('deploying', async function () { - this.eip712 = await EIP712.new(name, version); - - // We get the chain id from the contract because Ganache (used for coverage) does not return the same chain id - // from within the EVM as from the JSON RPC interface. - // See https://github.com/trufflesuite/ganache-core/issues/515 - this.chainId = await this.eip712.getChainId(); - }); - - it('domain separator', async function () { - expect( - await this.eip712.domainSeparator(), - ).to.equal( - await domainSeparator(name, version, this.chainId, this.eip712.address), - ); - }); - - it('digest', async function () { - const chainId = this.chainId; - const verifyingContract = this.eip712.address; - const message = { - to: mailTo, - contents: 'very interesting', - }; - - const data = { - types: { - EIP712Domain, - Mail: [ - { name: 'to', type: 'address' }, - { name: 'contents', type: 'string' }, - ], - }, - domain: { name, version, chainId, verifyingContract }, - primaryType: 'Mail', - message, - }; - - const wallet = Wallet.generate(); - const signature = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), { data }); - - await this.eip712.verify(signature, wallet.getAddressString(), message.to, message.contents); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/ConditionalEscrow.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/ConditionalEscrow.test.js deleted file mode 100644 index 3386ca5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/ConditionalEscrow.test.js +++ /dev/null @@ -1,36 +0,0 @@ -const { ether, expectRevert } = require('@openzeppelin/test-helpers'); -const { shouldBehaveLikeEscrow } = require('./Escrow.behavior'); - -const ConditionalEscrowMock = artifacts.require('ConditionalEscrowMock'); - -contract('ConditionalEscrow', function (accounts) { - const [ owner, payee, ...otherAccounts ] = accounts; - - beforeEach(async function () { - this.escrow = await ConditionalEscrowMock.new({ from: owner }); - }); - - context('when withdrawal is allowed', function () { - beforeEach(async function () { - await Promise.all(otherAccounts.map(payee => this.escrow.setAllowed(payee, true))); - }); - - shouldBehaveLikeEscrow(owner, otherAccounts); - }); - - context('when withdrawal is disallowed', function () { - const amount = ether('23'); - - beforeEach(async function () { - await this.escrow.setAllowed(payee, false); - }); - - it('reverts on withdrawals', async function () { - await this.escrow.deposit(payee, { from: owner, value: amount }); - - await expectRevert(this.escrow.withdraw(payee, { from: owner }), - 'ConditionalEscrow: payee is not allowed to withdraw', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/Escrow.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/Escrow.behavior.js deleted file mode 100644 index ab59059..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/Escrow.behavior.js +++ /dev/null @@ -1,94 +0,0 @@ -const { balance, ether, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -function shouldBehaveLikeEscrow (owner, [payee1, payee2]) { - const amount = ether('42'); - - describe('as an escrow', function () { - describe('deposits', function () { - it('can accept a single deposit', async function () { - await this.escrow.deposit(payee1, { from: owner, value: amount }); - - expect(await balance.current(this.escrow.address)).to.be.bignumber.equal(amount); - - expect(await this.escrow.depositsOf(payee1)).to.be.bignumber.equal(amount); - }); - - it('can accept an empty deposit', async function () { - await this.escrow.deposit(payee1, { from: owner, value: 0 }); - }); - - it('only the owner can deposit', async function () { - await expectRevert(this.escrow.deposit(payee1, { from: payee2 }), - 'Ownable: caller is not the owner', - ); - }); - - it('emits a deposited event', async function () { - const receipt = await this.escrow.deposit(payee1, { from: owner, value: amount }); - expectEvent(receipt, 'Deposited', { - payee: payee1, - weiAmount: amount, - }); - }); - - it('can add multiple deposits on a single account', async function () { - await this.escrow.deposit(payee1, { from: owner, value: amount }); - await this.escrow.deposit(payee1, { from: owner, value: amount.muln(2) }); - - expect(await balance.current(this.escrow.address)).to.be.bignumber.equal(amount.muln(3)); - - expect(await this.escrow.depositsOf(payee1)).to.be.bignumber.equal(amount.muln(3)); - }); - - it('can track deposits to multiple accounts', async function () { - await this.escrow.deposit(payee1, { from: owner, value: amount }); - await this.escrow.deposit(payee2, { from: owner, value: amount.muln(2) }); - - expect(await balance.current(this.escrow.address)).to.be.bignumber.equal(amount.muln(3)); - - expect(await this.escrow.depositsOf(payee1)).to.be.bignumber.equal(amount); - - expect(await this.escrow.depositsOf(payee2)).to.be.bignumber.equal(amount.muln(2)); - }); - }); - - describe('withdrawals', async function () { - it('can withdraw payments', async function () { - const balanceTracker = await balance.tracker(payee1); - - await this.escrow.deposit(payee1, { from: owner, value: amount }); - await this.escrow.withdraw(payee1, { from: owner }); - - expect(await balanceTracker.delta()).to.be.bignumber.equal(amount); - - expect(await balance.current(this.escrow.address)).to.be.bignumber.equal('0'); - expect(await this.escrow.depositsOf(payee1)).to.be.bignumber.equal('0'); - }); - - it('can do an empty withdrawal', async function () { - await this.escrow.withdraw(payee1, { from: owner }); - }); - - it('only the owner can withdraw', async function () { - await expectRevert(this.escrow.withdraw(payee1, { from: payee1 }), - 'Ownable: caller is not the owner', - ); - }); - - it('emits a withdrawn event', async function () { - await this.escrow.deposit(payee1, { from: owner, value: amount }); - const receipt = await this.escrow.withdraw(payee1, { from: owner }); - expectEvent(receipt, 'Withdrawn', { - payee: payee1, - weiAmount: amount, - }); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeEscrow, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/Escrow.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/Escrow.test.js deleted file mode 100644 index 025a2a9..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/Escrow.test.js +++ /dev/null @@ -1,14 +0,0 @@ -require('@openzeppelin/test-helpers'); -const { shouldBehaveLikeEscrow } = require('./Escrow.behavior'); - -const Escrow = artifacts.require('Escrow'); - -contract('Escrow', function (accounts) { - const [ owner, ...otherAccounts ] = accounts; - - beforeEach(async function () { - this.escrow = await Escrow.new({ from: owner }); - }); - - shouldBehaveLikeEscrow(owner, otherAccounts); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/RefundEscrow.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/RefundEscrow.test.js deleted file mode 100644 index 26c19b3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/escrow/RefundEscrow.test.js +++ /dev/null @@ -1,148 +0,0 @@ -const { balance, constants, ether, expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { ZERO_ADDRESS } = constants; - -const { expect } = require('chai'); - -const RefundEscrow = artifacts.require('RefundEscrow'); - -contract('RefundEscrow', function (accounts) { - const [ owner, beneficiary, refundee1, refundee2 ] = accounts; - - const amount = ether('54'); - const refundees = [refundee1, refundee2]; - - it('requires a non-null beneficiary', async function () { - await expectRevert( - RefundEscrow.new(ZERO_ADDRESS, { from: owner }), 'RefundEscrow: beneficiary is the zero address', - ); - }); - - context('once deployed', function () { - beforeEach(async function () { - this.escrow = await RefundEscrow.new(beneficiary, { from: owner }); - }); - - context('active state', function () { - it('has beneficiary and state', async function () { - expect(await this.escrow.beneficiary()).to.equal(beneficiary); - expect(await this.escrow.state()).to.be.bignumber.equal('0'); - }); - - it('accepts deposits', async function () { - await this.escrow.deposit(refundee1, { from: owner, value: amount }); - - expect(await this.escrow.depositsOf(refundee1)).to.be.bignumber.equal(amount); - }); - - it('does not refund refundees', async function () { - await this.escrow.deposit(refundee1, { from: owner, value: amount }); - await expectRevert(this.escrow.withdraw(refundee1), - 'ConditionalEscrow: payee is not allowed to withdraw', - ); - }); - - it('does not allow beneficiary withdrawal', async function () { - await this.escrow.deposit(refundee1, { from: owner, value: amount }); - await expectRevert(this.escrow.beneficiaryWithdraw(), - 'RefundEscrow: beneficiary can only withdraw while closed', - ); - }); - }); - - it('only the owner can enter closed state', async function () { - await expectRevert(this.escrow.close({ from: beneficiary }), - 'Ownable: caller is not the owner', - ); - - const receipt = await this.escrow.close({ from: owner }); - expectEvent(receipt, 'RefundsClosed'); - }); - - context('closed state', function () { - beforeEach(async function () { - await Promise.all(refundees.map(refundee => this.escrow.deposit(refundee, { from: owner, value: amount }))); - - await this.escrow.close({ from: owner }); - }); - - it('rejects deposits', async function () { - await expectRevert(this.escrow.deposit(refundee1, { from: owner, value: amount }), - 'RefundEscrow: can only deposit while active', - ); - }); - - it('does not refund refundees', async function () { - await expectRevert(this.escrow.withdraw(refundee1), - 'ConditionalEscrow: payee is not allowed to withdraw', - ); - }); - - it('allows beneficiary withdrawal', async function () { - const balanceTracker = await balance.tracker(beneficiary); - await this.escrow.beneficiaryWithdraw(); - expect(await balanceTracker.delta()).to.be.bignumber.equal(amount.muln(refundees.length)); - }); - - it('prevents entering the refund state', async function () { - await expectRevert(this.escrow.enableRefunds({ from: owner }), - 'RefundEscrow: can only enable refunds while active', - ); - }); - - it('prevents re-entering the closed state', async function () { - await expectRevert(this.escrow.close({ from: owner }), - 'RefundEscrow: can only close while active', - ); - }); - }); - - it('only the owner can enter refund state', async function () { - await expectRevert(this.escrow.enableRefunds({ from: beneficiary }), - 'Ownable: caller is not the owner', - ); - - const receipt = await this.escrow.enableRefunds({ from: owner }); - expectEvent(receipt, 'RefundsEnabled'); - }); - - context('refund state', function () { - beforeEach(async function () { - await Promise.all(refundees.map(refundee => this.escrow.deposit(refundee, { from: owner, value: amount }))); - - await this.escrow.enableRefunds({ from: owner }); - }); - - it('rejects deposits', async function () { - await expectRevert(this.escrow.deposit(refundee1, { from: owner, value: amount }), - 'RefundEscrow: can only deposit while active', - ); - }); - - it('refunds refundees', async function () { - for (const refundee of [refundee1, refundee2]) { - const balanceTracker = await balance.tracker(refundee); - await this.escrow.withdraw(refundee, { from: owner }); - expect(await balanceTracker.delta()).to.be.bignumber.equal(amount); - } - }); - - it('does not allow beneficiary withdrawal', async function () { - await expectRevert(this.escrow.beneficiaryWithdraw(), - 'RefundEscrow: beneficiary can only withdraw while closed', - ); - }); - - it('prevents entering the closed state', async function () { - await expectRevert(this.escrow.close({ from: owner }), - 'RefundEscrow: can only close while active', - ); - }); - - it('prevents re-entering the refund state', async function () { - await expectRevert(this.escrow.enableRefunds({ from: owner }), - 'RefundEscrow: can only enable refunds while active', - ); - }); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js deleted file mode 100644 index c891500..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165.test.js +++ /dev/null @@ -1,13 +0,0 @@ -const { shouldSupportInterfaces } = require('./SupportsInterface.behavior'); - -const ERC165Mock = artifacts.require('ERC165Mock'); - -contract('ERC165', function (accounts) { - beforeEach(async function () { - this.mock = await ERC165Mock.new(); - }); - - shouldSupportInterfaces([ - 'ERC165', - ]); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js deleted file mode 100644 index 5c65bfd..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165Checker.test.js +++ /dev/null @@ -1,283 +0,0 @@ -require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const ERC165CheckerMock = artifacts.require('ERC165CheckerMock'); -const ERC165MissingData = artifacts.require('ERC165MissingData'); -const ERC165MaliciousData = artifacts.require('ERC165MaliciousData'); -const ERC165NotSupported = artifacts.require('ERC165NotSupported'); -const ERC165InterfacesSupported = artifacts.require('ERC165InterfacesSupported'); - -const DUMMY_ID = '0xdeadbeef'; -const DUMMY_ID_2 = '0xcafebabe'; -const DUMMY_ID_3 = '0xdecafbad'; -const DUMMY_UNSUPPORTED_ID = '0xbaddcafe'; -const DUMMY_UNSUPPORTED_ID_2 = '0xbaadcafe'; -const DUMMY_ACCOUNT = '0x1111111111111111111111111111111111111111'; - -contract('ERC165Checker', function (accounts) { - beforeEach(async function () { - this.mock = await ERC165CheckerMock.new(); - }); - - context('ERC165 missing return data', function () { - beforeEach(async function () { - this.target = await ERC165MissingData.new(); - }); - - it('does not support ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - }); - - context('ERC165 malicious return data', function () { - beforeEach(async function () { - this.target = await ERC165MaliciousData.new(); - }); - - it('does not support ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(true); - }); - }); - - context('ERC165 not supported', function () { - beforeEach(async function () { - this.target = await ERC165NotSupported.new(); - }); - - it('does not support ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - }); - - context('ERC165 supported', function () { - beforeEach(async function () { - this.target = await ERC165InterfacesSupported.new([]); - }); - - it('supports ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(true); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(false); - }); - }); - - context('ERC165 and single interface supported', function () { - beforeEach(async function () { - this.target = await ERC165InterfacesSupported.new([DUMMY_ID]); - }); - - it('supports ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(true); - }); - - it('supports mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID); - expect(supported).to.equal(true); - }); - - it('supports mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]); - expect(supported).to.equal(true); - }); - - it('supports mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(true); - }); - - it('supports mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, DUMMY_ID); - expect(supported).to.equal(true); - }); - }); - - context('ERC165 and many interfaces supported', function () { - beforeEach(async function () { - this.supportedInterfaces = [DUMMY_ID, DUMMY_ID_2, DUMMY_ID_3]; - this.target = await ERC165InterfacesSupported.new(this.supportedInterfaces); - }); - - it('supports ERC165', async function () { - const supported = await this.mock.supportsERC165(this.target.address); - expect(supported).to.equal(true); - }); - - it('supports each interfaceId via supportsInterface', async function () { - for (const interfaceId of this.supportedInterfaces) { - const supported = await this.mock.supportsInterface(this.target.address, interfaceId); - expect(supported).to.equal(true); - }; - }); - - it('supports all interfaceIds via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(this.target.address, this.supportedInterfaces); - expect(supported).to.equal(true); - }); - - it('supports none of the interfaces queried via supportsAllInterfaces', async function () { - const interfaceIdsToTest = [DUMMY_UNSUPPORTED_ID, DUMMY_UNSUPPORTED_ID_2]; - - const supported = await this.mock.supportsAllInterfaces(this.target.address, interfaceIdsToTest); - expect(supported).to.equal(false); - }); - - it('supports not all of the interfaces queried via supportsAllInterfaces', async function () { - const interfaceIdsToTest = [...this.supportedInterfaces, DUMMY_UNSUPPORTED_ID]; - - const supported = await this.mock.supportsAllInterfaces(this.target.address, interfaceIdsToTest); - expect(supported).to.equal(false); - }); - - it('supports all interfaceIds via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(this.target.address, this.supportedInterfaces); - expect(supported.length).to.equal(3); - expect(supported[0]).to.equal(true); - expect(supported[1]).to.equal(true); - expect(supported[2]).to.equal(true); - }); - - it('supports none of the interfaces queried via getSupportedInterfaces', async function () { - const interfaceIdsToTest = [DUMMY_UNSUPPORTED_ID, DUMMY_UNSUPPORTED_ID_2]; - - const supported = await this.mock.getSupportedInterfaces(this.target.address, interfaceIdsToTest); - expect(supported.length).to.equal(2); - expect(supported[0]).to.equal(false); - expect(supported[1]).to.equal(false); - }); - - it('supports not all of the interfaces queried via getSupportedInterfaces', async function () { - const interfaceIdsToTest = [...this.supportedInterfaces, DUMMY_UNSUPPORTED_ID]; - - const supported = await this.mock.getSupportedInterfaces(this.target.address, interfaceIdsToTest); - expect(supported.length).to.equal(4); - expect(supported[0]).to.equal(true); - expect(supported[1]).to.equal(true); - expect(supported[2]).to.equal(true); - expect(supported[3]).to.equal(false); - }); - - it('supports each interfaceId via supportsERC165InterfaceUnchecked', async function () { - for (const interfaceId of this.supportedInterfaces) { - const supported = await this.mock.supportsERC165InterfaceUnchecked(this.target.address, interfaceId); - expect(supported).to.equal(true); - }; - }); - }); - - context('account address does not support ERC165', function () { - it('does not support ERC165', async function () { - const supported = await this.mock.supportsERC165(DUMMY_ACCOUNT); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsInterface', async function () { - const supported = await this.mock.supportsInterface(DUMMY_ACCOUNT, DUMMY_ID); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via supportsAllInterfaces', async function () { - const supported = await this.mock.supportsAllInterfaces(DUMMY_ACCOUNT, [DUMMY_ID]); - expect(supported).to.equal(false); - }); - - it('does not support mock interface via getSupportedInterfaces', async function () { - const supported = await this.mock.getSupportedInterfaces(DUMMY_ACCOUNT, [DUMMY_ID]); - expect(supported.length).to.equal(1); - expect(supported[0]).to.equal(false); - }); - - it('does not support mock interface via supportsERC165InterfaceUnchecked', async function () { - const supported = await this.mock.supportsERC165InterfaceUnchecked(DUMMY_ACCOUNT, DUMMY_ID); - expect(supported).to.equal(false); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165Storage.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165Storage.test.js deleted file mode 100644 index 568d645..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC165Storage.test.js +++ /dev/null @@ -1,25 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { shouldSupportInterfaces } = require('./SupportsInterface.behavior'); - -const ERC165Mock = artifacts.require('ERC165StorageMock'); - -contract('ERC165Storage', function (accounts) { - beforeEach(async function () { - this.mock = await ERC165Mock.new(); - }); - - it('register interface', async function () { - expect(await this.mock.supportsInterface('0x00000001')).to.be.equal(false); - await this.mock.registerInterface('0x00000001'); - expect(await this.mock.supportsInterface('0x00000001')).to.be.equal(true); - }); - - it('does not allow 0xffffffff', async function () { - await expectRevert(this.mock.registerInterface('0xffffffff'), 'ERC165: invalid interface id'); - }); - - shouldSupportInterfaces([ - 'ERC165', - ]); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC1820Implementer.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC1820Implementer.test.js deleted file mode 100644 index 8d9fe56..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/ERC1820Implementer.test.js +++ /dev/null @@ -1,66 +0,0 @@ -const { expectRevert, singletons } = require('@openzeppelin/test-helpers'); -const { bufferToHex, keccakFromString } = require('ethereumjs-util'); - -const { expect } = require('chai'); - -const ERC1820ImplementerMock = artifacts.require('ERC1820ImplementerMock'); - -contract('ERC1820Implementer', function (accounts) { - const [ registryFunder, implementee, other ] = accounts; - - const ERC1820_ACCEPT_MAGIC = bufferToHex(keccakFromString('ERC1820_ACCEPT_MAGIC')); - - beforeEach(async function () { - this.implementer = await ERC1820ImplementerMock.new(); - this.registry = await singletons.ERC1820Registry(registryFunder); - - this.interfaceA = bufferToHex(keccakFromString('interfaceA')); - this.interfaceB = bufferToHex(keccakFromString('interfaceB')); - }); - - context('with no registered interfaces', function () { - it('returns false when interface implementation is queried', async function () { - expect(await this.implementer.canImplementInterfaceForAddress(this.interfaceA, implementee)) - .to.not.equal(ERC1820_ACCEPT_MAGIC); - }); - - it('reverts when attempting to set as implementer in the registry', async function () { - await expectRevert( - this.registry.setInterfaceImplementer( - implementee, this.interfaceA, this.implementer.address, { from: implementee }, - ), - 'Does not implement the interface', - ); - }); - }); - - context('with registered interfaces', function () { - beforeEach(async function () { - await this.implementer.registerInterfaceForAddress(this.interfaceA, implementee); - }); - - it('returns true when interface implementation is queried', async function () { - expect(await this.implementer.canImplementInterfaceForAddress(this.interfaceA, implementee)) - .to.equal(ERC1820_ACCEPT_MAGIC); - }); - - it('returns false when interface implementation for non-supported interfaces is queried', async function () { - expect(await this.implementer.canImplementInterfaceForAddress(this.interfaceB, implementee)) - .to.not.equal(ERC1820_ACCEPT_MAGIC); - }); - - it('returns false when interface implementation for non-supported addresses is queried', async function () { - expect(await this.implementer.canImplementInterfaceForAddress(this.interfaceA, other)) - .to.not.equal(ERC1820_ACCEPT_MAGIC); - }); - - it('can be set as an implementer for supported interfaces in the registry', async function () { - await this.registry.setInterfaceImplementer( - implementee, this.interfaceA, this.implementer.address, { from: implementee }, - ); - - expect(await this.registry.getInterfaceImplementer(implementee, this.interfaceA)) - .to.equal(this.implementer.address); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js deleted file mode 100644 index 78e3272..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/introspection/SupportsInterface.behavior.js +++ /dev/null @@ -1,147 +0,0 @@ -const { makeInterfaceId } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const INTERFACES = { - ERC165: [ - 'supportsInterface(bytes4)', - ], - ERC721: [ - 'balanceOf(address)', - 'ownerOf(uint256)', - 'approve(address,uint256)', - 'getApproved(uint256)', - 'setApprovalForAll(address,bool)', - 'isApprovedForAll(address,address)', - 'transferFrom(address,address,uint256)', - 'safeTransferFrom(address,address,uint256)', - 'safeTransferFrom(address,address,uint256,bytes)', - ], - ERC721Enumerable: [ - 'totalSupply()', - 'tokenOfOwnerByIndex(address,uint256)', - 'tokenByIndex(uint256)', - ], - ERC721Metadata: [ - 'name()', - 'symbol()', - 'tokenURI(uint256)', - ], - ERC1155: [ - 'balanceOf(address,uint256)', - 'balanceOfBatch(address[],uint256[])', - 'setApprovalForAll(address,bool)', - 'isApprovedForAll(address,address)', - 'safeTransferFrom(address,address,uint256,uint256,bytes)', - 'safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)', - ], - ERC1155Receiver: [ - 'onERC1155Received(address,address,uint256,uint256,bytes)', - 'onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)', - ], - AccessControl: [ - 'hasRole(bytes32,address)', - 'getRoleAdmin(bytes32)', - 'grantRole(bytes32,address)', - 'revokeRole(bytes32,address)', - 'renounceRole(bytes32,address)', - ], - AccessControlEnumerable: [ - 'getRoleMember(bytes32,uint256)', - 'getRoleMemberCount(bytes32)', - ], - Governor: [ - 'name()', - 'version()', - 'COUNTING_MODE()', - 'hashProposal(address[],uint256[],bytes[],bytes32)', - 'state(uint256)', - 'proposalSnapshot(uint256)', - 'proposalDeadline(uint256)', - 'votingDelay()', - 'votingPeriod()', - 'quorum(uint256)', - 'getVotes(address,uint256)', - 'hasVoted(uint256,address)', - 'propose(address[],uint256[],bytes[],string)', - 'execute(address[],uint256[],bytes[],bytes32)', - 'castVote(uint256,uint8)', - 'castVoteWithReason(uint256,uint8,string)', - 'castVoteBySig(uint256,uint8,uint8,bytes32,bytes32)', - ], - GovernorWithParams: [ - 'name()', - 'version()', - 'COUNTING_MODE()', - 'hashProposal(address[],uint256[],bytes[],bytes32)', - 'state(uint256)', - 'proposalSnapshot(uint256)', - 'proposalDeadline(uint256)', - 'votingDelay()', - 'votingPeriod()', - 'quorum(uint256)', - 'getVotes(address,uint256)', - 'getVotesWithParams(address,uint256,bytes)', - 'hasVoted(uint256,address)', - 'propose(address[],uint256[],bytes[],string)', - 'execute(address[],uint256[],bytes[],bytes32)', - 'castVote(uint256,uint8)', - 'castVoteWithReason(uint256,uint8,string)', - 'castVoteWithReasonAndParams(uint256,uint8,string,bytes)', - 'castVoteBySig(uint256,uint8,uint8,bytes32,bytes32)', - 'castVoteWithReasonAndParamsBySig(uint256,uint8,string,bytes,uint8,bytes32,bytes32)', - ], - GovernorTimelock: [ - 'timelock()', - 'proposalEta(uint256)', - 'queue(address[],uint256[],bytes[],bytes32)', - ], - ERC2981: [ - 'royaltyInfo(uint256,uint256)', - ], -}; - -const INTERFACE_IDS = {}; -const FN_SIGNATURES = {}; -for (const k of Object.getOwnPropertyNames(INTERFACES)) { - INTERFACE_IDS[k] = makeInterfaceId.ERC165(INTERFACES[k]); - for (const fnName of INTERFACES[k]) { - // the interface id of a single function is equivalent to its function signature - FN_SIGNATURES[fnName] = makeInterfaceId.ERC165([fnName]); - } -} - -function shouldSupportInterfaces (interfaces = []) { - describe('ERC165', function () { - beforeEach(function () { - this.contractUnderTest = this.mock || this.token || this.holder || this.accessControl; - }); - - it('supportsInterface uses less than 30k gas', async function () { - for (const k of interfaces) { - const interfaceId = INTERFACE_IDS[k]; - expect(await this.contractUnderTest.supportsInterface.estimateGas(interfaceId)).to.be.lte(30000); - } - }); - - it('all interfaces are reported as supported', async function () { - for (const k of interfaces) { - const interfaceId = INTERFACE_IDS[k]; - expect(await this.contractUnderTest.supportsInterface(interfaceId)).to.equal(true); - } - }); - - it('all interface functions are in ABI', async function () { - for (const k of interfaces) { - for (const fnName of INTERFACES[k]) { - const fnSig = FN_SIGNATURES[fnName]; - expect(this.contractUnderTest.abi.filter(fn => fn.signature === fnSig).length).to.equal(1); - } - } - }); - }); -} - -module.exports = { - shouldSupportInterfaces, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/Math.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/Math.test.js deleted file mode 100644 index a71deb5..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/Math.test.js +++ /dev/null @@ -1,219 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MAX_UINT256 } = constants; -const { Rounding } = require('../../helpers/enums.js'); - -const MathMock = artifacts.require('MathMock'); - -contract('Math', function (accounts) { - const min = new BN('1234'); - const max = new BN('5678'); - const MAX_UINT256_SUB1 = MAX_UINT256.sub(new BN('1')); - const MAX_UINT256_SUB2 = MAX_UINT256.sub(new BN('2')); - - beforeEach(async function () { - this.math = await MathMock.new(); - }); - - describe('max', function () { - it('is correctly detected in first argument position', async function () { - expect(await this.math.max(max, min)).to.be.bignumber.equal(max); - }); - - it('is correctly detected in second argument position', async function () { - expect(await this.math.max(min, max)).to.be.bignumber.equal(max); - }); - }); - - describe('min', function () { - it('is correctly detected in first argument position', async function () { - expect(await this.math.min(min, max)).to.be.bignumber.equal(min); - }); - - it('is correctly detected in second argument position', async function () { - expect(await this.math.min(max, min)).to.be.bignumber.equal(min); - }); - }); - - describe('average', function () { - function bnAverage (a, b) { - return a.add(b).divn(2); - } - - it('is correctly calculated with two odd numbers', async function () { - const a = new BN('57417'); - const b = new BN('95431'); - expect(await this.math.average(a, b)).to.be.bignumber.equal(bnAverage(a, b)); - }); - - it('is correctly calculated with two even numbers', async function () { - const a = new BN('42304'); - const b = new BN('84346'); - expect(await this.math.average(a, b)).to.be.bignumber.equal(bnAverage(a, b)); - }); - - it('is correctly calculated with one even and one odd number', async function () { - const a = new BN('57417'); - const b = new BN('84346'); - expect(await this.math.average(a, b)).to.be.bignumber.equal(bnAverage(a, b)); - }); - - it('is correctly calculated with two max uint256 numbers', async function () { - const a = MAX_UINT256; - expect(await this.math.average(a, a)).to.be.bignumber.equal(bnAverage(a, a)); - }); - }); - - describe('ceilDiv', function () { - it('does not round up on exact division', async function () { - const a = new BN('10'); - const b = new BN('5'); - expect(await this.math.ceilDiv(a, b)).to.be.bignumber.equal('2'); - }); - - it('rounds up on division with remainders', async function () { - const a = new BN('42'); - const b = new BN('13'); - expect(await this.math.ceilDiv(a, b)).to.be.bignumber.equal('4'); - }); - - it('does not overflow', async function () { - const b = new BN('2'); - const result = new BN('1').shln(255); - expect(await this.math.ceilDiv(MAX_UINT256, b)).to.be.bignumber.equal(result); - }); - - it('correctly computes max uint256 divided by 1', async function () { - const b = new BN('1'); - expect(await this.math.ceilDiv(MAX_UINT256, b)).to.be.bignumber.equal(MAX_UINT256); - }); - }); - - describe('muldiv', function () { - it('divide by 0', async function () { - await expectRevert.unspecified(this.math.mulDiv(1, 1, 0, Rounding.Down)); - }); - - describe('does round down', async function () { - it('small values', async function () { - expect(await this.math.mulDiv('3', '4', '5', Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.mulDiv('3', '5', '5', Rounding.Down)).to.be.bignumber.equal('3'); - }); - - it('large values', async function () { - expect(await this.math.mulDiv( - new BN('42'), - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(new BN('41')); - - expect(await this.math.mulDiv( - new BN('17'), - MAX_UINT256, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(new BN('17')); - - expect(await this.math.mulDiv( - MAX_UINT256_SUB1, - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(MAX_UINT256_SUB2); - - expect(await this.math.mulDiv( - MAX_UINT256, - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(MAX_UINT256_SUB1); - - expect(await this.math.mulDiv( - MAX_UINT256, - MAX_UINT256, - MAX_UINT256, - Rounding.Down, - )).to.be.bignumber.equal(MAX_UINT256); - }); - }); - - describe('does round up', async function () { - it('small values', async function () { - expect(await this.math.mulDiv('3', '4', '5', Rounding.Up)).to.be.bignumber.equal('3'); - expect(await this.math.mulDiv('3', '5', '5', Rounding.Up)).to.be.bignumber.equal('3'); - }); - - it('large values', async function () { - expect(await this.math.mulDiv( - new BN('42'), - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(new BN('42')); - - expect(await this.math.mulDiv( - new BN('17'), - MAX_UINT256, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(new BN('17')); - - expect(await this.math.mulDiv( - MAX_UINT256_SUB1, - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(MAX_UINT256_SUB1); - - expect(await this.math.mulDiv( - MAX_UINT256, - MAX_UINT256_SUB1, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(MAX_UINT256_SUB1); - - expect(await this.math.mulDiv( - MAX_UINT256, - MAX_UINT256, - MAX_UINT256, - Rounding.Up, - )).to.be.bignumber.equal(MAX_UINT256); - }); - }); - }); - - describe('sqrt', function () { - it('rounds down', async function () { - expect(await this.math.sqrt(new BN('0'), Rounding.Down)).to.be.bignumber.equal('0'); - expect(await this.math.sqrt(new BN('1'), Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.sqrt(new BN('2'), Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.sqrt(new BN('3'), Rounding.Down)).to.be.bignumber.equal('1'); - expect(await this.math.sqrt(new BN('4'), Rounding.Down)).to.be.bignumber.equal('2'); - expect(await this.math.sqrt(new BN('144'), Rounding.Down)).to.be.bignumber.equal('12'); - expect(await this.math.sqrt(new BN('999999'), Rounding.Down)).to.be.bignumber.equal('999'); - expect(await this.math.sqrt(new BN('1000000'), Rounding.Down)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt(new BN('1000001'), Rounding.Down)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt(new BN('1002000'), Rounding.Down)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt(new BN('1002001'), Rounding.Down)).to.be.bignumber.equal('1001'); - expect(await this.math.sqrt(MAX_UINT256, Rounding.Down)) - .to.be.bignumber.equal('340282366920938463463374607431768211455'); - }); - - it('rounds up', async function () { - expect(await this.math.sqrt(new BN('0'), Rounding.Up)).to.be.bignumber.equal('0'); - expect(await this.math.sqrt(new BN('1'), Rounding.Up)).to.be.bignumber.equal('1'); - expect(await this.math.sqrt(new BN('2'), Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.sqrt(new BN('3'), Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.sqrt(new BN('4'), Rounding.Up)).to.be.bignumber.equal('2'); - expect(await this.math.sqrt(new BN('144'), Rounding.Up)).to.be.bignumber.equal('12'); - expect(await this.math.sqrt(new BN('999999'), Rounding.Up)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt(new BN('1000000'), Rounding.Up)).to.be.bignumber.equal('1000'); - expect(await this.math.sqrt(new BN('1000001'), Rounding.Up)).to.be.bignumber.equal('1001'); - expect(await this.math.sqrt(new BN('1002000'), Rounding.Up)).to.be.bignumber.equal('1001'); - expect(await this.math.sqrt(new BN('1002001'), Rounding.Up)).to.be.bignumber.equal('1001'); - expect(await this.math.sqrt(MAX_UINT256, Rounding.Up)) - .to.be.bignumber.equal('340282366920938463463374607431768211456'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js deleted file mode 100644 index 97fc22e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SafeCast.test.js +++ /dev/null @@ -1,164 +0,0 @@ -const { BN, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { range } = require('../../../scripts/helpers'); - -const SafeCastMock = artifacts.require('SafeCastMock'); - -contract('SafeCast', async (accounts) => { - beforeEach(async function () { - this.safeCast = await SafeCastMock.new(); - }); - - function testToUint (bits) { - describe(`toUint${bits}`, () => { - const maxValue = new BN('2').pow(new BN(bits)).subn(1); - - it('downcasts 0', async function () { - expect(await this.safeCast[`toUint${bits}`](0)).to.be.bignumber.equal('0'); - }); - - it('downcasts 1', async function () { - expect(await this.safeCast[`toUint${bits}`](1)).to.be.bignumber.equal('1'); - }); - - it(`downcasts 2^${bits} - 1 (${maxValue})`, async function () { - expect(await this.safeCast[`toUint${bits}`](maxValue)).to.be.bignumber.equal(maxValue); - }); - - it(`reverts when downcasting 2^${bits} (${maxValue.addn(1)})`, async function () { - await expectRevert( - this.safeCast[`toUint${bits}`](maxValue.addn(1)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - - it(`reverts when downcasting 2^${bits} + 1 (${maxValue.addn(2)})`, async function () { - await expectRevert( - this.safeCast[`toUint${bits}`](maxValue.addn(2)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - }); - } - - range(8, 256, 8).forEach(bits => testToUint(bits)); - - describe('toUint256', () => { - const maxInt256 = new BN('2').pow(new BN(255)).subn(1); - const minInt256 = new BN('2').pow(new BN(255)).neg(); - - it('casts 0', async function () { - expect(await this.safeCast.toUint256(0)).to.be.bignumber.equal('0'); - }); - - it('casts 1', async function () { - expect(await this.safeCast.toUint256(1)).to.be.bignumber.equal('1'); - }); - - it(`casts INT256_MAX (${maxInt256})`, async function () { - expect(await this.safeCast.toUint256(maxInt256)).to.be.bignumber.equal(maxInt256); - }); - - it('reverts when casting -1', async function () { - await expectRevert( - this.safeCast.toUint256(-1), - 'SafeCast: value must be positive', - ); - }); - - it(`reverts when casting INT256_MIN (${minInt256})`, async function () { - await expectRevert( - this.safeCast.toUint256(minInt256), - 'SafeCast: value must be positive', - ); - }); - }); - - function testToInt (bits) { - describe(`toInt${bits}`, () => { - const minValue = new BN('-2').pow(new BN(bits - 1)); - const maxValue = new BN('2').pow(new BN(bits - 1)).subn(1); - - it('downcasts 0', async function () { - expect(await this.safeCast[`toInt${bits}`](0)).to.be.bignumber.equal('0'); - }); - - it('downcasts 1', async function () { - expect(await this.safeCast[`toInt${bits}`](1)).to.be.bignumber.equal('1'); - }); - - it('downcasts -1', async function () { - expect(await this.safeCast[`toInt${bits}`](-1)).to.be.bignumber.equal('-1'); - }); - - it(`downcasts -2^${bits - 1} (${minValue})`, async function () { - expect(await this.safeCast[`toInt${bits}`](minValue)).to.be.bignumber.equal(minValue); - }); - - it(`downcasts 2^${bits - 1} - 1 (${maxValue})`, async function () { - expect(await this.safeCast[`toInt${bits}`](maxValue)).to.be.bignumber.equal(maxValue); - }); - - it(`reverts when downcasting -2^${bits - 1} - 1 (${minValue.subn(1)})`, async function () { - await expectRevert( - this.safeCast[`toInt${bits}`](minValue.subn(1)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - - it(`reverts when downcasting -2^${bits - 1} - 2 (${minValue.subn(2)})`, async function () { - await expectRevert( - this.safeCast[`toInt${bits}`](minValue.subn(2)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - - it(`reverts when downcasting 2^${bits - 1} (${maxValue.addn(1)})`, async function () { - await expectRevert( - this.safeCast[`toInt${bits}`](maxValue.addn(1)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - - it(`reverts when downcasting 2^${bits - 1} + 1 (${maxValue.addn(2)})`, async function () { - await expectRevert( - this.safeCast[`toInt${bits}`](maxValue.addn(2)), - `SafeCast: value doesn't fit in ${bits} bits`, - ); - }); - }); - } - - range(8, 256, 8).forEach(bits => testToInt(bits)); - - describe('toInt256', () => { - const maxUint256 = new BN('2').pow(new BN(256)).subn(1); - const maxInt256 = new BN('2').pow(new BN(255)).subn(1); - - it('casts 0', async function () { - expect(await this.safeCast.toInt256(0)).to.be.bignumber.equal('0'); - }); - - it('casts 1', async function () { - expect(await this.safeCast.toInt256(1)).to.be.bignumber.equal('1'); - }); - - it(`casts INT256_MAX (${maxInt256})`, async function () { - expect(await this.safeCast.toInt256(maxInt256)).to.be.bignumber.equal(maxInt256); - }); - - it(`reverts when casting INT256_MAX + 1 (${maxInt256.addn(1)})`, async function () { - await expectRevert( - this.safeCast.toInt256(maxInt256.addn(1)), - 'SafeCast: value doesn\'t fit in an int256', - ); - }); - - it(`reverts when casting UINT256_MAX (${maxUint256})`, async function () { - await expectRevert( - this.safeCast.toInt256(maxUint256), - 'SafeCast: value doesn\'t fit in an int256', - ); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SafeMath.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SafeMath.test.js deleted file mode 100644 index 7c9b937..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SafeMath.test.js +++ /dev/null @@ -1,403 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { MAX_UINT256 } = constants; - -const { expect } = require('chai'); - -const SafeMathMock = artifacts.require('SafeMathMock'); - -function expectStruct (value, expected) { - for (const key in expected) { - if (BN.isBN(value[key])) { - expect(value[key]).to.be.bignumber.equal(expected[key]); - } else { - expect(value[key]).to.be.equal(expected[key]); - } - } -} - -contract('SafeMath', function (accounts) { - beforeEach(async function () { - this.safeMath = await SafeMathMock.new(); - }); - - async function testCommutative (fn, lhs, rhs, expected, ...extra) { - expect(await fn(lhs, rhs, ...extra)).to.be.bignumber.equal(expected); - expect(await fn(rhs, lhs, ...extra)).to.be.bignumber.equal(expected); - } - - async function testFailsCommutative (fn, lhs, rhs, reason, ...extra) { - if (reason === undefined) { - await expectRevert.unspecified(fn(lhs, rhs, ...extra)); - await expectRevert.unspecified(fn(rhs, lhs, ...extra)); - } else { - await expectRevert(fn(lhs, rhs, ...extra), reason); - await expectRevert(fn(rhs, lhs, ...extra), reason); - } - } - - async function testCommutativeIterable (fn, lhs, rhs, expected, ...extra) { - expectStruct(await fn(lhs, rhs, ...extra), expected); - expectStruct(await fn(rhs, lhs, ...extra), expected); - } - - describe('with flag', function () { - describe('add', function () { - it('adds correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - testCommutativeIterable(this.safeMath.tryAdd, a, b, { flag: true, value: a.add(b) }); - }); - - it('reverts on addition overflow', async function () { - const a = MAX_UINT256; - const b = new BN('1'); - - testCommutativeIterable(this.safeMath.tryAdd, a, b, { flag: false, value: '0' }); - }); - }); - - describe('sub', function () { - it('subtracts correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - expectStruct(await this.safeMath.trySub(a, b), { flag: true, value: a.sub(b) }); - }); - - it('reverts if subtraction result would be negative', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.trySub(a, b), { flag: false, value: '0' }); - }); - }); - - describe('mul', function () { - it('multiplies correctly', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - testCommutativeIterable(this.safeMath.tryMul, a, b, { flag: true, value: a.mul(b) }); - }); - - it('multiplies by zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - testCommutativeIterable(this.safeMath.tryMul, a, b, { flag: true, value: a.mul(b) }); - }); - - it('reverts on multiplication overflow', async function () { - const a = MAX_UINT256; - const b = new BN('2'); - - testCommutativeIterable(this.safeMath.tryMul, a, b, { flag: false, value: '0' }); - }); - }); - - describe('div', function () { - it('divides correctly', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryDiv(a, b), { flag: true, value: a.div(b) }); - }); - - it('divides zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryDiv(a, b), { flag: true, value: a.div(b) }); - }); - - it('returns complete number result on non-even division', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryDiv(a, b), { flag: true, value: a.div(b) }); - }); - - it('reverts on division by zero', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - expectStruct(await this.safeMath.tryDiv(a, b), { flag: false, value: '0' }); - }); - }); - - describe('mod', function () { - describe('modulos correctly', async function () { - it('when the dividend is smaller than the divisor', async function () { - const a = new BN('284'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: true, value: a.mod(b) }); - }); - - it('when the dividend is equal to the divisor', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: true, value: a.mod(b) }); - }); - - it('when the dividend is larger than the divisor', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: true, value: a.mod(b) }); - }); - - it('when the dividend is a multiple of the divisor', async function () { - const a = new BN('17034'); // 17034 == 5678 * 3 - const b = new BN('5678'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: true, value: a.mod(b) }); - }); - }); - - it('reverts with a 0 divisor', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - expectStruct(await this.safeMath.tryMod(a, b), { flag: false, value: '0' }); - }); - }); - }); - - describe('with default revert message', function () { - describe('add', function () { - it('adds correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - await testCommutative(this.safeMath.doAdd, a, b, a.add(b)); - }); - - it('reverts on addition overflow', async function () { - const a = MAX_UINT256; - const b = new BN('1'); - - await testFailsCommutative(this.safeMath.doAdd, a, b, undefined); - }); - }); - - describe('sub', function () { - it('subtracts correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - expect(await this.safeMath.doSub(a, b)).to.be.bignumber.equal(a.sub(b)); - }); - - it('reverts if subtraction result would be negative', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - await expectRevert.unspecified(this.safeMath.doSub(a, b)); - }); - }); - - describe('mul', function () { - it('multiplies correctly', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - await testCommutative(this.safeMath.doMul, a, b, a.mul(b)); - }); - - it('multiplies by zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - await testCommutative(this.safeMath.doMul, a, b, '0'); - }); - - it('reverts on multiplication overflow', async function () { - const a = MAX_UINT256; - const b = new BN('2'); - - await testFailsCommutative(this.safeMath.doMul, a, b, undefined); - }); - }); - - describe('div', function () { - it('divides correctly', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expect(await this.safeMath.doDiv(a, b)).to.be.bignumber.equal(a.div(b)); - }); - - it('divides zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - expect(await this.safeMath.doDiv(a, b)).to.be.bignumber.equal('0'); - }); - - it('returns complete number result on non-even division', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.doDiv(a, b)).to.be.bignumber.equal('1'); - }); - - it('reverts on division by zero', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - await expectRevert.unspecified(this.safeMath.doDiv(a, b)); - }); - }); - - describe('mod', function () { - describe('modulos correctly', async function () { - it('when the dividend is smaller than the divisor', async function () { - const a = new BN('284'); - const b = new BN('5678'); - - expect(await this.safeMath.doMod(a, b)).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is equal to the divisor', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expect(await this.safeMath.doMod(a, b)).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is larger than the divisor', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.doMod(a, b)).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is a multiple of the divisor', async function () { - const a = new BN('17034'); // 17034 == 5678 * 3 - const b = new BN('5678'); - - expect(await this.safeMath.doMod(a, b)).to.be.bignumber.equal(a.mod(b)); - }); - }); - - it('reverts with a 0 divisor', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - await expectRevert.unspecified(this.safeMath.doMod(a, b)); - }); - }); - }); - - describe('with custom revert message', function () { - describe('sub', function () { - it('subtracts correctly', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - expect(await this.safeMath.subWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.sub(b)); - }); - - it('reverts if subtraction result would be negative', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - await expectRevert(this.safeMath.subWithMessage(a, b, 'MyErrorMessage'), 'MyErrorMessage'); - }); - }); - - describe('div', function () { - it('divides correctly', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expect(await this.safeMath.divWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.div(b)); - }); - - it('divides zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - expect(await this.safeMath.divWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal('0'); - }); - - it('returns complete number result on non-even division', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.divWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal('1'); - }); - - it('reverts on division by zero', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - await expectRevert(this.safeMath.divWithMessage(a, b, 'MyErrorMessage'), 'MyErrorMessage'); - }); - }); - - describe('mod', function () { - describe('modulos correctly', async function () { - it('when the dividend is smaller than the divisor', async function () { - const a = new BN('284'); - const b = new BN('5678'); - - expect(await this.safeMath.modWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is equal to the divisor', async function () { - const a = new BN('5678'); - const b = new BN('5678'); - - expect(await this.safeMath.modWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is larger than the divisor', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.modWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.mod(b)); - }); - - it('when the dividend is a multiple of the divisor', async function () { - const a = new BN('17034'); // 17034 == 5678 * 3 - const b = new BN('5678'); - - expect(await this.safeMath.modWithMessage(a, b, 'MyErrorMessage')).to.be.bignumber.equal(a.mod(b)); - }); - }); - - it('reverts with a 0 divisor', async function () { - const a = new BN('5678'); - const b = new BN('0'); - - await expectRevert(this.safeMath.modWithMessage(a, b, 'MyErrorMessage'), 'MyErrorMessage'); - }); - }); - }); - - describe('memory leakage', function () { - it('add', async function () { - expect(await this.safeMath.addMemoryCheck()).to.be.bignumber.equal('0'); - }); - - it('sub', async function () { - expect(await this.safeMath.subMemoryCheck()).to.be.bignumber.equal('0'); - }); - - it('mul', async function () { - expect(await this.safeMath.mulMemoryCheck()).to.be.bignumber.equal('0'); - }); - - it('div', async function () { - expect(await this.safeMath.divMemoryCheck()).to.be.bignumber.equal('0'); - }); - - it('mod', async function () { - expect(await this.safeMath.modMemoryCheck()).to.be.bignumber.equal('0'); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js deleted file mode 100644 index 8e9826f..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SignedMath.test.js +++ /dev/null @@ -1,93 +0,0 @@ -const { BN, constants } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); -const { MIN_INT256, MAX_INT256 } = constants; - -const SignedMathMock = artifacts.require('SignedMathMock'); - -contract('SignedMath', function (accounts) { - const min = new BN('-1234'); - const max = new BN('5678'); - - beforeEach(async function () { - this.math = await SignedMathMock.new(); - }); - - describe('max', function () { - it('is correctly detected in first argument position', async function () { - expect(await this.math.max(max, min)).to.be.bignumber.equal(max); - }); - - it('is correctly detected in second argument position', async function () { - expect(await this.math.max(min, max)).to.be.bignumber.equal(max); - }); - }); - - describe('min', function () { - it('is correctly detected in first argument position', async function () { - expect(await this.math.min(min, max)).to.be.bignumber.equal(min); - }); - - it('is correctly detected in second argument position', async function () { - expect(await this.math.min(max, min)).to.be.bignumber.equal(min); - }); - }); - - describe('average', function () { - function bnAverage (a, b) { - return a.add(b).divn(2); - } - - it('is correctly calculated with various input', async function () { - const valuesX = [ - new BN('0'), - new BN('3'), - new BN('-3'), - new BN('4'), - new BN('-4'), - new BN('57417'), - new BN('-57417'), - new BN('42304'), - new BN('-42304'), - MIN_INT256, - MAX_INT256, - ]; - - const valuesY = [ - new BN('0'), - new BN('5'), - new BN('-5'), - new BN('2'), - new BN('-2'), - new BN('57417'), - new BN('-57417'), - new BN('42304'), - new BN('-42304'), - MIN_INT256, - MAX_INT256, - ]; - - for (const x of valuesX) { - for (const y of valuesY) { - expect(await this.math.average(x, y)) - .to.be.bignumber.equal(bnAverage(x, y), `Bad result for average(${x}, ${y})`); - } - } - }); - }); - - describe('abs', function () { - for (const n of [ - MIN_INT256, - MIN_INT256.addn(1), - new BN('-1'), - new BN('0'), - new BN('1'), - MAX_INT256.subn(1), - MAX_INT256, - ]) { - it(`correctly computes the absolute value of ${n}`, async function () { - expect(await this.math.abs(n)).to.be.bignumber.equal(n.abs()); - }); - } - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SignedSafeMath.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SignedSafeMath.test.js deleted file mode 100644 index c6aa15e..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/math/SignedSafeMath.test.js +++ /dev/null @@ -1,152 +0,0 @@ -const { BN, constants, expectRevert } = require('@openzeppelin/test-helpers'); -const { MAX_INT256, MIN_INT256 } = constants; - -const { expect } = require('chai'); - -const SignedSafeMathMock = artifacts.require('SignedSafeMathMock'); - -contract('SignedSafeMath', function (accounts) { - beforeEach(async function () { - this.safeMath = await SignedSafeMathMock.new(); - }); - - async function testCommutative (fn, lhs, rhs, expected) { - expect(await fn(lhs, rhs)).to.be.bignumber.equal(expected); - expect(await fn(rhs, lhs)).to.be.bignumber.equal(expected); - } - - async function testFailsCommutative (fn, lhs, rhs) { - await expectRevert.unspecified(fn(lhs, rhs)); - await expectRevert.unspecified(fn(rhs, lhs)); - } - - describe('add', function () { - it('adds correctly if it does not overflow and the result is positive', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - await testCommutative(this.safeMath.add, a, b, a.add(b)); - }); - - it('adds correctly if it does not overflow and the result is negative', async function () { - const a = MAX_INT256; - const b = MIN_INT256; - - await testCommutative(this.safeMath.add, a, b, a.add(b)); - }); - - it('reverts on positive addition overflow', async function () { - const a = MAX_INT256; - const b = new BN('1'); - - await testFailsCommutative(this.safeMath.add, a, b); - }); - - it('reverts on negative addition overflow', async function () { - const a = MIN_INT256; - const b = new BN('-1'); - - await testFailsCommutative(this.safeMath.add, a, b); - }); - }); - - describe('sub', function () { - it('subtracts correctly if it does not overflow and the result is positive', async function () { - const a = new BN('5678'); - const b = new BN('1234'); - - const result = await this.safeMath.sub(a, b); - expect(result).to.be.bignumber.equal(a.sub(b)); - }); - - it('subtracts correctly if it does not overflow and the result is negative', async function () { - const a = new BN('1234'); - const b = new BN('5678'); - - const result = await this.safeMath.sub(a, b); - expect(result).to.be.bignumber.equal(a.sub(b)); - }); - - it('reverts on positive subtraction overflow', async function () { - const a = MAX_INT256; - const b = new BN('-1'); - - await expectRevert.unspecified(this.safeMath.sub(a, b)); - }); - - it('reverts on negative subtraction overflow', async function () { - const a = MIN_INT256; - const b = new BN('1'); - - await expectRevert.unspecified(this.safeMath.sub(a, b)); - }); - }); - - describe('mul', function () { - it('multiplies correctly', async function () { - const a = new BN('5678'); - const b = new BN('-1234'); - - await testCommutative(this.safeMath.mul, a, b, a.mul(b)); - }); - - it('multiplies by zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - await testCommutative(this.safeMath.mul, a, b, '0'); - }); - - it('reverts on multiplication overflow, positive operands', async function () { - const a = MAX_INT256; - const b = new BN('2'); - - await testFailsCommutative(this.safeMath.mul, a, b); - }); - - it('reverts when minimum integer is multiplied by -1', async function () { - const a = MIN_INT256; - const b = new BN('-1'); - - await testFailsCommutative(this.safeMath.mul, a, b); - }); - }); - - describe('div', function () { - it('divides correctly', async function () { - const a = new BN('-5678'); - const b = new BN('5678'); - - const result = await this.safeMath.div(a, b); - expect(result).to.be.bignumber.equal(a.div(b)); - }); - - it('divides zero correctly', async function () { - const a = new BN('0'); - const b = new BN('5678'); - - expect(await this.safeMath.div(a, b)).to.be.bignumber.equal('0'); - }); - - it('returns complete number result on non-even division', async function () { - const a = new BN('7000'); - const b = new BN('5678'); - - expect(await this.safeMath.div(a, b)).to.be.bignumber.equal('1'); - }); - - it('reverts on division by zero', async function () { - const a = new BN('-5678'); - const b = new BN('0'); - - await expectRevert.unspecified(this.safeMath.div(a, b)); - }); - - it('reverts on overflow, negative second', async function () { - const a = new BN(MIN_INT256); - const b = new BN('-1'); - - await expectRevert.unspecified(this.safeMath.div(a, b)); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js deleted file mode 100644 index 58d70ca..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/BitMap.test.js +++ /dev/null @@ -1,145 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const BitMap = artifacts.require('BitMapMock'); - -contract('BitMap', function (accounts) { - const keyA = new BN('7891'); - const keyB = new BN('451'); - const keyC = new BN('9592328'); - - beforeEach(async function () { - this.bitmap = await BitMap.new(); - }); - - it('starts empty', async function () { - expect(await this.bitmap.get(keyA)).to.equal(false); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - describe('setTo', function () { - it('set a key to true', async function () { - await this.bitmap.setTo(keyA, true); - expect(await this.bitmap.get(keyA)).to.equal(true); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('set a key to false', async function () { - await this.bitmap.setTo(keyA, true); - await this.bitmap.setTo(keyA, false); - expect(await this.bitmap.get(keyA)).to.equal(false); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('set several consecutive keys', async function () { - await this.bitmap.setTo(keyA.addn(0), true); - await this.bitmap.setTo(keyA.addn(1), true); - await this.bitmap.setTo(keyA.addn(2), true); - await this.bitmap.setTo(keyA.addn(3), true); - await this.bitmap.setTo(keyA.addn(4), true); - await this.bitmap.setTo(keyA.addn(2), false); - await this.bitmap.setTo(keyA.addn(4), false); - expect(await this.bitmap.get(keyA.addn(0))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(1))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(2))).to.equal(false); - expect(await this.bitmap.get(keyA.addn(3))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(4))).to.equal(false); - }); - }); - - describe('set', function () { - it('adds a key', async function () { - await this.bitmap.set(keyA); - expect(await this.bitmap.get(keyA)).to.equal(true); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('adds several keys', async function () { - await this.bitmap.set(keyA); - await this.bitmap.set(keyB); - expect(await this.bitmap.get(keyA)).to.equal(true); - expect(await this.bitmap.get(keyB)).to.equal(true); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('adds several consecutive keys', async function () { - await this.bitmap.set(keyA.addn(0)); - await this.bitmap.set(keyA.addn(1)); - await this.bitmap.set(keyA.addn(3)); - expect(await this.bitmap.get(keyA.addn(0))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(1))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(2))).to.equal(false); - expect(await this.bitmap.get(keyA.addn(3))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(4))).to.equal(false); - }); - }); - - describe('unset', function () { - it('removes added keys', async function () { - await this.bitmap.set(keyA); - await this.bitmap.set(keyB); - await this.bitmap.unset(keyA); - expect(await this.bitmap.get(keyA)).to.equal(false); - expect(await this.bitmap.get(keyB)).to.equal(true); - expect(await this.bitmap.get(keyC)).to.equal(false); - }); - - it('removes consecutive added keys', async function () { - await this.bitmap.set(keyA.addn(0)); - await this.bitmap.set(keyA.addn(1)); - await this.bitmap.set(keyA.addn(3)); - await this.bitmap.unset(keyA.addn(1)); - expect(await this.bitmap.get(keyA.addn(0))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(1))).to.equal(false); - expect(await this.bitmap.get(keyA.addn(2))).to.equal(false); - expect(await this.bitmap.get(keyA.addn(3))).to.equal(true); - expect(await this.bitmap.get(keyA.addn(4))).to.equal(false); - }); - - it('adds and removes multiple keys', async function () { - // [] - - await this.bitmap.set(keyA); - await this.bitmap.set(keyC); - - // [A, C] - - await this.bitmap.unset(keyA); - await this.bitmap.unset(keyB); - - // [C] - - await this.bitmap.set(keyB); - - // [C, B] - - await this.bitmap.set(keyA); - await this.bitmap.unset(keyC); - - // [A, B] - - await this.bitmap.set(keyA); - await this.bitmap.set(keyB); - - // [A, B] - - await this.bitmap.set(keyC); - await this.bitmap.unset(keyA); - - // [B, C] - - await this.bitmap.set(keyA); - await this.bitmap.unset(keyB); - - // [A, C] - - expect(await this.bitmap.get(keyA)).to.equal(true); - expect(await this.bitmap.get(keyB)).to.equal(false); - expect(await this.bitmap.get(keyC)).to.equal(true); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js deleted file mode 100644 index 545c82a..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/DoubleEndedQueue.test.js +++ /dev/null @@ -1,96 +0,0 @@ -const { expectEvent } = require('@openzeppelin/test-helpers'); -const { expectRevertCustomError } = require('../../helpers/customError'); - -const Bytes32DequeMock = artifacts.require('Bytes32DequeMock'); - -/** Rebuild the content of the deque as a JS array. */ -async function getContent (deque) { - const length = await deque.length().then(bn => bn.toNumber()); - const values = await Promise.all(Array(length).fill().map((_, i) => deque.at(i))); - return values; -} - -contract('DoubleEndedQueue', function (accounts) { - const bytesA = '0xdeadbeef'.padEnd(66, '0'); - const bytesB = '0x0123456789'.padEnd(66, '0'); - const bytesC = '0x42424242'.padEnd(66, '0'); - const bytesD = '0x171717'.padEnd(66, '0'); - - beforeEach(async function () { - this.deque = await Bytes32DequeMock.new(); - }); - - describe('when empty', function () { - it('getters', async function () { - expect(await this.deque.empty()).to.be.equal(true); - expect(await getContent(this.deque)).to.have.ordered.members([]); - }); - - it('reverts on accesses', async function () { - await expectRevertCustomError(this.deque.popBack(), 'Empty()'); - await expectRevertCustomError(this.deque.popFront(), 'Empty()'); - await expectRevertCustomError(this.deque.back(), 'Empty()'); - await expectRevertCustomError(this.deque.front(), 'Empty()'); - }); - }); - - describe('when not empty', function () { - beforeEach(async function () { - await this.deque.pushBack(bytesB); - await this.deque.pushFront(bytesA); - await this.deque.pushBack(bytesC); - this.content = [ bytesA, bytesB, bytesC ]; - }); - - it('getters', async function () { - expect(await this.deque.empty()).to.be.equal(false); - expect(await this.deque.length()).to.be.bignumber.equal(this.content.length.toString()); - expect(await this.deque.front()).to.be.equal(this.content[0]); - expect(await this.deque.back()).to.be.equal(this.content[this.content.length - 1]); - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - - it('out of bounds access', async function () { - await expectRevertCustomError(this.deque.at(this.content.length), 'OutOfBounds()'); - }); - - describe('push', function () { - it('front', async function () { - await this.deque.pushFront(bytesD); - this.content.unshift(bytesD); // add element at the beginning - - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - - it('back', async function () { - await this.deque.pushBack(bytesD); - this.content.push(bytesD); // add element at the end - - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - }); - - describe('pop', function () { - it('front', async function () { - const value = this.content.shift(); // remove first element - expectEvent(await this.deque.popFront(), 'OperationResult', { value }); - - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - - it('back', async function () { - const value = this.content.pop(); // remove last element - expectEvent(await this.deque.popBack(), 'OperationResult', { value }); - - expect(await getContent(this.deque)).to.have.ordered.members(this.content); - }); - }); - - it('clear', async function () { - await this.deque.clear(); - - expect(await this.deque.empty()).to.be.equal(true); - expect(await getContent(this.deque)).to.have.ordered.members([]); - }); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js deleted file mode 100644 index b1d0d0d..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.behavior.js +++ /dev/null @@ -1,181 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -const zip = require('lodash.zip'); - -function shouldBehaveLikeMap (keys, values, zeroValue) { - const [keyA, keyB, keyC] = keys; - const [valueA, valueB, valueC] = values; - - async function expectMembersMatch (map, keys, values) { - expect(keys.length).to.equal(values.length); - - await Promise.all(keys.map(async key => - expect(await map.contains(key)).to.equal(true), - )); - - expect(await map.length()).to.bignumber.equal(keys.length.toString()); - - expect( - (await Promise.all(keys.map(key => map.get(key)))).map(k => k.toString()), - ).to.have.same.members( - values.map(value => value.toString()), - ); - - // To compare key-value pairs, we zip keys and values, and convert BNs to - // strings to workaround Chai limitations when dealing with nested arrays - expect(await Promise.all([...Array(keys.length).keys()].map(async (index) => { - const entry = await map.at(index); - return [entry.key.toString(), entry.value.toString()]; - }))).to.have.same.deep.members( - zip(keys.map(k => k.toString()), values.map(v => v.toString())), - ); - } - - it('starts empty', async function () { - expect(await this.map.contains(keyA)).to.equal(false); - - await expectMembersMatch(this.map, [], []); - }); - - describe('set', function () { - it('adds a key', async function () { - const receipt = await this.map.set(keyA, valueA); - expectEvent(receipt, 'OperationResult', { result: true }); - - await expectMembersMatch(this.map, [keyA], [valueA]); - }); - - it('adds several keys', async function () { - await this.map.set(keyA, valueA); - await this.map.set(keyB, valueB); - - await expectMembersMatch(this.map, [keyA, keyB], [valueA, valueB]); - expect(await this.map.contains(keyC)).to.equal(false); - }); - - it('returns false when adding keys already in the set', async function () { - await this.map.set(keyA, valueA); - - const receipt = (await this.map.set(keyA, valueA)); - expectEvent(receipt, 'OperationResult', { result: false }); - - await expectMembersMatch(this.map, [keyA], [valueA]); - }); - - it('updates values for keys already in the set', async function () { - await this.map.set(keyA, valueA); - - await this.map.set(keyA, valueB); - - await expectMembersMatch(this.map, [keyA], [valueB]); - }); - }); - - describe('remove', function () { - it('removes added keys', async function () { - await this.map.set(keyA, valueA); - - const receipt = await this.map.remove(keyA); - expectEvent(receipt, 'OperationResult', { result: true }); - - expect(await this.map.contains(keyA)).to.equal(false); - await expectMembersMatch(this.map, [], []); - }); - - it('returns false when removing keys not in the set', async function () { - const receipt = await this.map.remove(keyA); - expectEvent(receipt, 'OperationResult', { result: false }); - - expect(await this.map.contains(keyA)).to.equal(false); - }); - - it('adds and removes multiple keys', async function () { - // [] - - await this.map.set(keyA, valueA); - await this.map.set(keyC, valueC); - - // [A, C] - - await this.map.remove(keyA); - await this.map.remove(keyB); - - // [C] - - await this.map.set(keyB, valueB); - - // [C, B] - - await this.map.set(keyA, valueA); - await this.map.remove(keyC); - - // [A, B] - - await this.map.set(keyA, valueA); - await this.map.set(keyB, valueB); - - // [A, B] - - await this.map.set(keyC, valueC); - await this.map.remove(keyA); - - // [B, C] - - await this.map.set(keyA, valueA); - await this.map.remove(keyB); - - // [A, C] - - await expectMembersMatch(this.map, [keyA, keyC], [valueA, valueC]); - - expect(await this.map.contains(keyB)).to.equal(false); - }); - }); - - describe('read', function () { - beforeEach(async function () { - await this.map.set(keyA, valueA); - }); - - describe('get', function () { - it('existing value', async function () { - expect( - (await this.map.get(keyA)).toString(), - ).to.be.equal(valueA.toString()); - }); - it('missing value', async function () { - await expectRevert(this.map.get(keyB), 'EnumerableMap: nonexistent key'); - }); - }); - - describe('get with message', function () { - it('existing value', async function () { - expect( - (await this.map.getWithMessage(keyA, 'custom error string')) - .toString(), - ).to.be.equal(valueA.toString()); - }); - it('missing value', async function () { - await expectRevert(this.map.getWithMessage(keyB, 'custom error string'), 'custom error string'); - }); - }); - - describe('tryGet', function () { - it('existing value', async function () { - const result = await this.map.tryGet(keyA); - expect(result['0']).to.be.equal(true); - expect(result['1'].toString()).to.be.equal(valueA.toString()); - }); - it('missing value', async function () { - const result = await this.map.tryGet(keyB); - expect(result['0']).to.be.equal(false); - expect(result['1'].toString()).to.be.equal(zeroValue.toString()); - }); - }); - }); -} - -module.exports = { - shouldBehaveLikeMap, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js deleted file mode 100644 index 58f4eb8..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableMap.test.js +++ /dev/null @@ -1,86 +0,0 @@ -const { BN, constants } = require('@openzeppelin/test-helpers'); - -const AddressToUintMapMock = artifacts.require('AddressToUintMapMock'); -const UintToAddressMapMock = artifacts.require('UintToAddressMapMock'); -const Bytes32ToBytes32MapMock = artifacts.require('Bytes32ToBytes32MapMock'); -const UintToUintMapMock = artifacts.require('UintToUintMapMock'); -const Bytes32ToUintMapMock = artifacts.require('Bytes32ToUintMapMock'); - -const { shouldBehaveLikeMap } = require('./EnumerableMap.behavior'); - -contract('EnumerableMap', function (accounts) { - const [ accountA, accountB, accountC ] = accounts; - - const keyA = new BN('7891'); - const keyB = new BN('451'); - const keyC = new BN('9592328'); - - const bytesA = '0xdeadbeef'.padEnd(66, '0'); - const bytesB = '0x0123456789'.padEnd(66, '0'); - const bytesC = '0x42424242'.padEnd(66, '0'); - - // AddressToUintMap - describe('AddressToUintMap', function () { - beforeEach(async function () { - this.map = await AddressToUintMapMock.new(); - }); - - shouldBehaveLikeMap( - [ accountA, accountB, accountC ], - [ keyA, keyB, keyC ], - new BN('0'), - ); - }); - - // UintToAddressMap - describe('UintToAddressMap', function () { - beforeEach(async function () { - this.map = await UintToAddressMapMock.new(); - }); - - shouldBehaveLikeMap( - [ keyA, keyB, keyC ], - [ accountA, accountB, accountC ], - constants.ZERO_ADDRESS, - ); - }); - - // Bytes32ToBytes32Map - describe('Bytes32ToBytes32Map', function () { - beforeEach(async function () { - this.map = await Bytes32ToBytes32MapMock.new(); - }); - - shouldBehaveLikeMap( - [ keyA, keyB, keyC ].map(k => '0x' + k.toString(16).padEnd(64, '0')), - [ bytesA, bytesB, bytesC ], - constants.ZERO_BYTES32, - ); - }); - - // UintToUintMap - describe('UintToUintMap', function () { - beforeEach(async function () { - this.map = await UintToUintMapMock.new(); - }); - - shouldBehaveLikeMap( - [ keyA, keyB, keyC ], - [ keyA, keyB, keyC ].map(k => k.add(new BN('1332'))), - new BN('0'), - ); - }); - - // Bytes32ToUintMap - describe('Bytes32ToUintMap', function () { - beforeEach(async function () { - this.map = await Bytes32ToUintMapMock.new(); - }); - - shouldBehaveLikeMap( - [ bytesA, bytesB, bytesC ], - [ keyA, keyB, keyC ], - new BN('0'), - ); - }); -}); diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js deleted file mode 100644 index 17e0866..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.behavior.js +++ /dev/null @@ -1,131 +0,0 @@ -const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers'); -const { expect } = require('chai'); - -function shouldBehaveLikeSet (valueA, valueB, valueC) { - async function expectMembersMatch (set, values) { - const contains = await Promise.all(values.map(value => set.contains(value))); - expect(contains.every(Boolean)).to.be.equal(true); - - const length = await set.length(); - expect(length).to.bignumber.equal(values.length.toString()); - - // To compare values we convert to strings to workaround Chai - // limitations when dealing with nested arrays (required for BNs) - const indexedValues = await Promise.all(Array(values.length).fill().map((_, index) => set.at(index))); - expect( - indexedValues.map(v => v.toString()), - ).to.have.same.members( - values.map(v => v.toString()), - ); - - const returnedValues = await set.values(); - expect( - returnedValues.map(v => v.toString()), - ).to.have.same.members( - values.map(v => v.toString()), - ); - } - - it('starts empty', async function () { - expect(await this.set.contains(valueA)).to.equal(false); - - await expectMembersMatch(this.set, []); - }); - - describe('add', function () { - it('adds a value', async function () { - const receipt = await this.set.add(valueA); - expectEvent(receipt, 'OperationResult', { result: true }); - - await expectMembersMatch(this.set, [valueA]); - }); - - it('adds several values', async function () { - await this.set.add(valueA); - await this.set.add(valueB); - - await expectMembersMatch(this.set, [valueA, valueB]); - expect(await this.set.contains(valueC)).to.equal(false); - }); - - it('returns false when adding values already in the set', async function () { - await this.set.add(valueA); - - const receipt = (await this.set.add(valueA)); - expectEvent(receipt, 'OperationResult', { result: false }); - - await expectMembersMatch(this.set, [valueA]); - }); - }); - - describe('at', function () { - it('reverts when retrieving non-existent elements', async function () { - await expectRevert.unspecified(this.set.at(0)); - }); - }); - - describe('remove', function () { - it('removes added values', async function () { - await this.set.add(valueA); - - const receipt = await this.set.remove(valueA); - expectEvent(receipt, 'OperationResult', { result: true }); - - expect(await this.set.contains(valueA)).to.equal(false); - await expectMembersMatch(this.set, []); - }); - - it('returns false when removing values not in the set', async function () { - const receipt = await this.set.remove(valueA); - expectEvent(receipt, 'OperationResult', { result: false }); - - expect(await this.set.contains(valueA)).to.equal(false); - }); - - it('adds and removes multiple values', async function () { - // [] - - await this.set.add(valueA); - await this.set.add(valueC); - - // [A, C] - - await this.set.remove(valueA); - await this.set.remove(valueB); - - // [C] - - await this.set.add(valueB); - - // [C, B] - - await this.set.add(valueA); - await this.set.remove(valueC); - - // [A, B] - - await this.set.add(valueA); - await this.set.add(valueB); - - // [A, B] - - await this.set.add(valueC); - await this.set.remove(valueA); - - // [B, C] - - await this.set.add(valueA); - await this.set.remove(valueB); - - // [A, C] - - await expectMembersMatch(this.set, [valueA, valueC]); - - expect(await this.set.contains(valueB)).to.equal(false); - }); - }); -} - -module.exports = { - shouldBehaveLikeSet, -}; diff --git a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js b/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js deleted file mode 100644 index 2b7d0a3..0000000 --- a/lib/morpho-utils/lib/openzeppelin-contracts/test/utils/structs/EnumerableSet.test.js +++ /dev/null @@ -1,46 +0,0 @@ -const { BN } = require('@openzeppelin/test-helpers'); - -const EnumerableBytes32SetMock = artifacts.require('EnumerableBytes32SetMock'); -const EnumerableAddressSetMock = artifacts.require('EnumerableAddressSetMock'); -const EnumerableUintSetMock = artifacts.require('EnumerableUintSetMock'); - -const { shouldBehaveLikeSet } = require('./EnumerableSet.behavior'); - -contract('EnumerableSet', function (accounts) { - // Bytes32Set - describe('EnumerableBytes32Set', function () { - const bytesA = '0xdeadbeef'.padEnd(66, '0'); - const bytesB = '0x0123456789'.padEnd(66, '0'); - const bytesC = '0x42424242'.padEnd(66, '0'); - - beforeEach(async function () { - this.set = await EnumerableBytes32SetMock.new(); - }); - - shouldBehaveLikeSet(bytesA, bytesB, bytesC); - }); - - // AddressSet - describe('EnumerableAddressSet', function () { - const [accountA, accountB, accountC] = accounts; - - beforeEach(async function () { - this.set = await EnumerableAddressSetMock.new(); - }); - - shouldBehaveLikeSet(accountA, accountB, accountC); - }); - - // UintSet - describe('EnumerableUintSet', function () { - const uintA = new BN('1234'); - const uintB = new BN('5678'); - const uintC = new BN('9101112'); - - beforeEach(async function () { - this.set = await EnumerableUintSetMock.new(); - }); - - shouldBehaveLikeSet(uintA, uintB, uintC); - }); -}); diff --git a/lib/morpho-utils/package.json b/lib/morpho-utils/package.json deleted file mode 100644 index 810a4ab..0000000 --- a/lib/morpho-utils/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@morpho-labs/morpho-utils", - "version": "1.0.0", - "description": "Repository gathering useful libraries and contracts", - "repository": "git@github.com:morpho-labs/morpho-utils.git", - "author": "Morpho Labs ", - "license": "AGPL-3.0", - "scripts": { - "postinstall": "husky install" - }, - "devDependencies": { - "husky": "8.0.2", - "lint-staged": "13.1.0", - "prettier": "2.8.1" - }, - "lint-staged": { - "*.sol": "forge fmt", - "*.json": "yarn prettier" - } -} diff --git a/lib/morpho-utils/remappings.txt b/lib/morpho-utils/remappings.txt deleted file mode 100644 index bdfc2ce..0000000 --- a/lib/morpho-utils/remappings.txt +++ /dev/null @@ -1,5 +0,0 @@ -@aave/core-v3/=lib/aave-v3-core/ -ds-test/=lib/forge-std/lib/ds-test/src/ -forge-std/=lib/forge-std/src/ -openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/ -openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/ diff --git a/lib/morpho-utils/src/DelegateCall.sol b/lib/morpho-utils/src/DelegateCall.sol deleted file mode 100644 index 4a84241..0000000 --- a/lib/morpho-utils/src/DelegateCall.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -/// @title Delegate Call Library. -/// @author Morpho Labs. -/// @custom:contact security@morpho.xyz -/// @dev Low-level YUL delegate call library. -library DelegateCall { - /* ERRORS */ - - /// @notice Thrown when a low delegate call has failed without error message. - error LowLevelDelegateCallFailed(); - - /* CONSTANTS */ - - /// @notice The signature of the `LowLevelDelegateCallFailed` error ie bytes4(keccak256("LowLevelDelegateCallFailed()")). - bytes4 constant LowLevelDelegateCallFailedError = 0x06f7035e; - - /* INTERNAL */ - - /// @dev Performs a low-level delegate call to the `_target` contract. - /// @dev Note: Unlike the OZ's library this function does not check if the `_target` is a contract. It is the responsibility of the caller to ensure that the `_target` is a contract. - /// @param _target The address of the target contract. - /// @param _data The data to pass to the function called on the target contract. - /// @return returnData The return data from the function called on the target contract. - function functionDelegateCall(address _target, bytes memory _data) internal returns (bytes memory returnData) { - assembly { - returnData := mload(0x40) - - // The bytes size is found at the bytes pointer memory address - the bytes data is found a slot further. - if iszero(delegatecall(gas(), _target, add(_data, 0x20), mload(_data), 0, 0)) { - // No error is returned, return the custom error. - if iszero(returndatasize()) { - mstore(returnData, LowLevelDelegateCallFailedError) - revert(returnData, 4) - } - - // An error is returned and can be logged. - returndatacopy(returnData, 0, returndatasize()) - revert(returnData, returndatasize()) - } - - // Copy data size and then the returned data to memory. - mstore(returnData, returndatasize()) - let actualDataPtr := add(returnData, 0x20) - returndatacopy(actualDataPtr, 0, returndatasize()) - - // Update the free memory pointer. - mstore(0x40, add(actualDataPtr, returndatasize())) - } - } -} diff --git a/lib/morpho-utils/src/ERC4626UpgradeableSafe.sol b/lib/morpho-utils/src/ERC4626UpgradeableSafe.sol deleted file mode 100644 index 12002c5..0000000 --- a/lib/morpho-utils/src/ERC4626UpgradeableSafe.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import { - ERC4626Upgradeable, - ERC20Upgradeable, - IERC20MetadataUpgradeable -} from "openzeppelin-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol"; - -/// @title ERC4626UpgradeableSafe. -/// @author Morpho Labs. -/// @custom:contact security@morpho.xyz -/// @notice ERC4626 Tokenized Vault abstract upgradeable implementation tweaking OZ's implementation to make it safer at initialization. -abstract contract ERC4626UpgradeableSafe is ERC4626Upgradeable { - /* CONSTRUCTOR */ - - /// @dev The contract automatically disables initializers when deployed so that nobody can highjack the implementation contract. - constructor() { - _disableInitializers(); - } - - /* INITIALIZER */ - - function __ERC4626UpgradeableSafe_init(IERC20MetadataUpgradeable asset, uint256 initialDeposit) - internal - onlyInitializing - { - __ERC4626_init_unchained(asset); - __ERC4626UpgradeableSafe_init_unchained(initialDeposit); - } - - function __ERC4626UpgradeableSafe_init_unchained(uint256 initialDeposit) internal onlyInitializing { - // Sacrifice an initial seed of shares to ensure a healthy amount of precision in minting shares. - // Set to 0 at your own risk. - // Caller must have approved the asset to this contract's address. - // See: https://github.com/Rari-Capital/solmate/issues/178 - if (initialDeposit > 0) deposit(initialDeposit, address(this)); - } - - /// @dev This empty reserved space is put in place to allow future versions to add new - /// variables without shifting down storage in the inheritance chain. - /// See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - uint256[50] private __gap; -} diff --git a/lib/morpho-utils/src/math/CompoundMath.sol b/lib/morpho-utils/src/math/CompoundMath.sol deleted file mode 100644 index 9f7b83c..0000000 --- a/lib/morpho-utils/src/math/CompoundMath.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -/// @title Compound Math Library. -/// @author Morpho Labs. -/// @custom:contact security@morpho.xyz -/// @dev Library to perform Compound's multiplication and division in an efficient way. -library CompoundMath { - /* CONSTANTS */ - - // Only direct number constants and references to such constants are supported by inline assembly. - uint256 internal constant WAD = 1e18; - uint256 internal constant MAX_UINT256 = 2 ** 256 - 1; - - /* INTERNAL */ - - function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { - // Revert if x * y > type(uint256).max - // <=> y > 0 and x > type(uint256).max / y - if mul(y, gt(x, div(MAX_UINT256, y))) { revert(0, 0) } - - z := div(mul(x, y), WAD) - } - } - - function div(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { - // Revert if x * WAD > type(uint256).max or y == 0 - // <=> x > type(uint256).max / WAD or y == 0 - if iszero(mul(y, lt(x, add(div(MAX_UINT256, WAD), 1)))) { revert(0, 0) } - - z := div(mul(WAD, x), y) - } - } -} diff --git a/lib/morpho-utils/src/math/Math.sol b/lib/morpho-utils/src/math/Math.sol deleted file mode 100644 index d154388..0000000 --- a/lib/morpho-utils/src/math/Math.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -/// @title Math Library. -/// @author Morpho Labs. -/// @custom:contact security@morpho.xyz -/// @dev Library to perform simple math manipulations. -library Math { - function min(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { - z := xor(x, mul(xor(x, y), lt(y, x))) - } - } - - function max(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { - z := xor(x, mul(xor(x, y), gt(y, x))) - } - } - - /// @dev Returns max(x - y, 0). - function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) { - assembly { - z := mul(gt(x, y), sub(x, y)) - } - } - - /// @dev Returns x / y rounded up (x / y + boolAsInt(x % y > 0)). - function divUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - // Division by 0 if - // y = 0 - assembly { - if iszero(y) { revert(0, 0) } - - z := add(gt(mod(x, y), 0), div(x, y)) - } - } - - /// @dev Returns the floor of log2(x) and returns 0 when x = 0. - /// @dev Uses a method by dichotomy to find the highest bit set of x. - function log2(uint256 x) internal pure returns (uint256 y) { - assembly { - // Finds if x has a 1 on the first 128 bits. If not then do nothing. - // If that is the case then the result is more than 128. - let z := shl(7, gt(x, 0xffffffffffffffffffffffffffffffff)) - y := z - x := shr(z, x) - - // Using y as an accumulator, we can now focus on the last 128 bits of x. - // Repeat this process to divide the number of bits to handle by 2 every time. - z := shl(6, gt(x, 0xffffffffffffffff)) - y := add(y, z) - x := shr(z, x) - - z := shl(5, gt(x, 0xffffffff)) - y := add(y, z) - x := shr(z, x) - - z := shl(4, gt(x, 0xffff)) - y := add(y, z) - x := shr(z, x) - - z := shl(3, gt(x, 0xff)) - y := add(y, z) - x := shr(z, x) - - z := shl(2, gt(x, 0xf)) - y := add(y, z) - x := shr(z, x) - - z := shl(1, gt(x, 3)) - y := add(add(y, z), gt(shr(z, x), 1)) - } - } -} diff --git a/lib/morpho-utils/src/math/PercentageMath.sol b/lib/morpho-utils/src/math/PercentageMath.sol deleted file mode 100644 index 55e586c..0000000 --- a/lib/morpho-utils/src/math/PercentageMath.sol +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -/// @title PercentageMath. -/// @author Morpho Labs. -/// @custom:contact security@morpho.xyz -/// @notice Optimized version of Aave V3 math library PercentageMath to conduct percentage manipulations: https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/math/PercentageMath.sol -library PercentageMath { - /* CONSTANTS */ - - // Only direct number constants and references to such constants are supported by inline assembly. - uint256 internal constant PERCENTAGE_FACTOR = 100_00; - uint256 internal constant HALF_PERCENTAGE_FACTOR = 50_00; - uint256 internal constant PERCENTAGE_FACTOR_MINUS_ONE = 100_00 - 1; - uint256 internal constant MAX_UINT256 = 2 ** 256 - 1; - uint256 internal constant MAX_UINT256_MINUS_HALF_PERCENTAGE_FACTOR = 2 ** 256 - 1 - 50_00; - uint256 internal constant MAX_UINT256_MINUS_PERCENTAGE_FACTOR_MINUS_ONE = 2 ** 256 - 1 - (100_00 - 1); - - /* INTERNAL */ - - /// @notice Executes the bps-based percentage addition (x * (1 + p)), rounded half up. - /// @param x The value to which to add the percentage. - /// @param percentage The percentage of the value to add (in bps). - /// @return y The result of the addition. - function percentAdd(uint256 x, uint256 percentage) internal pure returns (uint256 y) { - // 1. Overflow if - // PERCENTAGE_FACTOR + percentage > type(uint256).max - // <=> percentage > type(uint256).max - PERCENTAGE_FACTOR - // 2. Overflow if - // x * (PERCENTAGE_FACTOR + percentage) + HALF_PERCENTAGE_FACTOR > type(uint256).max - // <=> x > (type(uint256).max - HALF_PERCENTAGE_FACTOR) / (PERCENTAGE_FACTOR + percentage) - assembly { - y := add(PERCENTAGE_FACTOR, percentage) // Temporary assignment to save gas. - - if or( - gt(percentage, sub(MAX_UINT256, PERCENTAGE_FACTOR)), - gt(x, div(MAX_UINT256_MINUS_HALF_PERCENTAGE_FACTOR, y)) - ) { revert(0, 0) } - - y := div(add(mul(x, y), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR) - } - } - - /// @notice Executes the bps-based percentage subtraction (x * (1 - p)), rounded half up. - /// @param x The value to which to subtract the percentage. - /// @param percentage The percentage of the value to subtract (in bps). - /// @return y The result of the subtraction. - function percentSub(uint256 x, uint256 percentage) internal pure returns (uint256 y) { - // 1. Underflow if - // percentage > PERCENTAGE_FACTOR - // 2. Overflow if - // x * (PERCENTAGE_FACTOR - percentage) + HALF_PERCENTAGE_FACTOR > type(uint256).max - // <=> (PERCENTAGE_FACTOR - percentage) > 0 and x > (type(uint256).max - HALF_PERCENTAGE_FACTOR) / (PERCENTAGE_FACTOR - percentage) - assembly { - y := sub(PERCENTAGE_FACTOR, percentage) // Temporary assignment to save gas. - - if or(gt(percentage, PERCENTAGE_FACTOR), mul(y, gt(x, div(MAX_UINT256_MINUS_HALF_PERCENTAGE_FACTOR, y)))) { - revert(0, 0) - } - - y := div(add(mul(x, y), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR) - } - } - - /// @notice Executes the bps-based multiplication (x * p), rounded half up. - /// @param x The value to multiply by the percentage. - /// @param percentage The percentage of the value to multiply (in bps). - /// @return y The result of the multiplication. - function percentMul(uint256 x, uint256 percentage) internal pure returns (uint256 y) { - // Overflow if - // x * percentage + HALF_PERCENTAGE_FACTOR > type(uint256).max - // <=> percentage > 0 and x > (type(uint256).max - HALF_PERCENTAGE_FACTOR) / percentage - assembly { - if mul(percentage, gt(x, div(MAX_UINT256_MINUS_HALF_PERCENTAGE_FACTOR, percentage))) { revert(0, 0) } - - y := div(add(mul(x, percentage), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR) - } - } - - /// @notice Executes the bps-based multiplication (x * p), rounded down. - /// @param x The value to multiply by the percentage. - /// @param percentage The percentage of the value to multiply. - /// @return y The result of the multiplication. - function percentMulDown(uint256 x, uint256 percentage) internal pure returns (uint256 y) { - // Overflow if - // x * percentage > type(uint256).max - // <=> percentage > 0 and x > type(uint256).max / percentage - assembly { - if mul(percentage, gt(x, div(MAX_UINT256, percentage))) { revert(0, 0) } - - y := div(mul(x, percentage), PERCENTAGE_FACTOR) - } - } - - /// @notice Executes the bps-based multiplication (x * p), rounded up. - /// @param x The value to multiply by the percentage. - /// @param percentage The percentage of the value to multiply. - /// @return y The result of the multiplication. - function percentMulUp(uint256 x, uint256 percentage) internal pure returns (uint256 y) { - // Overflow if - // x * percentage + PERCENTAGE_FACTOR_MINUS_ONE > type(uint256).max - // <=> percentage > 0 and x > (type(uint256).max - PERCENTAGE_FACTOR_MINUS_ONE) / percentage - assembly { - if mul(percentage, gt(x, div(MAX_UINT256_MINUS_PERCENTAGE_FACTOR_MINUS_ONE, percentage))) { revert(0, 0) } - - y := div(add(mul(x, percentage), PERCENTAGE_FACTOR_MINUS_ONE), PERCENTAGE_FACTOR) - } - } - - /// @notice Executes the bps-based division (x / p), rounded half up. - /// @param x The value to divide by the percentage. - /// @param percentage The percentage of the value to divide (in bps). - /// @return y The result of the division. - function percentDiv(uint256 x, uint256 percentage) internal pure returns (uint256 y) { - // 1. Division by 0 if - // percentage == 0 - // 2. Overflow if - // x * PERCENTAGE_FACTOR + percentage / 2 > type(uint256).max - // <=> x > (type(uint256).max - percentage / 2) / PERCENTAGE_FACTOR - assembly { - y := div(percentage, 2) // Temporary assignment to save gas. - - if iszero(mul(percentage, iszero(gt(x, div(sub(MAX_UINT256, y), PERCENTAGE_FACTOR))))) { revert(0, 0) } - - y := div(add(mul(PERCENTAGE_FACTOR, x), y), percentage) - } - } - - /// @notice Executes the bps-based division (x / p), rounded down. - /// @param x The value to divide by the percentage. - /// @param percentage The percentage of the value to divide. - /// @return y The result of the division. - function percentDivDown(uint256 x, uint256 percentage) internal pure returns (uint256 y) { - // 1. Division by 0 if - // percentage == 0 - // 2. Overflow if - // x * PERCENTAGE_FACTOR > type(uint256).max - // <=> x > type(uint256).max / PERCENTAGE_FACTOR - assembly { - if iszero(mul(percentage, lt(x, add(div(MAX_UINT256, PERCENTAGE_FACTOR), 1)))) { revert(0, 0) } - - y := div(mul(PERCENTAGE_FACTOR, x), percentage) - } - } - - /// @notice Executes the bps-based division (x / p), rounded up. - /// @param x The value to divide by the percentage. - /// @param percentage The percentage of the value to divide. - /// @return y The result of the division. - function percentDivUp(uint256 x, uint256 percentage) internal pure returns (uint256 y) { - // 1. Division by 0 if - // percentage == 0 - // 2. Overflow if - // x * PERCENTAGE_FACTOR + (percentage - 1) > type(uint256).max - // <=> x > (type(uint256).max - (percentage - 1)) / PERCENTAGE_FACTOR - assembly { - y := sub(percentage, 1) // Temporary assignment to save gas. - - if iszero(mul(percentage, iszero(gt(x, div(sub(MAX_UINT256, y), PERCENTAGE_FACTOR))))) { revert(0, 0) } - - y := div(add(mul(PERCENTAGE_FACTOR, x), y), percentage) - } - } - - /// @notice Executes the bps-based weighted average (x * (1 - p) + y * p), rounded half up. - /// @param x The first value, with a weight of 1 - percentage. - /// @param y The second value, with a weight of percentage. - /// @param percentage The weight of y, and complement of the weight of x (in bps). - /// @return z The result of the bps-based weighted average. - function weightedAvg(uint256 x, uint256 y, uint256 percentage) internal pure returns (uint256 z) { - // 1. Underflow if - // percentage > PERCENTAGE_FACTOR - // 2. Overflow if - // y * percentage + HALF_PERCENTAGE_FACTOR > type(uint256).max - // <=> percentage > 0 and y > (type(uint256).max - HALF_PERCENTAGE_FACTOR) / percentage - // 3. Overflow if - // x * (PERCENTAGE_FACTOR - percentage) + y * percentage + HALF_PERCENTAGE_FACTOR > type(uint256).max - // <=> x * (PERCENTAGE_FACTOR - percentage) > type(uint256).max - HALF_PERCENTAGE_FACTOR - y * percentage - // <=> PERCENTAGE_FACTOR > percentage and x > (type(uint256).max - HALF_PERCENTAGE_FACTOR - y * percentage) / (PERCENTAGE_FACTOR - percentage) - assembly { - z := sub(PERCENTAGE_FACTOR, percentage) // Temporary assignment to save gas. - - if or( - gt(percentage, PERCENTAGE_FACTOR), - or( - mul(percentage, gt(y, div(MAX_UINT256_MINUS_HALF_PERCENTAGE_FACTOR, percentage))), - mul(z, gt(x, div(sub(MAX_UINT256_MINUS_HALF_PERCENTAGE_FACTOR, mul(y, percentage)), z))) - ) - ) { revert(0, 0) } - - z := div(add(add(mul(x, z), mul(y, percentage)), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR) - } - } -} diff --git a/lib/morpho-utils/src/math/WadRayMath.sol b/lib/morpho-utils/src/math/WadRayMath.sol deleted file mode 100644 index 9986cb6..0000000 --- a/lib/morpho-utils/src/math/WadRayMath.sol +++ /dev/null @@ -1,319 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -/// @title WadRayMath. -/// @author Morpho Labs. -/// @custom:contact security@morpho.xyz -/// @notice Optimized version of Aave V3 math library WadRayMath to conduct wad and ray manipulations: https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/math/WadRayMath.sol -library WadRayMath { - /* CONSTANTS */ - - // Only direct number constants and references to such constants are supported by inline assembly. - uint256 internal constant WAD = 1e18; - uint256 internal constant HALF_WAD = 0.5e18; - uint256 internal constant WAD_MINUS_ONE = 1e18 - 1; - uint256 internal constant RAY = 1e27; - uint256 internal constant HALF_RAY = 0.5e27; - uint256 internal constant RAY_MINUS_ONE = 1e27 - 1; - uint256 internal constant RAY_WAD_RATIO = 1e9; - uint256 internal constant HALF_RAY_WAD_RATIO = 0.5e9; - uint256 internal constant MAX_UINT256 = 2 ** 256 - 1; - uint256 internal constant MAX_UINT256_MINUS_HALF_WAD = 2 ** 256 - 1 - 0.5e18; - uint256 internal constant MAX_UINT256_MINUS_HALF_RAY = 2 ** 256 - 1 - 0.5e27; - uint256 internal constant MAX_UINT256_MINUS_WAD_MINUS_ONE = 2 ** 256 - 1 - (1e18 - 1); - uint256 internal constant MAX_UINT256_MINUS_RAY_MINUS_ONE = 2 ** 256 - 1 - (1e27 - 1); - - /* INTERNAL */ - - /// @dev Executes the wad-based multiplication of 2 numbers, rounded half up. - /// @param x Wad. - /// @param y Wad. - /// @return z The result of x * y, in wad. - function wadMul(uint256 x, uint256 y) internal pure returns (uint256 z) { - // Overflow if - // x * y + HALF_WAD > type(uint256).max - // <=> x * y > type(uint256).max - HALF_WAD - // <=> y > 0 and x > (type(uint256).max - HALF_WAD) / y - assembly { - if mul(y, gt(x, div(MAX_UINT256_MINUS_HALF_WAD, y))) { revert(0, 0) } - - z := div(add(mul(x, y), HALF_WAD), WAD) - } - } - - /// @dev Executes the wad-based multiplication of 2 numbers, rounded down. - /// @param x Wad. - /// @param y Wad. - /// @return z The result of x * y, in wad. - function wadMulDown(uint256 x, uint256 y) internal pure returns (uint256 z) { - // Overflow if - // x * y > type(uint256).max - // <=> y > 0 and x > type(uint256).max / y - assembly { - if mul(y, gt(x, div(MAX_UINT256, y))) { revert(0, 0) } - - z := div(mul(x, y), WAD) - } - } - - /// @dev Executes the wad-based multiplication of 2 numbers, rounded up. - /// @param x Wad. - /// @param y Wad. - /// @return z The result of x * y, in wad. - function wadMulUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - // Overflow if - // x * y + WAD_MINUS_ONE > type(uint256).max - // <=> x * y > type(uint256).max - WAD_MINUS_ONE - // <=> y > 0 and x > (type(uint256).max - WAD_MINUS_ONE) / y - assembly { - if mul(y, gt(x, div(MAX_UINT256_MINUS_WAD_MINUS_ONE, y))) { revert(0, 0) } - - z := div(add(mul(x, y), WAD_MINUS_ONE), WAD) - } - } - - /// @dev Executes wad-based division of 2 numbers, rounded half up. - /// @param x Wad. - /// @param y Wad. - /// @return z The result of x / y, in wad. - function wadDiv(uint256 x, uint256 y) internal pure returns (uint256 z) { - // 1. Division by 0 if - // y == 0 - // 2. Overflow if - // x * WAD + y / 2 > type(uint256).max - // <=> x * WAD > type(uint256).max - y / 2 - // <=> x > (type(uint256).max - y / 2) / WAD - assembly { - z := div(y, 2) // Temporary assignment to save gas. - - if iszero(mul(y, iszero(gt(x, div(sub(MAX_UINT256, z), WAD))))) { revert(0, 0) } - - z := div(add(mul(WAD, x), z), y) - } - } - - /// @dev Executes wad-based division of 2 numbers, rounded down. - /// @param x Wad. - /// @param y Wad. - /// @return z The result of x / y, in wad. - function wadDivDown(uint256 x, uint256 y) internal pure returns (uint256 z) { - // 1. Division by 0 if - // y == 0 - // 2. Overflow if - // x * WAD > type(uint256).max - // <=> x > type(uint256).max / WAD - assembly { - if iszero(mul(y, lt(x, add(div(MAX_UINT256, WAD), 1)))) { revert(0, 0) } - - z := div(mul(WAD, x), y) - } - } - - /// @dev Executes wad-based division of 2 numbers, rounded up. - /// @param x Wad. - /// @param y Wad. - /// @return z The result of x / y, in wad. - function wadDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - // 1. Division by 0 if - // y == 0 - // 2. Overflow if - // x * WAD + (y - 1) > type(uint256).max - // <=> x * WAD > type(uint256).max - (y - 1) - // <=> x > (type(uint256).max - (y - 1)) / WAD - assembly { - z := sub(y, 1) // Temporary assignment to save gas. - - if iszero(mul(y, iszero(gt(x, div(sub(MAX_UINT256, z), WAD))))) { revert(0, 0) } - - z := div(add(mul(WAD, x), z), y) - } - } - - /// @dev Executes the ray-based multiplication of 2 numbers, rounded half up. - /// @param x Ray. - /// @param y Ray. - /// @return z The result of x * y, in ray. - function rayMul(uint256 x, uint256 y) internal pure returns (uint256 z) { - // Overflow if - // x * y + HALF_RAY > type(uint256).max - // <=> x * y > type(uint256).max - HALF_RAY - // <=> y > 0 and x > (type(uint256).max - HALF_RAY) / y - assembly { - if mul(y, gt(x, div(MAX_UINT256_MINUS_HALF_RAY, y))) { revert(0, 0) } - - z := div(add(mul(x, y), HALF_RAY), RAY) - } - } - - /// @dev Executes the ray-based multiplication of 2 numbers, rounded down. - /// @param x Ray. - /// @param y Ray. - /// @return z The result of x * y, in ray. - function rayMulDown(uint256 x, uint256 y) internal pure returns (uint256 z) { - // Overflow if - // x * y > type(uint256).max - // <=> y > 0 and x > type(uint256).max / y - assembly { - if mul(y, gt(x, div(MAX_UINT256, y))) { revert(0, 0) } - - z := div(mul(x, y), RAY) - } - } - - /// @dev Executes the ray-based multiplication of 2 numbers, rounded up. - /// @param x Ray. - /// @param y Wad. - /// @return z The result of x * y, in ray. - function rayMulUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - // Overflow if - // x * y + RAY_MINUS_ONE > type(uint256).max - // <=> x * y > type(uint256).max - RAY_MINUS_ONE - // <=> y > 0 and x > (type(uint256).max - RAY_MINUS_ONE) / y - assembly { - if mul(y, gt(x, div(MAX_UINT256_MINUS_RAY_MINUS_ONE, y))) { revert(0, 0) } - - z := div(add(mul(x, y), RAY_MINUS_ONE), RAY) - } - } - - /// @dev Executes the ray-based division of 2 numbers, rounded half up. - /// @param x Ray. - /// @param y Ray. - /// @return z The result of x / y, in ray. - function rayDiv(uint256 x, uint256 y) internal pure returns (uint256 z) { - // 1. Division by 0 if - // y == 0 - // 2. Overflow if - // x * RAY + y / 2 > type(uint256).max - // <=> x * RAY > type(uint256).max - y / 2 - // <=> x > (type(uint256).max - y / 2) / RAY - assembly { - z := div(y, 2) // Temporary assignment to save gas. - - if iszero(mul(y, iszero(gt(x, div(sub(MAX_UINT256, z), RAY))))) { revert(0, 0) } - - z := div(add(mul(RAY, x), z), y) - } - } - - /// @dev Executes the ray-based multiplication of 2 numbers, rounded down. - /// @param x Wad. - /// @param y Wad. - /// @return z The result of x / y, in ray. - function rayDivDown(uint256 x, uint256 y) internal pure returns (uint256 z) { - // 1. Division by 0 if - // y == 0 - // 2. Overflow if - // x * RAY > type(uint256).max - // <=> x > type(uint256).max / RAY - assembly { - if iszero(mul(y, lt(x, add(div(MAX_UINT256, RAY), 1)))) { revert(0, 0) } - - z := div(mul(RAY, x), y) - } - } - - /// @dev Executes the ray-based multiplication of 2 numbers, rounded up. - /// @param x Wad. - /// @param y Wad. - /// @return z The result of x / y, in ray. - function rayDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { - // 1. Division by 0 if - // y == 0 - // 2. Overflow if - // x * RAY + (y - 1) > type(uint256).max - // <=> x * RAY > type(uint256).max - (y - 1) - // <=> x > (type(uint256).max - (y - 1)) / RAY - assembly { - z := sub(y, 1) // Temporary assignment to save gas. - - if iszero(mul(y, iszero(gt(x, div(sub(MAX_UINT256, z), RAY))))) { revert(0, 0) } - - z := div(add(mul(RAY, x), z), y) - } - } - - /// @dev Converts ray down to wad. - /// @param x Ray. - /// @return y = x converted to wad, rounded half up to the nearest wad. - function rayToWad(uint256 x) internal pure returns (uint256 y) { - assembly { - // If x % RAY_WAD_RATIO >= HALF_RAY_WAD_RATIO, round up. - y := add(div(x, RAY_WAD_RATIO), iszero(lt(mod(x, RAY_WAD_RATIO), HALF_RAY_WAD_RATIO))) - } - } - - /// @dev Converts wad up to ray. - /// @param x Wad. - /// @return y = x converted in ray. - function wadToRay(uint256 x) internal pure returns (uint256 y) { - // Overflow if - // x * RAY_WAD_RATIO > type(uint256).max - // <=> x > type(uint256).max / RAY_WAD_RATIO - assembly { - if gt(x, div(MAX_UINT256, RAY_WAD_RATIO)) { revert(0, 0) } - - y := mul(x, RAY_WAD_RATIO) - } - } - - /// @notice Computes the wad-based weighted average (x * (1 - weight) + y * weight), rounded half up. - /// @param x The first value, with a weight of 1 - weight. - /// @param y The second value, with a weight of weight. - /// @param weight The weight of y, and complement of the weight of x (in wad). - /// @return z The result of the wad-based weighted average. - function wadWeightedAvg(uint256 x, uint256 y, uint256 weight) internal pure returns (uint256 z) { - // 1. Underflow if - // weight > WAD - // 2. Overflow if - // y * weight + HALF_WAD > type(uint256).max - // <=> weight > 0 and y > (type(uint256).max - HALF_WAD) / weight - // 3. Overflow if - // x * (WAD - weight) + y * weight + HALF_WAD > type(uint256).max - // <=> x * (WAD - weight) > type(uint256).max - HALF_WAD - y * weight - // <=> WAD > weight and x > (type(uint256).max - HALF_WAD - y * weight) / (WAD - weight) - assembly { - z := sub(WAD, weight) // Temporary assignment to save gas. - - if or( - gt(weight, WAD), - or( - mul(weight, gt(y, div(MAX_UINT256_MINUS_HALF_WAD, weight))), - mul(z, gt(x, div(sub(MAX_UINT256_MINUS_HALF_WAD, mul(y, weight)), z))) - ) - ) { revert(0, 0) } - - z := div(add(add(mul(x, z), mul(y, weight)), HALF_WAD), WAD) - } - } - - /// @notice Computes the ray-based weighted average (x * (1 - weight) + y * weight), rounded half up. - /// @param x The first value, with a weight of 1 - weight. - /// @param y The second value, with a weight of weight. - /// @param weight The weight of y, and complement of the weight of x (in ray). - /// @return z The result of the ray-based weighted average. - function rayWeightedAvg(uint256 x, uint256 y, uint256 weight) internal pure returns (uint256 z) { - // 1. Underflow if - // weight > RAY - // 2. Overflow if - // y * weight + HALF_RAY > type(uint256).max - // <=> weight > 0 and y > (type(uint256).max - HALF_RAY) / weight - // 3. Overflow if - // x * (RAY - weight) + y * weight + HALF_RAY > type(uint256).max - // <=> x * (RAY - weight) > type(uint256).max - HALF_RAY - y * weight - // <=> RAY > weight and x > (type(uint256).max - HALF_RAY - y * weight) / (RAY - weight) - assembly { - z := sub(RAY, weight) // Temporary assignment to save gas. - - if or( - gt(weight, RAY), - or( - mul(weight, gt(y, div(MAX_UINT256_MINUS_HALF_RAY, weight))), - mul(z, gt(x, div(sub(MAX_UINT256_MINUS_HALF_RAY, mul(y, weight)), z))) - ) - ) { revert(0, 0) } - - z := div(add(add(mul(x, z), mul(y, weight)), HALF_RAY), RAY) - } - } -} diff --git a/lib/morpho-utils/test/TestCompoundMath.sol b/lib/morpho-utils/test/TestCompoundMath.sol deleted file mode 100644 index 6140ce8..0000000 --- a/lib/morpho-utils/test/TestCompoundMath.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {CompoundMathMock} from "./mocks/CompoundMathMock.sol"; -import {CompoundMathRef} from "./references/CompoundMathRef.sol"; -import "forge-std/Test.sol"; - -contract TestCompoundMath is Test { - CompoundMathMock mock; - CompoundMathRef ref; - - function setUp() public { - mock = new CompoundMathMock(); - ref = new CompoundMathRef(); - } - - /// TESTS /// - - function testMul(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= type(uint256).max / y); - - assertEq(mock.mul(x, y), ref.mul(x, y)); - } - - function testMulOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > type(uint256).max / y); - - vm.expectRevert(); - mock.mul(x, y); - } - - function testDiv(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= type(uint256).max / 1e36); - - assertEq(mock.div(x, y), ref.div(x, y)); - } - - function testDivOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > type(uint256).max / 1e18); - - vm.expectRevert(); - mock.div(x, y); - } - - function testDivByZero(uint256 x) public { - vm.expectRevert(); - mock.div(x, 0); - } -} diff --git a/lib/morpho-utils/test/TestDelegateCall.sol b/lib/morpho-utils/test/TestDelegateCall.sol deleted file mode 100644 index c715223..0000000 --- a/lib/morpho-utils/test/TestDelegateCall.sol +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import "forge-std/Vm.sol"; -import "forge-std/Test.sol"; -import "src/DelegateCall.sol"; -import "openzeppelin-contracts/utils/Address.sol"; - -contract Caller { - using DelegateCall for address; - - address public immutable called; - uint256 public x = 2; - - constructor(address _called) { - called = _called; - } - - function delegateCall(bytes4 _selector) external returns (uint256) { - bytes memory data = called.functionDelegateCall(abi.encodeWithSelector(_selector, "")); - return abi.decode(data, (uint256)); - } - - function delegateCallAndReturnMemoryAndPointer(bytes4 _selector) external returns (bytes memory, bytes32) { - bytes memory allMem; - bytes32 ptr; - assembly { - ptr := mload(0x40) - // We write a slot in the memory before the call. - mstore(ptr, 0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) - mstore(0x40, add(ptr, 0x20)) - } - - called.functionDelegateCall(abi.encodeWithSelector(_selector, "")); - - assembly { - ptr := mload(0x40) - // We write a slot in the memory after the call. - mstore(ptr, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) - mstore(0x40, add(ptr, 0x20)) - } - // We store the memory in allMem. - assembly { - ptr := mload(0x40) - allMem := 0x00 - mstore(allMem, mload(0x40)) - } - - return (allMem, ptr); - } -} - -contract CallerRef { - using Address for address; - - error LowLevelDelegateCallFailed(); - - address public immutable called; - uint256 public x = 2; - - constructor(address _called) { - called = _called; - } - - function delegateCall(bytes4 _selector) external returns (uint256) { - bytes memory data = called.functionDelegateCall(abi.encodeWithSelector(_selector, "")); - return abi.decode(data, (uint256)); - } - - function targetDelegateCallBehaviour(address _target, bytes memory _data) internal returns (bytes memory) { - (bool success, bytes memory returndata) = _target.delegatecall(_data); - if (success) { - return returndata; - } else { - // Look for revert reason and bubble it up if present. - if (returndata.length > 0) { - // The easiest way to bubble the revert reason is using memory via assembly. - assembly { - revert(add(32, returndata), mload(returndata)) - } - } else { - revert LowLevelDelegateCallFailed(); - } - } - } - - function targetDelegateCallBehaviourAndReturnMemoryAndPointer(bytes4 _selector) - external - returns (bytes memory, bytes32) - { - bytes memory allMem; - bytes32 ptr; - assembly { - ptr := mload(0x40) - mstore(ptr, 0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) - mstore(0x40, add(ptr, 0x20)) - } - - targetDelegateCallBehaviour(address(called), abi.encodeWithSelector(_selector, "")); - - assembly { - ptr := mload(0x40) - mstore(ptr, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) - mstore(0x40, add(ptr, 0x20)) - } - - assembly { - ptr := mload(0x40) - allMem := 0x00 - mstore(allMem, mload(0x40)) - } - - return (allMem, ptr); - } -} - -contract Called { - uint256 public x; - - error DelegateCallError(); - - function number() external view returns (uint256) { - return x; - } - - function returnBytes32() external pure returns (bytes32) { - return "33333333333333333333333333333333"; - } - - function return40Bytes() external pure returns (bytes memory) { - return "3333333333333333333333333333333333333333"; - } - - function return32Bytes() external pure returns (bytes memory) { - return "33333333333333333333333333333333"; - } - - function revertWithoutError() external pure { - revert(); - } - - function revertWithError() external pure { - require(false, "delegatecall-error"); - } - - function revertWithCustomError() external pure { - revert DelegateCallError(); - } -} - -contract TestDelegateCall is Test { - Called called; - Caller caller; - CallerRef callerRef; - - function setUp() public { - called = new Called(); - caller = new Caller(address(called)); - callerRef = new CallerRef(address(called)); - } - - /// TESTS /// - - function testDelegateCall() public { - assertEq(caller.delegateCall(Called.number.selector), caller.x()); - } - - function testRevertWithoutError() public { - vm.expectRevert(abi.encodeWithSelector(DelegateCall.LowLevelDelegateCallFailed.selector)); - caller.delegateCall(Called.revertWithoutError.selector); - } - - function testRevertWithError() public { - vm.expectRevert("delegatecall-error"); - caller.delegateCall(Called.revertWithError.selector); - } - - function testRevertWithCustomError() public { - vm.expectRevert(abi.encodeWithSelector(Called.DelegateCallError.selector)); - caller.delegateCall(Called.revertWithCustomError.selector); - } - - function testMemoryUncorruptedWithRef() public { - // This test makes sure that the delegateCall function of our library acts on the memory in the exact same way - // as a targetBehaviour function corresponding to the desired behavior. - bytes memory memoryReturned; - bytes32 pointerReturned; - bytes memory memoryReturnedRef; - bytes32 pointerReturnedRef; - - (memoryReturned, pointerReturned) = caller.delegateCallAndReturnMemoryAndPointer(Called.number.selector); - (memoryReturnedRef, pointerReturnedRef) = - callerRef.targetDelegateCallBehaviourAndReturnMemoryAndPointer(Called.number.selector); - assert(keccak256(memoryReturned) == keccak256(memoryReturnedRef)); - assert(pointerReturned == pointerReturnedRef); - - (memoryReturned, pointerReturned) = caller.delegateCallAndReturnMemoryAndPointer(Called.return40Bytes.selector); - (memoryReturnedRef, pointerReturnedRef) = - callerRef.targetDelegateCallBehaviourAndReturnMemoryAndPointer(Called.return40Bytes.selector); - assert(keccak256(memoryReturned) == keccak256(memoryReturnedRef)); - assert(pointerReturned == pointerReturnedRef); - - (memoryReturned, pointerReturned) = caller.delegateCallAndReturnMemoryAndPointer(Called.return32Bytes.selector); - (memoryReturnedRef, pointerReturnedRef) = - callerRef.targetDelegateCallBehaviourAndReturnMemoryAndPointer(Called.return32Bytes.selector); - assert(keccak256(memoryReturned) == keccak256(memoryReturnedRef)); - assert(pointerReturned == pointerReturnedRef); - - (memoryReturned, pointerReturned) = caller.delegateCallAndReturnMemoryAndPointer(Called.returnBytes32.selector); - (memoryReturnedRef, pointerReturnedRef) = - callerRef.targetDelegateCallBehaviourAndReturnMemoryAndPointer(Called.returnBytes32.selector); - assert(keccak256(memoryReturned) == keccak256(memoryReturnedRef)); - assert(pointerReturned == pointerReturnedRef); - } - - /// GAS COMPARISONS /// - - function testGasDelegateCall() public { - caller.delegateCall(Called.number.selector); - callerRef.delegateCall(Called.number.selector); - } -} diff --git a/lib/morpho-utils/test/TestMath.sol b/lib/morpho-utils/test/TestMath.sol deleted file mode 100644 index a86b504..0000000 --- a/lib/morpho-utils/test/TestMath.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {MathMock} from "./mocks/MathMock.sol"; -import {MathRef} from "./references/MathRef.sol"; -import "forge-std/Test.sol"; - -contract TestMath is Test { - MathMock mock; - MathRef ref; - - function setUp() public { - mock = new MathMock(); - ref = new MathRef(); - } - - /// TESTS /// - - function testMin(uint256 x, uint256 y) public { - assertEq(mock.min(x, y), ref.min(x, y)); - } - - function testMax(uint256 x, uint256 y) public { - assertEq(mock.max(x, y), ref.max(x, y)); - } - - function testSafeSub(uint256 x, uint256 y) public { - assertEq(mock.zeroFloorSub(x, y), ref.zeroFloorSub(x, y)); - } - - function testDivUp(uint256 x, uint256 y) public { - vm.assume(y > 0 && x < type(uint256).max - (y - 1)); - - assertEq(mock.divUp(x, y), ref.divUp(x, y)); - } - - function testDivUpByZero(uint256 x) public { - vm.expectRevert(); - mock.divUp(x, 0); - } - - function testDivUpNumSmaller(uint256 x, uint256 y) public { - vm.assume(x > 0 && x < y); - assertEq(mock.divUp(x, y), 1); - } - - function testDivUpNumDivisible(uint256 x, uint256 y) public { - vm.assume(y > 0 && x % y == 0); - assertEq(mock.divUp(x, y), x / y); - } - - function testDivUpNumNotDivisible(uint256 x, uint256 y) public { - vm.assume(y > 0 && x % y != 0); - assertEq(mock.divUp(x, y), x / y + 1); - } - - function testLog2CompareNaive(uint256 x) public { - assertEq(mock.log2(x), ref.log2Naive(x)); - } - - function testLog2CompareDicho(uint256 x) public { - assertEq(mock.log2(x), ref.log2Dichotomy(x)); - } -} diff --git a/lib/morpho-utils/test/TestPercentageMath.sol b/lib/morpho-utils/test/TestPercentageMath.sol deleted file mode 100644 index b94fa74..0000000 --- a/lib/morpho-utils/test/TestPercentageMath.sol +++ /dev/null @@ -1,225 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {PercentageMathMock} from "./mocks/PercentageMathMock.sol"; -import {PercentageMathRef} from "./references/PercentageMathRef.sol"; -import "forge-std/Test.sol"; - -contract TestPercentageMath is Test { - uint256 internal constant PERCENTAGE_FACTOR = 100_00; - uint256 internal constant HALF_PERCENTAGE_FACTOR = 50_00; - - PercentageMathMock mock; - PercentageMathRef ref; - - function setUp() public { - mock = new PercentageMathMock(); - ref = new PercentageMathRef(); - } - - /// TESTS /// - - function testPercentAdd(uint256 x, uint256 p) public { - vm.assume(p <= type(uint256).max - PERCENTAGE_FACTOR); - vm.assume(x <= type(uint256).max / (PERCENTAGE_FACTOR + p)); - - assertEq(mock.percentAdd(x, p), ref.percentAdd(x, p)); - } - - function testPercentAddZero(uint256 x) public { - vm.assume(x <= type(uint256).max / PERCENTAGE_FACTOR); - - assertEq(mock.percentAdd(x, 0), x); - } - - function testPercentAddOverflow(uint256 x, uint256 p) public { - vm.assume(p > type(uint256).max - PERCENTAGE_FACTOR); - - vm.expectRevert(); - mock.percentAdd(x, p); - } - - function testPercentSub(uint256 x, uint256 p) public { - vm.assume(p <= PERCENTAGE_FACTOR); - vm.assume(p == PERCENTAGE_FACTOR || x <= type(uint256).max / (PERCENTAGE_FACTOR - p)); - - assertEq(mock.percentSub(x, p), ref.percentSub(x, p)); - } - - function testPercentSubZero(uint256 x) public { - vm.assume(x <= type(uint256).max / PERCENTAGE_FACTOR); - - assertEq(mock.percentSub(x, 0), x); - } - - function testPercentSubMax(uint256 x) public { - assertEq(mock.percentSub(x, PERCENTAGE_FACTOR), 0); - } - - function testPercentSubUnderflow(uint256 x, uint256 p) public { - vm.assume(p > PERCENTAGE_FACTOR); - - vm.expectRevert(); - mock.percentSub(x, p); - } - - function testPercentSubOverflow(uint256 x, uint256 p) public { - vm.assume(p <= PERCENTAGE_FACTOR); - vm.assume(p != PERCENTAGE_FACTOR && x > type(uint256).max / (PERCENTAGE_FACTOR - p)); - - vm.expectRevert(); - mock.percentSub(x, p); - } - - function testPercentMul(uint256 x, uint256 p) public { - vm.assume(p == 0 || x <= (type(uint256).max - HALF_PERCENTAGE_FACTOR) / p); - - assertEq(mock.percentMul(x, p), ref.percentMul(x, p)); - } - - function testPercentMulOverflow(uint256 x, uint256 p) public { - vm.assume(p > 0 && x > (type(uint256).max - HALF_PERCENTAGE_FACTOR) / p); - - vm.expectRevert(); - mock.percentMul(x, p); - } - - function testPercentMulDown() public { - assertEq(mock.percentMulDown(PERCENTAGE_FACTOR - 1, PERCENTAGE_FACTOR - 1), PERCENTAGE_FACTOR - 2); - } - - function testPercentMulDownRef(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= type(uint256).max / y); - - assertEq(mock.percentMulDown(x, y), ref.percentMulDown(x, y)); - } - - function testPercentMulDownOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > type(uint256).max / y); - - vm.expectRevert(); - mock.percentMulDown(x, y); - } - - function testPercentMulUp() public { - assertEq(mock.percentMulUp(PERCENTAGE_FACTOR - 1, PERCENTAGE_FACTOR - 1), PERCENTAGE_FACTOR - 1); - } - - function testPercentMulUpRef(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= (type(uint256).max - PERCENTAGE_FACTOR - 1) / y); - - assertEq(mock.percentMulUp(x, y), ref.percentMulUp(x, y)); - } - - function testPercentMulUpOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > (type(uint256).max - PERCENTAGE_FACTOR - 1) / y); - - vm.expectRevert(); - mock.percentMulUp(x, y); - } - - function testPercentDiv(uint256 x, uint256 p) public { - vm.assume(p > 0 && x <= (type(uint256).max - p / 2) / PERCENTAGE_FACTOR); - - assertEq(mock.percentDiv(x, p), ref.percentDiv(x, p)); - } - - function testPercentDivOverflow(uint256 x, uint256 p) public { - vm.assume(x > (type(uint256).max - p / 2) / PERCENTAGE_FACTOR); - - vm.expectRevert(); - mock.percentDiv(x, p); - } - - function testPercentDivByZero(uint256 x) public { - vm.expectRevert(); - mock.percentDiv(x, 0); - } - - function testPercentDivDown() public { - assertEq(mock.percentDivDown(PERCENTAGE_FACTOR - 2, PERCENTAGE_FACTOR - 1), PERCENTAGE_FACTOR - 2); - } - - function testPercentDivDownRef(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= type(uint256).max / PERCENTAGE_FACTOR); - - assertEq(mock.percentDivDown(x, y), ref.percentDivDown(x, y)); - } - - function testPercentDivDownOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > type(uint256).max / PERCENTAGE_FACTOR); - - vm.expectRevert(); - mock.percentDivDown(x, y); - } - - function testPercentDivDownByZero(uint256 x) public { - vm.expectRevert(); - mock.percentDivDown(x, 0); - } - - function testPercentDivUp() public { - assertEq(mock.percentDivUp(PERCENTAGE_FACTOR - 2, PERCENTAGE_FACTOR - 1), PERCENTAGE_FACTOR - 1); - } - - function testPercentDivUpRef(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= (type(uint256).max - (y - 1)) / PERCENTAGE_FACTOR); - - assertEq(mock.percentDivUp(x, y), ref.percentDivUp(x, y)); - } - - function testPercentDivUpOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > (type(uint256).max - (y - 1)) / PERCENTAGE_FACTOR); - - vm.expectRevert(); - mock.percentDivUp(x, y); - } - - function testPercentDivUpByZero(uint256 x) public { - vm.expectRevert(); - mock.percentDivUp(x, 0); - } - - function testWeightedAvg(uint256 x, uint256 y, uint16 percentage) public { - vm.assume(percentage <= PERCENTAGE_FACTOR); - vm.assume(percentage == 0 || y <= (type(uint256).max - HALF_PERCENTAGE_FACTOR) / percentage); - vm.assume( - PERCENTAGE_FACTOR - percentage == 0 - || x <= (type(uint256).max - y * percentage - HALF_PERCENTAGE_FACTOR) / (PERCENTAGE_FACTOR - percentage) - ); - - assertEq(mock.weightedAvg(x, y, percentage), ref.weightedAvg(x, y, percentage)); - } - - function testWeightedAvgOverflow(uint256 x, uint256 y, uint256 percentage) public { - vm.assume(percentage <= PERCENTAGE_FACTOR); - vm.assume( - (percentage != 0 && y > (type(uint256).max - HALF_PERCENTAGE_FACTOR) / percentage) - || ( - (PERCENTAGE_FACTOR - percentage) != 0 - && x > (type(uint256).max - y * percentage - HALF_PERCENTAGE_FACTOR) / (PERCENTAGE_FACTOR - percentage) - ) - ); - - vm.expectRevert(); - mock.weightedAvg(x, y, percentage); - } - - function testWeightedAvgUnderflow(uint256 x, uint256 y, uint256 percentage) public { - vm.assume(percentage > PERCENTAGE_FACTOR); - - vm.expectRevert(); - mock.weightedAvg(x, y, percentage); - } - - function testWeightedAvgBounds(uint256 x, uint256 y) public { - vm.assume(x <= y); - vm.assume(y <= type(uint256).max - HALF_PERCENTAGE_FACTOR); - vm.assume(x <= (type(uint256).max - y - HALF_PERCENTAGE_FACTOR) / (PERCENTAGE_FACTOR - 1)); - - uint256 avg = mock.weightedAvg(x, y, 1); - - assertLe(x, avg); - assertLe(avg, y); - } -} diff --git a/lib/morpho-utils/test/TestWadRayMath.sol b/lib/morpho-utils/test/TestWadRayMath.sol deleted file mode 100644 index 4f30233..0000000 --- a/lib/morpho-utils/test/TestWadRayMath.sol +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {WadRayMathMock} from "./mocks/WadRayMathMock.sol"; -import {WadRayMathRef} from "./references/WadRayMathRef.sol"; -import "forge-std/Test.sol"; - -contract TestWadRayMath is Test { - uint256 internal constant WAD = 1e18; - uint256 internal constant HALF_WAD = WAD / 2; - uint256 internal constant WAD_MINUS_ONE = WAD - 1; - uint256 internal constant RAY = 1e27; - uint256 internal constant HALF_RAY = RAY / 2; - uint256 internal constant RAY_MINUS_ONE = RAY - 1; - uint256 internal constant RAY_WAD_RATIO = RAY / WAD; - uint256 internal constant HALF_RAY_WAD_RATIO = RAY_WAD_RATIO / 2; - uint256 internal constant MAX_UINT256_MINUS_HALF_WAD = type(uint256).max - HALF_WAD; - uint256 internal constant MAX_UINT256_MINUS_WAD_MINUS_ONE = type(uint256).max - WAD_MINUS_ONE; - uint256 internal constant MAX_UINT256_MINUS_HALF_RAY = type(uint256).max - HALF_RAY; - uint256 internal constant MAX_UINT256_MINUS_RAY_MINUS_ONE = type(uint256).max - RAY_MINUS_ONE; - - WadRayMathMock mock; - WadRayMathRef ref; - - function setUp() public { - mock = new WadRayMathMock(); - ref = new WadRayMathRef(); - } - - /// TESTS /// - - function testWadMulRef(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= MAX_UINT256_MINUS_HALF_WAD / y); - - assertEq(mock.wadMul(x, y), ref.wadMul(x, y)); - } - - function testWadMulOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > MAX_UINT256_MINUS_HALF_WAD / y); - - vm.expectRevert(); - mock.wadMul(x, y); - } - - function testWadMulDown() public { - assertEq(mock.wadMulDown(WAD - 1, WAD - 1), WAD - 2); - } - - function testWadMulDownRef(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= type(uint256).max / y); - - assertEq(mock.wadMulDown(x, y), ref.wadMulDown(x, y)); - } - - function testWadMulDownOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > type(uint256).max / y); - - vm.expectRevert(); - mock.wadMulDown(x, y); - } - - function testWadMulUp() public { - assertEq(mock.wadMulUp(WAD - 1, WAD - 1), WAD - 1); - } - - function testWadMulUpRef(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= (type(uint256).max - WAD - 1) / y); - - assertEq(mock.wadMulUp(x, y), ref.wadMulUp(x, y)); - } - - function testWadMulUpOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > (type(uint256).max - WAD - 1) / y); - - vm.expectRevert(); - mock.wadMulUp(x, y); - } - - function testWadDivRef(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= (type(uint256).max - y / 2) / WAD); - - assertEq(mock.wadDiv(x, y), ref.wadDiv(x, y)); - } - - function testWadDivOverflow(uint256 x, uint256 y) public { - vm.assume(x > (type(uint256).max - y / 2) / WAD); - - vm.expectRevert(); - mock.wadDiv(x, y); - } - - function testWadDivByZero(uint256 x) public { - vm.expectRevert(); - mock.wadDiv(x, 0); - } - - function testWadDivDown() public { - assertEq(mock.wadDivDown(WAD - 2, WAD - 1), WAD - 2); - } - - function testWadDivDownRef(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= type(uint256).max / WAD); - - assertEq(mock.wadDivDown(x, y), ref.wadDivDown(x, y)); - } - - function testWadDivDownOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > type(uint256).max / WAD); - - vm.expectRevert(); - mock.wadDivDown(x, y); - } - - function testWadDivDownByZero(uint256 x) public { - vm.expectRevert(); - mock.wadDivDown(x, 0); - } - - function testWadDivUp() public { - assertEq(mock.wadDivUp(WAD - 2, WAD - 1), WAD - 1); - } - - function testWadDivUpRef(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= (type(uint256).max - (y - 1)) / WAD); - - assertEq(mock.wadDivUp(x, y), ref.wadDivUp(x, y)); - } - - function testWadDivUpOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > (type(uint256).max - (y - 1)) / WAD); - - vm.expectRevert(); - mock.wadDivUp(x, y); - } - - function testWadDivUpByZero(uint256 x) public { - vm.expectRevert(); - mock.wadDivUp(x, 0); - } - - function testRayMulRef(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= MAX_UINT256_MINUS_HALF_RAY / y); - - assertEq(mock.rayMul(x, y), ref.rayMul(x, y)); - } - - function testRayMulOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > MAX_UINT256_MINUS_HALF_RAY / y); - - vm.expectRevert(); - mock.rayMul(x, y); - } - - function testRayMulDown() public { - assertEq(mock.rayMulDown(RAY - 1, RAY - 1), RAY - 2); - } - - function testRayMulDownRef(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= type(uint256).max / y); - - assertEq(mock.rayMulDown(x, y), ref.rayMulDown(x, y)); - } - - function testRayMulDownOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > type(uint256).max / y); - - vm.expectRevert(); - mock.rayMulDown(x, y); - } - - function testRayMulUp() public { - assertEq(mock.rayMulUp(RAY - 1, RAY - 1), RAY - 1); - } - - function testRayMulUpRef(uint256 x, uint256 y) public { - vm.assume(y == 0 || x <= (type(uint256).max - RAY - 1) / y); - - assertEq(mock.rayMulUp(x, y), ref.rayMulUp(x, y)); - } - - function testRayMulUpOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > (type(uint256).max - RAY - 1) / y); - - vm.expectRevert(); - mock.rayMulUp(x, y); - } - - function testRayDivRef(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= (type(uint256).max - y / 2) / RAY); - - assertEq(mock.rayDiv(x, y), ref.rayDiv(x, y)); - } - - function testRayDivOverflow(uint256 x, uint256 y) public { - vm.assume(x > (type(uint256).max - y / 2) / RAY); - - vm.expectRevert(); - mock.rayDiv(x, y); - } - - function testRayDivByZero(uint256 x) public { - vm.expectRevert(); - mock.rayDiv(x, 0); - } - - function testRayDivDown() public { - assertEq(mock.rayDivDown(RAY - 2, RAY - 1), RAY - 2); - } - - function testRayDivDownRef(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= type(uint256).max / RAY); - - assertEq(mock.rayDivDown(x, y), ref.rayDivDown(x, y)); - } - - function testRayDivDownOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > type(uint256).max / RAY); - - vm.expectRevert(); - mock.rayDivDown(x, y); - } - - function testRayDivDownByZero(uint256 x) public { - vm.expectRevert(); - mock.rayDivDown(x, 0); - } - - function testRayDivUp() public { - assertEq(mock.rayDivUp(RAY - 2, RAY - 1), RAY - 1); - } - - function testRayDivUpRef(uint256 x, uint256 y) public { - vm.assume(y > 0 && x <= (type(uint256).max - (y - 1)) / RAY); - - assertEq(mock.rayDivUp(x, y), ref.rayDivUp(x, y)); - } - - function testRayDivUpOverflow(uint256 x, uint256 y) public { - vm.assume(y > 0 && x > (type(uint256).max - (y - 1)) / RAY); - - vm.expectRevert(); - mock.rayDivUp(x, y); - } - - function testRayDivUpByZero(uint256 x) public { - vm.expectRevert(); - mock.rayDivUp(x, 0); - } - - function testRayToWad(uint256 x) public { - assertEq(mock.rayToWad(x), ref.rayToWad(x)); - } - - function testWadToRay(uint256 x) public { - vm.assume(x <= type(uint256).max / RAY_WAD_RATIO); - - assertEq(mock.wadToRay(x), ref.wadToRay(x)); - } - - function testWadToRayOverflow(uint256 x) public { - vm.assume(x > type(uint256).max / RAY_WAD_RATIO); - - vm.expectRevert(); - mock.wadToRay(x); - } - - function testWadWeightedAvg(uint256 x, uint256 y, uint16 weight) public { - vm.assume(weight <= WAD); - vm.assume(weight == 0 || y <= MAX_UINT256_MINUS_HALF_WAD / weight); - vm.assume(WAD - weight == 0 || x <= (type(uint256).max - y * weight - HALF_WAD) / (WAD - weight)); - - assertEq(mock.wadWeightedAvg(x, y, weight), ref.wadWeightedAvg(x, y, weight)); - } - - function testWadWeightedAvgOverflow(uint256 x, uint256 y, uint256 weight) public { - vm.assume(weight <= WAD); - vm.assume( - (weight != 0 && y > MAX_UINT256_MINUS_HALF_WAD / weight) - || ((WAD - weight) != 0 && x > (type(uint256).max - y * weight - HALF_WAD) / (WAD - weight)) - ); - - vm.expectRevert(); - mock.wadWeightedAvg(x, y, weight); - } - - function testWadWeightedAvgUnderflow(uint256 x, uint256 y, uint256 weight) public { - vm.assume(weight > WAD); - - vm.expectRevert(); - mock.wadWeightedAvg(x, y, weight); - } - - function testWadWeightedAvgBounds(uint256 x, uint256 y) public { - vm.assume(x <= y); - vm.assume(y <= type(uint256).max - HALF_WAD); - vm.assume(x <= (type(uint256).max - y - HALF_WAD) / (WAD - 1)); - - uint256 avg = mock.wadWeightedAvg(x, y, 1); - - assertLe(x, avg); - assertLe(avg, y); - } - - function testRayWeightedAvg(uint256 x, uint256 y, uint16 weight) public { - vm.assume(weight <= RAY); - vm.assume(weight == 0 || y <= MAX_UINT256_MINUS_HALF_RAY / weight); - vm.assume(RAY - weight == 0 || x <= (type(uint256).max - y * weight - HALF_RAY) / (RAY - weight)); - - assertEq(mock.rayWeightedAvg(x, y, weight), ref.rayWeightedAvg(x, y, weight)); - } - - function testRayWeightedAvgOverflow(uint256 x, uint256 y, uint256 weight) public { - vm.assume(weight <= RAY); - vm.assume( - (weight != 0 && y > MAX_UINT256_MINUS_HALF_RAY / weight) - || ((RAY - weight) != 0 && x > (type(uint256).max - y * weight - HALF_RAY) / (RAY - weight)) - ); - - vm.expectRevert(); - mock.rayWeightedAvg(x, y, weight); - } - - function testRayWeightedAvgUnderflow(uint256 x, uint256 y, uint256 weight) public { - vm.assume(weight > RAY); - - vm.expectRevert(); - mock.rayWeightedAvg(x, y, weight); - } - - function testRayWeightedAvgBounds(uint256 x, uint256 y) public { - vm.assume(x <= y); - vm.assume(y <= type(uint256).max - HALF_RAY); - vm.assume(x <= (type(uint256).max - y - HALF_RAY) / (RAY - 1)); - - uint256 avg = mock.rayWeightedAvg(x, y, 1); - - assertLe(x, avg); - assertLe(avg, y); - } -} diff --git a/lib/morpho-utils/test/mocks/CompoundMathMock.sol b/lib/morpho-utils/test/mocks/CompoundMathMock.sol deleted file mode 100644 index 79bd745..0000000 --- a/lib/morpho-utils/test/mocks/CompoundMathMock.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {CompoundMath} from "src/math/CompoundMath.sol"; - -contract CompoundMathMock { - function mul(uint256 x, uint256 y) public pure returns (uint256) { - return CompoundMath.mul(x, y); - } - - function div(uint256 x, uint256 y) public pure returns (uint256) { - return CompoundMath.div(x, y); - } -} diff --git a/lib/morpho-utils/test/mocks/MathMock.sol b/lib/morpho-utils/test/mocks/MathMock.sol deleted file mode 100644 index 0cee086..0000000 --- a/lib/morpho-utils/test/mocks/MathMock.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {Math} from "src/math/Math.sol"; - -contract MathMock { - function min(uint256 x, uint256 y) public pure returns (uint256) { - return Math.min(x, y); - } - - function max(uint256 x, uint256 y) public pure returns (uint256) { - return Math.max(x, y); - } - - function zeroFloorSub(uint256 x, uint256 y) public pure returns (uint256) { - return Math.zeroFloorSub(x, y); - } - - function divUp(uint256 x, uint256 y) public pure returns (uint256) { - return Math.divUp(x, y); - } - - function log2(uint256 x) public pure returns (uint256) { - return Math.log2(x); - } -} diff --git a/lib/morpho-utils/test/mocks/PercentageMathMock.sol b/lib/morpho-utils/test/mocks/PercentageMathMock.sol deleted file mode 100644 index bb76b83..0000000 --- a/lib/morpho-utils/test/mocks/PercentageMathMock.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {PercentageMath} from "src/math/PercentageMath.sol"; - -contract PercentageMathMock { - function percentAdd(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentAdd(x, y); - } - - function percentSub(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentSub(x, y); - } - - function percentMul(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentMul(x, y); - } - - function percentMulDown(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentMulDown(x, y); - } - - function percentMulUp(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentMulUp(x, y); - } - - function percentDiv(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentDiv(x, y); - } - - function percentDivDown(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentDivDown(x, y); - } - - function percentDivUp(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentDivUp(x, y); - } - - function weightedAvg(uint256 x, uint256 y, uint256 percentage) public pure returns (uint256) { - return PercentageMath.weightedAvg(x, y, percentage); - } -} diff --git a/lib/morpho-utils/test/mocks/WadRayMathMock.sol b/lib/morpho-utils/test/mocks/WadRayMathMock.sol deleted file mode 100644 index 21cfe90..0000000 --- a/lib/morpho-utils/test/mocks/WadRayMathMock.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {WadRayMath} from "src/math/WadRayMath.sol"; - -contract WadRayMathMock { - function wadMul(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.wadMul(x, y); - } - - function wadMulDown(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.wadMulDown(x, y); - } - - function wadMulUp(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.wadMulUp(x, y); - } - - function wadDiv(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.wadDiv(x, y); - } - - function wadDivDown(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.wadDivDown(x, y); - } - - function wadDivUp(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.wadDivUp(x, y); - } - - function rayMul(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.rayMul(x, y); - } - - function rayMulDown(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.rayMulDown(x, y); - } - - function rayMulUp(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.rayMulUp(x, y); - } - - function rayDiv(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.rayDiv(x, y); - } - - function rayDivDown(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.rayDivDown(x, y); - } - - function rayDivUp(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.rayDivUp(x, y); - } - - function rayToWad(uint256 x) public pure returns (uint256) { - return WadRayMath.rayToWad(x); - } - - function wadToRay(uint256 x) public pure returns (uint256) { - return WadRayMath.wadToRay(x); - } - - function wadWeightedAvg(uint256 x, uint256 y, uint256 weight) public pure returns (uint256) { - return WadRayMath.wadWeightedAvg(x, y, weight); - } - - function rayWeightedAvg(uint256 x, uint256 y, uint256 weight) public pure returns (uint256) { - return WadRayMath.rayWeightedAvg(x, y, weight); - } -} diff --git a/lib/morpho-utils/test/references/CompoundMathRef.sol b/lib/morpho-utils/test/references/CompoundMathRef.sol deleted file mode 100644 index 3c2d437..0000000 --- a/lib/morpho-utils/test/references/CompoundMathRef.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -contract CompoundMathRef { - function mul(uint256 x, uint256 y) external pure returns (uint256) { - return (x * y) / 1e18; - } - - function div(uint256 x, uint256 y) external pure returns (uint256) { - return ((1e18 * x * 1e18) / y) / 1e18; - } -} diff --git a/lib/morpho-utils/test/references/MathRef.sol b/lib/morpho-utils/test/references/MathRef.sol deleted file mode 100644 index 0ed0b10..0000000 --- a/lib/morpho-utils/test/references/MathRef.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -contract MathRef { - function min(uint256 x, uint256 y) external pure returns (uint256) { - return x < y ? x : y; - } - - function max(uint256 x, uint256 y) external pure returns (uint256) { - return x > y ? x : y; - } - - function zeroFloorSub(uint256 x, uint256 y) external pure returns (uint256) { - return x > y ? x - y : 0; - } - - function divUp(uint256 x, uint256 y) external pure returns (uint256) { - return (x + y - 1) / y; - } - - function log2Naive(uint256 x) external pure returns (uint256) { - for (uint256 i = 255; i > 0; i--) { - if (x >= 2 ** i) return i; - } - return 0; - } - - function log2DichoBetween(uint256 x, uint256 start, uint256 end) internal pure returns (uint256) { - if (end - start <= 1) return start; - uint256 mid = (start + end) / 2; - if (x < 2 ** mid) return log2DichoBetween(x, start, mid); - else return log2DichoBetween(x, mid, end); - } - - function log2Dichotomy(uint256 x) external pure returns (uint256) { - return log2DichoBetween(x, 0, 256); - } -} diff --git a/lib/morpho-utils/test/references/PercentageMathRef.sol b/lib/morpho-utils/test/references/PercentageMathRef.sol deleted file mode 100644 index 85a564f..0000000 --- a/lib/morpho-utils/test/references/PercentageMathRef.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {PercentageMath} from "@aave/core-v3/contracts/protocol/libraries/math/PercentageMath.sol"; - -contract PercentageMathRef { - function percentAdd(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentMul(x, PercentageMath.PERCENTAGE_FACTOR + y); - } - - function percentSub(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentMul(x, PercentageMath.PERCENTAGE_FACTOR - y); - } - - function percentMul(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentMul(x, y); - } - - function percentMulDown(uint256 x, uint256 y) public pure returns (uint256) { - return (x * y) / PercentageMath.PERCENTAGE_FACTOR; - } - - function percentMulUp(uint256 x, uint256 y) public pure returns (uint256) { - return (x * y + PercentageMath.PERCENTAGE_FACTOR - 1) / PercentageMath.PERCENTAGE_FACTOR; - } - - function percentDiv(uint256 x, uint256 y) public pure returns (uint256) { - return PercentageMath.percentDiv(x, y); - } - - function percentDivDown(uint256 x, uint256 y) public pure returns (uint256) { - return (x * PercentageMath.PERCENTAGE_FACTOR) / y; - } - - function percentDivUp(uint256 x, uint256 y) public pure returns (uint256) { - return (x * PercentageMath.PERCENTAGE_FACTOR + y - 1) / y; - } - - function weightedAvg(uint256 x, uint256 y, uint256 percentage) public pure returns (uint256) { - return ( - x * (PercentageMath.PERCENTAGE_FACTOR - percentage) + y * percentage + PercentageMath.HALF_PERCENTAGE_FACTOR - ) / PercentageMath.PERCENTAGE_FACTOR; - } -} diff --git a/lib/morpho-utils/test/references/WadRayMathRef.sol b/lib/morpho-utils/test/references/WadRayMathRef.sol deleted file mode 100644 index 8fef256..0000000 --- a/lib/morpho-utils/test/references/WadRayMathRef.sol +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.0; - -import {WadRayMath} from "@aave/core-v3/contracts/protocol/libraries/math/WadRayMath.sol"; - -contract WadRayMathRef { - function wadMul(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.wadMul(x, y); - } - - function wadMulDown(uint256 x, uint256 y) public pure returns (uint256) { - return (x * y) / WadRayMath.WAD; - } - - function wadMulUp(uint256 x, uint256 y) public pure returns (uint256) { - return (x * y + WadRayMath.WAD - 1) / WadRayMath.WAD; - } - - function wadDiv(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.wadDiv(x, y); - } - - function wadDivDown(uint256 x, uint256 y) public pure returns (uint256) { - return (x * WadRayMath.WAD) / y; - } - - function wadDivUp(uint256 x, uint256 y) public pure returns (uint256) { - return (x * WadRayMath.WAD + y - 1) / y; - } - - function rayMul(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.rayMul(x, y); - } - - function rayMulDown(uint256 x, uint256 y) public pure returns (uint256) { - return (x * y) / WadRayMath.RAY; - } - - function rayMulUp(uint256 x, uint256 y) public pure returns (uint256) { - return (x * y + WadRayMath.RAY - 1) / WadRayMath.RAY; - } - - function rayDiv(uint256 x, uint256 y) public pure returns (uint256) { - return WadRayMath.rayDiv(x, y); - } - - function rayDivDown(uint256 x, uint256 y) public pure returns (uint256) { - return (x * WadRayMath.RAY) / y; - } - - function rayDivUp(uint256 x, uint256 y) public pure returns (uint256) { - return (x * WadRayMath.RAY + y - 1) / y; - } - - function rayToWad(uint256 x) public pure returns (uint256) { - return WadRayMath.rayToWad(x); - } - - function wadToRay(uint256 x) public pure returns (uint256) { - return WadRayMath.wadToRay(x); - } - - function wadWeightedAvg(uint256 x, uint256 y, uint256 weight) public pure returns (uint256) { - return (x * (WadRayMath.WAD - weight) + y * weight + WadRayMath.HALF_WAD) / WadRayMath.WAD; - } - - function rayWeightedAvg(uint256 x, uint256 y, uint256 weight) public pure returns (uint256) { - return (x * (WadRayMath.RAY - weight) + y * weight + WadRayMath.HALF_RAY) / WadRayMath.RAY; - } -} diff --git a/lib/morpho-utils/yarn.lock b/lib/morpho-utils/yarn.lock deleted file mode 100644 index 76458d5..0000000 --- a/lib/morpho-utils/yarn.lock +++ /dev/null @@ -1,496 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - -cli-truncate@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" - integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== - dependencies: - slice-ansi "^5.0.0" - string-width "^5.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colorette@^2.0.19: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== - -commander@^9.4.1: - version "9.4.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" - integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -execa@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20" - integrity sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^3.0.1" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.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" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -human-signals@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" - integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== - -husky@8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.2.tgz#5816a60db02650f1f22c8b69b928fd6bcd77a236" - integrity sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-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" - integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -lilconfig@2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== - -lint-staged@13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.1.0.tgz#d4c61aec939e789e489fa51987ec5207b50fd37e" - integrity sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ== - dependencies: - cli-truncate "^3.1.0" - colorette "^2.0.19" - commander "^9.4.1" - debug "^4.3.4" - execa "^6.1.0" - lilconfig "2.0.6" - listr2 "^5.0.5" - micromatch "^4.0.5" - normalize-path "^3.0.0" - object-inspect "^1.12.2" - pidtree "^0.6.0" - string-argv "^0.3.1" - yaml "^2.1.3" - -listr2@^5.0.5: - version "5.0.6" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.6.tgz#3c61153383869ffaad08a8908d63edfde481dff8" - integrity sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.19" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.5.7" - through "^2.3.8" - wrap-ansi "^7.0.0" - -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== - dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - -object-inspect@^1.12.2: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pidtree@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" - integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== - -prettier@2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.1.tgz#4e1fd11c34e2421bc1da9aea9bd8127cd0a35efc" - integrity sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg== - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rxjs@^7.5.7: - version "7.8.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== - dependencies: - tslib "^2.1.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.2, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^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" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.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" - integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== - dependencies: - ansi-styles "^6.0.0" - is-fullwidth-code-point "^4.0.0" - -string-argv@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" - integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - -through@^2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tslib@^2.1.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" - integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -yaml@^2.1.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.0.tgz#882c762992888b4144bffdec5745df340627fdd3" - integrity sha512-auf7Gi6QwO7HW//GA9seGvTXVGWl1CM/ADWh1+RxtXr6XOxnT65ovDl9fTi4e0monEyJxCHqDpF6QnFDXmJE4g== diff --git a/remappings.txt b/remappings.txt index 242f15d..ba124b4 100644 --- a/remappings.txt +++ b/remappings.txt @@ -3,10 +3,12 @@ @morpho-blue/=lib/morpho-blue/src/ @morpho-blue-test/=lib/morpho-blue/test/ -@openzeppelin/=lib/openzeppelin-contracts/ +@openzeppelin/=lib/openzeppelin-contracts/contracts/ @snippets/=src/ @solmate/=lib/morpho-blue/lib/solmate/src/ solmate/=lib/morpho-blue/lib/permit2/lib/solmate/ +@metamorpho/=lib/metamorpho/src/ +@metamorpho-test/=lib/metamorpho/test/forge/ \ No newline at end of file diff --git a/src/Snippets.sol b/src/blue/BlueSnippets.sol similarity index 99% rename from src/Snippets.sol rename to src/blue/BlueSnippets.sol index 6a253ef..87b43af 100644 --- a/src/Snippets.sol +++ b/src/blue/BlueSnippets.sol @@ -21,7 +21,7 @@ import {ORACLE_PRICE_SCALE} from "@morpho-blue/libraries/ConstantsLib.sol"; /// @author Morpho Labs /// @custom:contact security@morpho.org /// @notice The Morpho Snippets contract. -contract Snippets { +contract BlueSnippets { using MathLib for uint256; using MorphoLib for IMorpho; using MorphoBalancesLib for IMorpho; diff --git a/src/metamorpho/MetamorphoSnippets.sol b/src/metamorpho/MetamorphoSnippets.sol new file mode 100644 index 0000000..d225d92 --- /dev/null +++ b/src/metamorpho/MetamorphoSnippets.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import {IMetaMorpho} from "@metamorpho/interfaces/IMetaMorpho.sol"; +import {ConstantsLib} from "@metamorpho/libraries/ConstantsLib.sol"; + +import {MarketParamsLib} from "@morpho-blue/libraries/MarketParamsLib.sol"; +import {Id, IMorpho, Market, MarketParams} from "@morpho-blue/interfaces/IMorpho.sol"; +import {IrmMock} from "@metamorpho/mocks/IrmMock.sol"; +import {MorphoBalancesLib} from "@morpho-blue/libraries/periphery/MorphoBalancesLib.sol"; +import {MathLib, WAD} from "@morpho-blue/libraries/MathLib.sol"; + +import {Math} from "@openzeppelin/utils/math/Math.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract MetamorphoSnippets { + uint256 constant FEE = 0.2 ether; // 20% + + IMetaMorpho public immutable vault; + IMorpho public immutable morpho; + + using MathLib for uint256; + using Math for uint256; + using MarketParamsLib for MarketParams; + using MorphoBalancesLib for IMorpho; + + constructor(address vaultAddress, address morphoAddress) { + morpho = IMorpho(morphoAddress); + vault = IMetaMorpho(vaultAddress); + } + + // --- VIEW FUNCTIONS --- + + /// @dev note that it corresponds to when the fee was last accrued. + function totalDepositVault() public view returns (uint256 totalAssets) { + totalAssets = vault.lastTotalAssets(); + } + + /// @dev note that one can adapt the address in the call to the morpho contract + function vaultAmountInMarket(MarketParams memory marketParams) public view returns (uint256 vaultAmount) { + vaultAmount = morpho.expectedSupplyAssets(marketParams, address(vault)); + } + + function totalSharesUserVault(address user) public view returns (uint256 totalSharesUser) { + totalSharesUser = vault.balanceOf(user); + } + + function supplyQueueVault() public view returns (Id[] memory supplyQueueList) { + uint256 queueLength = vault.supplyQueueSize(); + supplyQueueList = new Id[](queueLength); + for (uint256 i; i < queueLength; ++i) { + supplyQueueList[i] = vault.supplyQueue(i); + } + return supplyQueueList; + } + + function withdrawQueueVault() public view returns (Id[] memory withdrawQueueList) { + uint256 queueLength = vault.withdrawQueueSize(); + withdrawQueueList = new Id[](queueLength); + for (uint256 i; i < queueLength; ++i) { + withdrawQueueList[i] = vault.withdrawQueue(i); + } + return withdrawQueueList; + } + + function capMarket(MarketParams memory marketParams) public view returns (uint192 cap) { + Id id = marketParams.id(); + (cap,) = vault.config(id); + } + + // TO TEST + function supplyAPRMarket(MarketParams memory marketParams, Market memory market) + public + view + returns (uint256 supplyRate) + { + (uint256 totalSupplyAssets,, uint256 totalBorrowAssets,) = morpho.expectedMarketBalances(marketParams); + + // Get the borrow rate + uint256 borrowRate = IrmMock(marketParams.irm).borrowRateView(marketParams, market); + + // Get the supply rate + uint256 utilization = totalBorrowAssets == 0 ? 0 : totalBorrowAssets.wDivUp(totalSupplyAssets); + + supplyRate = borrowRate.wMulDown(1 ether - market.fee).wMulDown(utilization); + } + + // TODO: edit comment + Test function + // same function as Morpho Blue Snippets + // a amount at 6%, B amount at 3 %: + // (a*6%) + (B*3%) / (a+b+ IDLE) + + function supplyAPRVault() public view returns (uint256 avgSupplyRate) { + uint256 ratio; + uint256 queueLength = vault.withdrawQueueSize(); + + // TODO: Verify that the idle liquidity is taken into account + uint256 totalAmount = totalDepositVault(); + + for (uint256 i; i < queueLength; ++i) { + Id idMarket = vault.withdrawQueue(i); + + // To change once the cantina-review branch is merged + (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv) = + (morpho.idToMarketParams(idMarket)); + + MarketParams memory marketParams = MarketParams(loanToken, collateralToken, oracle, irm, lltv); + Market memory market = morpho.market(idMarket); + + uint256 currentSupplyAPR = supplyAPRMarket(marketParams, market); + uint256 vaultAsset = vaultAmountInMarket(marketParams); + ratio += currentSupplyAPR.wMulDown(vaultAsset); + } + + avgSupplyRate = ratio.wDivUp(totalAmount); + } + + // --- MANAGING FUNCTIONS --- + + // deposit in the vault a nb of asset + function depositInVault(uint256 assets, address onBehalf) public returns (uint256 shares) { + shares = vault.deposit(assets, onBehalf); + } + + function withdrawFromVault(uint256 assets, address onBehalf) public returns (uint256 redeemed) { + address receiver = onBehalf; + redeemed = vault.withdraw(assets, receiver, onBehalf); + } + + function redeemAllFromVault(address receiver) public returns (uint256 redeemed) { + uint256 maxToRedeem = vault.maxRedeem(address(this)); + redeemed = vault.redeem(maxToRedeem, receiver, address(this)); + } + + // TODO: + // Reallocation example +} diff --git a/test/forge/TestIntegrationSnippets.sol b/test/forge/blue/TestBlueSnippets.sol similarity index 99% rename from test/forge/TestIntegrationSnippets.sol rename to test/forge/blue/TestBlueSnippets.sol index 5d854ec..bc70501 100644 --- a/test/forge/TestIntegrationSnippets.sol +++ b/test/forge/blue/TestBlueSnippets.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import {Id, IMorpho, MarketParams, Market} from "@morpho-blue/interfaces/IMorpho.sol"; -import {Snippets} from "@snippets/Snippets.sol"; +import {BlueSnippets} from "@snippets/blue/BlueSnippets.sol"; import {MorphoBalancesLib} from "@morpho-blue/libraries/periphery/MorphoBalancesLib.sol"; import {MarketParamsLib} from "@morpho-blue/libraries/MarketParamsLib.sol"; import {MorphoLib} from "@morpho-blue/libraries/periphery/MorphoLib.sol"; @@ -24,11 +24,11 @@ contract TestIntegrationSnippets is BaseTest { uint256 testNumber; - Snippets internal snippets; + BlueSnippets internal snippets; function setUp() public virtual override { super.setUp(); - snippets = new Snippets(address(morpho)); + snippets = new BlueSnippets(address(morpho)); testNumber = 42; } diff --git a/test/forge/metamorpho/TestMetamorphoSnippets.sol b/test/forge/metamorpho/TestMetamorphoSnippets.sol new file mode 100644 index 0000000..f194eb4 --- /dev/null +++ b/test/forge/metamorpho/TestMetamorphoSnippets.sol @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import {MetamorphoSnippets} from "@snippets/metamorpho/MetamorphoSnippets.sol"; +import "@metamorpho-test/helpers/IntegrationTest.sol"; +import "@morpho-blue/libraries/SharesMathLib.sol"; +import {SafeCast} from "@openzeppelin/utils/math/SafeCast.sol"; + +contract TestIntegrationSnippets is IntegrationTest { + MetamorphoSnippets internal snippets; + + using MorphoBalancesLib for IMorpho; + using MorphoLib for IMorpho; + using MathLib for uint256; + using Math for uint256; + using MarketParamsLib for MarketParams; + using SharesMathLib for uint256; + + function setUp() public virtual override { + super.setUp(); + snippets = new MetamorphoSnippets(address(vault), address(morpho)); + } + + function testTotalDepositVault(uint256 deposited) public { + uint256 firstDeposit = bound(deposited, MIN_TEST_ASSETS, MAX_TEST_ASSETS / 2); + uint256 secondDeposit = bound(deposited, MIN_TEST_ASSETS, MAX_TEST_ASSETS / 2); + + loanToken.setBalance(SUPPLIER, firstDeposit); + + vm.prank(SUPPLIER); + vault.deposit(firstDeposit, ONBEHALF); + + uint256 snippetTotalAsset = snippets.totalDepositVault(); + + assertEq(firstDeposit, snippetTotalAsset, "lastTotalAssets"); + + loanToken.setBalance(SUPPLIER, secondDeposit); + vm.prank(SUPPLIER); + vault.deposit(secondDeposit, ONBEHALF); + + uint256 snippetTotalAsset2 = snippets.totalDepositVault(); + + assertEq(firstDeposit + secondDeposit, snippetTotalAsset2, "lastTotalAssets2"); + } + + function testDeposit(uint256 assets) public { + _setCap(allMarkets[0], CAP); + assets = bound(assets, MIN_TEST_ASSETS, MAX_TEST_ASSETS); + + loanToken.setBalance(SUPPLIER, assets); + + vm.expectEmit(); + emit EventsLib.UpdateLastTotalAssets(vault.totalAssets() + assets); + vm.prank(SUPPLIER); + uint256 shares = vault.deposit(assets, ONBEHALF); + + assertGt(shares, 0, "shares"); + assertEq(vault.balanceOf(ONBEHALF), shares, "balanceOf(ONBEHALF)"); + assertEq(morpho.expectedSupplyBalance(allMarkets[0], address(vault)), assets, "expectedSupplyBalance(vault)"); + } + + function testVaultAmountInMarket(uint256 assets) public { + _setCap(allMarkets[0], CAP); + assets = bound(assets, MIN_TEST_ASSETS, MAX_TEST_ASSETS); + + loanToken.setBalance(SUPPLIER, assets); + + vm.prank(SUPPLIER); + uint256 shares = vault.deposit(assets, ONBEHALF); + + assertGt(shares, 0, "shares"); + assertEq(vault.balanceOf(ONBEHALF), shares, "balanceOf(ONBEHALF)"); + assertEq(morpho.expectedSupplyBalance(allMarkets[0], address(vault)), assets, "expectedSupplyBalance(vault)"); + + uint256 vaultAmount = snippets.vaultAmountInMarket(allMarkets[0]); + assertEq(assets, vaultAmount, "expectedSupplyBalance(vault)"); + } + + function testTotalSharesUserVault(uint256 deposited) public { + deposited = bound(deposited, MIN_TEST_ASSETS, MAX_TEST_ASSETS); + + loanToken.setBalance(SUPPLIER, deposited); + vm.prank(SUPPLIER); + uint256 shares = vault.deposit(deposited, ONBEHALF); + + assertEq(vault.balanceOf(ONBEHALF), shares, "balanceOf(ONBEHALF)"); + + uint256 snippetUserShares = snippets.totalSharesUserVault(ONBEHALF); + assertEq(shares, snippetUserShares, "UserShares"); + } + + function testSupplyQueueVault() public { + _setCaps(); + + assertEq(Id.unwrap(vault.supplyQueue(0)), Id.unwrap(allMarkets[0].id())); + assertEq(Id.unwrap(vault.supplyQueue(1)), Id.unwrap(allMarkets[1].id())); + assertEq(Id.unwrap(vault.supplyQueue(2)), Id.unwrap(allMarkets[2].id())); + + Id[] memory supplyQueue = new Id[](2); + supplyQueue[0] = allMarkets[1].id(); + supplyQueue[1] = allMarkets[2].id(); + + vm.prank(ALLOCATOR); + vault.setSupplyQueue(supplyQueue); + + Id[] memory supplyQueueList = snippets.supplyQueueVault(); + assertEq(Id.unwrap(vault.supplyQueue(0)), Id.unwrap(allMarkets[1].id())); + assertEq(Id.unwrap(vault.supplyQueue(1)), Id.unwrap(allMarkets[2].id())); + assertEq(Id.unwrap(supplyQueueList[0]), Id.unwrap(allMarkets[1].id())); + assertEq(Id.unwrap(supplyQueueList[1]), Id.unwrap(allMarkets[2].id())); + } + + function testWithdrawQueueVault() public { + _setCaps(); + + assertEq(Id.unwrap(vault.withdrawQueue(0)), Id.unwrap(allMarkets[0].id())); + assertEq(Id.unwrap(vault.withdrawQueue(1)), Id.unwrap(allMarkets[1].id())); + assertEq(Id.unwrap(vault.withdrawQueue(2)), Id.unwrap(allMarkets[2].id())); + + uint256[] memory indexes = new uint256[](3); + indexes[0] = 1; + indexes[1] = 2; + indexes[2] = 0; + + Id[] memory expectedWithdrawQueue = new Id[](3); + expectedWithdrawQueue[0] = allMarkets[1].id(); + expectedWithdrawQueue[1] = allMarkets[2].id(); + expectedWithdrawQueue[2] = allMarkets[0].id(); + + vm.prank(ALLOCATOR); + vault.sortWithdrawQueue(indexes); + + Id[] memory withdrawQueueList = snippets.withdrawQueueVault(); + assertEq(Id.unwrap(vault.withdrawQueue(0)), Id.unwrap(expectedWithdrawQueue[0])); + assertEq(Id.unwrap(vault.withdrawQueue(1)), Id.unwrap(expectedWithdrawQueue[1])); + assertEq(Id.unwrap(vault.withdrawQueue(2)), Id.unwrap(expectedWithdrawQueue[2])); + + assertEq(Id.unwrap(withdrawQueueList[0]), Id.unwrap(expectedWithdrawQueue[0])); + assertEq(Id.unwrap(withdrawQueueList[1]), Id.unwrap(expectedWithdrawQueue[1])); + } + + // OK + function testCapMarket(MarketParams memory marketParams) public { + Id idMarket = marketParams.id(); + (uint192 cap,) = vault.config(idMarket); + uint192 snippetCap = snippets.capMarket(marketParams); + assertEq(cap, snippetCap, "cap per market"); + } + + // OK + function testSubmitCapOverflow(uint256 seed, uint256 cap) public { + MarketParams memory marketParams = _randomMarketParams(seed); + cap = bound(cap, uint256(type(uint192).max) + 1, type(uint256).max); + + vm.prank(CURATOR); + vm.expectRevert(abi.encodeWithSelector(SafeCast.SafeCastOverflowedUintDowncast.selector, uint8(192), cap)); + vault.submitCap(marketParams, cap); + } + + // TODO Implement the TEST SUPPLY APR EQUAL 0 Function + // function testSupplyAPREqual0(MarketParams memory marketParams, Market memory market) public { + // vm.assume(market.totalBorrowAssets == 0); + // vm.assume(market.totalBorrowShares == 0); + // vm.assume(market.totalSupplyAssets > 100000); + // vm.assume(market.lastUpdate > 0); + // vm.assume(market.fee < 1 ether); + // vm.assume(market.totalSupplyAssets >= market.totalBorrowAssets); + + // (uint256 totalSupplyAssets,, uint256 totalBorrowAssets,) = morpho.expectedMarketBalances(marketParams); + // uint256 borrowTrue = irm.borrowRate(marketParams, market); + // uint256 utilization = totalBorrowAssets == 0 ? 0 : totalBorrowAssets.wDivUp(totalSupplyAssets); + + // uint256 supplyTrue = borrowTrue.wMulDown(1 ether - market.fee).wMulDown(utilization); + // uint256 supplyToTest = snippets.supplyAPRMarket(marketParams, market); + // assertEq(supplyTrue, 0, "Diff in snippets vs integration supplyAPR test"); + // assertEq(supplyToTest, 0, "Diff in snippets vs integration supplyAPR test"); + // } + + // TODO Implement the TEST SUPPLY APR Function + // function testSupplyAPRMarket(MarketParams memory marketParams, Market memory market) public { + // vm.assume(market.totalBorrowAssets > 0); + // vm.assume(market.fee < 1 ether); + // vm.assume(market.totalSupplyAssets >= market.totalBorrowAssets); + + // (uint256 totalSupplyAssets,, uint256 totalBorrowAssets,) = morpho.expectedMarketBalances(marketParams); + // uint256 borrowTrue = irm.borrowRate(marketParams, market); + // assertGt(borrowTrue, 0, "intermediary test"); + // uint256 utilization = totalBorrowAssets == 0 ? 0 : totalBorrowAssets.wDivUp(totalSupplyAssets); + // assertGt(utilization, 0, "intermediary test"); + // uint256 supplyTrue = borrowTrue.wMulDown(1 ether - market.fee).wMulDown(utilization); + // // assertGt(supplyTrue, 0, "intermediary test"); + // // uint256 supplyToTest = snippets.supplyAPRMarket(marketParams, market); + + // // assertEq(supplyTrue, supplyToTest, "Diff in snippets vs integration supplyAPR test"); + // } + + // TODO Implement the TEST SUPPLY APR Vault Function + + // MANAGING FUNCTION + + function testDepositInVault(uint256 assets) public { + assets = bound(assets, MIN_TEST_ASSETS, MAX_TEST_ASSETS); + + loanToken.setBalance(address(snippets), assets); + + vm.startPrank(address(snippets)); + loanToken.approve(address(morpho), type(uint256).max); + collateralToken.approve(address(morpho), type(uint256).max); + loanToken.approve(address(vault), type(uint256).max); + collateralToken.approve(address(vault), type(uint256).max); + vm.stopPrank(); + + uint256 shares = snippets.depositInVault(assets, address(snippets)); + + assertGt(shares, 0, "shares"); + assertEq(vault.balanceOf(address(snippets)), shares, "balanceOf(address(snippets))"); + } + + function testWithdrawFromVaultAmount(uint256 deposited, uint256 withdrawn) public { + deposited = bound(deposited, MIN_TEST_ASSETS, MAX_TEST_ASSETS); + withdrawn = bound(withdrawn, 0, deposited); + + loanToken.setBalance(address(snippets), deposited); + + vm.startPrank(address(snippets)); + loanToken.approve(address(morpho), type(uint256).max); + collateralToken.approve(address(morpho), type(uint256).max); + loanToken.approve(address(vault), type(uint256).max); + collateralToken.approve(address(vault), type(uint256).max); + + uint256 shares = vault.deposit(deposited, address(snippets)); + + uint256 redeemed = snippets.withdrawFromVault(withdrawn, address(snippets)); + vm.stopPrank(); + + assertEq(vault.balanceOf(address(snippets)), shares - redeemed, "balanceOf(address(snippets))"); + } + + function testWithdrawFromVaultAll(uint256 assets) public { + assets = bound(assets, MIN_TEST_ASSETS, MAX_TEST_ASSETS); + + loanToken.setBalance(address(snippets), assets); + + vm.startPrank(address(snippets)); + loanToken.approve(address(morpho), type(uint256).max); + collateralToken.approve(address(morpho), type(uint256).max); + loanToken.approve(address(vault), type(uint256).max); + collateralToken.approve(address(vault), type(uint256).max); + + uint256 minted = vault.deposit(assets, address(snippets)); + + assertEq(vault.maxWithdraw(address(snippets)), assets, "maxWithdraw(ONBEHALF)"); + + uint256 redeemed = snippets.withdrawFromVault(assets, address(snippets)); + vm.stopPrank(); + + assertEq(redeemed, minted, "shares"); + assertEq(vault.balanceOf(address(snippets)), 0, "balanceOf(address(snippets))"); + assertEq(loanToken.balanceOf(address(snippets)), assets, "loanToken.balanceOf(address(snippets))"); + assertEq(morpho.expectedSupplyBalance(allMarkets[0], address(vault)), 0, "expectedSupplyBalance(vault)"); + } + + function testRedeemAll(uint256 deposited) public { + deposited = bound(deposited, MIN_TEST_ASSETS, MAX_TEST_ASSETS); + + loanToken.setBalance(address(snippets), deposited); + vm.startPrank(address(snippets)); + loanToken.approve(address(morpho), type(uint256).max); + collateralToken.approve(address(morpho), type(uint256).max); + loanToken.approve(address(vault), type(uint256).max); + collateralToken.approve(address(vault), type(uint256).max); + + uint256 minted = vault.deposit(deposited, address(snippets)); + + assertEq(vault.maxRedeem(address(snippets)), minted, "maxRedeem(ONBEHALF)"); + + uint256 redeemed = snippets.redeemAllFromVault(address(snippets)); + + vm.stopPrank(); + assertEq(redeemed, deposited, "assets"); + assertEq(vault.balanceOf(address(snippets)), 0, "balanceOf(address(snippets))"); + assertEq(loanToken.balanceOf(address(snippets)), deposited, "loanToken.balanceOf(address(snippets))"); + assertEq(morpho.expectedSupplyBalance(allMarkets[0], address(vault)), 0, "expectedSupplyBalance(vault)"); + } + + function _setCaps() internal { + _setCap(allMarkets[0], CAP); + _setCap(allMarkets[1], CAP); + _setCap(allMarkets[2], CAP); + } +}

    {23QAMhgmDFwY9!) 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%0D)pvsh zCqn(*_atI8 z#I_8oQGW&sg0;?2UhI@LD4lI3+LJSxirLPiPabm^TT{pNj0>v2p?Aik?2Xc zQen{ec2m;=1KE`*)*85Z(V*Sb=BFxrl^C^)5;0e{X1r@pr5){40zH8hzht8{GQ<~O z8|>UcgLH#U+S>c44(`N}-uUldzI1c38$T{u(LSo#z&I?@zZ*`Ph7JXvL` zfh;5(FoGr(KLq(K14zV>f0q~xGMASG($6fw$V2P@OehKSTqgKr!@rgceYotXX=g>0 z`c!1nw<*(l1Z!2MblFGw97LVgOU(8J#% zS-et>+8;7w3+mLk7fM+NIxY&#syc0Exz@6Qn_1eDqs*?3y5xAPUlHXrf9O&*<;pgA zjJv_L5`X?ebuKTr0c}&6&zZ(Hpm~U(9wnec4LFn3GpD-j3qDO0m4YulY6U8S4Bx>} z-2;nOVk3>*z<)siZfnOL@)>%cMZsw*dSo)}78m>x&7pI9lvAz6!knq?eteF{TW<3- zd}gp8L3;c-4sycP;5R8M4P`%$_Hooj;LN!G?e~MF0|V&|Yj0X`(o^U6zCAaA)5_u+c#^UHHu2Q@gwT*mWn@@2;p9hM-dd%Y2YjZv&1{T&d-pk2CNjZ}yl zwI(9J^_2QGSYZ{Rd0K%AaJ@Zq=tZxrHSdfcLg4ifVX$M{w4Q#F-ge-$M&F}zsm>wy zvLH|eORdDsZbZg?nX<$52jKu$#o;#+)Or&rpJe`zQS!|bq)usa6~*;DKvV#RA=B_F z(gU2-x1?Kf`VrMjd+5Zc&uX9NPF2J47F$Mp-&=Ih)X$SGGLem|WJ0vYX=I=(uX#U< z04S#&S#S6BnT!(72+}T)8usDVKdW|{3i6n3Q!^9hD6!Mf@cJp4pFP(t$$?;uJ(qM3_+q1G05qHQo`SoQwa&Q~=d9JPNAP{qF)4?bln{(O7}+7(egn^ii-@Ml0*^H-&! zlOqKC`8xnzSEP5NEBiB1SfS$M{AZ$&(`tPXzuP!cvBHZcg?d<@`-E)e)DlF-e`A=W zniewZE46d`#HYIuH}?(m7nJf%?x1%rY>_v;jOZz^6nCNNnUt!dc#dk<>(h+eRY>Ma zOgbo!0WvuL1)Zy4_MfwuS!TkP5jHjYN3DGBkyr{H$8*y5@CxSFG-V)&dUks@TU};l z3G6#;Z2QUs$}f(-E2WqgoP6V@I#-tYSs(;S{MM)ym1OhPtSIc%QNWo)y@)8oe*@h< zQ8G7|8H>g*j@Y86F8@1~!RN|un<7XRnUQ+_y%z&2r*z+m?x&EWchxYVy5qx#`eQXI zh*xeX!EMf{ycah(pK+B&&S38mbZoRirvyDW_JBdA4A=FF zvnz50_J4Wp4f>$^E6ZIZ%0kB(T%97kbgZ4~eWZ8n()B{@DR9&&#~}lzPct44B1H;{ zTYpX~H|lC%YW$mdj_!0)Jr~cML;t)u%OCwPl0?b7lLxEU#5hm=Iys-({Jx!NnSjhI z%ek$w?Z@8T?H>Q6u>0W&#sX5xF6xW>){LO$%<*0 zYc5T(BwDed-PyB9PJi>4Rrw(zIP*Et%bFgG;w4_J*D+;5s$?sQ>5EU3w1*ZT7p2a9 z6%}OsFoTBFb%-B<-U@kZocXV_T^EbOJoA)FE67D!$Nk`A=d8qE8Vp&FclGB_biDb- zpzYWM6qBBTr1!t}Zfyda7n9m%ni1N?L$owe1*;x679D9ON(Mn_2Fj^_7PpWM22!crzL?BD<6>Z`+|>Y{fIlu~JskQ};{F6kIR zx;vzsp<7x&YAES0>7iRXhLrA>92%s#hwpcvd!Kv%p9jv_=j^rL^~O4#PT4|vD;ygj ziPK?moqvqjwykJ6NSs%FUPXYl6QFNe|Fe+~eL9!S0`Cl--+wDt*4zfHQe%?L*Rl1P zn^JT?0W*&1Cn7nXndyzMemv*@<24?)SoGmo$pjwLbSzMg%k}tGLGPZP9!D~;A5Q86 z+q$UW0JjGibzJ@vNrFJt=By|PpiG^ydD1el^%nNo z{j`7sj!A1N{8B*ezo0UzIWqy5t!+Tz$iE)P>(G&k_NzA1#0-_l+074z!mW)s{5=@%pNH`ucF-) zS8L<)@OcuYUgASPfHTEKjefTE=nQ?|WTpUJWAy@F(l3SR$<{!d)3nqvj41qXb#fOF zfs`j9R7K!Cjb?zo)0KeYLdP_50cUmGxF4I6Nd)=N0?*n}+K4h0Kx$SOm{A9AZ8rA& z^$o^Z_>iNI2YaPfnT8U`KK9vWAw9NycqCwkn74!2j+@7k31CQ-QZ}}a+bf3u7;ii} zH^Q<7K)2{A?@txL$(Xqz1(U1k0YVZb;EZi_0H3^$>)`nop10g~_e79yV zgfghVb}Ra&B8cN{%FuASudRwnm;y$0_I3a#U=N}FdXx8a$Rx2WQ!%!s+~VM=z4ZSe z?YDZ7@fs1aU#cN-qVbh0)j)rVSq+q{2uL<8)ixd9K_=25Vwk=>v}jvg=TB4+pa$^N zaqAG=aA?Ldrwm8vyOBQ~J^)N&kp*_I78pR|d$Z;J_(@4_Sx=qm6S#Y|)W_hvNlOO> zs3ZjVW{E=X@11U@2tBOZokUk}@!ZR&LZO`z*ax#E_h-&kMgZre$N%E4e+aNl`w9n2 zMj`Ic%x?E*DzsRCtXD{uEFZcJ#c5qyxxsAicU=+H^{jy24h6h${^B|c4?B(@nP#*{ zZ`wP;55|0mfX+TBsC6C?bErW&CzRP`Vn8)~(Fd?4`=@_}j+_wi)KUV;lYi^&kM|WG z?^^;WvtzXCxUzwZ0hmTW-QWlASm|AM-On;{<^0 zY_bv{9|e?siA=eTFlQSf=BeJnLPnTawTFj~lRaz{aOJz#>O9G?*_2vDu{<}i^+*)Z zQt4wVfN=uy=k(C&>n+5v*fe_XmDeXyVyABE~dzXDrlgAjPXfCsV|VS*>YMkr@#;rEef3~|jt zhbv>y{*ZdnN%x@7kxIawy|PI)K_ z>ctZ7?8~(N3DDq&+4uwh97!KxBYxVa1Uh3iNOuNIG(1rV^NX`McFsa|laN5~Vi(6q zCY|%~Zd}wWEHrwGxgg3lQlLXNl-2}8d|m$8u|7IJ?(C;RuflDBlLyF3Q{7z{{>T3U zGCD6;jkQ4!bgUr@C|DiM7>$L6M$^{0SF+=XcgwA#RT}&%pblri7{ElK)dlsInXRRz z207RoCI;PzCo<0h84ExiD$Gw2yizs^PD-lpS_HHS_u4?pjxC}+DSff~emFeoJsxZ@ z-o&<-nH~i2vw&5KK)U@XJ=4JVPIJsJP}L;ZY#*jueu4N`7)w^E0kCw!Q8pvdK#c_0 z5PpD_SZ?Q61r`Qxhj?=B0qee881VjCWh&s~_QPI5OmxEPFxh4joozy6@-*r6ba(tf z46qJ3e81W6(!TuA5@?ygOWy;vjVdQs`=e!XIacmTWm zf8m6V?|}U9pxEpx9s4^9$rZsiGd*Fk_`%aW^6c?o>qzafr2j>|8^)uD+iX*dFH9c+ zTm~vCF|Zb}FyC$?X}VbeWc&Gx2poV%Dh^i=TS5nTLVC_HebSzl?~WgN17$R22$V`*=Tgwn?QchlOx%U4B~Zrvnm_=d|7|x9fbC1c{@+z)6%ynOJHC-bIf6RCEQPFfj8eEtCt7L{12knT@H z*f5YZ#lSznna_u-1K1@db^{P#$y|V6A$oInc2?rI{6W7MS0naS)6(-L+$~6Yn-E}- zdyoEe+tSkVr`D~(&t&oKE1>;G;IhG| z)#6eQ*9%c8~^rTs_hl3bay2=zJpC6 zg?M>c75C*WsYL6%=i}%@f^uj$lY`&w@!{j`EMVB~D@g}Txld_0p$@1CI2QaAG_0Y@ zHsps|?XL@YHF~$*HH}Sngs+4v`JFpfT#beX?FI~1>4Vpiy!v88yY zDDWQ0$Vj9Oa{NKM!BUS^+{Ogz?Tc_A)8KkLFYtDm@#eG8zJ&6f-qq>l7D(e^d&#I# zHxvuN0e`*+QG*s>Px(_pFCalW$q0xe#}o=UUJcWJZOXuXa$lZ7ZkL2YLy@IEQa%@Y zK?Mj?>*6{(fGR4tkgWzZxm*TtuEK-@&q5J&Ki)9kbhZ8U;rKYuWj;e;yZsTNc$fbELh8cU z>2c$vxwR!5yeO{d0el_rcf0!5A08a{H**{piChzafGo{e#qA%ZEuo`J zY6&)y$V}QbzgjRVstPeNnzZtVg;;BVD}dN49Uusnefrb4N@gysQ>>;-@~;?$+YiZD zNcVz!Z!sD%ysiuV`>=s!Ng2XF>nX{7ioTVeP=-~3&OHDn$miMIV{hn(r-XqDJ~V!G z&&%sNH}KEYT*5=I#vRui{w}kslQo|VmiFe`cY5IubcPkK?*Xs3Q8=i_yL+IvR&Zl_ zK_hPu$^@`sL(nVVXW^S&p^Fcp#wD{Pf);j?J@%d31M9!MwH8@h{W42bQ@Z>!t;7LJ z#)KPi&##*PsRCTVDQ}j3kqK_@H+ueSDtR=|x%zx{db3sMsq(qB%`XW~M#?Vn;+HZ0 z&<83Y4p|IDDv@yC1c9(5i~&^M=I8A!iNi>irkB3QP1keu(udu0i|FWKZsj(nx%nDY zZBwNLq?!;WbJ$D+N#7~8$Y<2WpAM_v_S2*PmdQvD@kY-g&F_V9dX74WGWAJnqXbEh zTKR3%N9Vqao6Tu|!T(cozkL-uqy{P$#YR&EZgX-$ThcFjNZLg_EmnC zy<%4=g`Um1+tp^)7r!{hghVQe=T1QIYrxKi1?2w$NUZ{=p=>O!pm+axAClZD%=y|Q z=P|zMs`lsg1bhO1=3VWoxo{gZN=6E_Bp?tQ9QX@!P2otnzpH%sxNuRwEGR^mkS%Wy zBIBi)+!k&9lhmq6UiTw85B=BXxH8B&e_p-5w6+|&c#jC=u#!q-PMy7xn6I@TiT1`~ zfW}Z)xq?C{s~YPvL}EGS$^Jot?{m3)G)bntW}*!YE{NmT3D$v}`O$8Hm+x$rYRSjbJ6l3LRp{zaZd7yHYq~}%T_F0S#CvNz8oupG zjB0yh(UnU4S6E;HVH2BlN|E|6K$qm77-S}T;@Ez*_O(s9v_49QV@fjHQK{`cM&G#{ z>wd86ox&P?pWtzz-Flh(^lj6Sc8_}Q?BW8W_o5Kw$9#SeD32ZR)vu_=wxH!~PQjS7 zWRHuI>-uXs>j25ME>lgLOb8$NkoL7BI@5sZZjRH`c%MNyBB0G{=x(?0Od(QtNx<~8 zRbBML?QKsqS;W6g(p{@OYiJ~Rb&7=^>YQ|`<~-n8ahb$j0Dj|Q@d0o;tb1(0;rvZH zPRM-(eFV-b9J?%nr9%3j|J?0T{ddJj-&kmGWcl6SryPMiobuDjYGoP+m-XAUfrg1P zaz54+AjkpG1%OK+)lcgbZYYqCI`*Yy?Yo^?ie~k!0P8$PgziSUFF)xHP%#ou652#A zyqlU*LL=47=L+l=>80(|!8RSTe<*~|L$)fJe>=(!Op~SY+#~Gj-WbX71MEl#i zf9TOR$5%9QA?bL2V&ccTVx=oAD*DMQLz!I>WGD@^KLFRm1LUEv?mBS?KK`6!Ef*po z#XB|M&X=tOT^LtuTPUV&Sxp(|I(o`030Y1@5#vr7r{@^gPvsVQo75#3mtiCHB#q{T z57)mkhAoT3iO|f0HAhGMM-nBwK_y|Wuy1R>Tv5VPX8B^ZlkscS`ldTuYh|+4nSUnL zel;hmQ;t%rG(xLQIT)Ut!E`57Kc&bavBvz+Q2K_yRIO1bL)b{mflq;uWlwjg+P@^< zE@zI1w=l)3TwW=c4F1m#ba z;s$IB3e|3*N?z%g)5w@3GiTMofKYpN zYJ-T2H1`T?%RrV;x`Hn>MCFNWU6Yr^6x$>&)Qr~N&ljvmGr(muqn}f{PH(n-hh8M%S16moEB-`CP?9JRn6i}OU0E=q0w}v%&x7mL~WH9WzNG!weK7B>&>MWdL6sE zrK?^3l#;4jH)`h!b4%oUEaqii(_U9&ke!)N(GGItz9NSYx3lri&`++aoab-dJO(j+Y6D(ib_DWqT zcQ7KDHzi6-qZ#Bz<+t`Oi(u-D7QojOsrZXN(51UTUL%k5%3C=y4F3kcu{rnJ5M9(Oo2 zvZXV~YPHYDC267dlNi>VeCSugE(Ea@!Mvn$|oH^bKX~>28hXh@+$>S^| zip)C2u(rb~b=^${j13Qh53w3F$KdXj{g2BxMy4>R~_T9MU`Mlh$?vfGoQ%wX)--dj;= zaJz+5%2No$%%pPqViRUTIEtQ!Km8(r&(PFMroMf{uNu`4hnSa(k}zg$x95=ZD2?`OBq z9;GhkNqu<66^{Y;xt@~(g%w-3Q#T@!EX?8RRhEYlxvumY*H^K2)m-OP2cp0xhp*c< z;{t&t=|sTJMrSxLpNZ?`73>6jY?AdrZv3~L|LywX-L`a~Jmxmo9I=S&dH+Z_<9Da8 z>2lAy(w(N~deiBkS?#wuocI6^w`FeR6mMMOI=jHvV>eq6U?rlE^l4Xr)U+ifYRXQx zuZ<{+$mP;gz4Zz<&VG~Y+7QEo4Kzm6C}O_A5tsu^d}ur=%uv|vbyM_T*u->I{K^C4NB zB%sT_I_Y->fgE#yEV*egC{qh;>}0D~!!o?&=^)Ck3j-n7^7$+yG~e^-_62-*bmY*J&kq1 z_#3=1XON}dl288!GQ1MR>6FJV%*FG0VzU9^AUp2RgJB%HtDCNFV|2!pG+wWt^s zgi=-^r8-Im%M}h^8Q@7qp>-j3^7gu;2-D;8$yR}KL>*{8{-dIm*CD>6t73i;$uymn zM;GhlaPF$2&>z9p7CJpVG;^=ezL|d?ZY(@AMm`W=a{*4GCvM{#^>c|A6RwpYj^z8h z0g-ZN7gr~(HhmaKT~?WuLnMB+<;sNjN=}+dmEL7(bN*C^q$0ZY!#J@vbmsL855W)i z@-%D%y+v|_G2OuH25g(uohZ$Bp7=s5Yz$itJc=BQREn&2{%l7ugonDR*NxG}PE4f; zFINehRgP_`7%6Tu)C)e|V7hP}riE0_n(V3L`tss-+@CI#v*=AOM6sAuy<~lcvOo4L zj;qHq8}_eCu{izq+=m$&BRtV@*Y6q$5HcP3K5a3Y6YoMR?df>1#NT3|?a(?VS{WHg(~z-dWY*tb;E?qoaJE{+Tq-E16iQ5;aXzFkOMY`iT;qz}9v$*Pg%a?k-FP>lu#LCM|fp-g+Z zIPI?6oWAp1-gE^ii;L&LD~!=k+MDOOf=sl>k=6R2JlviOH4JxFGCOX)hjc^Hos}rs z@s|jktH!CN{33TxttVMmMPG0tE893Gmf3pL(tcRzX#Z~?P@u~FT|K_q=v%)&=?Q*2 z4Gj{Pb~YH3Gde`Cq5+Ee$;@Nu7RSitAS{E`Ugg1X;pgCKGMz*GN+zTc<`z}b;>E#0=2vKM?f`Gf(smPA(&|HH|jh!F-T`n zM1^1BGFiKk#^jbW*W2&jZ6pYTwOt5n+Y7cwSN@n?{Z~m@!L}zA0yC=+*#FhYILZ)el4?ZB~&G(6>`I?FZhYTvqVz~)dq|VvUr%3*OY9yq)%!WmH5oqz$VMu9 zP8jK+E2U4l2oz~Rs6mk)sW`ekrInJZji|N`Kl?+y33^K-Q<@Xhh)uZFWd-X+onv#^ z=P0nHHgMzHyljE<3h;)b?#T?58C$36;m!TH?9IhigRm3AXtea5RA;x1m`%xVSM?-k z+17~~3_Ss8?d0+i3w~2XXr=rP*GnaYzv%SrQSIJA&dOg0X44%*l}KnwT2Dcm-N0mE zkiLYAW`27em#XkVGX?~ZYgw)Kk9+x~uVvr3B)iAqR|p0GXrJ$agvn&#PiAQ4ONlDaLnU53)A@UU6UpB7Zf0-(89CNvZ4OJ!#=Vr*C*Ew`6$_BkkxlY z>n4=5z%_2w7rBWPpg`sb%S@815Uii;n@5G(vzSun)WjSvd3L&b+yGH+XVLSgwj>M1 z2omEBOXvbOA&IbFf8r5(Q&?t0v+sy9bEY3}n(s|d<&sqTCH?=bU)o5zzp|8;i!$VG zTy81v)?`&%X7jUHKAcxUF^`TP45i~^Xil>%(QYhTx{*o|<1 zesO&5dIuDaP z%lp>LFeFZZMGa+fTo!D7cx>2jzZoZNVzAChT5MzJ6zKdl?{~tva9?R-5VE9>_{#DT zB~h+uu0|UrPIo`Y{hjaT-_5+b)3#E~%4TFO@p~M3|U4?x*CUVc*%p1H};$ z()Ux}TXi!@?1Z$7?kn?2+~%BkuH7Sf(C2<@(T$sF9i_E3x7=3gO?5lKEziCuif38B z?pTj?ZS(M$ENI|u%#*eAYj<~dIKLW`2xqpOd{=Ra0L<+pz;M(|MApHA?^N3e87UcA zqD4qOZITAZn(_Xh#c{I-WhqUxQZgjU|IsTrYV z@%poQSU&x%)IT#~yw295;;?roG41$rsTe=zQ;7s)h>w#8{nxwHuBq!wdv4ZJ*b578 zC7+WVHxaf*Vf)x(kMBi8Hw>9PsW?`myk%6&J@sdrnMw0cxz| z%$l|*v4(u^BYZll2n;Pi0Aa7+(3*-PA$)oH=>4RGRCskNPy!RFjL$mn)*NDQa^XEMh9bm4pGBppX%RW*DU#7j9k z@sTP~-4KGb9t%I^>~Yzu(=0vMRku9#OZOlzte?jGb+w3hF|?WEjqPxcVXoRs|h z%Cwa21pE9sM43~RIbnbvG!R>IiYIYh^l)-qwA>U!UpM>RWS<2j-RD{W79IqzTy}}> zlKU;P80cr}sf?vr{xy`=?kfYU8aG0BzNAk%urcshV!9_y^a=|AbU5u&UiQt}hul|}(R~FYwNS{r zkw4UK)EZt>UlKp3)>j-lcYfxe)b7Slk?Ufu`TbND>B@(wWME+#lSeAZKLyv-k|^vyL4Oj+5)Yl<8|w2~ z@6wE*ZYo^os-^TL{L}odMPTUWw;&`9Gb_O1kPTLEh~vSPwvaKd1!%RyLq3j@IOB^t z@0W?2;l6(}b%6?US>Qm5o=V#_jvxFnM{1oSlX6dt6YcTH2f~`c<%F@A${ute_d4Zd z;%YMS1bM!ycR;YQOI#}hY@@;9#A}ohw(vXIZ;$?1xqC){3%Lco<$qtRqdJvt_>Nwb zTKILI8#VurWyLW{LrEL6?8Hrg3sa3E3gx|#ge3eT69Mn`;Uj=#9;FucG<1yi)e^x> zzI79;gUUBPBqi)60>|DU0>z3)p_?0_q8a9hs!{>W8KI+B=-9 zOarmr5j|9^Qin3!=N+;90xapO$z(v1hn}=P!41|FN`xVBq4bv@XKv|+=vw!L&IGa>{x2-`?fF}oDv9QZa4}`Y9QO>1kGy~R` zr+^^vZR)8WIYBpXD1UPy2D$50DRwumyKk>%%SVB9VNdBnk}8zZo%<^<5jR$oTBa4vOqp= zS6ANje#dkoU+GrfxHZ8U=LDNHzGSt}8%${vc|=G*v8W0eI6B(&$n?IEH43!~!Zps2 z`(_ZtQld~`Y(X%=fW3T8k4_~>87w;9cI~Xllq63)b8%a;$J}GORiM`f6-TWD|9t6U%YbVMK<%e`dzdv z_`9B2>3a?}8qdBN6;Ufzs-zex+{-lcFb(}}y`;E1d8YtGmxb*dJ+kr*uUPKdxz=iL z*|F*KVeK`Rs;v>?s@kE_ll*RX+un&hUNhI%DIdiT#a!@&PBI?Fhy^!9b<;Ycayi#Fdg1ZRR zZB^w|ehASiN7}Dq`mNbv#h8;6g6VJ8Z8FWro3x1n4qceHy{K`F5wc4&=tS!FHD%YT z%0BT;QG{rHgEfecPa8d8TYsyw^Eet;&DTSAI#9o?U7rhW9C z>@XL0R&*FybIadrqqtBMxVQUN{|8PvDusTj(Y3SjiL2bog`%-;Do>X0%PHetOS<}~ zIes`E%L}*{cgI3}pmy)ZMLaqBJ@F{g$kgZy-Dv&kv$y8)$HEKdOAqKbkoZ|xgE@#+ zeUz0qVyoutZ9QX#hX}4a(a0RH=|Tv8yJ-dxMec9(dFSoniF)7fa(xpb$U0*84${{s zIxrp$%$5S6YL&G@Z>ON9ZP)~EAVfQrJ)xUh zHN?yws=gjz9)EXQC2EB>`b0(|?rFbMj-*#+1u1J<8=9ZgCwqCR%#C^K@X9jM1l)Rt zbGnjRYjYeuI!x=0ORp%UCamYUQFMt}Xq(D~qZZZec8r@VmhsN0o9+M)9s>dPX3tHX zkeAi4)yieQi&r=Fcm3x)@FAJgbzGe2R=JIR_#e(!n%Dw3lE+_-9t=Ehy?>&w!FL)R zs|S+o-pe_vHq7_yc8?}E;`la=jLu4ozWvnA=5FtOzQv*06T^iF;c213z{1gV?No`R z8O0bPK5W7+R!Pe=;AcT73&HdtpsAYl57IxW2Y`=RZx(nv835>_ z^MGQ7;IA)$qF3e4ZysM(_|=St>G8JM@(lS zx}rR0lT7EI6C_`#XVXy-B#jdz@)xU$x!>iRn2&X%B8_d5S}sS|XTfQMlarsFe|92AAH+xD)^5usL74(7$b_~JVYsZ^SKHCj7>_Vpr50#Jh9#4*lL_m6bk+`{j zxt68Ll9a-Ial60w0eB_*r8QMwG=YXX@M3A$pqwj<)YnOqW)~aN|49C5e@bJjv0<-y z16P$cH>tO9Am!wjYNfk#&O)Bco_O{v$o*Qhk;y>PI23(O@Zz@#HF2>M zM&-M;MCdK}lpJQRh^ox>V(UAFl$Be3?QQc-*RCbA2GfemO)(3iJ)Tn91?cbxHlrD& z`f6__L(RZvd2^!jl#SSFM47c``gv`v#TUg#5)h9Wk^ouL;nY;V=e$mHw$86uSih-l zUwp>8Xm82DvDKE>N|R^gt4z3r!i|nuaJy}(|MdV4-S8 zi)9zcHsc`A(9iPwMA+|%W{;xJDcW4VJ6)wD6(bK06tZ-t$f!FwV5A+R4Uds)xz6)!r)sZ? z9ba*KqkJL5$6^122XHL3Jy&{BF8+tweK9g%aqtB)c7H!uXp<*@_$EV% zUhI;_S~>du0Zg{86Uq}>;nDcFd#hofhvkhe5S#{ro2UT43+xt^0A5p6?<%K2| zA8((Zh7?`P`-?GGC^v}(jBr2ZvBRX zqyJ6`*F5QLTN97<0sX&$+82JjTB5F74Na$WEX7$d=A1;A{#B6@G#% zxe4|%Hbf`f<9eG{0X#MRk$9$K(|6a*D}OGgc|MPB$s#UYe!UuSjhxrmnm3lhMgt=F zgiZ92Yn&U!=88q7F&izjo*e8p`bBPS0GpoNuogtV7pkqxf0hG#8)r5sd5&Ga4?$-L zsSjgW2v!q&2@kqMZpr* zfTSqq1vx)%Xmg}eBS{q<4Y_BWm#NUAvit*O%4`p$PKj5LEdHcM_fnV>?wj-aAcCTB zSZp<>GV^Ljz4JjFbk%xVf z!-<>d1c}J_;!4}^|we6MiNyat5eiu6i8?-t1qM_Hlwc$)mfMt5a=^Y5^ z3r#RoscuCABUBF!pkQ8O*)c~6_DNV$zlqqP827&M#$*p?sl z0$x~u0hobuUA4eVa@_{~!+SH0;tR&qFj1XJ-7$`j$yY3sy5E_N)jZ?^C(Q_E$Syel#{7i@0tt`pB{-v6p*8!YkjfRlRN6x{QC? zQGta1Cf|^a7?5nf=Sh$g$8MtJ=<|&dz=tn6_oaAx@FytS1IVQFp9m(2lLn{|U-Pf! z<(XmCs@AgP&{>`jX}R%<|pkj=I{aZrxxN}`DbiYYA zWLwofZV2Ix;KR%-W-M`j5FoP`R zKx{qk{r6nz*l9#2sV7ItspEb2<#DkmnILAJLZv;N`|k1Vw0+0)IM8??kLM(PSUp&5 z;(s2{|M%bD#r1S|bB{)49{V}@w9P5w3xEH}+&P3!gR(8>uXIOlF$YBPESjHDkU zPJo0Ul=`{IOJ>yJ@PIZ>f4*)XfBqNT!D2~y%UD8=cs^$@z-2T0kLxoAj|7vaJL_yr zsfewUe0q}LVA(d{#ZAFNbpndpGJ@ z@m$xE_?qnFhQ+m`>!Q+p`=N7T)vU?$QsPgsp!csu>71Zy`!y1gmvc_-!o0uMAYLva zb?skB@P55XD=Q_~+JfV~HRe>xn=ItiX-qOG7uri*8~VtL7T}glyS*aVY}$WWGQFM3 ztTL*1=t48VnvD}1fF)n@Y76MO!sQX!F|0~&GFtM20FAw@8gwuVOgX3op~InzOWu48 z@uT6j@(Fg~x5z0DbA!@5O!5_nROLv{sG?Asl^<#d)7Hi2Uo8b4zXo_N_P4!#oMUg; zm~bU{SZ6|b1?C4|w2L2?!;P({s*0b#qvSP)F?qRO(wJ`@xX=)?$ks4=@R5s?Xd|5n zli}y50uw>v?JRW|xxyQ4H>`rtxi$opb(;z!}wtW2i6k-qSjdN?-ACsh@One6p|*Iv{7*w_f<;o zi2uMPjQdb!x?q4yy4;?}ZE<-N_BG+9_HdzHz3itjWBI74ag+IJKU^v~Dn z)H+07?~^ASDpu;*+ySHbN$Bt1eN2S~%$qU*N(l=>D8|%UZn;bq74;|9bfKmS_DI94 z#LcyAh5EfY>5c5=-AVqx9WIFH7(pjrW*4z8t3E;;PU4KNpQY_L9;lwK$$J%Mno!i% zZ^BK4tcm!MX%_f#WdB==z)iyZjH7?0!jL0w+IF*@NxZL=#w{M?=q-T1TpUxusU^X7#($0L-W4QS~lOcp`SM`X@8Ut6Vr`kAM!2NV}bc6-) zO5TOz>d2QfV^T+e!KWTiDymq z^#57zz8l_8uLOFdIafV(-t8-tn;f6{v1A=g@`UCcCWP|G9&{7V&ru%kRwx>yXvGO2 zvF`rfBrFs9P&o7%Y}Rcd$;A7@EKiIKKjF4-Pi!O4Lzkzy`35P%wVU9knHdOdHHqsa zD}uhngDFsZF2w2;f2FIQid3T087GFgoNHJiUYo4qYtWs8)#VwlA|gWpw2 z((;&il-dsA{#X#36l|2;(}h-J8)X`%=Gt{7)h%zziQ2m+`3x|3K{Uzize(K}t;Mh& z?frxIDt(TEzAD6yOiI^CeCyu)hNJSi(rfP3!F&@jlH14Xe|GJ*By(+#k0z@E2$5wP zc6%LtUrYtkGMh zD<(mQSy?*$#(EZ!^(^X{-K>6jyoT!_V?uE7*5kEFaf^-^k0_PYJb`G=QWDZlWvhyp zK&B60CTqpvGwM0~I7%{!_^bd8_GyZM9cBDue%EYz+jbDkf4 zJG7cykXREEJ3ycPhs3D2K2UXsd~vuo2go zmCAVG>7bI#J9d#5O|nz%;0ldObm?=H_6?S>7^TN|Nm>6DCq5dP($8MaB1kG z0A0yF{3ID|Ea=Tt^YWmrQ{$~a3QDL7Avlfo)3Q2#Mws-;!Cay%I`r}c%S8&iZawiQ zZq8SoM%y&3H}Mvqa)=)TKR(RGWpDV2us_sy7k)F}75i-%7ZpRmbd^M|iu4U^h7-X0 z?T5fWEHMwug}`@n5NZvq`E#s+by3nQl%<@{Yb>BLa_or$P!2ns7b7+vf5x?kHh9H| zV&~D7riJQJzQ@N_LZPdRS_d5^MA5J^O7#^5dg4Vz`MB(=JcewUNU&ygTH|ZZZ!JTW z7u$rT9&ek2V$pvZCeuy5j~@D>gDP7ME0C4uE4Y*?OPnf3WO$;Ny414&ney0Ru3mS? z`-y_|Y0LrHf2dzv6XaCe_(>-QhZQZL+v3IG(X>bA^3wr37$|I@R{6E z4Tfhjn$Da9J$;`h z#QKfDl z8-H;6Px^8adWC)F=5$QN3P{X47 zd)XIjpd8v@a~*}hiD152KGBO63Pa9vnl#G++F`{Fb(wp)S)A69a>=gj z)9O%UQ%|3h@=rG1eU#+(m5B0#QWilkzNA;;0WmpWzXx#!d5eR(Rq@V5y>o)&a5KBlKsZz8jy64+h zt-HDr4dM0Fv$#IlcB`!{ z#Cr8V>ir>H0e7#!Du%d%L$9DXv-XNLNK>MvA~7Kos|{GXr>9-cWB8k2o7)^|hO~YM zSm1#2N@_%FFrt~*TY`tPpq0GELXh-@O_oZoj|EFvoN=kp+e(0X4f`SZ;RE|P`?xbd zPS#riwakP9q0Qp;s)M*#w$9)KE(>nf0!a`1#?wtlvqR~EHotGT)e~2-Q4&ulOxAX) z{x=6#JHi{S=Q2?0QcyK&AFN#ql|%&7Ms$L-JxgO;u-ZSdgI>-YY$iEiZflyy@%@rv z5EbW-TBBFp7olZ}@1DohTAjNBN+>VLBYOh7MV$w&dSRuw_?v3u-2uS05d^eJXb|KH zZoo8@xc}zg{y7g_Eaow`0Z*!1e0eE3NI^I^fR@mMg*g!S*r>T&`i!LGDt3gaW=c=I z^O9O?VcDZ5Mn~IIo#o(lJd!YKCHCV^UxFcJ7Oi_8Dkc#vfj^t62?yq%9QLT+Z^Ls) zfKRJs1RUeSwAZ-B=4W zwCK<(RzxLAu5hQ!^&>8aCh_}mo5qo4Ud;$T=3aqql1VzT?;D-d9L|6!3H5`L;^aKh z;(+6U*hjMWuPKe!%*>A)zO=F_>}QYi%V&(NKd>dEz+_-FY-z{m9wK@_!JqfC=x+$r z*VHcrrHFYqe--s%Xrzkgc^*Ylj=qYQ(;%; z+G=A*y;14vL(|D;?I5Siq7U}2#`X3<}$+C25aK|Dy`bQu!?V>Kdeix$NMP8@taeg^&XVaQ)rGr0Jr zA@0c9w-bSDUPu0G@hgH{+@3HaO$>^jQH|};Jdm^ z2-I1H7zvNBdMS}xF>i;@Q`XJ++x_N@b30ZXxa4xDk5lf)-UDEf<~VC6Pm-GPQXgnfVg9cQj|kaOqht?^5l_l)Orm< zG%H(1qr=aIG>ZxO>8WcV9jKd~mtilM3CQJFNEsi3i*2am0qpu}5g|`lH8Y-9U0v%@ zjg)bT8}&96CmUc<60eI3F}sC~eF0}08q#X;t43+I zm|r$Y^3ckK*|E7CBePY($td_A|M!>2$^vQp#?b-Fo4p<_v~{Sz-5Sc*!W=0=lZBXE zU}z1>d(b3*3Q!|-M_yP!=+byb=~nO~LVa{Vt?$mA;P}e4U`wv6PF#?+O_ z3S>YR-(Oo9t;)#jiqULJ^Aw^RICuk}Rol!-+^E*;m!=KD#R-0_i_Fm~o@(l`tE!1@ z>?77oN33oo-T@7hTIJo*5^-#t-wDS{zsc+HT}!?;Hy8!hCsr8k(JD_0OXb%C^@{wD z-YH0SeQh_K$C^;k{OW+i3@y@PW(mkX;~u(VgK8!ucRD!kuonnoyI2J8PZC8fmD#cv zwv@i!T%$^pWy#o43ww^3W>)ahnn@M6(07A-^$u9i8iC>zMXKIO=C>5nKh{<+O3Wvx z&<*oq;OCA7j{dTauTI@ucl@(gV~sf&sp#1|s(2ED;Xm=6J96oG|B zTqv7|L!x6?=%?)P5qEiB`42K_{9CgZCVmki2`mCiCct-*$HHOHmY;!Ohp`XvgV>C;0}n(Z=gz(nZnkL@vIsybce+dea=P*icITf=v*sU<>V z5bD3DZ%-F2?w`H!tlDa3sXP2Vb{5mHPOX;wgbVGwVqkR*wYxvy0OX*@Z$hbXJI6vU z&ga4e3Em_{?xUmX>bv|2%Ui!QHKCSAT{p<5=9%1YSf)q;qO*7|=A1>QOBw@OGah@C zEyJ7jzxhq&Tmn#O=szYW^G@=>lg0YAwao;Yn)n0LB?mcAMw|4lZO$XU`4qQ_32N$*@c4m4!Cy&9-6S9oAe zN_ecy;r>F_&8*bhWpqrT00TcZMCu4}z)m zmV?KcXIz>G6DjNQ$VT%-SP)c-ax&6G9HPB`Hjrn~*T?42u8%u21oP_a6Gas~BK)rw;j=HB{SkJs4s zC8beD1?Eg4_Sqqz0wj}aX|`gsKz`!CM`VV0Cio;X+3smI1ooj5?5i#zI!)x6a5n3cw@tA1_s#%MYNz7b^xR-C zhify5VWZQ{Y+Fv30W{+6nTSTE;ID6fe7_}uCF0LS)S{O zXzM(sh|K~+c{%>6$PMg6f<0EBu}?R}XL(xm#yor#S^e}qfhuiO7W|?_M6Q-;Itvut z4^!$&m|<6OZZ<@dkM*-!J0TZC<88cn6Chswd3=&OK<5QElX9Ve;7U(^Un_ z+oWJ5vvs{O$nZu_fL9@~D8PWTC?)MA)t9%y!by!`-*s=2I{8A579pNNFM-$6WGw6&to&)unz-mwXKkT4f!qysN+4@by86C+tD2nGj-1r+f-mu(gTve6?d4u>>x zsO3qvka>D8N;DOivGed{J$ z#KU9H9;^p@b4J0W9>VY}>4dV7#~CYJb>jsl5iX+F1N}@(luVhq-pA(}2EzH$v^Xk) zcER3)*6y-Yuj&+a?+bE{D6I$+T0`L7m5RjBh3*Aqw@T<%ky?hJkW9OI7zBr)>?NxDW}@lMtvPzIXVx z735NN@+@>s1s^ElAl$*l=Mgb$OMb%FsI1Y}ASh7HnOf`h;~ji7w~DcmswhBz@$g9n z1M!iX^F#IXA<|l6e}b5)a?Dj$o0a3Ot@zK}3#Q%Ix*NZrNJoN((?mmASf1vYIn;cO z3REi8|9P?(0;SCc_#c0GtPq7mtUQTwho&Nyry}-GXGAWVEPzR%uW8%yCIx?=NYaC& zfx31HF~V#-m8_Gl?}(}7H)d*;y|@R{Ru12_wzXDR8}rYM<5E`jOcRQCYe7{!-8YM^ z>oic5c12;?G_Ni_hNBD?30;aW>S{Gt4{jR|a2;5+0>0Xj8C#dhW&I@h-NdGSgfs#W zcxZ#pMxH&oxw{8=u-c4P9j3Wjn+E+dozcx@rhh!uO@k`uNiqekjdq{r4UO=+@Y-SU zx!zX-<%)U)VLYZJW>>LIRPL8ywfJBSjsHu7ehzUbSE@FgO~qX!yFs0^71dtOrenGfA;Y!^#pXIbd;EyTd*O z%$=|BG=%5^O@o*ebm`^bv;wv7P}}{?%Dh^})54FTl=Zl|VEguKIJmja+R3bt7aq<5 zsR{Qr`M8Q3WKFVebL2ZcvH88r5q!CKWy8_j)lPv=BE+d@i+dfAs1kyo3t(Y`t3oUo zB3vtGPQ2a+3*f;wauAX)b%O+f(VA;!X6B!AMm!vvA)I*?)<4tyFpjSz>qq{13x2&M zB#~Z7D%02o{z8%i1u+%g{>rjOx)rBxj)%1$#xp~B+LCzZc-hNeGP|V!yVoS z`Bg>cf5pxt$OYsQBo{*9toHp<#Cyc0>Uy(X z5o_L@4a7j!HF)6dD6T-n&XX`owvle@GK>bxa<3?93De{l%6zeP1Xn}e+LB7Fil^k! z?h+fvmx# zL(7|zfb5{er~T&G&sm~d6f+f-uoxn;`Cp?`rK;B{F7wcVb@lyR2Mh4fdpO@mRF(9gr#FI4WTH}OVf6iI58FMy?4 zWzo9Wy^u8tRgR6Ap%{3fivkJ+dVl=$5i_A73cB?cplWa~+x}QdcU^~(iJiy3yc6dV zsXDFYjr#b3iKj5b)iZOReFKL#!PT&}f6?(iIlew1=OT`7oQ_L*G9S+bTNWWP15m9~ z!1Hqm?!B49lur5dJ@U$Ggv=y}e|qVqVCdpge?v1K22}%0+;k}e2<9E=$Nj>=C)74b z#8$j7ky z!7VjR>b@xHs_52DFWF*kPQDLbto{3)DZ-z7%RA-&aiF4;diUT*oco(CMG;Yr|;=hCm9x@d9DBw3r56%gSdh~MO20kzvPiqR7@NO7+(9tWecUw68IKb0o6X_;=`bAGxZ+ab}Owzi`yr;lhc3slACa@;H z-i?`y#gS-lTdem(aC;_1$EyWDRT)bzE}mD`VCtdX7IjQmgOOQWHNNipA7`flRGUQ# zbN%#~p0@!P*Ngx~3^^Q!khG)Z3e%6UZX4!{^2rtt zcR9=uJS_K9H?~<&p`y;=m-}JTf)NEyVOgU{8>IBk=HgAfa|5-&&c50e;Z@ z3n!3L#UxXssd=00+w#z|CPtN*HVuxgeV~4KsPx%x_Pgi(s0GnKYp(j`67_tpqnLv7 z2B;&{OLKU&+K%#uPTEOb!0#e_3@#T9NoU&#qn21B7G`~Xjw8zCk<@H~Xz35**C~x! ziwlpkET~fMCzw;PTd}WrmfNqG@~Q)r!|Xfac8~jMht4Ughmz+SGi6!ACqbVYjV zfZlZS5xfUw-oGr7;~9fJ@jK%)3GsfJ6xSOmT23MDPxkT%zD5T>z!hjMHfX~_$XvNI zsC>;$3!Gy>+y?V0(QNg3*H_!l?7NIqS1NxPS>)j7!_zM|c5X_FT^#q6_ig(_OupHzd>}ZGn_h>rPp&{eM61 z<&Jaj7N-?{LN2`V1j%rB|L8{Z^jZ}ULOkN$!((Yp2|H&&9|D%IeZ|drQ)SjChW|qA z!ut&DML+zZ{jaqnP~Fx}_$VPLwLsjEH;><5UM!TA*x;9mpEkdjB%kM{!1=Cm^0)hfAGPBbEM^;naRXpznfRijVoOoq#z1+WAOh52&*VnUAsXM5gnmS~D zQI;t#BpI*B|IO6>!O z#AwdHb<)+ky=xqWcRI{BG?jw|#eR@CX2`gd{SXTtm2_+8nJcaly6_!Tf%7b!Qu{CV z737qH2A?3c7X2NVO}J*%;*7C$zrnrt$wx!iLU0jAj#yLziq9kUxMM*(G5}##)ZYrn zMR#%S!!fTpzQD+OvLNG#@lM)B8n8WZjQ~@Fh0_e9jCQk@EyhM~<=oYxDs;A>srU2a z;xPZgWLQHLSh6>>AZz;K86vbvr!jX(@fO?&tYKvEQ-(~6F~FW8!+EaZ8&5&Nu09Zn za*o8Qmm#Y6RXD9XqA}s_pp`+NegtOlsmVgCLVVnR+GL)h_H4m>=s^*vKs^g{e@vov z-ZLV~ByP|}$*W8mQxcpnNlfcn>gp1 z+5|&s=^`mUqerwUF&-LwcTHtZh*Y|#W!jMx?pUp$Jyk%CuVR(CCD~r#Fi~m8H?)da zj5~D4&Tyn>6yZ)yjn6XZN7_@xD~CWIOz)qy>8O?REVca?FEPChb|uc_!pXS|$3nT- z|JD{*j2rP6&(Jx`yYe>Rx<_32x+pDDUtJu-tAqbN+8{C6%`(+=g{*Bwa!JeyGl|pd z7O_RYOy^!aw-gQF=vD&2^$-ks_QlxnLT$}g=jahfAQWfD<|Y8i@+r46T#3S8yu~PB zHnj<>(#2iZEbAh^?vuSdIU?wBQUQ#A`(z@pD%2m5k)bmaI7+~!l&b0NXG6MJbMMAE$pxF^Pw(4zVM}gTw4pqhH4(t8%MzN|OM5AET#kZmrp^o*% z9;dFx4nXczNx7qOm9|HzntO7mai2^9B)xjQEXObn{mQ9v3uO()j$8OdI%cSNK?<7cx_E zm25a44-AlOa2YAftg)W-T{S{ngf7|OXp$6{AcY1V@*4zXjKXJ6&_OAI4Ji3AWBEl= ztoF|bV_41bbwy}M3cP^x30{R#CMG$qdjIj7IV1JruwzUI0@`%4)X-P?DC6B*;1mW@ zm7Ae2b;=`JJXP&uhdM{&U5D1q-s|x6i}^a~3ViGM)sXCukhy65!F_OI?IKzwFFA{5 z4mKN_Is6lm(|BG-T3VrWK_R6P*U!;hI(bWm zMPb;wtBBQo^TJU4Su3_jpvqsYXI-D+pC2ohuWNu9Q)S%lLt>lGF(tfbmLf579Fgj5Mp!P<@Y8}rIWHF5nT4?)6*LM{R51(dNe&YA zotPy6gj32rF#%zlig(_Ke`;F-$JBg!UzpLcGLT(Mb{_`aClg8y5ewI85DYEKz1Y;N z$>d7OoVAWS=$gzA=Azpz;|YoZ8mAj7W$AP5yh*7gUM#f;=Pd*SZxivMwjAuVS_|qX znASm0@$|@^$y{si;z11R&YrOfyWm&8`2_kA)^yRa4b4V*8|qP5=@I{&+x4Mh_<+IW5v2#1EzXp%d!*Xf*x zlll@#>R*RZ^Xlo!_6hIK%s*IKG`ygZ#e6dJZH_5o&6zo#;421NLb0=9`h;BNiIWpQKRV#7kH7XtZ!WiE#JA{G5OjT6bqi*_1T3A-FjA}T*S?t zHhM)uO0!;UJ+19fVLI6{sPfzChN6HA%c=4Ofe7VQ?X-B`*rbV*sX@t zP-kEnfv`!wMh|F`J%sHn`8RND*<-NdSH6+tyWTLY5U72QT5G-Os`r$8xr7qCxPP*{ znT32+ogqZDwZi9V{Its(4L(@jiTqK$Bfef@!oGUyv6(|60Hz|j6rMk0F1Rrgv?4ry|7uzRfkOs(I1}VxIsqN2h%v$Z&xhHOI>gPIauTvZe_Qi&v!+ z>m)tN8wce+#gow{D@x#G#5NZ}90+FW`}d{Sob$_a_lEzw-q^U&UW2FyWl-n%i*#QqES;11?cUVkCW z=DZSuPJZI^^f+;wQnbj-vVDv|bfF7Ggm^KHLR%C$Yi#w!vFRt-FJTfe$Wx@0V9a1D zWwJg&#*W(OsjHblQRRIisuto!@&x2kqcJ;bfNl;qO!eJWIhO*}sUxMN8)1yfVAoN6 zEcUI4rq7>cDlyc+Iv>lzK67nXQ-g2pHA9=>@N)-63cx#AlnDHsL)Ol&Zr zmbFpq{lnI!zOI7x4}L^C9H9bsf630?SL7jkku_=1#e&KVEF|D8nV#7>SUezSCq+t~ zhcJLVcTLOm!K}>3%Ft*Lt~@u_oh$qw3;+n~b7a3oexJFUn*5}NMm}AsNJOglCnBl5 z8%ktuWJK(|CrruDdsi2-o)5jz5&K*i(;t45Xe=_BP}$Fl`klxg+|OiTkmSD4qQY-q zXBs2PES>)il$^aklEwgXkrlHG?Ej5YFzsRi>ha6TNH-d1Svza4MD())OPG>Wz&b%S zVGMHl)`YCk9{{LGh(7pRzgfQnalB)uUJNA(HpFsyqs^D0PIGkx zmyjYGkg>_5xYL{e;IOVTK>+N>_0i`HP`_(5rZh{0~t+=PqN1^{7b zQ*H~TfgM5htv&V@gjj+64_p$x+WVp4ALJAz!6vUks11Fvk0|@oH&oDk7ET7hQz=L< z7n%aAxlVx+-cYddN<28-=0H~p(+l3uolKoPoy^b(zi^Ib-vJ1_2!x|)H!&xGXIlVu z?h85Q30CWosb!yOcA1V{=)IidCG7XYyoQ)n|yB+TY3g2IkJ6H!Dn48}=8 zk!RY-3iiPj%jUJv|MyJIYso7>CZ}P;BUp4uHnR#aBXxBm>PN zIx}u1_KP6ck@pjFn0_%WiPcPGV!9rjI?zlJh6*fM)w5v(at!0|s(jO?CA3S1r2OGP z&$n2%2H$g~AiQH^jYx>x^-1fQn==Al5C2CH?Mdx??Pq_Hjl3VPvJ=ul8q;rpQP4#k z4UJY!_7#`rl?R=nnFP4QFF*T3zonReV%@vwfk&x#faI@epU}#Mw%i-D#Vhjm!hNXy zVqKOaDGLZjtB*oggz8lQcJ1@hDf-{)7qAa|!E7-U6nK2pn~RKLdSdmded<5D#^ z7p=ohUr-(aw^^Bb&p;@Pca;%4LDB<5WvV`S$aH&HuOh0W1I>+w3>_U8^a>>yNIHFk z#22t=y64Kj@i`bk$AN=&(u-z5LvO@Kw)+|-Ww5V;earMOoAP+B=wl;(kJeFCiVzHs-l2c}@;08wlC4 zSFd;wna>d%?ye`oN90cR2SD)R=|z~TBZj~^<({37@6zdEvfjr~XepO$Y0{syirf+O zl92T#w?p*M@K7s4)?%Z3f<*_awxiJhO18`U)&fEkafhcOt`p#ti`Zl?x@Y^I(&6cRaaq z{3{1H>zU-kkDM++es_y#{ErA;NuY+2>NS2GXrdl9+P689#-ZCDKquz!5xCoyvp@L4 z-Gw41@aTav$tIYBUelhCHO~yKVd&86mZ2>y_074*jxAEp$#=nEqvtGXqtBYyA^^`r zLIk0hkJS+QZ6WXvj#~rP!@&oz$K!4a{X>W7q`s+6+f#k}|E#I7sO{GZ`ifF7GgY?Q z&o~5wjuu=*w57u4`K9-!e{y$2ex%&pUJSioSBKxj{`|3@0;bi&E9DKa;B8M?jGi92 zpT#C~Xi0Mdl)qwj%Vhcp0uHNR4Aq@xK3uHMzog(?y~Y>w_uapk^V?VD==z%doIZx0 z|3ZBO%*{myOl9u;K#ndImA>@7@qESoN{13QZ<0{a3_wUkV;k=_`Aw9^MUV(bF63JH zCpJ@NwA@Nv?|%)r&F;Wz?rfbJ_oe_cLcIi6wH|kM_9@ak8Gn=w33|*QcBE|rV0eXN zY4gJ9=?$t{zA`q&e=MR%*P_zCUg~sV<4EU4CdnmX!XiP@h0-Pl)9&A_rw^4yg7#MD zOExq|GU}G*{>=x?CFR)YR{yv@FYdViVwj*xlCPQnqPgateb#!Jh&JH#a$42XX5m&k zfP6x}JxCuiJ?`^;BL9XC$p9YNiEY}Nt3iW0vXU@AeI%fy0*Y#emf=l6_J`sO0<@q*r1 z@bThkd*DxTSl7c3J9q9X2yf+8C$WZ5$Cc3Q9o?Ub%$_?!kPC(Jj1Q#H5!OY;&s?7p#XWRTw zE)Z*GAW?)DPQ!*M8rqI4v z&zcgmSq;2*;5pswmt|gPn;1{<8wtE#n^yh9iG1H#T16B<5#~}rDUu(Vq{s(*KS&M} z?y)y_4Iz-u>U6vZ`uL7gicXFL;vy(5Ua?xdJoP*qO)r9fO-m!0QXiEyWd8naCJ=FR zbRT0iz))3MLymyq5i-=}G?A+J3kd~*?*7fgD7aeQ6xZp7gR{up#r5(?;{%-^AYU)8 zefSLr@A+>}MlyB7qn^p_${fCdJD>>wemETIl5f9y)1nP`&?N<%2d10C@RI15?77)x zy0-9Y=QE%{jY&5z^Z}iGdN9i2%(~+w&Z21!Ftn+e6h|35AGJdOC)*o+rBG=z!ndoT z93ZYOg#su32eTTo7li6u%E?wAA?LQg?wk1G4rj0Ko_{KwE=Ja~vDH)wdi`xrO$hle zpzX`(OUw_N047NYlb3_p^oYUye9q2lUQm-eC?H6tmI&Upk8Y^mcY z`*W4kG}mcfwi?$Liga}OaUj&O?)hV0Jqyas=6Unw@6BHfCT+skEp=<@zfk7r2VP(l*kC%UWS*bITBGFsV8(ZyD zUyaRlR;ez37UG6ngW*b614C$>0-9wZt*D$b+lZl^G<`hw5OH4@3In#J3E@Q7oK>7CPADx*>64M@L374U|gV#tM!}yl)Y7b?eG%V z@*4FoKJ;yw7cgMzJ=zW|ctk1gBh;2(J8?Yoxn)wIo&dOQ&IJRM4h8$fpTMyhzi}u` zl0H|y9z?ReUb)#N%};D=E_%wk`h8~ojAXW9oq-1i`97&N+4Zih4m=bz_-caxPVB5# z%j4IljNrTPdz=&LNJg_y9^9S~Ex#E{_y*02HTYX%q_YytR5hsZ;j&a1jJb}YojeOj zrZWf?usO!1mzA|=6UkHrzsS)Zr`z^!f}d~j9H%36lZx=(+l5Gu$<3_SnLSwjVnb_> zHn67iuI&XeA|zevRcGlNlD{!mm540CIwE)RQ0V+uZK*$Iy4!)FoGe~PbwY$}#RkKt zMYcLgB+CWHP1&9hkwSfN9R>#vx?>8x$G+Dqt-b>)tPz<~I=_H6`41#DO!6nGILO%S zr<#6w{6t^TPHF%C6-u~f6~DE|=IMK%o7n_W!-Q423#P>{9x*TN5o$Z!BtjsVyaj}& z9$A!wPc!!XdkDE1BxW)x$}m9-4k0ebCUU>09YGfZFB-eRcT#!(?DJwe_N8 zo8oux&PYqwCWKTW_1WiEXdG+E2xZ(PdbbWjfT8}hesxzf?L9QQFne`mnM%iMKhgP* z@;6SFhJ9viHht6&x_QY~HuYb{(=Rqsx?@yb2I&XFm`^xY<*VW(?Ize~vNu?$(KzUH z=}%740&{IQ{x67NeLFUt9b>d@1DaN!w*HQXoh1k`F(==~{$Z$&X4d1-eizHe6=8H7 zH>Vq!(RiAtskba{M?FDtxmQ&93)Djl4Uxeeez2mxt9JCPx>~#|qhudTdKC7z z3#=~Rp8tSddH@s2H;WS8*&#>II1YW?3q zz-R~V>$T#59`3h$6|#OlqP?ekkvMZSl0rH86nD^*J5vqb%JXdFpR6dGQFQx{zY1FC zb`F1CkpYBlC8#Bc1%9RDBf&rl48L*_#Jyem#rqwMsD$-C9W4N>&*TJsPekOl)mpFj zDr8)~&bk;4r5a#$r;b_u!gWYPwo`TqWiaARMPvAB#QERyI~#u%1tA+XHS3fv{|;@U z{Fhf!Ekqicjk=Xqr$vg21W%Cp!7cpMs*~P)FlIJXz8yKg_!ruP2Au*<%zxcsdJdnC zbvd=*4rm4AzPS+Gwy%$82qyBS%E<69W=A$>AlaD`nNU>kaGbwTyA^kR zzO6|q{Jn(L>G>Q1v=SG6dYb+lY6UAC(YEHu!C#zdkoY@yd|))64j7u~dtEfcPMraA zm4Im(Q|yH3h7*+t{>r|K86WKG9NsO&`4xCCfA_pkYd`V|lKY+Z_2fu0I*jxvf}w=* zj}Hys_5-&8)Gx9RR#yR_1>H9(5s3~?1$xNFBJC~g+z_@Ko^!_rTpAz8ieruf=77gi zN&W`M#oWS@4Rrf`{se`E0;a`h1V~%JCbKYYQWad6FD&>VNYv>?6Q{!3-d8>7r)2UA zNXB{NADKF+eOKJ*$$U1?3dtwoT=X0(k9rIwNr*V&g4Bw<(AZ}+F8EHbc=5gzXD z(c8pmXKEgZ_ZD9?q*uZuH{`{7jPuOB1H+<;HG$aY;3)8_@+B7)XXFek9oGyONoy%ltH}bRss9 z!N9rL^*e(cvw?rj(r8O0wPLs7=R1wam!bZE{tANXW8|w&Asb;8T0XJtReb6~47Ri1 ziMNb%5?PsAvQ1NLO5jsF${|5kkPBw=nJ@^U%DKz!i5a6*;mF0Z+_h#Z7zata!;a6V zBuBLFr)(>}!X_kQC2v-Xf&ZJR5K9afu!iv7`D`DmLO_|_oLl+OR(e$f(^{xJJ26J9 znpwJ|r>-V#LdT4KhOq3>j-5=V&9sD^2Udnke8$sPtMWDu)TzNiVproWgZv@kf- zEP7e-kEIJetZ*9tjR*1I)e>Dte1C=ABImF?z%zj*Ez(kK>Yf{PBs$J-_3<6 z?T24aq8}`%-@N~AB4O)c{S#TiTS{^)^qYzTgp{)iCau17=G2fcvQ`I={{-!b-dt+9 zND){9MC#4(I1pbFA9PpkAiWQlW7Hz~IUKvpS5J{83cKO(Z~=|k?<6#ni7Ma&K<7 z@4E5zoJyGNI2ujK5$W7L$mM7N3~XWvy7Ll_3B^$ zc&U$ez+$ZRiHjr!8M-R7q9_&GQ+7z$1;4ZMg>%+3+3&>jWZ@(k5h6#IMiYA5iY z3=z2_&J>Pwn59ol=8gy6fPm=N&ctAvlm0B8-(8_N@UdjdyK9l1BZiTBjHRD67B9&OmZG!l^nTz) zKmRODDIyplpq)x+0tHsWKA+%?Epj!M&Y)&6A7V zM#g9Ra)FW0Y8Sz|h5YF9@j~3;f8nCy)qDJI51VqUPBCGB4=paC3&!cQ4w&Xc0TvgZGq`uo$Zo}<%=y-r?eSHFps9kY)W1eUc? zijZ*4*;hSD@W4W%3w+)OmAHfk7j?6#2a5|{X36SizVt&}ADT?v6a*iCWecQ!+a`F6 zv!ApXtM>D_J2iX87JY)05u2V1+Y_=k!J`Bc^1|E%ft}xF%Or+eEz}Hb<8SeyF$f?Y7EuBPDI^G*v$Z(k*pFJv=-GMqRU zz0+-EvbZ1vUOLU@) ziymnEC}$JsyaX?7gF6TcgUJ1l<~Vmv1+hW2;xBCMH6z%HeVYB1(9W8t)#3S6iZ?N` z7626Xe&Mc_A5dRF{qkftnLI~Bvg@H!0hq4%NQSH1 z*wSRkD13pLiSZq;=e^}orH;)%nTKt||2?Tg1Fa8the^)@FOy)Gk2i(V5R_ar_6rzC z^|I9Qza7c=EXo121W<=un;_0D6CVp5&e-c#&9Pf$pjTZ^fi@zv>ig z2(xh&fh3zzFW#sUfSknZl5lvG5NP60{jknZ>J`M$ru{KK(5&pGF=>%Ol0M19MRp+mC33d$qHO+`;2 z`zt|tgIPfq{*H9!qlsUqGcCtQv*aihrlQR5NC+Nu*>92fxUWLHI`7>|{?h$KZiSNK z0aO~V?RK}ncfKt>C>3^^r9b6{&>donWFEig74=*wrlurWo=7bT<9fTdZ8*otemasQ zZ&s${Q{M6X7ZgH=7%+mHkAjxOU_}I2;!8D+|@}@b?jGdX>Qayaq+bd}c`T@}+-+s>D6eGJzQ>;zXh4J-dm* zn!J-aq50`Yl)^lOG%PJ30qmA9sO=8c1He zbw@@-QyONV;I-#+AZ%vOb~Jyg@8^P=*R-#|Pc4`ahIpPz^Iu zOEzWaaD@Rr4QnB#m-#2^wUH%9qznD^?N0e|%d5shEh6v?noZM;;>xeWc_{ct24ujo z3Opt&3~BzcOr|Cq^@QC-(i^O-ysK9G@K6Px%lP544dnS!*}_LXiwQOe{EHPgy#aRzjy}?Q<|7xa7C{{C>3gqsZ_^ zxn5dpckxrS+a2qCE*ejfzpT33wj$bDuY#Ff7sqU+sk;*Zw2gp?z8JU$JubNp572Id z?W`@0jJknQ5M>5imtTA;lur4XAzwgVYl~xDo6 zcsPPwVO+5>@Oh6^eh?y`upDzjjOA}Dp;)w`g0|WXPu=s>zgkrgLCaZm?bHTjU{fYI zRecjODiBDcODlw*qF}Ufc^WX3lrkk75uFQIRReg2I{p4F-TBlDG2`CpU(GyGlbQ0< z0|&t2${4Pfvei6m4+MEAK`WfQ90nM0&WDwtw*tWV%g6spOEG35K5O!xByK}(PQt{5 z6G7mO#;Tf3hK%5lhVLK^O_qmcGDWGq_-v+$OIAFf(17tmafyBxDR;t>o9j6zH9cSXykm+@Em)s0*9vnpw&jH+)M4pJ8*ke+5!#nbXIigiSQH%wU_ z4t+qr*SXJm|AB~!sW-vJ8ey1VnbUir*en$k3{&_o0s-!XujkCcS0?Q*G+ts4j6iBX z8h~=Adts~Q{J$#xOugT7(&-v)1=%8w(zxs59#($XwYF7$rl*+k5BtPeYP@gC>>8`X zM00r^3j>YRdB-HGFR?T=sd3<$xRUOWH7YAFE6iEOYl0}dfe!6{S@q*)dQPG#3oJ)P zZNeWpWR#ohG(#0dX7!bO8`~ePf6e04NHy6Ky-{v6b{kzFH!lx<)A)|Z z{>0x=Ub}h{Vu*hbebV}j{^!%r2MFxKMQrD1qK2xlM#XiLbyuqp}p1+bj*3*8QBq15GsO@zTbP{_w)OU_X*G zL!}inUXA{&8Y%ng6;hXfi>v&ugFiF2i&qsqexEQ!b$$=kebVy*qgX64dCb+1|f!d6%KS6itL$qEw zrRr$EOvE>@x|grz!zQZ>zfVUceaWB^4k6r|J*5*&~0tuRJIzoDSG=3$Z!V*D6RT1BXm!;36oXs&81@^F(c>4 zJV6Tq6`Zt_nH`gghPte_=XZ@oG^I9WHcP`0&OF_=38n*9IV|;W zUDiHUkz8f0Jw$yf%#bl7(Ha?>nBiZ4nwtuK{x1d4bf5x+7H2l0gHKg|UDr^sWA7cw z0#R|3Gd&0e)PpiO8aDIA2bhvZO9!pZ%M@>Pf@czSDd$h?A^`77G|ksjn&Swt@eaN! z-i<=_1f91P)(<#|;mq0#mb-Cz00*v@d1fvQLoIws=z8g#%$!Q>6NDVIVrzW|3of8f z6>4#XJ8!7cNL9gKq`dqDZ2Gj{|fi#6j``&Xf?H=-`neeRDZbi*5(f zOShkADfQu!{N;?aq=Eb8@A#)p_fBqf99HE|9@5KtfT(G70}6^&o`RKS1*)HKy``JZ z?dHRSBaX6JJ7QzouE&x>%>thnN8|3(AKS438iIqBG(A#QLYi(IY#UgPffy z{JH11OaILLvEGz>gPOQs-T;VBnsm)(?BgHh!YPvY{#zoC5Z+z3?%2&AVV1VKM!1`Q z6X+(FTVASj4t`GlJ=}zJMmTXkrjdGNgX;J$|LhyJIKge*cV~ltl!i9!-8lEZj7mJC z836_y@%<7p`tYTt42-89&ij;0?8C;3dAv_QUGJ2BIpEZRILH@&VD^mHUI3Y*Q-q+>f+tLbGa~6USmAj zJ%zxMUxT)`3^IwFyer!I#@+fPcK2`BWGJ%vc=ymH*63ioS27)T1?Ji@ziJIYmi;R0 zpgp&iyd7=I_Hf|{uvHoybcb(?5AcSz0E@@m47}mzWB$a7g(j~C3h9?U&@dP9I7XIXLR`3CVHwuoFHU$X9CSyU?q({&z@PepkC{;{OuJrZ1Cf zf6^)+Yvp`ILTJf$gIS>cxq*IBQSs_sxMq><0HU4iV?uPu2pyE3V>)!BtF{@FL2c^` z@X~YYvdiP7>7OjJHst5et=wD+8&qHF*AM7Ez!Gi%xHmt{R~JnYz`qky11OU$y24Cz z>MyIM9Aw5ho*Lp*k*Cwnu!!>)3C}%*;jl;dj;&d}uc9yB^MKN#qY*Ri<^)x*PZFnhG1mtb6b3gF}EzR)2{bLHQaQq&pHQYL51kc`AkCZ;M=TCpnJW5 zqSLD-N#H-2%k^a>l01V-*GJAgWm4ugK1{2^1DNHIm3Z;*eo@vXGcopiySnZ7es;C{ z<2n{juiCilWcqG)&+;33X{eW}Us)UPliyR<@-@9Ix7%m{KOjKWNEIn6_D9b>{)v80 z7*bL3!#BoRRxi8wZW`91x)aNV-yum{&MiZ@&6)dQ$PXdvFRr+>#8`EU+YKWlcfYEJ zNV$s9A=-#U&_jJF-tO#!(Cc(8**J#6?_u=`{^yDrPPwpytPnG<3w(w=?e%vs6nU1;=OHlphRIeu5BBbQVb4FiTS6H4d5Z*ZU2|RQnUO;M z_3Nys1f{6ZrP~T>EV!UF7&=d@=O!g5nQ5VOKjm1xRO-2mZoA=F>a4`qnCcMrBc#gB zf`EJ7qs3l4pxMWbA!cHFu$`0hg^^o<~s(R?iJ775?3Z+&1KiG*YQ>zE5mT8~mvM#*J~0tcKmr zFo2_wIX3YV;l|M2*Pswby-+_zR@REcUAdGw7W{u~q)&|bkdxJ3WR7ekEE=V_qzI33 z9j^smtMJpn_clje@r?-|FuHp2-AiZn`O#lxIrul}N)fQVa*zP`Xuu|v#iG9SLmKXr z_(H41FhR|QVc61&yK=WAOwBmSkc8PJQUcqA-h*jacD=qyW=SZQMR~=mm)L1(*h37A zch>2i7c+?`yc1=4)v2peV%D=K8|!Fm7cYq+%xGnHK=W3?@2)D3Kyd&m*ub(HJP!at z!{j!}lu6*a$g9j-0N+V5w&RAHrObYKPTxsPyj~t@o>-hHcJDK>4JRpW(#a;H^KC+` z5P>wL;FW|h5a3k>uZl7O!AV65I?taj*}A6V&0MGY2X7y05<)h1Me}dgE#vZX#+l`e zcPzbZ>K9LpHo1KhM}E+nraJ_qFPP{B?_cRv+K!NeMX-|q3kq1Pe}SCiA9^K1Y#Gg; zJAc&O=y${&vYt+^6^ls91QzfQvfwtEaT&8!^f{9&f>~STfKPa`<+9}F2p;?`%ey%1 z8vN=b^)%h_2Zphy9}kvE1gi0pO)Gw}Qvv2BXx|AY5kb<^B{<)Ys{}4B&o%hb!@b^{y)aZJ_UyK1EV!fe}6V z+nNthK?teVZ`7F@;SxKBAx7pAkq?-t%+mk|q(;GsQ7r%6d(HSy4H}K)`xmn{TYFK5 z5u1cF0{c&({cV(<4wc(Y+Krpj?q&7H!`WUFpxOrv?qenV@;fjqfAG@vZfXt<4(KeK z`%3@ZJkMmUbYC=IF)`R@pJh<0cW79eIkG zUi}qL(!_IXN|rSK%kr(HZ%irmoTShe)+f$Jlb#2@w1(*)U!uO38Z)$RQ=RPb2ylV3 zBts1VCI?~#6w9p0rK>lAd{1I&%h!^eNaS+ct1*FoOrOSL=x(rJTxJEK%J|HEF)q@J z*&#%iJWrv+?0tb%|5Re3GlIhEjx2J3?U6ZV=Se~E{{3^h6*dSu#I`%L6;CljuI0Xf z;A*!sMA@AJK?2m}i>liL>8Z2b!;F`89kC4j(9OMn+1-FEyG)T_uBjXYXJb!}lZEx# zzF}8u=}L7!+#7O}k~mtUN(To}&EuZF>jTYG09~=b(qLLk>SgVy9e)%P*IWr0M)M=r zPn_0Pz;bzM%h!fPuYg)MF*V4?Mv1L>_0vO4M*y#=g0km5EOGxA3W1tZ{$pChu&hES|5@ivLe`>x!wgy7a;fFy?o zZqW-(XSoTvqhKO(X7c+(8M_NDi*uFF$SYTzwk)mx&2bLw>Ef4&4oku{weS=iwhnS1 z4g|D3_dWgU+d1&=S@?m;>5CAn0mnH+>lHTbYaX`hY0{K=T^bDNj-Mb`983MxnOAo{ zocyUFDi|JMF1B$w0M5)2G~!J|_IrrxL$7b--WFwv*(?v3nlI7u%zJ7_E`c~>kb*ek z04dgKX7DE+uPmqoY=ss`JMa{$FchCC-iQcID&;un$g#Sx84h z%kA{8@(>xfOF+P2_#ramy$X_H+y5E`dLtCZhYs(EvGZr+a&?n zg!gFs$Eb7wotEw+|6PWRIUn@NS-tzyu~;_t>;`8bKh-Dsn2^cF%IQr-sjehq+Z&P`naz{&oX8D%s*2@I_Hc z86$he!^zwIdo)9)V|$EDyscnsOXX(pM5P?$o)x))tOL%5l^(Hz*+F@5reG$H2~~T z6W)$Sa#AToBI1AcaBnZSFn5dN1rynV1mxU|I5UolFlc1WRDec;@)g0`l!)6j8R8=z4llBEintjx7hN`MmYm=E5)CIx?r3Wf%7YTtBN zUQK_2jK`5|4^GnkGUMNCJ8*SJw(Z>bzgSwVI{QFzb{GGO}-_U-uT|N{Nt$kRL2W}Dals=C@=21m0 z#(XP3f7FCHoyqJP8~K}e_3TjideP7m zK!+8ga}KWf5%;`JqG~tW&^xOu11a+~gMzVqOZAaDDvQ!`>u=<}$KJLgXV1$}v~2eo z;Ld#YcA5aB@7pV8lE2W|RrG!o;wt&EsTKy zei&cU=ORKjb2wUQwPpq65H~J{o)#n)cU@3t>SzK*O>%b+vz3 zu%AF!==w4CaSJFF{ThWlE`HZN#Z-MOr_=YYBga%bsDeUau;b(1%)ecHCJBwlf44wC zDG{}=F1$abmLa22oF`r^3iMbTL_o8bm67k1X~qtTmG~`f|Ec%K`Xf#-A1b+ch)2{9 z5Z2B3aCKh&MDK^Ha_1-!TI}yx?RF9#I?ghz4lh-2jpi8HgaJz>jNGGxUbnPz1_+WM zpbXf|ec#V_+5)qZ%`rcgBm_bpMDpYZif3j764j@Rk~4x=)16p>`&r( z_Y>csE`B%p+&W>6%utGTr&w2T79M5W(Myw(xG5iS^H3P7L3pzX=WU@o$-aXLlSX9< zj7Zm)mzD1^-%>2Ut7pwE9QJe2OQA6IshL)hper~9cZ4NO20HEXf6%?-v)%sy(7!hL zE$kN{*TXg9IZV-5jYFdzq^GKa}>Q*xqkEY34&23UUjI0bHSAJf)BC zIkgdfcIpSd&s}8qga_OFLh&yi)1~tv-{qYnNL$odZZMU(%hs zmo73e@if!wnFNzxQ@{K{5s>!#e0{^-k22Z6x_HcLhgQ*9{lnIx+Gy?42!7xQ08o0F z0xwLHn>cEXPM<+>&4bNJn~eoa?oZjKG@W>?V9%>gIa-8G$;_Fs9YZn(6F1|VB^Wf zm$U=oG*M3BFYq3?o{W+NkM2t}y12-;;T_qPm!azD=uoNey%_?(viW)!US+o_k*y)J zE6N2-KGp;Vgr-lyn=Ev696~jYQ4rOPPBwgcgl5q{xGYhuW?Dd%FgozQ1Y0OF{$?91 zso>V4p9#bL@G9OM`br`=(?=R|Mxr# z2rNJRUu8%*P_@azcJV`y=4SHF^X58l71qM6eiI1ZS6eB%2i0&jmAsix52tr|^`9b9 zBIBIVitTh`2Jk!~xsQ=OPge=-^5T>~=B-%{yV}V1D&qzRWDJv|xbHyWniV)KE@{Tm zo1dIP1}>w+Dxa_-w6N+0*Bn|*%agA430FObg7r;`&)|dzJ9peeWK`g;heONfqcQ?y zhLQsA31&#>P$AYHy)X!wi>bK>sE@dSlkGCdcj>B6_`Ls#%%olKhXKjq#NXa`sE+(V z&2rS^q>hT;&zo4L`?aaj6xcpa$cy&?hmCZO#wp7ISsE(j9yZPHU%A{rurxkV$oMbm z@@h&O|L%xV6#RE=2ACmaOdj9@3yE)lCElTep?IYw)6`qUs1u2Ed2ti_{$|V|K2GF? zcMu+>R{bRP%lDK(LE51}ChzHw(;gMd-Pkn%^1Go5WdYV+n(`YdHkO}bE@TX2>#k&x zWb!<^N{_hT{DwJFh(PmK28<4WiMbjDh9K1uvNsu%lgNP#wi~Swh2-Qk>w}YU+{pmh z(`(p)od%tk`DeRB1F=T~lp=6*ECv~(ONf8(4*Uu*0WU^+qkLhH_zviGVApHkeg^B4 zG*O!H&}eXR)FQCnA&DTaic|#$$GXIalk-8jJ{=>`Fm;0$b1@-cMfiu289A_n!~-R< z{X{?{QBTh-9eQ|~KFHh+G@cwea1?wzc_H;*^F~XM7xvFPSYco&5~ElbIwfbXu0AsH zNaqz~?OLykBGA3Us22(MT~=hH3e&P0BKV2!0>K-ELuU#D%`X`r(4j-j4XITS;Nlfp=gz`m!uGxqNum_FL=;$cnngGkrnu5@JDErhe4~iK_-%B3AMGORBW{0A z+^m5OH=;&U$f3W)szAFFCNE(C66|u(4^grYzRUAlKU<`o0QiSnRcX%(mw)L~mWQ^e zf~VlnFm}%2LflC+8C|(a^Akx>k1NZAYdERWU&9w!^QofEw5Z+=TiJkPMgfU|*QkWq%4@PgZ;4)k( z9ukRRM5oQ5%m$uwLqwqQ_X4;M2DA~rI*A&-* zZ`KmC)PKQU6XUaA95VC_3qu9X;{2+p!k)q*zuYFtga&$cIi#YNb+!;zHMVd=S-t&lV4_6MdZh2(TFUcZPb%rPyvkkG1>Yb(ebOF!QDK__w{0h+n9;m)ck)HF-|LoKqci7!;`(F4DsskD=*yr5+pQayd6+W4xfQ^hZ zKZf8Cs=t2-y%WocTiPc5mZCqzI~@ENu?sOYm@toP=Z4?J>ba!#q{mpGwEM7>@AA`< z4sz?mkX0-o;p>XYkqo%)jdZ>d`u{_*x!< zx@yH5*%Y$a4EUk4#{M`P7Mb=xljT`xla8qAX2G#%K?od|t`(&9+1M#WD;Zx-cbY3y7tOVt1i*>8TV8z{NNocA2lffUXH01{0@OnfRB z=#|9M%x`XLP;2IVh*#3wpZ(92BV{C*AE97$D<>7mYv}4d7ZXEBjhlr?2&*Bwoi;Ce z93GEy3*_>A)XKL+G?+gO4{v0LEg>=wEkE3k8JZig8$&%d$SRp)q ziFJl=OY%fE@(vXAUb*d@gopAUxlC- zAt>Ut$SL5aHy+U$LH4%`NIDjJT133}zD)wjCGrQVgf;w~{WhgSe^U4F_c`8yv5fG* zVixOp0B0D=<-|W9tle_tamZSmrKZ6oL~E190(~#?M}V%JG1b>wGcBC;7JO{va7r^i z7<>N$-IMywAxFT+sgf0RW11&+%47EJb8&9AU|OI$pjrx}-{n7|`Wa_vGUfj(!S@p% z#TMe9jIj;(k5*3HHS8JNN-fv$K2Uyx1__N0;8_ z1qVl4YW8a{+~b)%7KMi|0uQBDMDLhUvgrV()GhnD?-cYR@{!F`>a8Z1ORsSrZ@|I( zG`=Y3CHyGk&ZI$kz~5hy_Df4nH#wGN|Jh*26o>kv>TkXVvw<+#HKwFq*mxPG7u0BV ztH+^%@=%61q8F!8IC6v3-&4dk#EiYK34oxSXErPT^l!U`8nrpBNH-(CvL88>cRIWXZqqxr`NCzp`fJBci0SQ| znBi*V+E3v1-x1FocRsVrGi@`WWgJrVYVMebTJ<$~4bKpC&M|n^fC-*Sv{$OkZ&`SAM5T627=vIA0GYzPus@SEXBqjVwW)Y5WY< z`ulQYcC7CfJMW6AYeCFH#7hp9gSg96ST;?YyQ6Jo*z2HwSXzC6Fy$9cq2NewEjyu@ z_Pt7@j|axu`EJ$`uQh6!^Aqo2Y%6i~G7>g9wp_gXI7czuf)}>z8>OeRgfHNd!Ri5N z3(C4@^I=3Fn+5^<^eL%Z`A5Y*VzZDbd>J@;NC7*Oy_LorFKsTe!M21)qA?p{#rj zo9Bfkx1&}NL}jTfp^&fRJ!a_%Eh!#uBk01*VSpgSmvrAcmGT`N*OVG@E>NNgQOY-I z63Xbp?E&)w_}dzTH0(q4L+JH$F8$?DMLGE4kQ#wkK2^(Q?O6Wze3kSQKu%FP0HF1^ zmv%{)=MKsM<`YUy?X=(PD^Z{k6idT?6 zkK~WAdt1NGZpAgwYXmU;>dSlOcu+`6*QDb=YhKY$@f?2UUI*e{G0d!*?~|u3JEw>)u7co>Fw$q}FdN&YZ2@yzspv@kB0> zUPA2Qk4ECSR}GtnKnPG?(7lr2AD*X|4vM(XQC9zy-2jD)2#{;%`e*{hJr*;U{9X%a zz@7KM?_Z`ix%ouS*FhvMIS}i)u1ARy2j>;qMb@lv$Brf(kJE1@Dfq9*tj{=Jv@>eR zehZc5=;45=5U*jR7G~{cXHkmj428e%sJxy*7D2~!?d19gC>s^?7rw-)@sB>MNzvoO zQ#wY#R$B7DeHYcqQ+-$Nzq=M~dtzcAQ}QJP;({;xb?tN5Z{>F3*BJOqO~2Q*L;63< z+z=TTLMh^c6e3>EdJ=dAOun2hG5h!Jl3w-5i%=^Z{d?$=ajd_Z-bb_`vP}==$S@u) zF}hWg9Kxv&$970>VHUQP9yR8f?$<-}BUh5kbYMjfuM57aj%b_^ z1teVS`^FyMU0v=sY5IKHEV13PnBCv`p27^FfKTH=>@C1J`y4iN^DlR3qz~RN&jG*C z!ohtOPL&}I`Xb{5(n_7oEI>LmdMlKN9Pv@oBr8Vx9?xOhR`3>nqjy&+Y7XV4LY;=@ zOIw(XBlALgcF=#G?revpOHyvmG~Gzic`9Lf^L)MhZyeu4&J=Hlmd)d?CvL4Wkm2X0 zO~&_k^$QSaf$+($AZh28b#eCn^H3mXDs75q3ck!2>GOWv|W zk^Vf3{*X3{jf2a%*O$G-lQY5@NNBDbV(vB5ymhWhyk}`htxqCQ{O>ozy8J~@@>;MGxRpW0dulAruexyRb3R^?i&g}`&m#$>r6Dh@f+ z1gB1rr%Iv?WfA|e?zFAExhPrS<_KbY?)swsrhZa8B?lY&!zK$T;?;bd@AfS74 zhp6sbK>ibrTc&edCO0yWb7|n^^~z)?gH%)FYAl(}HouGW8I1S+U4-2ZSodQfdl{Ca zWz@Qtcq>OpoG)3W$}+bEd8S{}2RFpeMT)Q0Z>VF3!snSe+KL?3PWUNRT)KyB?P)xA z)o2=^0wRuYoxU3TnHX)aqj#gumj5o_7Vjs=Ypkm`+x;50k|Zi&iJSbC$3}@55Z1=J z7$7uF%Gx1X*POEIZHQ}yx~Jcz5|=cPUesPzeoYzuzO*0mFEBI&oU{n#wYg?LZ#8|T+N`O~-L}B4iq+8d&v)9N#9;bEL#cWb{TQ$gP z$GMoP!Ld)D9{r=-J-sDq(B=#;=Wixv!njQzF>Up(K|Dr?O8l7GXtWuh=I}9FxmuQn;IEUWCE9A#r8{OD#$Mx;kH50c{b|Tlsb6LKeOE zu;`C4J;w!E>^Hcfz6K2QTyph^Q!PbERQw4|7?HPB9eYE*vVe$%UWqf_@7zrxvgGyi z?m^o=D9x+uZkYKzPTaSZK{qZZ?K@NX zxh_afq%5ZRgguY!%QPE-u2f?PNU+3Y3Si&d|3=*UA=a3USdS&}(V{GQJeR}9$>cTd zBDsDUkjpWVaLr!8!Uw|}!HMJ7=1tbQysgalwHTR3kVKjb`$OeVYvE@4uf6O=C#Q^H zf9$bfOUk^8jCDtA8aE{H1_N_~3e9C6@gv!zJQ80|`!g=F$MzP}`b_izCgqp}Q)as4Pb)w%b4U6i^cz29{Q-{+}nlG_>9_}Afsr?BBrZ8HD$s($0 z;>O`$SiCx%sr`CCU*lIWM*M7!GLv8C|DK0FG=m|h@(LoPb1*1%B?eGB8g`urs}A|eQ~ky1=Oyp6 zHZANTuy9pU8WQix#A=x(j@Y5eF`o>NFL#wxTh4#pWh$Vve3<=rD4_7iSCO)s3amlj zn<3<_WVaq#(^&g09W1jHo)=iaETk%jqtTP;{#NkK}Y<6hz0DFkQV;{vyfz8$Sl zV^KW1^b(@5f)l<+b1&ahqpfY*Rr$u`2u@G)kwc{tQ*4jHCdJ>e(rUJ`V$mbP(~a{w zJY?cD#q)UMKv_bC4dDu$03Q3MW*+jMRL}W~cKU;HxYqP1vCzuD!*M0PhcTYUf2gz_ z>8YrqQ~qWvAp#~^A3%cj!xnDpmEZpi0ii4kx?^CB&kgzYNI*Aprm=TO|0wVJId!Ry z0YnpfkF-S2XHVB@Al}K}`%w{r|KE%Coxj6s;@9XB?O%M~s~Zhdy9C4>6mJ9#m^!lo-ZGHQ$vbGiN|Jzb3$JXIt zebr0hGWLB|Dc^)H@f*#mQ6(gUFHp6Y+h&&OR^i?DrOnB8_dss3uPJKcgLjEEU~l?v zAk3FqNJaW%=dDFj?Ca|5H^$+=$Qs{je?YYV*!}mS;gab@;jpLr2FFx^E_S&Z$w1}k zYJiZ5T9U_J+jib~+)9~bv-TT3JHishqllMHVzZ0MLiMQqSY7Qsv=c*Q@SlfelFigy z_NN=S4Xtq1CAuF-ih~Wr?-d|C)!Y1}nwJ`$Vc2)H@9 zHfng^eaZAZCW`_j78)=tCoa&`f4`=uy1i$5@G~@Be#`dEzm((XkrvIyxx!k7oMusH zj?~0=tTPH-qfEa+jev-};fB<~k>A=Vj*vS9y$f~5YPDE={dmb^ONE_6!qxBpRI%U-pn z869`GXa>?Vi{bb4d0iO0miA@BD-<`AS9?MM#hKN9W^UeVeR`8DrNaU-aWNtCEsM)a zGmfqAq=6;K+oDW*c!pwcxN)83u|2Q2wI(ijR7Nob$MP;xz({4J)LpVkUbrUwocXAF zywzJCh;_0=5tzAb3Jd&dZ$>wNuvOg$&phnH*YCCME4)nDg+J5 z-Fab(Z`UvFefJk9@+bHk;2!a7K}FCN1a@eZ%3CFUczVlLxjZ`H_i?atKzo`Ry_JTBEH&R4~V(v#|f`5@xl%QbQ8X50Y)N}#?2LcaUNJcF+RnHRyufr#dm_R-zVWrwy&DPT9saekQN~>}Svy(#D`-gB%GC)uS zF!+07j)@Ed0-ZP)J7qX_?7i@Nj%l$)O_=Ze?4N-2n>U-hV^ll=!z<=Q%jnH^Hfuq# z*eq-eox8{iym?fgw{sDOz<2oZ!v6i4pPhd3fx_~5&3_!EjVvykWicm7+Yvw0=Zh^6 z-*n~$!5t5@#$_A+MDj%#i#I%f*6UN8a-}d?6W{JKou1z~8Q1vr)aW-0TcPSzvUd-p z%|oZX7W%{c4Zg-FnaDkaHo2$qfH<4c9%iAoxEkqzfrUT3LyVYvL*?kP=w{;N!<(gZ z?ms8-!hK-XsgDUUcUh!%v&kK9r0Cdd&gn9BK+b~6vLEw1+&2x}X9r_j{w=pPHRH5K zOMj_-ltDnKMIXrRb8E};g=Ew$5lyI-e`IjQ6+zQ|!K-Rw;MH96#y(^ZJ<=F|?YtE{ z*MRY`tJGf7g>t7!wVqHWijrul;!y$%0nrhxyTs0PF0t!42czHh?~xzO@k;7nL0)+I z{i~{HNWRZ@CXpCtOZ#NyL!=^N>}LTYCdi~JnP}|+?o$Z#b7GAQPWm|v#K->Vtz;Qc zs0HG;>d&XRpLvWDD)A}>OrLpL6>~6pP4hI~B>B8h|H)kG7hjCKfusx^yGN|dzBV;Y z(+%Pi%5CQ8PoI+f=B=Ma^#8uwoVcCC#gE<3(P<`cYJ2MtE1Q;9gc`7Yf;7j`PlD@4 z*de-Rk3;IYsTset>8kA~*~UwgD~V7uh1r5Zv#YGXi5s&2F5_2Ezex)^g|1FrHFr-1 zTNaO));em0XCfb;qicNc>XjrL;2bNSb$@vP8J252J-HET+|j~5+#|pP$x_Ass2(1m zRYlCDLeS83<>Zt{Z(m#5|CdLVyeUQC)joE7V>-if;?j6g_{8r(?+=x9+{-KjEOn22 zt^bLQpql0PYNRJMsK&D7u~i6(Q!9;qICZyui$~9Ik{H&msI2ce8wW?sRSsx`4VwL< zB;Ri0akjoE=H#7sVK-L2)=KpipY6fYD+)(l8Lk^)`hTbmbG~GmjFHOPRf%^v%0W#^ zl6fEaSHo)Xs5D?jP!fEpPTFc11#K6d+K{e+pYeHc^X0fKf1=9Yewpi!e;mf%YH}es z_-l#)K6T1$p!2nEt(P{;O#O1!t?J-wx7!+baUlm@Zw}&be+3PW8BfHxFE!B_eArd| z???y1)nlfA-6w`V?M zI3@Y4r}`}hMouC1s5hRnuIGTxE5(L;`9-}tEb3^DXWeg!dEJD;2q_-Q1Ok(hER6z% z9?rnVaW?0(ul#o!5@)tfD>WxcN>-%TQ@Pg|QM*2LhX0DVz%{!Sg`K!gB$2+uWP3rvW2pv>5}HQr@lL69=azw#QW3F!j1M^0N9nyX4ai zYpp}7O<9aXMrf zCr5|x8`P8|Kf<=-b}G_OI~Omd5&y|<8DDmN&ABea()4yI z^Go3Fwro`W{LFEC=+fKIz9)Ue4I|wE)RWWIHc!+d+b^?^>_N0gi)RK^=8L$$L{fCK*)$t!KPs#mDv+AO}ZwR!->@UA^r9qd#cKq zg*ZOOH-g|4-DR5Pj=CT9RqS6;trW*7P14Sq4#o0&USLrECPCh<72Bk`DU?<<| zt#@^IU3t-WL)px32Zm>8MVS)myj}o8p-m9ql`2xG$d!$p}nSVd&TZmt9xx@=G(PJH}G04JEe$| zuZj_KqY{Y+V9uwVI#)ppgUy%pxX3T`hslM1JBi`@jbDt;_3^h>L0F+W{u`!*ZIl`o zUl@W`1z9{RKqidO*W|jl3XeBEszdlP<6q2W-CG&O?If5dP91`ld2v8KJQzvia%a`bZNT4Q0oqrwCl z1qC6t7RsgaFg-WC%lq;)s*V2e0f!Z)n62{W)HkYB*Gb{E0HRqKyYJseOZ}!W!I~rhAIG zNr5i<6}V#sjcYO@t;fkF0`w#G(RFs}fu6{!f4Ub?b`ELD?S&mJbncoM0_=u%U`E#A z;>2mv=FL*%RUt8~`6uzxGvp!7%L@mQZHJh*0sA1HJQw$~=TDB1OQ8nOwJxwo7ThqQ zbIV}u<+qmWM~2U#{{v5%)i4CH@N&KzJ|lJ3*93os86!Kz?O$s^cGq6`&=kWijx$Wc z7G?r41Qjc#s&jN7$=3~Ft_Zwhd8BT@gy^h;$aij>d0G&BgOS2F>U=v)-bUtbcGyU0V#?-+A;LuX;TMWGa&u3LxnvyAiO4Ky|u_Ov#x_vq2xs2>?2Gel4$<$X%Lyv|z*TZ}O zY`)YV*vV?2mRu*)|Jh{ZBXAr^Ra`iE-?Nzd3bVO;#$O5SZXP;DrP>ectn91*c!~Fm z;l}=py|2MtO&2J!_i{D**~vVkzP!y*>{XIp?iwIKd2vA2y+L;SM|NkT(5XM@al%*! z_T;hJrhSC-wU^49BqJ&DLJS5!B&a~$mt3&u7)^w5er2O))VIAb&({~v!2$rQh45c%CAO6&CTxM^jhHXDm|nCUMhmfLlb6mQGxKG+(rVz}@A7u@lximNy*v`Z6alVmdL^3fmSaqZcH|M} z|Izf_@l?O>|L-I->)4y)9D9?p!#SK|?@dcemL^$R-BqQsPP4-l_M_bbA#F3T?0#gGB5g^viK=TS6NbYUEj=MkNeWccwc z>hCO;>-u9o_g~dFS{(Ev#yxlDj&6D#;`BFa3E-I|CIY9A^nYAc`AYxbH5Vz1;dRbb zopvtKN)HzLgP0$~ea}FNb=GnKvf+y+dh`n@Rv6bN45@37$k3wvloDvbSK`&0fRTMX znwXP$x6Lw{#)2k)6dH4e{i)Rx);tgs$cXDR(Vn;7@`5Do~5?@2x^;g6;ziuLl z_-t}`z{N$`m3s_Euu@RLB{bI1^Y^{F z()%Gy(gg8y;7=teG%1pWMeEss6^c<2pIJ^%Q@;s}MFf43+VB1nPTkO|P4RyQz#vA9 z`R){o{@OyCjBR{+^57R=>)$1QVW(H_UNS7swgZK?P+dco+2CP{&B5aSNg-+T-#r;c%!E0wo__#XYy-2HiuK-Af0zXa6y98T$Ds z2RDQnOl}>zT{q6*FRE>PPZ*cvgyt&&Ij+IR9SE9w@uWD6-ouH|`>L@ZiRMkQ6Wc-gIhd6L2XeD}nxcG$;o5d@ z-hIMn3vrlS6^5u9Gk{v@nma&Xj1Sb#K0P9INFbZYYDcHzX+B_=zI4&9=;@xI;WHad zOy_j))d#K?0ufk+(f?&0$dwSm!}c8j6??{>a)+%O9a9|8>#Q9gGT5y5svkHhFmCqz zP3X|etr|>`q`wnbj0!2`c)E!wMJ=1b;0p(~KVFKTbH6U{MI6$ zoEMs$+l}wJgdw7#9*LxE*&Ue@NcDr3U$Sw}LxOe%Iv&lsQdzUu$ad&;vY6nB&W0{7 z*D!&7zb<47Gn1Z9ePC~hpV@DFC$wSNZTu$ku;_<$*7oL)M?BcoxsA=80Qj$`hA?}J z120~WWo#shZ5}|kme(kwiT|$u9yQs_N(}2=W|sB%5#8~LsD^8eqVO^K!+iTGD61?I zZ}ojns2pk~aL-5RZ_eI94q1a$1BJuW>?e-Lz@P~lO=FD2$slXC zK9h2v?2r3uC+h&n46rPDk3X4w{@Wdu5X3JUVV zdW(WIjIsA3D2X3JDDN z*%WiV5;SO}5X)>E3kyPq{~_BME`u6f_;}JgegpfAw}4HgrTk!PmD?0~@$tZFH>NgH zi>;$8FYNdC4vPD}OS}gGiV->hsev$>J@)zx*<8f`rFD2vP#r1qtf$3R@#wke*-lxR zLAF?N?D}>2?I@YDV&>ODj+-;p<>(Ip;JIX|%g0F0#7U58JUSG%UYo zrM$Qa6(mV5o_IVs7rZ|3KIgh}!rqKPq#*9b6XWuo17nG)0|VV6s9LSZ(a*Nr=__^} z5A44b89*-{R*OKo`Dad*=X-E2`q%}~sxv$m(wF}wss49sYADP2$f5N5NR(r%kV>m1|Mwx1hwdD1Y#=e%2UrT$ws>@%# z3~J3%PHkzov^bE>q}Le!=Y?K~ZJ0ha2hb#LKDPz-9#bIJy0=8%3iYUxd|E_<-}}0o zYF=a#$Xe569tr~KY6QAC3$is|9kQZg1chP~$Kr8R>cisqaTH-+{3 zpV5&9lvYk%kPLI^D&_cT5Ln4xuLX`DUa?c-)=2z~;N`Y?T+?~<EL|iywzteC-5^Dr)pqH^I60g$!fUvI{8Cvc+{h z0h`Z3hlehLO8wI8kbm>Jdw552VKC0JWs}0*YM z&C$GMi|Gjk*jvRrF=%s8pC`OgWV`wa8qI0si zb`g&qx$I;j!wQ5kFs`3Ps8Xu3Viktv`}XV3Y1;>50>~OxZ_C2@@Oqe)Ri*OPJcgL> zuL1@|4ldcJt1ADohTY8IIG@aH-E;oCK6CN0^Yv(C<-IkNqV!wU)E&QDdy-G6LBpmO zj44QULgKy9$8wm0k@F=$A?7*f1Uwe#ZGo$S2k<_{I`K%~1#KEP26hgl87mTdk4g=x z8YBx8y{F5G+0iF-HnU`#qFzX8@P^Z>v>Z!?yMIjdA_hxxSlMF!Wc)Y((ONc6T(Rqv z;d2@>BU-SPPCugwqvdd-%`roAU;8ErGQ|)H@CEN^7hd&KC*7B%Fyo~>m zf#t&>)>G25nI8=S`NKZw%U+p_j8M1WcEm)rF||7RLguhXU6j?9G4Cso%a_iL>dX_W zqEa=Pfk*)#a|c>pGH!C3;b!p4Kq-C+!~wc`*Uynp`IX{b`;K_C{I^d~h?f<&4zd(n zjUe{1uuW~kDa%R>kq{6{o}3@djVQRvIH3R2AHfjg5amf7&>v)OBSX{}AcosTpbci$ zKyeR&!+j~);UnX<|A2XDk>^GU&W^VpRHZD5^Az&x3^6=B;AE5}8LB~^J=?++Jj7Ro z-Jna#?P1{NS(y^CGb?5EQRMg!s`es zUbAQ@c_gzp`h}ne+fQaL{Q_Z9wu$bG87e{=B zMc$<-7cmI0#mKb`U{&5MDV>y9-MHK?D`A)R_DnZG>k zFBnf#hyB}v4o31hHa`f1;QTXlB&09ye(H-^t5vl?a;p3qXURh?7626I1o|@j9B5#- zg#4A05bgh#@SwMtwzgIC)s>wXu=SM)x96E=Fgz-P!x%11{6i^EA;MPLAz^8F#YWBfB+H!m20B_o2`Bh@Xqo>mg?;_6Xf z{C6gM;7IL}S?8%lh5=dIhOh$tHh-SawXrxgh#($?>vGiaJk~h5#6}w>LO>-E(QKJ; zE6Rp5Z?t=BCCa5ah*zgdq(TuoD_>tOAjdFpwUG&Z;fV&fVkzTMP7F}T(`5ZT0kDj} zx%9n-b{oo^Vm$zsqy8b9mHoJ%@|bKE_!b3+ zajNusS*Sa0ae(6x)}=5_TXp?^>v&2rgV!u|7oV=2hN7c@x(FJPJN|l}bDI2q@)v|n zRak+6zl+Sw^I~>-BqX0z=twOrL{$yevuQPhjngq=&n5^O9!<%SVRSC zrUf!+4a)~qeRF}Grtw(MHx7z;y|0H>H}|#>5w=cO{#Zx6FF@S>qXpB zuEfVz)BbT2F(ce@nU=9bApxd#(7}4jS%Bg~!kUkN^xQU%lLdu}pYB_>9cnH-3X%s_ z5J2dnb^nfR|M8c=z890?L?22+QQjNuSEgRJ5E5P^vnjAIK&hZhPh3v=8%j%&KqC6M`Ep3cm-4#1> z3nURExhStxi_4R^7`JNP-LR(HiJl=091jlpt{K5fh&L|JCEFM>qSXm$1I!xq7^!y! z^@(X`U<&#wkhmm4V4DE-d4Gs`v}rT_mU3rIgZI?8%Gat+e&OI=*BdJNyLt@hZT|w| zAf3+q*I$AhXpv*w0hKJfU17XFz+MoE8KxQ#6KXeMC8%7Hr(>`iqvnB0WvI4K7Q&+^ zF2Qco9-i-;mF?wkM?=v91M`>y1~di5KPGPg{vs%=c=7uw-CUm;OmW~1ir~a#H(oGR zuzn2V z3}N>!OK5Q{U-qD!dQ#PidN{-KAFn$2W%XQ+k|RN$G2PL(Izz}?D=0PsfkQ@)D`!%x zOZCzU>#>A@JADu+&Oa$uopxIvt=$)cYHV8{xYck=XB`J`Ykje`+3W+H|7s6a7mtJV zWU~nu0js=Q`gh8311=$k0E1xeKbpAy&!vB2A|~OPioLV&Kxa+tJJ^MT7-9@7QhnwA zSJzo5=b7w++SR*!;Pl+j^^v{(S3j2*)Ec7Ay~31Pl=HR=S9hoYR?O zb^k*WiN%Oci@RKHX+!m!Sa$-ngj0Q`^4ze84Y|nj%3TM6zJ(;;7R72-o})mqtZv$z z?O7%EzleI3h5jxVsSk`x7QMnqE}|C)O>ZU|Lgj|JRNm`NqEU(!bUag*CVlB9bTyAz zDoUwUe4s=Vm`a~SC!s2}N3PlY&u0VyFJJyOuN2{6TSQCebz7$Ne_uin7Ej+ zKUX-_#3w#H${0DhL@@xoMp|j)$p{zk;=k-?%|Jc|w*`zC^zwJDwl51-yp!b0i?u1q zRoU>wQ@*R<_xcswuL>e{ivAS}k4v6t5&_N2>YR}n!HFNdYtL>?_bS_bgOt7uFunx7 z&(@H3+q2uip;k~iwlUw_$$MZ~a*2#aFrhrQg?}qxYIC^E&#psPBp%uS&qlJsI1)?j zeajR{6F(|4`)EeA(y|&yOHZwCd+#oOYXu-_9Zt~Lc1c@J02eHe2R0Vgm2QSO z+FP%40DLY#8FPo(SD7{`V9vzh-&!IV2l!`?Ed1Vx;HsZMN4FX>C+EEo30GfRFvEnBR< zBtB?tR=+czkZ203fr1TP3@r%}Q|%JQb=tk-6iSqgQqox^6EU>(7XyG;L2_VKWUG8I z965F~wdeBuD}9278^zds|YUlyc;91MfuMLOo*a_by|M zPpa5H-=m*=@WCLJ6NV675Tv|jk8Q3ftE&Q-K#_mQ5~JcL)bsS;YV@(c1L0ywyx(Mv z;aM&-?moCLT-aYH>Ar0i83mZxy|<&~iAPBze^TTRSN7~6oao_%_L?kO`_8-{l4uoG zR0%VVA{-2?=2%(9b75TB7v%wKNW;5`dS2`$M)IMrvD_Qor*3^pEyu!%&l9vqQ=HS+AN z0#(ekafaUk1!r_|xKIE6CMNQ0eAMGli7Dda-r)?9L@#-&hu*?_M6|w$E2Qv&Er~Df zxMm9dh@$)oU}I*k>2Fv~p&E`tTE>5i@HK9kGzT6Aeflp8I}{Vozi?<>!bH^gr2C3+c@V6`wyAw*KRTvb z5MpZ7Wla;naHPefZHa_Z)(fCxw%KMreFT}s%(Qdr&{R!hodyVRyIh!c{x%SYXn#pc zlKxi*PhyD8u{S8uB%g4Hm8R}ER!(6YYm0l^bOi^xolxTOCefB$IZ~?#zJyiBIBZqH z){Flood81}CtI{MrUymaa0~eGt7R}6aLrxW@_f|%VFWX@K?LxKSA-xpHkcUTP`y)x zkh{iDJQB2@#?hY`Ep9qBk2!;Qr!|7@JNd`KA5+rgvG8*K%YUVe1H~OoF-EWq2VQd9 z6of50)M9zoOH-j9M#hj6u-3+mz`BG7)@0tpr0ToqE~kg+OaTvq;Ko*rwZ+HWAerui zb~@@}=!wsuT4CY;G<0}B@+9VU&n+b06rE2EYL(JuagU~0M2j4s&mG-5v+CjcYd7#N zj!xC@MRc<>6V_aD`q^3ug18CeEAhg!b{x01rSulh82y2>uF*iAnZz(J+-s05|4_dGw!Y! z5n*HFM2k=6S4ShcZX@(5hH*vTX!Gb`E{r453*2*#Cj)>K}w+Ll<&u!e~(ocreon7=M)bLcC|q%rxE$JlC@c&oS^yV3r|C#4dgz@GSx)Io&7pzuhR8PNU9%60s@t z%AJNPujyxCj-h0Qeys#-yVHNEU~eWjxepz(2`J5N;! z^>5k|;W!Wc7F-o<0RL-kjACOP0H_&6P>lD8@7WivLVf0mdq7L`waOo%QCam%%b;3| zwajVI=zD)0=+|5#18dFz9$$7n=xabHDp_B?YA>l--8EMv@xDvuZ9;u-^%ZE)77sek zpDkm#RTq0VoO2BJT7IcLitK3n<*_VLM2Rzn%^z#NN(H4$CQzago@m0R#q0h4!rSiC zJfM9a?YX7@p%^C&X-Mjkl1LqTVc0!Zjjq-MUZ7itj7KNT)|Z{!dL;N>ZR9yJtFm(Z z_BDzR7W1dIgkAd2TUgzDn4VhkIs2SoFG<^h zugvGS@C&Iu-(LDohapt0hCCUvTnecuT0}R8foP$ow`EVeP~RYZDW9T<@`oX68qkQt zTLN1^D}c6t7~qM{<=&45O%`aXB-(!dG&-le001Zf{Tnn z9yKcNMOpDU=RpdL1$cPvO`(ZT;6QL_=O>;pZIE1lf#h0eR3DsC z5%Yj*0$p#$rSaaN{;jh_7y%bC9Wfglv&2azQ+9rF?zrIDkMjbw2+qTLser-}oejqO zgi0wiTp2)#TxfTdi^3YG_GSG|Mh9Y%z)pN{UY{v>!oA-wYpXCE_lK-K_x(oVM+!R7 z<8R~5P@RpirQd6n!%yLkMxDQQLvE^Sy}8&NTItnFY#~0n5fOd%?}TeNV&=9sR}e$% z6uOKg8YYc8D4y9NAs#~jAFzM2++AH2ZS@wR%(kqx@S8A77>UvH_Uyh}94i?G^)Nvi ze{EnK`y|zeBMj*zNCr+wlqxVh<#x0~3keXAi|56sHozyoN-lqM7m!BMB5_KxyaPf0 z5e(d%0}McJIwiH-?SqcfrBfYC{U``Y%=8s0)&Yz+N#_fW(DTc0C3`6Q6Q&<8;)ITH z^ocpoV`s0OxJ|uC(@5wEoZ2QNt9-G6iH#CF&4+*HgjM2njc7&zwSv3OX|w?`b-?Y% zfQHf~MXJ{DDERkAEeMGD3ZZ8IuUfi%uL+F}&J}Q6y5QP?oGa(3e()U%yU2)6ATi58 zP=27EaHWwCKx<(NhOA-RY`d4CTE*~cy__rjS+Ns|H+ld685gh#@W70Qakq4MaJRt# zxM~8rLC-aV*Jt>To%cyHWwnlEfE0ZC321yt>)yI`>E+blXmID(G0I_!S@Jm@h=ble zqoYYlzA^1NTqY$S>ck={(KUhN_#rYLywn(#jvJ&Dzox$5RFATZU%qWXXaHOi0xR!% z1aw;BE}v0Pz6vAOA9z8(zHQ^|?gpw1%nhqWCp>oAfr*m;+cJN9S znd0f(!)eM^8fiT0=cPZ{=eW$5{>;jn{--Gz(ti_XJuMgALF#jJVfcZG01p%-$~Ny0eT{ZAK*A1!e*8Wrg8 z{GUF-!lKf7icz`Wa<`NI6IPiKhGZI$m!Q%BZUu)u?+k#yX+Jd==?wI>KBKD=9Jbm2 zd=pJTzQUf3_1C?(#GN)aKYt$R<}k3>W3n_0Ji255Rg@Bh+~gtLf+$J6^9~r`jpp7U zGJ-Yp8d}_Fu%yyg2>!Wf60_uJ-d_r>me3os#Xm{_TSOz5Uy1?>vL$-fxnx zSCUR-dci4}#-*)ror@g!!%#~{Bpz&-0Qcj+N4GjkF8=EXp1v%9$mi=k<|7XP0uX~) zT44)+P@du}zhb*%mW*|)g1V=;rx7-FsXdFpY0wU$F(+GLVNOE(t=d#OFZsZ+SA5?k zs?H;j9HXWmQ6ad2#}u3+Y~1@QC_HFVMAH8w|GI{2)#$EP1V~ZJO}9dj(8NkzY{&~= zGWXf6nl5X#XfmLQ?sq=dqR#UX00--X-+5ZSi2)!fzj7?hl&M5uN)_Pqn4Zff-syH7 zqoM-jr&zVLV6VFYqvahVg<(Bjjlap_N9Envu5NsKQGk9E4INN0Oki<#5{+5=Y)2!S zC=T0`IOWr7%VphoNKixpaHsR(nbi9*mmw$3snc?l_X|EBx1~)(K-g?x`QFHZA&<~s zG++_YV0=l~P1!r+86&)$6$owQh+gLlL*@%?wqJUTDiO#HaXN8A8siAVzL;&u%KefuKz0diRifE88^8FDU_*GA2E z&!ekhsz0Wy6;8_<=W_4|13u1k+VsK83VM(pFt^81#pUfq7{WNbR}IF+hcmf_NFvD? z;m9H>bR*PJU``#>wP^GEK(Fwo?V;@c{QBjDdeqeE8`Of#-9YJDa8FPF1E56%1Mnw3 zetfY>t8+f5d=Jn2sW=+}!fijn0N+wy;{DY0`eITw$HQW@)_DI_5PJsYq=5rl9U=Gj62r3FMo~T4 zO%||$4AAjFctsF5Hq2jQA}Uxn9$C(6go#C0NeAPgK?@@J4Jb zZh&_lL9VMf&J`fOjaJb3OsJ*@6=ue`YG2Qs9^Axk*9#+cSRMD$|Z4Ta=S>A_KgxQ|8ztZ3;I zC1`VrKYknK(w_e>Pvl>x4aTNWYf>vF6&J%ETp#5=|GGOd;3D^qZtX=nD(%gu zLhh0n=)jGwPh7$XPrI@xS?A0EO0J>b2p~(1m{9*dZOvB$;`iMW4b!XLM8q-WIJ@~zy@}J`ju#6T>i&4 zNxwne*wpXwLet;)HuXhRYb;qg@7#VQxQeaU>-wO1P#j3+e=bF$sOpk~Ss&elBR|EB zJh#ExrV@si)k$yib{zwNWjQTaq>c&n8wJEQwu%*S$3XH)ZqAZq!#XqAi&LHT@(4s7 z>O%0urlE7U5GeoC3n|z{6Ewmv8^OrGJ*`kITyZYqoN>&*n@6v=~Envp#I7WwnXA)5H<-f z7JOWLHbBQgMn2}-eB7{or?o$k$H;$rtU(BuFb%C{#6`o=SF>ue6IEEb=)w7`#wZ){ z8MqHrDRkb@zwlC|;QuWJLM5WL-r$~fSEuR}u*i**Q!!Ox5!uTLdxAWk2XeRwKBpS%cHX_%{K~8Nh4?7&(CB7L5oNE zYXF409h7JB>xZ1)p<%7WZ1$2jqsa(Va(^CFjk1Z^Zla(#LVJ*0#QbHG z4yqUm?!pH5tk9Jsp>iI!u~=MiFC@K`vF-h8@n1~QsPi6O^=%Jz}5v}r8V7E<6Y*l5%R2rG`gQTQNVmU&f zDH+vokCjW$3lVUqt67~Q$d^|c$o@gJHpp=P>7O^}o83d>?naig*KPI+lF{!yM}ElI>hMx^&as|KvUkUOLzwog-PQ?s6(?OH;p&UXija@R~+} zE|Pc8TQ?)z@L!O{C}G?4=xE$q{Jn{Tzf4Cj!*>wP(xGBQm>v;PmotE`aspDV!I>SOB=3p*80Cs(HrI!g88E6)<9pv^brLmiz8k5?s{r@ts88W;d|D*;&Er<{DYu}gJz(xDVs?8Y%b^u- zNi#Pdh7l9uMaSV@)2oLt0{U~Vuy)4FU zI?~(dYY2x(B9C~e2s6Jc!>y&+1PkoQN&Tx-mw=l4jt>j>eNI;Ht#y5=Qm|;hAyxJ{ zw4S|D-2&Sbt34Cb0Q$bUcde8!EhgF-3$^Vsv63RVXesnNTuRg5g5>W>vt56Bt2a&} z%fOWc_3@dTeSLjyAMC*fd=Q*;;5+#kq}lXvqx7%Son`$9X%!<0zh;F{F|a*+3SL_5 z>cc6qdVWpSVKQKIMsB4gs<4Za?Tmb``ZZSC&xn5DV|RAAe(PEz6zw%8)+#$7ki8fa z5YqpxR9|UX&ztQv<+733;P{|(ex#1f>z*vK<>P6axkcN|=8Pt*eyOdu*U|QthqG}v zkxoJEJ0D(8?#Eu~UGn?fXU{kG8ZDiNVle4F!N#!ejrlJN1@n^LMAodC!fItGnJ3u& zzWR6QpmMoq9YdHZ%TG(btc(-3=>A4&$Tz)D9|O0v)?wD=^m)l%v$EQ`My+=bx_%$7 z_q={FW^Fo%&1G%uNjx-&y^)X_9$#Q3R=Hu-AY3moUWj`8_K};nllkKO*lUp(8dJ@Z z@aME#Sx45EO&LwJdBv@z5?azigV^6E3Nufl9O6b~24yUu>4t*TrIYMKo25?j`%fVx zQT4OecBuTqPRxMw?92yesGN`0_uKnR&3s`X&j|1`{GlMq<@n99?V?rh?SoH3W+6MN7w&Zh6DipLoYGicKR==~KjbgY0o<=xbwq4)V+ybh|6 z!ah-fj~ZN7Fqe@gsLhL(Shtm0h&(4!FA8UDd^@LW8*Mms-FI_7SsfC`yuhYiptYV< zKU+Vrj}MuCF}M{&Nhil{>;ADG9tl%d71IBtB|T`)0f?8O6Os7(GR)nQZl^nn{Q&&Q z!QUG!UaEDcD?llQQlapvE{-8a7M>3uZ3Qi>NBBFR>pTiAdszwJW%x-f%UADkxie^u zILHoSr!H+R!CO)}iLYQCsDv7UXNlMSsH;CT5MZNjTD8@%b*x>Yq_Sa`mL?>2D|Rul zY86(O3QH55xK?8}FO$m6rp8PDIgZl@lVHoVS30(`E*YM8Y~Vg>wdUT1 z;V)C)zo^`CaZLzm z>+hp`0i`#jrDWt*(PA;Q((Wb^W0Y_roo>R_ zS*hkH>LMQPo?7%$ps(<~CS|S6y_is1(pyV^S|qI)bRdjdywq?%@ly$Hw)sMCRxw=z zrgSsZX)&tH5~m^p={>D@Qx7+?&9I_1f*$I_Emi$zZAP~eVPCXH{#e_tl9dWJpBxo7 zz%a92U1omQ_HA2|WTvzyn{@{BBr(87bkig)L6Wg4y}-sFKXBD_^Ssw zQ(aS$DFKKVUS!c_wbO+H-vfk841bKt_cE5AYq2fE_+ZTdFwxE9- z2JmTPz6O!{?@MxjATK^J7HOmX@pATEpMBFPccnJzUT8oqC%X3NkFUUy#y2gdx^!lrb$xOF%L%cG6pe?TW4*Q zO*Xk_5{ctEMCEm^uWU#5ooV~Ht))WBxS#sF2+Z)utY$V|*U_=4hmRikf}=2;mi!w% z@?a|CRXU}G>X?xS`TTSL6<%OD{C6~ZVjBR188_X-35Wvcp}%O;x! zY5S}d?0x*MZz@gkH7wP_klvv;zFVw~x=8e6P0`1?XEvR=$?t~ta)xiA@12v?z$hs# zK4z6!V1J`1njQTgPPNsG+X<_w;^f4fbjSuZco8~|U0&_={H_+}!bWrLGYm0K&fi=e zO9Kx!BLifJ=#LwQ<2n?-`MHI+7MiS6(A*4Fh|K=Hf2HVsY>PkQ-h&O#Qvxy-(kC`F zG2`v`Oi0p}&6L7f=BQVTZ7cEq%eBlSz7R&-(9S!5n304YE-$8mXS$T#r1t@zHgTS! z_>;aXkAq!(OW164&i4lNt9wI|9ey?keKU7{vB|0y&2cnkUC|P&6%u8hVMyK;LT_O= zF!W}N=q~;Xs}Y2ed5dq{n`cI!SG%w9GF2^jLnmuyn%&!)kb|-zGDgh>OixPkO(ST8 z+eD3`@b8aI%-|s47gte0F4ndj^k^CM!#69gOuK3M!|E$n%4`~$*WRp~u@LiGPn>Oj zcriINAB=xA-dBo}-L!g+FVN9E-w~Wa#*;YbO0DhT`*@7Vtp(x&E}`IOz< zVr(b&=GMi}vi>3D65;QbO!yYRq<=3+MQ!nC=Si)({jH^@^cNrK*f;-9mKnZ*@9*nU zS~MLqimz$Y&dJ=jZ8f*EvFQl(x>xp9O)y3$DapHhN%T#HfJ(MHwINMph{U4@-^$WH zmw}lnwj&6rIyP4kiYgY4-~53KJ~U(p9bvzx-=(s@K`*w|KkN`W<+T~N+Mh{_yx>c~ zK#qjXE6q>kd><@ZKPz*Hbx^#g8(809KRa{kDPkz+#DIPUPJ;?4UBrzh&V`!znJhA4 z_G*g+GWC{OUaDik&1$pQDk_^li`1&*p||g`KYl{_Xqno5CH$=rB#*fvoGQg*2}Y&X z&t>C48SLmR!ooA-L$-Kr!+eg9Or06r{ec)Le0`5zRxY^V{5a_HIEzEW4wYP-a@`K8 zH)*H>evAG}XXIac=7!*#0-h^L^A4>8tF}&q+k~cA`zIVm9S(Jtt<=k_FfHch= zNiHhp7|Me;ia1<8=2zTdQ(U1?>`deI?=Lj6?COb-=10AZR)~pIJhsaiaaA+{T9l7Z z0o9^KD?O0f?xrJ(CLUW!sO2S7F9Mh2vB>S%IB4z?4@Fx-S}8n4v<;v6Xw1#gj>6Tq zw}~5{Q4Tftya6`}AXqGm#nCmc5pu-5G~0J}I0waRcqe=p>bIZg<$s}Oi202r9+@A{fJTfKwis)*BsL{6YcVk?@u0PAlWSL5g7U9iso(BXI zZM6`Dj$0iwv)_0URcLBBcRP8otEU8V)gN6I{F1R>xC-sc;C5txIm8NnfM>uGNzU zjPGKJoslX_nn78k3%IjvG{;=n4{Ngq1iG(Ws-gGZd!qTbSubclgns_IRlYgQ7)TQ{ z=WPwTycKnHhMT@tGBke`B&iZ}uO6x+iF;AEuRG+Zh13fb@H&>Dnu&$p&{R z)%V`@sBE{F&)&zlE# zC9Zq_pq^1je=NjfW~%CCDBQ3sWq5p6w!s4LbhQVau%Y1( z>R{hPR~LG3KT_3d`im^+_k~L~O_b~sc~T!q>ce4h6YS!h6}i9k6Mxkgb@v?g5$@XpBiKhA@-3)E{)PUf)l za_EUCP>VhIK6K)x%AS5wbkF4CyjE&RhS`ns`djrsgC`#Jxevme5}xO=^mYu1=cj$0 zqhdRb8e?P#TK0^5UZT$s^ziPB=jT3wmm^E&a~(U=Y&=7&Bom#upP%UGi&sK1qo4g?&r7lcwi%^Qa(cSLKqi@<;db@-mI2Z?Ph>S9=A+ z6kB`ZNXQj$M3U~LQ@(U(;jBA#Pm)w{-;{G_k#WCgVfYdCg1v6=HbY^EI@Mgbs{7-E z#>dVi6)J3x*`HNCGv|(XU{Q2We5?}RWzXV9LIplDl$^%;k?hTP7w+C0xszI#d)(J^ zOGbZl^V~dOWt9zNmyP3;y;v{y-CiZ}S&G!*Dd%cVWUqUC@=$?A?gMp(yr;vGx~y(u zpDy1`KLdO5amj0JGV%X)haRbQI|^#gU#y7U&cq36@HG7 zGWRL56<*ej3s2B|G@`L6=XHfC)<$%N zeTeVlz2@Fo^=QGpSfAk-dY$cJoLjbg&ox!NVo81E<%z(aG^W{|RhB`{1^jc&?J~k} z*thOptd{Q>AZtoPm7kwSBKFaJM9o?288w?Cn}*BC%xLbjW5u6L6pHRe&1&qs{v-HD zl%u0ho;4Ib^?Ws&Z`69b!FA;Lzs;!d;?_m_xROL*Y$d70u58Y?h;CB>in5MKR2rKs zgE_Y>zF&Qg~d4Gh|y&6%C&xRA@}k#<{_2&{lzc02#|HQ;qkqs4hu7ov9H zoxlGnxNp02WD7>JQW3ryQ8Q`mq@JSzZg{K#>7!<&awd&`KFWT!iXiX(Gw!xvv;GIp za7^htk_~2I9k+8w*+YFosx4cs%0Exc&u$JG`O1EN)oz=3=}#b*H9oKR8pE;5bvCz3 zQ@wZ1G({>Ze;TLlZ&dG<{9?E`SnWuY3=r!5x-YNbE*nQZSNq+~9XP)1RbpH3cX55| zb0pCoa(}foFH_HD8;A>!xXY6I?1C>dE`cC?Q}SJ$<-i~(z8d)B48ha3UsHZ`SGwy; z@h_SMH9P-r^;xSVJ5hf}x#b*4cV2Fat&qCUsGaqmu>S8clw=~iX4EvKR98qU{xU%w z{XU7y`0+wCN%ay*h^R6w+8@+ap}O1pc*$hkAG7B>cKi-!m1WZ;-C3nXvT6ElSIpjK zkm;k!V54H_qyFE&Z0%D2+e;7=<#oBw3N{IEBeH zx366hd3&`5#etwE4VyZZkxcH`3e}!8)!E=`4f)8QEe08PkUb{IxauwrhTS|srn@+v zrUbSG$qJQrN++nhNJ8aI;^WEH`{zMAyX+nX#Wzx)=0Uamd|;gere%`&1QJDe5Rtjn z`D&y)G%m7l2dOd?_FMlSRc{>@<@UV~A5v-*MmnShq`O0@p$37WrQ0C|Bm|_pVQ2&y zx*LWPrAxq}8ziJdNdbX(^nA|ucfEfw3|uqMUUBbxt-YW1tQ{v$ECJI8s*-MkCk=uU=pqQdhs zlCBY>2+H$l*c|h#{uiBID^;)Qf9>-De81IfzX)95cp@&X-ZPbeQUd(pw`eGBc9s&q zJqkUem`L>kN|N|IQE0-ZE*XFlNy6-fG|}X3V=I&uqUYSlwi72UEmiPHxGuJzGx;>A z_T>CI>0iD(NL8^FQs+vAqAhKU3g#!UMLiRf?-@b(%@Qpr^$4luI8>jS2*N-I?QsRf z64X!AX3!BLE`Zmx7|lpiXk`Q5eZPH9e?8^0J}52?`$M1|Xb~tSsUMZ2A&*R_0h}|V z{TN61eIM^y;F0=R0i`EuiZ~A~t~yUDl#)&e2Ms{#J+g5=32L-Dlym@(TRyaTcxcEM8$g&uv#}}%`tycQnwr_c!+owR3J93Q zNPIPj@H@U0{4-ZWk;7zJQ^3e?5^*aW^?zlr`h+VV+Xw(%ye(}e(mwzQBVtj?I8 zr}NY4k`Wu_n;@FFfOq#qe<>HuDdWF(Uu_7*u4J?skqY+4_2)%-lU^t}3r!IV$2(`# z$}bry1G4CmYqX63mnOgs!YL3kO_L_OC}V&Nh;S`{%JCl{gcX^IF9zmqoP}mI(aiA& zM>t9a_%}=AwKIs04eGdS^lLj(I3{mXfiMu^}y}=ev*BB8# zR)DtM9W((~#^m`3Z0doNjl3(gPVaSXf$Q6MNBQw~p=F2ky!-_}2O#N27J!FwU-?6j zwYHe*w*$YTLQ3vt8;*~?&orX%+m18v<}8ex|qk&fme2SI9pIuAfm3*dv%7byE!-F(VWv^aqMK6`D&cF>i)-70&78CLcf{fh`qW#4cC z%l89Ih^h&63K7s9a=|YNix}v*KN%ayI=%*Y3aMo%b}&(2+~)CW&dDz!%HE){0%P0y z>=GiX}u!Q4-(wR^3wnUXAB;lMzIFVUx8H>i$99Q;6}} zYqY0|t2KHwW98y-qoE;+J!oX1{~Hnt^ART7$zziaCbZ|U1PwZY0^7j7?a&er&)xR9_TwV+8Ts|KGs7U^bTo88ucQ{ z1x+`GzF@7f1g0wVw`2MKY~5+(z_EqvJ!YHb@N_;6gg&<@fx=WEEapfI&CRzzMu1&$lS3c!7R;2IK>- zN8hnHK>Uo}e11}_eDV97iHNOo85RvMtx!gnPMLD@X!jv}&}{v4Dhv`Hkdsw%w9(n} zz>2hHjAtB8{)p#4r}iWOlE{|m7sIIpfSc3rXse^+!Z~x|oo2IaPjGtqg9?f;G}q4> zVz(s(aC0GQecV#n;8+`A(u?==Ea)2cxQ_OgV9RGFRpYg`-gtO7U#3sAnZ?v{Vt}6q z$o2Lj6fse>Cp0TIq;Jfp&{43pF|yk?I5 z)l;xJv$WY-$rj^ci#=mol(Ip_xcP&>jPEWqCtD!;C&>0s9^(Fal||$9aV{$ws8dcT z^mNojbM7AdDVDAKM(Pky62>ai^N<=3)g^dfgolo%u+pdFw8Eutpo+K4*N8Q~the{_ zeke?SH0#v{R6H_dP>aI_I1r(K=P395mUWOV3ZD_hJI~h~S=|c>?@{Nfu}JO)EUdQu zNng=v%wNG29Z-lUK8&6hdm-c_LHCD-qqM>wB|polsb+@f7#PZ1{L6M^JVLQs+xJek zBz?3k289-TpIJ#Sh83d1rE74x|IVK7SaekTtK*-j*7`gLU7htX%Li8{g2E9v|17eI!Wj z{x>`AN26ZIQ)mZqD|xwe9)P<3LGDxRx|509hM|PMds4bTi#7JO5!n+P{_Ar7%Xxu+ zp#4XeJmsFds@gfCQ*p6pN<9zNM+*2nm;l<(F~gu`dFO!jw{|#v?>w6nd(?TVEt2bX z6!~w)zLvh>4a^{n8=u>zpEfFIB>l|Ib#$6wZ~9TQ&?16$3p$tgQ=GbZ3~aG?jb8d3 zI1r&Da!q7-hrXfgpVfl_vn!xSWGYHX?Gbe?h{gv+%rLY>ba!}$DGCds%;Da~1w5@b z`^fhNKyAe|2s4)F&o!xXE2xX^o=P5!QzQ#3+m}=-82bE`XHlsD=U<)wBnmH<6~l2y zugKlv6fa-r{aJC8;=a&N60(=q*=XQIClMJ}kB+Iwc6h3HaT^q=A-mRPzUdAYA5z+5b{_S@)Xl6rXRPH zDew{>*(dt2sjDjCy8h(8n4^BlI^vE3x=5bE*=j?vjIVA^eUa{GRz) zy9IHCQ$)Pl=l_R8n3PR1Zv~%iYvelz;0EST_C6&{_^->(y{PdEM2k&HiGJ;t)vdnx zmR{zcPn{oU)Z9>^Jlx!Tck{|>)%$qrQa$_hJP6S==uvG_!hfUJ;JEqjO+NRIs`Edh zt|8HnAg{7@Itz_->&dVgpC}IU^v&>EhX~jeJYkf~zTO1tf^G{lRdCyx5fNL>IE?a* zZg-3e!D-CQ3Mxb(nu|LCF!0S-nz~W|g~D5QS=d+bvH`|o)7Ec8+cs{&UGmYh{vbV2 zc*1>eiZ5O;F{frE%JDNwS}`)iWQtY9!hAfH^|B+t)B9GBoJ{5FVkY4B?JvnVyP8kh zxmWfgcKk^Q;ynLN37P|kq(C;tXzV7syL=}ZqO?M}hxoz7?95~SDYhlja;)rc4htvm ziTm>t4d>=_f*AH7thsHKc*!N7p zV-TgidrC~_tmw)iMp*<^>&};?7)uqVStiFD!`gsAkD<&jx-F(de#g1XE%-Ao8tB%( zUELplGCvoWbhQWD&fD*6VlG;IQ&JYkH{zZ^mT>2!XX{9?bCX~*s;iOH9TLnJJMIeU zFpXsr@}rAw1mxa)QF+>olgFH;a_9CYhFZ=@+zo>bIF;!jB1gM`XCJ?xhPzB4_v9r; z!|SSFx}Z-4uDkFL=o%b6b_E3$uIf$0+GV{+q70t-%d5sZkVY=2by4)@7s*9>Q=aEP zRQ%GamgUXRRrz`;#@ky9!54*93wSkBa|9{QF{R%my^vlm^LIKgW4~ z>5^C3Ucph8AR7uZZ%_49mpJCeGeHgiPXDQgKEwmP9cy$Z8=&B3)3D5NOM}SuB#=vE z+=n+7FIs+AcJKe=)4~TC6Q9|@EOmRpO;rRr6`vsHcoXP;HsIYwN#=K&W)VRsc-`-+ zY3%Bl{u0;Mzsgi$2p~91&JL1Q3{kHDQ+Or>Mf)`~$te(D$Bm^Gm@ww1gg7bVIED%R zv6-dY7jsU$c{yKVuYh$+rY0GPK&j)|ma6$SE=;D|i$HF#CDP}&A-r<}#1P`cxR+9i z-kVf@I+$uq3I$ft@;f!yc&JQ_<$uj?HD12FI?MbXZBH@dTo}-L!F%j@X~y{u+Uksq zr&J2OF{YGZZg1l{{2WiM7@x6=RQ?|6bis}M5jsx0&Dr>>XG?)LB9<7+&sVu}akI$! z_WibEme8}$LtBe_0^kwG-^~Th-KbnhtoDUeZ%MI0MsQM}yOnnZjOoOEwYqrw5a{Ba$Tm1(_Tuq+ctxJjIxgQQo*O8T63%@@o! zfM}8yEvA@*7%Xzu&eqXI|LE(c4+@Q3nZf9R;B@^M4qs%*_=kE|tohL9G49d|4(d(N z8y4nscNmS0=5xBxOizk!MY$irGck(+&T}{8`jjs%>W7!|_T%n6)Z^VZG^x|=o$2`F z|G8}C3sk&to41boe@a3-I!(LTs=hDi&oC>#hvXr8pIaVWqg+ooM*E=v9RszjUXr@9L2bL0gp8M+lGpmv#Wy&#V!tF8B7?;jVP z+_!Yuku``W90ZH(nRMxe@?pOVXFa-bq34GLL#EkRe94?hb!r;eBVW?+@y&)qV;>1$ zthM7|zh(>PCl|Hsm&(po3LOBs*o2MmlK$Af$;beP0f6LP5K82C-~8ic-iVHP>dtsm z66#RXmHQr8U|Y7OSKTi3&0R5hBlp>YB-r&0L0A9ugE4qDa}ar5q{&Wh@x1Mg{5O>24O1APW=wS!I3iF z)Ae6@@kaH_u^UC_quS`o-KG1Kz1-I=Nz%@(aNHh$tfCerna@>^bChc~#Bw^Q;dp2E z2Xt+`V;^?>#Sc7q^qk$#qEQSjg7;2J;ZK_WTt_^-`S5eoMwU~=xZf$P1;+f_iKu33 zT)HjKmz3g*XjVj^3cu3(r?_PJ5(<*zQD+kIXnDK%reqcqDP9jJeT(9Lo{x3VnK6C> zXz>j)4q66mD9}Eia)lt@|LnsK;E~R0$Czw=D9Jr5WWoAYnzG@@il<(^dgg$U{c?t# zwdu)k_S%5uF7SC^;HDH!Nd4_j;)W7Je(Uczj8QT*{VRDl>jzOs={=@O0CS}pJb;{$ z9q=R<9{-3=bl`K1(_16{io2@n>I7qlgKCj$eGzv_230*8@x@dUx?!mNX+I!Qu4*ARfxo~V};ry=;kuUu&2T=t`bU$37fgi}*W>4dWL%z1x zPXH873T`xexx7=qG6L8q%lI!R5!0{ZgH4zT%^xj+mFEB0;|Iknjlz=J&WyUIeYy@N zA-q_gR%F*wzplUaSzd8?3ptFEQ+5%LG@ROz@}SWq`7k0qI>hq3t#)wZV-^+Nq}XX^ z&qIZ7Bm9UwM0@S_X;a*fi%_sx(8?2E;fYoZbe~I_vqbi%KfU4-@KB9UWi2eE`Y0R} z?PY4#90*q%{<-YJBe^HFR;v!Fz~NcBCSlcgME5#>s9*D5k#p4u|2qjS2S%7j%1^~t z^IG%qI#SWH`r2{4db7Inua__Bw{SdD5+kIyaJ!eVVm@KgJ$S#cvo1U_zVBW+5-8cv zJrWbwdsq89fv0~}nzg5^)*@N_GET)vC1~QDEmtE(*fBT+U4wd0+Y=|Mq5OtqLb6ep zh^=!;Cd1c!TpzK~SpnEiaG}gZ>i4f>T?q9m-9FRDO2Y8cv^$nv((C4amgp(VFC?}( zTKlATOLEDu*N?ny5gh`q9|b9Xi%C5vIWkLp!P{`VO{0&H>naxM2KCSDe7qSx+An?L zmy4`T#Q&{)@W?~L5&nE+G?ePGjuFXSs#aI;ic|;J4d(drUckfCgo(b-WrwTd2S~LC zv1aWLxmCWIU^oS@+9lJ4pU%#_WUI3ItU}zR@c7LWr@%rx0zjfaBZv_{k+|grR@q@=A|=rfAT<5O z+b?O>((#3FKp05Jj-pflL8bbtbZ!e;C9f*s%PimOft77#33$APe?PTvWygi_o6)9= zy33jC1Mw0VhGapn%l&g}wGr(QMShz-#%FBD=1C8oeRKLC)(TNCt)|PC>dokr`ZC^3 zjqUb}zX@*nLU#~R60IdeC-1}xmD4DbS<>^Cra5V3(ao-U^F_Km5I0>jGGAm5L~Z%XmB8 zCXglqr5gMiO+dSWpEBA2s@Ps}GUSEt4Y$*rlGo+1yXOc{*GFn|T{lu_M15SWqX3;3 znJUT8h0VOUG8K@Z6SY_H6)Vq;kA^CKm#R-HJX_5;kQ!X;j=b3wh8Z{ag?nowK~Q{6dwwov5(G zJ<58n_pxa_4&E4ZS-uFH-qo!!P%|siH<&-teQk{I?P`>)ccADmJ!N7Am4(a>5hlRs6H3&!A;(HDI_k%dM@@U0N64 zE;tfmfkWfxqh9omH7UNNQRKZPqI@LhUNfX@lazm?HhC=4@Oya?vqS+U?&Ohrjf-q$ z>X~|PW^t3k+W1TUujQ(`dzbX4+(Y>=5-X>hKqhGW`jD2nCoojkO7+k{j&RVN&ewwQ z5R9XVKW)d}7~b;<6=|YrWagUYnWunT{vwO|2S*e7J(6X#Vyc_%q_4<7D}pJ?G7M%V zu+BPM#2`v2MpF7fvfsx@Qe{(nPK!V^n_HEsDAmAsW9}iDPoV%?A}BrBHKw5vGFJzT z2RG%7vM&=Js*p&tPZCx11eqDuSVp@S}KgbCduD*P=k;9N9nL1ulQmV^n2dpgT+Pi#AOGd}{ApH#LirptZ z%qt@;CD+x)PEKAG`ULP@lTnEy1XINaUx&=rj^g8jMt}Z-+SwhFmAfvC}Pu%oay`s_^xi%GGQf9^tM z!EFBl5C&;nrj;P=WXD#jvLNT|w{3bNr-5pds8EHOG8FV_spCi*GVeic*R(!=ite79 zJt~SQ*iejvJyJ@YbdB;3((Ti!356(Vz(B z@#uA#n>BrWU|LFTGFa}jEmvdsrgzuTia9hUB>5=h{uEWuVfjh$lOJ#A-q>F3I)6tG2eba+JU4~CyPs4^jxe{hJGJN-sTmnJf&$_8Pe zeG!%WU^iHQmB|X~#1Pw88}ZO7%c7~}4L)`wuzXSr28i%G6z)2@Dz|=2(8-FOjmgJw zVJx)q4>%il2JZRt>pppDhJMmVJl-S%k>Ef^H6awxGZae8%njh7Xc+1=7MRg%*kZam z*ZEnD4Dx-T=+B>2^E6T~y1GB0ox5yQ+OX-v$qc6`LqV8LR} z85w?({U+PPXLKTZMy7XIow+GFmQZq~miu7&mOM^#=ZN1lA5+g&*x=->+)H!6yn@lc zvecD(bY zVKw|xpR~z&Zmx7SfS#PAIA+Q4Ddt+4FptPYgo3-5=CDBE!TT@8BdcjC! zW@LbUiRPP5W0Z|Mk>?9x!yRjAg4fR>Hp7tCZg5p?K?z+Ya1W)5@d^m*acuE8inYI;^H!w8x^ox4^%O z2aSk5_IPFJ%}sO(+GHR>$PwH^EaJzV#-z4urR~`IfRkWjRq_AdhLT zVZ2f?AN47rFVZYhl1`^Ip5r>rQf2d^Y$1VVYA7&YeaCfx9jF@IvN{y8xE%J9-RjW4 z;)S7#E*mnRe(zdL#z=E6g`a1fJVggbiRy<5fNVm$qEC3D9M!5xSP<{N-X>r!yk6~_ zqHe}(9gwfbOj?ls@wAD2)E-1|cmwlrJ$CDjT&c5PVt>^qb;|U)=Z~qWZ4^foK5B>H zM0{uZe2<}RG56$PLcdNx*+?x@wgQJmmul)<_J3Zj^lX+>Fp&fH-yY-pcT7i(EAU;s>( zpRZLKdd(Vrzw+E?f2}L`lk`d>>5%+!?4iUQ&#=DaYPBGO9Nj-_oy14CWl71qxf*a3Bf0FLio9NfFaOL+o6}I=f zqz)S_R1p-yi*$ozwUzb7$HJ*1!E!a;E9h`M-%dJ%YPqZC zTcMZ*Lh@`f9FRA@F2bm~%JYQW6ff70X$oc0FWV@kg}E!eXDdA(5*QZ=)IKYpP{MX8 zk#?LdO2Ct0(an5Jrdp#3NR!gV?5ORNOyo3w30A6$p7qz<5&o+6J$~omVN*6o;f2xR zN?1Kqk8!dP-M2d0>gWk0KEutj6{3>!QYLFnA`a)6ORba-Y%Hctrh*?UALu@@ zd9T#TL@2}@XdJblUdNwS$VeI`s+nyiGcuTd#dO zSaqqb*+8O$taP%jlwXgcCg-Qf+tCZ;TVC*PnO)v2UybdsPw&VW_3WYCapg3jbDd0PST<8uN_8Q{I`+$d5#`%(MCWIrQew6c{tS0|2 z;pLQaI)gGnl;lz@sxsSZ0VJajY1Z&g49&yKyP1&{lT^!eswiciwMfBY@BXs1+&ukd z?dBZvw*4c54d;&zQAK?A5zmMDWpg-c$=hehqn*L2^*%A@A zyDzO#rDp{Wy0&{_gB()QjOigkF5JJj-Xyq!TQk2xeq6+c#={x)*0kEogpB!@8*L^# zIZZxY+@23k;w`J5-+I4&;D(d0H*t;A26tDe@%||)bXNjwEVaBJ%cCnUxY)iSJ7>Ug zhoGuK%Wch_x*W%Ph==Z2!$xGsEDkBZfCa}xm6fIDH_Pb^vVo3d3EtaPYTew`dv7wAjRatw<~tnj-f zDS%k!NuoC;Z+m2tmXgE_-!s((o8^6tECw4p%S}D*WMT(Gw}S#+{YN`gAT9vh@|^?-VVW=t+}M% zDokJ-p5eY0hGx|5$^Da{M}ip?E77gUZ;$YJZIvRzVGCGuBc37d^?&5FR_*~n^kq@o zUr=u}^|oWKkng9&Q#Nox_jhwxMGRwQKH@^&OIBAPKfG6OA5fmLGfGj@p(qr$46hI$ z?)Sf!W{4G~-p@Co4CgM7k2?b{+YNX^Mj%El_Eiu)S??H&pMS1v@6H`1QN-NO6{G)V zN~mt!l5<_yU}4Esz6tEquuiy?_frd%-{*58E4@>+ezA5CeN>lfN->anNVseM?{i!LNqD5+mcNC zETdk=ku%HK7+XMS2#m`nUuLhto4l&X#&+V@p!!4)`?M@`COTZvn8?a{ zRk@BvMGQ>hwEr0gq|L%)^d7VS!?+DFUV4OHWx2M%$LGf<$_izV?h2Us5ZVk+_Sy z%~;RU9c^#j-wb`9-N7mUi0AJKx|CBsb^&3`!drv#bC|76jE8L5;22L4dV{Ggx%=pSszUleT`{@&kH_Qjru-V_NWc-@l~ktaq=9<$L-`s_BTJeDH z!`RHB0W6>PA1oPB-I2Z_yDZ;ciSn(&Pa##d<-}43mc8&z#HS)Jl^HT543H>dmV)x{AcGNRO9|HbD2BoJuH=#)fBWO6wv@GpO0OhdKWC`Cvo-8gk*)~l#Yc+#P>8IxT`iN+xn*nuzn zh(|}q>?IV3S6A6e(>;a}E6y35_HK>@Qp#th5(t#q8iiaTFg+@FCclr8 zmM7j@W7l#)#K2PFa|iVpcP)AEU71*MKhdjI>Q^r+i+-%oH5YWSDkS{8N$8OExVwAY z#e_ZJEG2x9R8kM0CF`K6F|x)tlzD2`$SZ60X~K#lFI5?%ijgw-j6f-BLX%H;(<0tx z14zgA`jPDPx~^1TrWT+d2u6>r{;Y8no%G^DVt1PLds=a3f+;V@xumbCq=w-Y|1dLf zyye&z=T0V!@x{McAS+=e_lcqo8D6fdWDE{AIq4@}vGW=5P{Nq`$B6B{4AtYTN^3!d zAy#%^fJ_zaHJx=prDQPo(RD?IY={1Ih@xvsDuIrV3gPn6L+q0v>$wb3pVq@Jma0{) zhh+Pt?V$zl{mRPtd!Q9uSWA$(*=jMmLt#drZmV8{8De+g(s_5PvaMRn`2BcGq9jrB z>=jjqpFREA9lxLrwfX||cgi21mnZ|gwL|t&2UFu9pW3OY6A7n>(;PJwd|gH=ta!w5 z$%wyDb)$j{6&Z4;Lu@%Mtj2b}BOjzkO6!PIquV(^#M=PD=>zP0rF9#ZQ zY8^vV4q9-2%d&*%Km1u+>U8+Ykt$xZ64Kbo;zNzxb_D3Hegnp5RA{O!uuw`<30EbVy9!WNQ&n97N-*SH&lHVcb%GEzwDK0*`Iko9z&m(dnffV z+_c0e7#6#8 zK*~OkPCYN(pwjN62g6w#m?T@LMqNM5LO?I0Qh#@dfPs+s%5)}I9Aq$46q6F4^n>%= zA5Om>+*}o!LPsLS((0g7x_RjwdW`ycDM8l!G;wXyk^Sb(Ss2!U42yY{7hvX5t(gJ0 zbgon$4+1hrlI8Z3wW&6D@Fhn`;3w+AoultOOo}{FleKb-qgoSi7AY1#hzq_tG_Q!9 z!~T79WrBSKeN`}l_%NIkoS_hodffYI8I{55k=*KKME6E4h9E0%;R}+bb?1|2I@WI9 zc@;l*imEY9;ub@XZfS;i0peSWxyS;_#`xr{o_xko^q#|;A}u@ri2<5N(xGMFn0^te zVZ3gBv${*VLz~mrIE$LzxYZ5i++B!j7HgrNo2RR`&b-4_R_b|jbD8j^eth+FRWBRa zKKUY;7qOB%a3L_&Q{epbEX=1mv>RVINkObj6MqkMNan_6P#B%2+OJx;<8*N%Jx!j;pup=8H0?gXYy^&j|4xcY|&mw!E>)XBNP zZa=g6h+WdLCZ{58PlKE&hzeXWZ=moBTgnIs`i+oM77EK;Zmcx zYL0rbBGY=(DfI$)op1z;c7B5kOUFiA8VzKVW^nNfl5eAKv_^Dbs^;meNO9rqS*Dv|&%V?YtTYhsOE_u&Cc6%n888dd z_Ho%13-^=q}7BU>hJdq-@T$IPfzo|i=xy&CWpW52F^ zPqo;f49>-=uho&QA%&DMPGh$gLdt}xAjLfLTY2@{2XaAdO&`WnE&8X0b}M*s1ce8R zF0dQXy{2k`)f)X!t$}Eqa1z1bR<($9g|@ zHF(!x#xr)sVfeWie9jcax$R^IPc6P+%FCRO%idz;wuCd2`)RVKx+ztIuqE8`wOHdC zO);NfB;?~zo1ky0DW>!?o{=nYDj0>8pOfd$WPvl!rpYF2f9U9hy11l(oqUJM=k7zv zISMo&s+HEmq3^310zIZ2%ckRkYFXy(j%d90I*!JSWwNljy_c+chPYu%kMz&S98sn1 z8y~!>c*>X?3#7<;$UELt-@uP7%!n1W$Ki-&O=m-Rvm#N%jvLo(1LtH^%ku77loYo` zK_Y2G4|_%hNj%VbA^FM>@?ujSz(!TAHM6>s+WcyB&aAkjvZ%nTmwMrV25-_*9h5D{ zme_poC;-gAuc(njZyH+Iffqi%ys1P6=bB0Ay}n(1e(>VKQR%HHWv9J&UybrJ@p%x#ha*_Q#(Xre5}&MoB%SKASjqAqA1N4ZVx1 z6=%=KVCm5vzFurUy@;i~`O=u)(57!-u3e`qn%J%)nFfRbfcDG3#4yP#W zKCDTbw#yW{2E7TQ>>%)fs%#E7vLtanzFm`HP~)iX7O=aFPTgViVGtsVBf8eQNixqj z<(Mi1srju#wmvzL;ujk~0xsRWQzX@(sD)xU*pAE^>>+S?)`G2-+n0E`^8yzlA1;1p zdO*|4qBUGtq~;5KqQIHgy+&-iDw9E;C=1BTVM`P|m=);#r5Pev!=-D)8uv`amxQRn z;+W2;d-OL~6{^)BM$>JCO)2s}Nw|{x^zRMW1i^an6}%pJwy>pG=qr21a~Y@F_Q_qN z=lGXOI2F_Z^uqfjTrG^TGxpE&jda_DG(esC?;v;zqWY zpMRm>ljb7$T%Oa0n3YW5BD2xAPt~1NTGO0^qw5nxicu0*F@4>ri@nixgidPR!?iJFn<@^BPNObKZ-=G1~ ztOF&%@Q|mLIZ~W&L7_cb5yZiC~sKAk%|8Ged$3+S>_>c|Z~(fi&=vOtJspE=LMC5q8@7|X(M(n~Pa zS6Rnjjxw#~bz=WX;Hy;FM^@Y0DdN~{{gJtibsW8&Akr3NuHLF`8sVuhrd3d zIy&t8(L8bn`dgKdm3~Cu)Tug7?^Y$x@mo?{)*wnMX|`$$1U;+GL+SZ=zC#G8e|D_SXAS>y1L61Y{aHOID_#F=3B#=^KTp?W7L?} zZyV*>TH-9nqo+0H=S0~y%coo#Eh`Arnj|>*=bP86Lg)Rd8 zKDtCU$eRpnNE0hsS8h~sRkf6lHjE8_pKL=}n6{7Jpw8YMpA~W-L}n;hFKnb;5N8@T zcF^6bqjpo*ms!ToyKKqbRQF+Q=c0-~E+swM5FtiGtBVol))zhft&uW2oZE&;t=iIT z$~G5x%O=BXAxW2m>?JLLh|_+V+=0bN-~a}CLn!0dgIK;8)4PhJo4sa6GJH&xPjM7R zA0ny@JWU|>?~TryPUrlrTN$m7c|)<&?r`>0mZt9~rFa%jSj9RAIfoie9nMXbeuV<# zw00b24z)S^0A$5XN4KIX3vLmkp`nQa30MlteQtMlkFO3B_P=i=@Hdu2naysEBpNNvKKGQ7R3IDF}Uf&`;(R+Mp^Aew?4Y`wHGiEg301@_pr>Q_6+0b@;JWoBHCT zrsH)f%cS!0!sHxH?5pf1J_+kiTTS3b>vKEBHV?NM_6)*nUJvnpqZ6GnD|hl%WB%P4 zUxqFvRY&@dK9Mf^LHSu>Ajb9c{YD{^O}DIW42w*!&dtz9V+YK=j;6+0 zLVI#vUmZLeuA-XiFr8=x7al0Bvy2`G^IEyEYfztl@F2wQo}_B)l1?!j> zkWHl=Wu(`3A@LFp&;*sz!xPNqJY)aCy<;X8D}8DrVfulr|CEL_q|4k&|pF*$=aocE*R)>zPeKP|_$8vkIx%5`l!s;Fp7vHp2_U zORdv~pJo4uZO%tYTCtv5?9;Yrp#noyd5FUu1DWcWe1a|s=Ki@bH>kQ>ANjr4F4FUE(;DoZ#7p^M2&?4#S(VjtrADU`1D^ItckMyv5PZX zzBO(`zQNVf{#OW43$&f>V&s87CV3GV&%|G!nE1^Qv>h2+naVX*Y1&dd>J|D&CL&yB zf_cFhj^%fK(d}fLDrS!$^%l|Cin8}4f}hgVs!sI0JxP5 zHA&{-rJ?sCR&?)|*hE#qw@Gj19nWFW3a_kqpT-Ds{+^ZoYpGb)o~g1h=RO4kyQPrq z-J(_rE2pY-rab6JV}I<4VXs$^+bgQO{SSXNP;9Ws_i1~oy;txFB(C<&6wu@31OPJ$ z@BcEyk{C|Apik;*T4C3@0z{)f?nz#8Y_jt;C8YOA;z%!}Q~G&~jxwpfr6$O^vWoQ- zJp>XJhRx*QvGpY}V3SBG;;)TD##6)$KcF+ewuT~wXXYw_<(*T9=ji7oE|^s8-LUf= zgD~(@HBAlr?*8bE9wv*Jg2$A0Q018%&N2rEbi%B(*jfwzl6hUvv8C!<3*?#Rc__tX zN1Yl__|$}YQ191Y;j%CYIgeGNtry~3So~CUQn=M#XoWC|d#z~OQAdZe+L!!}ELI-Y zRD7lJ`t(}xUu;iBT}^uhF(rKhT@e79Q$cG;>Lak6c48ofN@qgpZ|3d~b;-YR`~Ip? zpi)UH6^}YJ*Db*AR|MG`xO!1 zXMg=jqjblN;|jLi0C9_(ScBaKs}5yk1XJs4 z7oib3x!+2GOuHkH`y}Sf^}5W~Lo@IHNpM|vc61eACP(bdNfExNy2oZ9Os67}7K3e~ z%+O2TI}5bMvtrd4Jw7Y{mp;vVEj+J`XRS@^K*X*UOX(HZ-iw4yS0pM)zl+fuHnxmG zT!+M#gjXa8<>(R$FCX1MFtaeX+|sek59EqcRTT*N1ajs9J_oyvQP@CI>F^uBpEK=F z1|fx>YwZrEg3#UCi!^v0PwW3@)Jj71RFD$L)Q<;oFh|8V;jAHH#+8atkYADbH#2k6 z)cg)i_JuGiI_i(v@Z2{k zlo2^Kt|~i`%;WK5Q*xl;^p*bqNxQdMR$W&~)GTb$8w7XS6KPxQ+4LRaWB!!ZyH1ZC$u>q-VI1$QjWZ#s4 zlYP}u?*JT35JS|rf|*`Ny;-9hiag5^4()(GyLFa__VP$)8#|GRgw^1qZI zB&;{~d6qwIH+#^tB!<|5GqVD1y>-00+H1mwL1)Ks^fQ|ZwDJ@{aXl(vla~g$#6Uxi zRp#VhwG@*X1%2BbxE7^9L>L(P?bd%+)}jCdM^g{*z$ZWIhG>kmMUh4R0zzb)_Pk%u z%M}ju0|`}>)V-6`C=8!A{GVz38{=NZt8IBG0*Cb8S~&@WPGWYXlN) zZDCiE{$C7w$ho~LDUhaT3i3uMlfKGhg9ocA$q6ET{Z#fw!047&qtg$glo<%|73TLS zUkHM`(R?-T_1E{q{|C}4E4$bx7IxrwWgzwfQ#=UDHROZk6a^P5 zaAX8CjlgKWrerYvnYy?k<4XqO_og>H?wxR%2~Tj6GH=31^##)pG?CwwX240It;#7B zQQzg53LN8#6JphJO-<+joAvJJI@`)^4niSy$m~cQ9rUGFt&e zY_pGgoAnpef4q?(&#Vn+8sAlBK#^;KhWeqP6t*B4(~L+3B0p;Z-VqpG&X$bP|H30J z+TRW|nfCNKX)23PPo*=pUhCO7ejSQE#Oj-8FllE}S}D(7;X=0vgr^iM_sVo+GC(EY zCN)0N;Q!b6xP{7X{q>6do`=fy4|(Blo>W_#n1UQwArr*Wg%rRh&NPJw3k2-&p2wN; z8@oe$WlpA^go0lPHL3Fty(q>^-(7-I!r6?aycnN1V-_(IQ2iCm@t<$tiDyZNY81Ma z+`G!bt;+DCR)4U)<1>mVG8;lHryxRnO;C5nMEANnFaCc-1p*65QE7r63(%=(;C@sd zz74Z4*F1cX24WhXX~S|V`+an*zoSLK0SM$rc_ums>B;5J8dCU(&V-qWt)?QOY@aUKt=3Ec$Et*Ns z-amSE^X!35>t(|_o1vcK(M!63AKeFQs~=v>P9fhO$sN!A{*<=<{8-xm`*Inl^M31Z zdPzGHZqeU6JD0hcKGp5;+zl?Pf35ZSAwUBYoG*xsFa^O`pr)X>d}Zr=&lgE386#pF zNQNuSy4?L=+CwAcMO^CXannN$WP;j|J1F^zhs=SH4VW1dYVA0XvQKl$gkPVyV+>MB zB{7Xf2YXKqa)n(@C~_gqfg-mWF*x+=dV0h(+pb1F6BL;XPlUJJ;o>sSen5P_W>y~gy?aZJiHS%@r{Jy54BR7uY%f;^b_R96s@qMpn50Y2vuG*i_d;Iyz zpI>R%$L1BeMp%}b>9yMu(R+DE`z*>O?zy3fHt7zzy@HlwR(cf%po=t6n#B<1MP zj{oRc6q6U8#DLPf)RFa0(s4&m{atYWuz4STqwY&lus|f~|HssO2U7jV-{XahD7jrO z5xHJMR;ZM{Ztf+UkX53TRd!}(xYoTHMfT2$?3wJ9O>UuN%eeOTecs-m&+qr?AN}FF zujhI^&f}c(cs*%4hS}Y4VOeDej6WYV#O<6kudFSbem0(1NPk4s?bJoh@n_F*F!A?@$i-bb;60u4|E&_JCr$4tK zi!=k1wy&O;bO##+1eGuRNm*0a>gx=#Ph76EtD39+TsQibD|)G5`x9R7{nGt5_TA;L zBAS&&nQmZHIE!%ERV@)kuB!Y?H{T_|ZN8?E#AOVNu@o<=q{A4>QHqY@=)g!^?H-nq z@T#QY#iu@2ZXtFYY5dLq@1R|eXCg&>PjiJQHXOY!_bh6%&W4n#DC6HQpe^zRV~S0f zg3I(oc5%*U2#cdy<)lm(OyN+bm{P#SHE1M{`|#}GWg@)exm`-JB8cIw2jrp1_lwL) zD-g>MeAW3NPd3urW<7*zotTH|Ecz@yed0N#Vsd$54LG@KR&ee)ed6`i9z9 z4gn#gWd87a`RO-7Je-$9w!tm0T$re0lWc2yx0C{=QJ1aLK{C*w!zr-Y*#sAs1jpxc^No~mMS^M|G zIy4&je_^H8TMk3}>TODGs0NN&uRDI!JzQvlhEM~zw{Xmo1rskmq#zZ&eXjIo6k8Qh zpI&BXUq9~RXy*V|q^f3iW}DRZyX9)RHln!w?xCwsznlX_SBz_R(o&&K3;rK|BFf+G zT5C?l@nLWv^Go0zkQ^Ypg)L)H(Knj05XJ!~mm(-Kh3oJepEPBNA9NG+!AB2`qaR4jr#SHEDV+bv8%x)CeqDMOHK4x7l+q=G6PfkET`<{&U> zc}vRl#~1kUU9yLq=PUlJ#+q90C;;q$@9-q6MeC*%M4v4^V+uV=DL6}0F{2GNY->Va zBITIy$DWMF=sql|%0yt6wzZ+pRI8z#)89xBK%ohV_Qis8^Nx4(9;3$~cM~>%g76%$ zDL1oWjTMTIh)TTZ!n%D>`h=L@Vu$j8A@N z@c7@YtSf{MDaY}}W0f+ki>{ys%;ITx85qs1uOuNudQfB$&^s((0Mg)?gSDaGsYJmw zWL5I|m8s3I=7!P3hY$CjCTGTdQ)7Sjw-2N_;<4PNI?`5IA=V~h11h6#L?MZn26_LN zuD5&6x(f(<`x&?d-U;#KtDMn$^Ckd-KXB|3eI=ot({#ZSL79>{0;4+B{+<3ct9dO} z&`uc~(Ob`xb+H$}8PP-gexhH@b%oV3_8&A4vpuB=fdGcbW&l|GdT8EWse1cLCsUSn zoGHYK8n~78Z2XQeJ~dt0m*XWLOzXD29ycQF%mP8xk^Eht zMWS!HRer%0FppsMqOch{bI37+lmf88dfwjBf|+&tj}!4%ZgzDG*Bf|k$BNm~Cnrcb zymWrXKk@;@TcJCBPRlp??qAcvSn{7nDb%8qZr?h}6yI0cyW1wIw)8)6e?juq1NaM0 z@X}EJzWZFf__tjf;o(JFTTdInl8>rh_Nfzy_(oxdvrp){T1fFTn9Y}@;8Pq>zs*1gg9`Hc~-luAu)@_5M)xr zVr6YX#fu*v9#;0L77s%1{hc)V+;dgr-v_Op$O*x~Z#X^3vgUz@sEnG%z%iWdC{Z~_ z+&tjwJgiBFeUmnE@7gp{q!xX5koA12W#GW`hj+I2kMi~!3k*mFe`SCixoy<~!6cNT zi`coK>W7q%ZEi;m%sVYV?Jc?$%dxjOxT8^FS~K*rjJNCK!!sIj-TT^Y*@7&Dmz!n1 zEz?gMP8Rsq*iwUckgqmuJ^DfLZVs5JK3P~$6B7NmavU$Npd2hjCu8_Pw29mXUy$MJ zTkg&^P*xF<>Dr8?C@F2zgg#Uxg2ezsJEILPrw?AfIHnF>x$~q;dJMmb?8ucfLbXKd zs-FWmusQZyr2!NuS-m=n`mN~;|qR0GQO$>PLTS$~vEB9&Y z(qV7&v%L7E+_Z#3uU`Wh=#)+O!7?M?@>_{mi%B^n@;wGEZTsURhqmmv2;(x(>1!{I z7k6)b5OU5LeOQ5*h>=%(5quMV*7IoVK0PTw`d*wK!7 z2cD2e7i_s+7)?tfUOW_aPg0w3EuuxN+s$BpGiI0HPwAl0M4$H&{h-|QK{qW z7_HU{kN(f3UoZYEx@?$55i}G8ZE%c{slMfxP`H$9;8-j0;YW&{K-#{QZ7sWYxUuzr z7S}J!x`G#D+ z27t@g+*Os;1@^8WV)a9Ep&3{Tf~W%y)MdV=5U62<5EzYTx3uy<8bdMPJkOBXmZ{Ac zwPsB+zyAp)C!VuB=vvkLnLr6uOP5l@%W>_4!pvw=LZ1jg#ecab^aiUs3-^4^o2XX)Y|HeI!g3Tg3VjH^@DGAy%Bdqf% zvIT;?PX!oP>o|ijEIzaDD(dU2AOAtqQ}?Y>3W!(wVmndVi-T|)H=M!m@}F`>F4Zn? zc)<iN5=j9fL1!IO3vN6R;V! ziw0^%QSWD*ZLZWx?zL+l#HiZp3vuj4-|nmyNY)noNG52jf4trOt0l(4lR@;P`oL1y zh}f=b$mT@+8ECzV?Uq_^S7o`-)mxy{Vf@nLtI98S#+O(;A6OG`a2MNBe|LbENZ;}+ z2r$4?D7({j4Z-}AR&A1j42$Xgj{bSPWccvEQ+pb0HC*mU@g{hEgM;NIEB*;whI%NdFnD}l z^!t`K%l%R);i^LC3oQSi1JN3Jll4b zby1Wtw09kB@oFVghx)u0 zM5mGR!mxWv>)kK5Rqd~$s_KpkvNF;2gR-?t4{LZqy|SsNzQs~p{tvG&5IFlrp46fj zUve5EQ0u09F`4&Kex;P%!5>eCOUB5u5&C{@Blf*?cVj@=x;q_X9vr z7~j9p#HI7&Ew;I5z?A3zKQa%ix3~KjzJ-9A*1r6wBDrnMYzp1C59fCo@D<~0$gx51 z-O=3Bqk$PxR8?ro(0F7=U=`X=&ZtKom*3)^5?m6``n~oQc#4ZFiY~68aZ-7Q^MEgcujgp=Tpd1S49J>m9%HYur z0VVlMU5{$=ub|SnPeOIciW{o`yzbJJn$T`$;JEWHWJ*%T-AKW>Y@;eNscKbUM@zo+ ziZG4n722o5)Z9dodeXE2tQit}@#33cL`WLC^F|-j?bkLkeN1ay82rCnW~uUH6*cwb zS7LQ!S@6&+?{1R=QK4g(oSjXDr|T4eE4g6b~cFP^7t3Oe|#wMG!+2YFTgHm`bZ2x zkFZ+NKDIp*0d-;_y3(7XWzwKUO4Z{CPBUlwl(c*PkVi1`^u>0QfOqCuJwx3T!Fx)6 zXV@?VpN(%zK!!@sKpT4lqPpD}YPoI#>eDDtGPRRPuqP>Kitktw*5v(y&3Fu5b_YE2 zO;p-rTN6K0FuK#{vib#G#9*0+TOcfjm2h_!P_c(!TNvcg`du>^iELyrIW`Bc2a`+G zhVU1)EJN7reSRs+9Gjn2-VFNf!1Z!w?!J55EGqT=2w?q!iQMuXyvneMvVSF5t2-wj z3{)kLKla7&|YfPb+7`&rpxP>`%`Vgaj1=N!=FH#l=&r$^W5j0s`Rl2-*lThTI>B%Qy z6OT+z-*UiH<-J9Q@F~WyU6T@D)5G|%?FS&`Q`SR%ZT9gnZ7w*xSP&K}q#%|APxEN{ zU)Z=irm(`*8W`}zq`@&+K3$U@=Ox%;rHqdXuKGPGRi!?E;lIef*qHhovxa<@+)il< z?$=S!f|#xHw5rfnq^c1VJzx|Py~LTD;Q@uXaoT zTb?v7JEkr9Uk<$?cpqd7d-ZiL5`&4WB<*sgs;JsR2V8&<#0W6?FI52DJLgdYBJp;T zB4Z;!NC8Pg%Zp#O0o*MOKyxcMl{g8nkcBp{BcB1D{AQLGyrZe@s=bX`$okvIZ$%Ly z<``JZN8ZFe73IPq9KU@Ma&NL|#a;kaGUPoxkg6e2et0M9vO&l-1~^7Dw8(n^A!B{v zP0h(OA0g+(DPrp{8@ig}7uyQaLHu?aDKJis-qh>NuVb4`TzwAYd1+OURgMazIT6`eQr!7EKL2^<-e-lFGhWVBLQrYUnI8p3l?HoLYD}IQharx zDFZnjpd0yWmq&^KU&XrP+&-6b-6^T8+)b7p_h_>{K|->QTY3#{iybz%baB^W?4ixwC}gMHOf)!^1~BSUpjlk9 zqOC*sr2}gCDDavllm_Zdz99Cl8;aH2poV<5I*jwGv8GxuzaD?qi9c79ceV6Rm?|S+ zObQhLTy7dPNq@gWl+uJi66!&TqRDKfU)t=e+HZ!ehex=^k6zsK#_>jZUw#zETLMq0+03<%fE8_s()#Gpj{d zEM6v7{C4&^i80YXk)3k;(_=PyGPDtB{wGw?2A9I`)4qd;b2i6s`>p*@a&yB%lXEK|LzdPTc#SMcbiW3LLyHVl!Z&3fK=0KDJ(u%%^91awF(hC4~|3a1c0|wN44Y1*D0pHCL_=3AbpWSvQj;2zd*!t%$ zH7?6g7(K9bCBiSxv?eqh_t?u0t;r4u(mvkA=4y4cdV9-N;CGGGT7yn65Cnx`834Jb z!f9gv#0>V_!$EmZ6+$x{&ho-yB9ydArA<~PODN>EIPE?bWkfHv{|krM+2Zi7Jy{b| zu0f3@x}6iNGP|Al;Q8L}R079aWnO!48={&s-2)5DnO)bV(!MUc=0T=H1ZH*qJ#+D{ z!ooYiuT&0FP5-WVO|>%$w~2Wn|QDWY?X zeyQAwS|;gK-=CM#NrHOIq~;qcjSXWiT0Xjp@)N1~hiN-clW3~)cgR#jLh|v9u)|os z)jjUFX7zimvPbPR2D~W0Kp409QPVk4#uASyy~soO6vFDQh6UExvQ26=T=wTD$5S+v zq7riUW>pEmuk;*HG1Ohvf!J$b{-L|qz_+{>j$xff_D4W( z7*V3Xv`IYPbD#Q;e6VFwRbMak zVy?MicnFp#z$dk6sZou?k1PG+2p8V&{*4z@UrMgehU|S&^jM7knZW|&z*}KgOe8x< z!=wvUQXYH$FFqE-X+A+E^KwSxf$vuoxY46Yd_fC@yzG%0J4LZ7cPm^%(s*6u1!M)g z+ve<3SC2aMHw67P^^CiQca9S!1U;uS!&Hp`2h=p|wnE-AqMI*hFN%u~+z)ZPneW=e z@`H}}GtB*?`4~8ayu!yXCZ=^3@L6akrZ^XqqchhRR_vuKd(vx~m503j-2RYOsnUr! z8}btH6C&?d?;%iHa13`l5J}EZMX6B|6og@7efL4WwQ;U?X&N>Pih&N}-`0ZaoK30}DE z;a($sd5u0&m_iUO%~fs@GTUduc%=uK)>Ojy-^(fJTbdsm>Sv}FM`qtW&L3`b51u>k zNvsqJwXkrSdYoK&>#nx3?a@B33BxcXHcJ$NDW5u5>ip~# z4uDEvurR5S$CZYu*#qbzEX%GD@zdc~ajMFScse-~4*(X{&d*n;SoL$(`vb*``nLF) ze&ra&N*-?;pTwm;6vBVb74Ay=k^1wvPs8LsQWi1&d}o%b(V;0aqFP4=XXO3(#WtvC zokg$ePb7Y=ca@g8^q4OFj{MGmtI1JdY*S*O!Yd1lDPJnrL1k8Ve$Ov__?zzqDr--2 zpSDN{2;2~G(o1~dN@G{Muw>d1={0o;_yfXJ5$~`RydZ51zfG106ow!Ib|jpLqS{i4DGGFlC0+Z+8xMmKr78(~|3dJL7K&&OV4TN{F zFQ66b(3E;-JTXA%y)^*5N1{L*Rlb`=ioC6z-NG5G9kb^iH@}uKusx!u!O%5#5oUwnfQ3WL#2)}Oj$x{$ffZ~7I_P+eAjr8Q1jcg16tdN6dw!KAmxmdl4XvuLn0Wq4Pg<`o(u%>(0o>uS zRnBqPAQHi9%5hQb-pGxh9}c*p!k<;WP3}tP+Tb0T)I@!kO03 zI116iO4*r-4lsy*0j6$$uX~#lvn3h_}}aZ^?ATGa6=95o9x4ixaOkN zu;>Xw8RL69kngD;1o43K@o9Aqn5YH9!6jT_;yRat?UzViVLb5pL=}4R*P*YoNNuDRh!B|OBnp@k7E`moO4J@$B4 zzh_rJ-Xc`|IdfQI+nqLSb0;9BKd3zuh6$?<+#M|A4~3|U_4>~QI-d3>vrU3pP1u}0->YK{=e{($LUbwGvq|$=mt9La+B}?6bG3P`lH*8E zRmG~`ee^L^>&NXvmWfxxy8KC_Q@JLNnym+{6UGoFN`cH)D=lNM4ow%UWNGup82U%l zjFE*-6Mb)Sjz~EF^=a5w0;%g(=>tLKde5KTfc_#zYIqqae^GESG*NoC#gLk z7gDYtJ2Kz|FlOu}#Xql*%{mUf6Gxk?)>=EQ*?u1c zhTL8*+QH@6Z)m;nC%aD>s#&7!z4cP?!B*40X!NV)(!1HLa1p~l_I1nb((d!B<^^FM z+06^>^8wcHtTLA9#wODycA9zVrAphht?TN7XTG-hM(VTB1qH@l1QN9jZrBu>A!&zt zm(+2aiuncC`(iCHfG*9j=17#eAzFrlcQldA5m{8iis+Y!3LfjE8 zu9S3+iYi^D=dHJuaoE32k#JUgX&z*stu`+l7>U=J0UOX-rljk@ zZPw(%@w27eb?9HP>Zth);OC6hj48^}1(XbMoyE7i-f&G3%*&spv^M%;APZK0>XGh7 zmGN6-qZhvGgRsfyJ*KQDU!5LBZt-{?vY)pTt%L#(EL@in@k?W^4Bt{1E%|%K<~~>D?lH|c3p!^j~zBX*Vs$1%>xSH)$g7k2(yz0 zl;MT8QQcQ2aid@Vj7_VpGMY-6xyeUQnow_Z|JwBYjq<{X z?`;=TsCchWFg|Kr71!*Rdp-X2Cb|DRrT5kh^)#ESPK(awj3385YYB~F1-2W!q0n;y ze*X7vYg*zg50oUm1nOV>D$7A9jg(ZbiaA*xqXsXQ4q0H#|7LK+GPA-xlD;sef1GFP zT#-J0_r!T3w=DQnc4=U}WQ&qw<^kmt)x`(j`wUpXl2QUq@qu!-QQLqV&dE|GTNBD1Ao^CY(Pdb;bA194IK;DxgC0h3`D2+u;Cq0lUM zc>SN>^>5y(4|&siN2)XhX_A{eEE?LoTW2kmj!H$tFE6O8Mn72k5wmLvyiG>Hp)p6F z%xus49`IRorQ9m-3KMVRhyI{MHEG^6Tv4{jWK$Z$!!dSQ!bW$6VclTMiVnM*o9FT2 zJ9~@F=3j-y0@l;)XiHE`!>d?5G^2Fqxw={jWALj_m*_WxH?xRvj2a$AP2HopExTtE zmM9Y0pCirY*=c0YwR`WU^A=)F!@J9Sw1>i#IX{x8ZWZQK;ah)Qsm{&d`GWPSwuSvG zkE=z0c$=3THS5M@p&?Zg3w^zB#HdAQYS(3NQ>t(AN z*M~~(xaherSS3KNgEW*y3ji9ROtvWczpjtRK4o8({m>mr-!uI!DGuILGOflGbnTA7 zUOx|9Y&|;W_4%vTv;L-si3k2vJHc%tN7MAl^09BT zE-<<0G?06Rx%0uW`3&O=a+}<~GJfN}YpM2`a*U7rpP4>cS*sy8+^!@yxr?uI)5=cV z6nIc4tI98QXlebl528>jhAta`lZc9WU2{%5<=0X^WX0 zu!7p4qYcmd2L6(c7yrQmVUw8h{~YtEAHiNaxImmD-gttL z{4#lUsGMm%l%8==XDLH-}e?9XTWowX)89^GfG+>8bM< zp*WlV%=ehOl_RE}S;xA+3O%oQkz>=8O5@sIkG(WCrnlvB7wh#wRa_JzNcdNJ_&2g@ z)&v@}8Y)WI`fjt*3GM!ywIu0yalYthu{S(FRr|OO-el+$370&Y5(%PBX{I7z5ERN4 z_}9VQWh1eL-@z_%9IVeDn^dn2cRkDFaWq#y^$ja@rT#(RPF=h;+HB&>EjFO{8CbEz zngVV}brzXQl5>IE3s2xY1GGJ3h+D+GO;}`vS-@|!s zCD-5Uz*(4aWOF^L?R{vAsN`kP%;e@gKle?#Nx7Uym9L!y_Dy%xj!c!q;Y~Ci+p=2%p&|g% zkZD4;O>coDdB56a5mn+VXXNijfxxdDpCz+p1e9}KRH3xsV3})}Wki^IMdaV>C_e+X zUA>;a%L(H6M~!C_Ps>*oMA3>IUj`2~&XmKV%ul%~qH+?TJWFQAnje1VXKsqo-OW5o zSJpQ&M(O1*UkGV=&`xN)u$Gx5dgv4X28C0f-#I${1`wrC9jFi_HGxr*KPHjEQj>~M z4SW&*L+agAp2|euio+`X%6jT*|Bm~mBkpje?o3Be?Z@vI9++~47aest{Lq`*uXiig zkHyZN?b9Dh#jzilRSjnfuK2j0U2a%kiH;-e&egS9cc#eEfh!!lf#^p}zaGyrg^}kF z-z-8c5gAZ8y2yLMa}4ln8av-pTU4|1QEPlFpJTkCE8SU-e=D+7E1y%kdFthbGUrc| zJBT`dwz8{PxyPlm*0Z#yj^6nSQRkHL!m5)`napFU4twl+ZnWmbc@LfLVzhiGZX!88 zpYj~nM!f3u_&T#G&;hvKlFaC?_Xn7w3NMq{-UO0Dj>;kkI%pvGD_;i*KGRy(Gl#o> zxUBk8>$Z)wXFIDaKTylNhij}X3R(gKseIOsq-($xnEotbmz%leaeb=~3jP-F22y&9 zKB~L(%eyPJNuFKrkW#O9^%Wn?Q#Cp{36EeTYCo^j9?(ZD9kq=IeI@;TL-=C%iSF)2 zg;^v^(ib_SM?&}yfI8d5DKG+G8NiHU+B9P2iqQqHxp5>(J_)!H(W64-w#%gm8kAbB z#l~Gxfg#UN6Z>Tz=09bZveCCLR$b!gsVO`rv(5f-WexMXtoXGN)kqCXyT3w%kV|M1PP)VPUDW7SAxXe71pV} z!m%Z_*NTW%iG)tq2=)R?2ZMp#kFwpx69dmJE^Lvf5*xx)D@I?YPGIrw1taaYDc{KI=H_#<5}{3~miFrP6?muH#S$HEP%tu~aMOA66Bq3@ig3=Is@gqiPuRNJq(UUF+CEN!G&mAf*<=hxtZ6me+dzN5X@G%u*A0tfwziKFB{}TFRr}&+?^A(Oan%m=P%|TDb-9@m0;fqB6wF1$_II z`G8pweN=tEl>10B8iA3+*$9|O5|K2X7|1mWPo(o%(n4dRgt%w0A{)!X}zEn>D! zFDv5ysebB|XS_bGRPWR7e#-KWup>L)e9H~TOrvI3?=SN=OoMy)mS5Q$#e=VtyPJ7I zH~s&td3ryzrLC-Ca(iCPDuhxH7fCafx^2kZq~QMK8z|Z&O%_$-3XGw1+34C#SN`x^D7eUQ{z91QnWHruA)G2AR8$2N6-NNCzM3E-qOH9F|-)`G!lgBAP^q3AhIf(ZQz#EjP~!9<+$kD zm5I(ThVT`ov+`W zDK;e=S7QvQImehhTsMon4idxH&b^HS9vfj8mgF}Q?8Lw3!pLeuXVh@hPSx8TS4=#9 zgv_R)pU_XVz&l)!vyFgxVo)TKmvbU8YOA{YeNG(dyS9QE*J)3t^(W#AkDRQ(mNXO6 z*SxbA3qM*L^dRUd$uGF$-c^xA9umQ_W(?d8z-A$}HZs3u4;6aU9i&#=wXAkgzyZA= zA%kSX4bMb>n@cwF+>1mRM$I_nw8!cnGZUV9{f?2XcN3z&jPjDF9Tbv1?7u9t6D|@{02|BO$% zYf2T&lVkbtyyUkOaeYSt3`bc3>Ksepwfn1L??Fd{%UKYGKyQhN9-vCUK@!qXY{$sTu8f!5oT=HJCSyhLCLey^tectcuFmONK($-=Q4l%_K->R| zA`^m2JYK15LBkoqP*(>`sW3{yb4ihYDL7_ptg?3b9_|Jkk^cUrnx+GB2Pu^K?bo|W zf7eyXm+x`1r`%O-wt~QT_Og+%~*Nm?!V41rtmUcs{;)W^z5%gn;p?Y$VtTibn2@du(8fd~^rc z8gPg0NH#so(<)yQCX)Y?YER-0d zYdch|uDafJ{F-1*F7Np0*JP5G$KM+t8N+}4m8p5m3$ux&DMgK6pCQ+M(_PZ};IGa* zKW*~+-zn^Msa)@Z?U93cKIC+TD#z95)MQZ~kxJ3F56xhgBG?6eWHW#9Te^V7s!Qc1 z%uxqSsB{V(Xl3}~^7Zf?fUyR zQj3aYNfwtir|f!9O+#^}3y7J)z)&V)CSZp3;kdG=S5#L0CyzlwbP(~*9q5{I^Lg=% zRzu^hsjIR?VbG+Sp8HS}*cTx#K774#pf+Ucoxv^)<2^zxphT~v+nlLF>sD`<+#8KB zg?ivtOJ5c4$n=f03>T~;j=vy}8yCGhtvE@WBstaY_L4jDrB)K^>fI2piT;Hzk9D2e zlm&xIzfv#r)`FhH3$Fwg1KU6#fb-NcH0Dr|bXDNI1EMH!llnu5f0~7wI_{Jz5aEE| zR#}}SFSW|=Nt5iZPJ#!Y4yw*8-B_!hLXSQlBw|_;#wbXmulS6woQFj;K74X zQ)O6KdfAKZuQzwjw|;^`d1(@5rntFJ24L&L6KG?=v;X}5T&$es#$2!)9ux?Lxm0N} z1{4icDUr82HQhLhHXD~S(aoRf16pwB=j_)1d>-E4Fs!BjqNBmK!`rhPB)4#i4K2kz zu6+H-h?y~z@q%M9G+GV}cLy|IZ$-nizSf*u+_cj)pjA+F26X*k9>PqWx7Y7cnLyLe zGZ`CcI}h^9w-mpwyeP7--CK&|iwK%DV5SoWo(T%V;(x}(m5$za^6X^n~O!?`#ZaL6c?}EX>_58Mg z+rYgReH}r=rZY7jrVYI%v7A!F1R(df3}*s!Z`&GI+6VWedeXj;z3_ia(3@hjI7PSBC#gikiAn<{75pRHQy4AM_1 zPW+T)J)yvnZ`ZD}>zE+ZBBWCvySe9VNP*IJylpSTu#YIN`1NPqmujauczNt%30?Fx z2ihZ}@1(eak9RRY6`FJI?EZbZhVV^o=!W!%3Qc9*k9W*1O^Y1QiMU|m zYVRLN*Lptf+q>VU6>0!AE0FWSi17^ekFW$rLu?AVyI1ThLO~c+a(@YE*Ji2H7b8Xs z^yc$sSEMzX(VdYG^nNky6R*9IczWH1jkFIE-|i*dqXBY-NljRE8EAlm-~SRw0sQmo zRD}5RWVV-C675)%o&!gFW@GlKD$dy0HBbf9$&w;KmU_q&Fw_wS`lU<_(FLJ*b2LXTtDNw zbLDsWlp$V%57rr(kNT&`tI|#_T=-li$R2-x?e0>MmYbcsYkNz2r&r~lKYCtHPhC?r zTFd66m!^o9w%C-W$S<_W^fknf4k7%tu%Avkp5|s8eEsw)6lzr$=|Px!_UNH^sOG)> zT(^Y8cJ4JNymQ@}HxTJkm`tCqH6MvO4&_a_Tg5}^?;BNxZsr)hMl!L&GOXViFTZ>2 z_13ri3ywmxA)Vx91K3Ut#}*4@axR6f#l^*R+3}?kD6N!T0-~sQS(2@prVjW{pxgk+ zxg}Epm!CTtma}tue|shqJ<{$?d&GVdv}&v-YyFViY|?sd^>We^tuFpYPb`!>RakX1 zOUa9-`yb8sE!qBZl2xFb(Le9^8{px_6#`2jL(wCN%iu9ofcwo6Ie8})^ynZFBn!~+ zQ+r?04Xki$Yy1A+_vLRi>R!siql!Rki7%yA9wR&-%0T~=t>arvMUR-fqLe(OSHhUG@9&Ev49i2c}|pls7N z_{zZ*xcl`s_C$C=O|Q zdyP;47`o)hDZ{Jkb&}twinNHz{OC{~;p5Z%gcdIPA1&l)so7>7Bi$5`P38jzIixD7 zbQ}NN3*&u|&y(&p>$f)kZL&%M*7Id$V)PUqYN0E5R-aREP@G4j$a|Jr*;Q zsxQXLJb$Ci^QkUr=OU*f;=XRP`+#SPE@$0MbC$ZifIObiM2_YP_X(vZS3-8E?^VxO z?N%=0htXfnK!jwGT6L~>?X-dN&$cAZ+^@}K$$+Fd)Qtyb6;CG44P zD&1hfAYAz1XEWZ6rSE3R}5p^nBayA#PvRS9Ohm1+~&G!StrnV zqd;7aq+0*cOJU7!uSpz#?E@xjhw|48$V=}I$EfS+WH>Y!?rK_tKN;8h4YG#AxERAj1@H> z9_O^A;HC~#mEj=_#y@l|5`Kfp_Qr}C+9Ey>)r?pR{%8AJx&x^2q_6fyMY#lS!AQ} za+;igu*e6xQXnZ;;E)WrJ##Eg;J~vNX_H|4p9?Ua3AEMBDV3|%${T`Y!GMY8!q|d{ zt@LwISS1!}N8$B=FZu@|nyz%1bX>0@Fw*_Sm$YNwnA+`{0Ml#ORVvVWCMz4-Bh zg>L*)Wk3(+$yWQ1w4ZUeCrVAB$pwxHQUhijp{&l-Tzoq_&EO=^Px zbvg#j)@4GWoKf)6!S*l)_j8k8+$Q_c|4s=oD9T8T`@%6nZaABGB#W+ca0zz|{9^}T z5(lz*@k$aTcS|`@&IqB8sPJVYLEsIZw(=<<@CV5Qn4{`G1 zcZ=)?{gy&DYIXls@PFP9QQwF{}HU> zRPS>T@KX5zo(IM;i5nxcj=0yffP^7K29c~?vB3G!i&c8)?d`qOBwL8V8E@rkI0Os+ z=aqlWc*)Az7(fn_ni#Bw|33+!7|N{;`^g=>Gh;!j#2SG|mgg486SGtm(QJGtfA<4d z+Jp-2mPUoaRQ5{&`gIDt-oL*jk2BhA99g4r<9XtEnsHrUL?0*d@)PFIxJ> zMWe~pod$_gZ=tq?6X%t!lVhKK!ptLB>#C1qQ>Oc2ha(3i8nO;l^qx`P@j0ri2=_TE z8!m>JPl117EeAhP4!De}!n*#R8<|Q-)*mrx4CW>tBOk31irntbmVL2$qwHNVPXut( zw?;=bqS4;lv#eq=*GQjMViL3J!lO5Hl$km-pYS9L|Ev6^*6L+!Q(J*!dn%h}VX9!6XVfikPmBhM3U3RGb<=jsZ*fDz+W zp>+j>x2tAw0B*WxIgs`R8a7u9i&oR&?9&L2_4c~sBJgH*U?CU4)t>lDJ>v=G>Qe^K z^ZJuPdki942`|9%#H6O5+e<0Tng0?$JOr}FKo1ZY*W3}N14fTHd7~2SG#&fR!?{s2 z`Y3eL(U0t>K4{X2f(4G{jXoB7)s4|-W0efiIfaSkS1W$bt0F>JN{8`__xj)6wpto> zl>{TG{{sePe3Sb~U)E=JcG%4HAlu)yVHuBV)`)PSHMhPV2A(KF5NBlqRV$?-Z~?ry zUG{tJunxvS6uu0Coh7J>V_T&&Vzl zgD%pY+JWdBVDm`<~`Ukk%L7kGBL;C3N=;>QV88U*e< z#|{*Kr6Xty!RiW4{yun%ezJ^Ykn-GJ<1q7V)JNVqu|JusaqayTMH=-5Lv}VV8!B5v zSjaVP`l7<|MI=tqrr@T5{WV0$S;B(?*VwLt%qd-YBOts+dHishbU!KUU25=qL~-hr zXYTe6pHitnqrQ{rJs>6G0sg+~i^G@x^8Rh9225?`7BH zadA_L;&87{qO5mMHZ?oxxi9`Hur?E^=07)xF0ngfd+wr4Yk@USjFQcJzj8J(7mJ1% z$S>&8t_qZM%~FaoS++jMhntr-;zUCk<(hr>(<`$4%I`;G zmHx&r68`+iG*p57RedN!z%bPVYS4dygYs#?$XL!!ceLPBlLOU;9Pim>ZjpMnAHn%b z+P7;fWGcCWl1f_SjjmZQmHL&xbDKfGrE|W}lrz;p8Nl^@B;{2FstcNBLynQIjpq??fu4ZQ|~w^O!(WAB~-Z1E!E7dN2pv z4G(io6G>Ox2faR~;>rt-7zmMkGGTa`jx;4mYmy}c4z`Nfse_MDD%s{`)EhU92jkxEF0s=QH%xpcjb zNxS|xO=N1NU@ThZsNwLp;bj`qaMHr;`$nFRPohK%l+w=F7Krb|=eYgLuRXmA8X5O! z(a@<=FOb6%riV}Xs!R+!NAHKKVy-}e;{g=H(@AN{lvrrEdK0mX{*Lua9>bhOQe61H|n}?a_~H}AQbIhZvt)b;BxW{hQCcbaGmT& ziSma8RE}9oCG3wyPX*UEo@jf_#C7=i>Jv|F8IBKf0ZaPtBh61q&`ynO1^bs^Br2q8l9uoihDQLvCjB#jA@DE+RF8+M)m3NMwshJnRQ z)^Uaa|KQO1)X$+bycS$-LO$(ZlTTvSvN@~)P(2Xh43~{eWalfizYsB zKrC`c)MFCNSF!ysaHQ2eMbYHE+>v-~xXiJSsRn&-N157rIZLS|6~fynQrcSDgk)Uf z#wYw%g&OLARK4AmZKi*DdJxq9cU3@ z3>Cpy&3Zj~TV-dL22keCxbH%+^tbsH7-R_JM={6$zWv@kn;Q6Jt~TQTvGwQiQ1{>e zIIgbBC6!ES+EC*;*+<$-5oVa7lARbLgrOp138j)uW1C5|k*wK9)|f$yQK7PvsVF5o zk)858Pj$WCpYQGV^WSxAu9@dNmUHgse(v`(j11av*7{FjyVzs$Fv~2|AuB=IoT`?- zy=FXOy~LmBCM0zJ`PHN(Uk(u?BJ6I+I$%ZCN~dA3GRa4W(4#-go1LTsE8hpa_im&>g);HxsCL}{upAS2__$M$cdK1ZpEmDGqXAnGVJD# zJ$Sa4A(w3C>Mn1yUXsU5E;}taJZHkrr6NtFM5Ch37|O$#*SEfwU=Vow(2dQ%dM}?r>JLh5P!JWH0RQ z9^3@SOoXB0RJX3V@Fp?Oc&+YYGy@0;iFZG*f5rSzNi2sK@W^8c$_=`yv1I40dzw~d zyJ1ycP?0>2BnE;oF~ZeA5B?+WN|C}DMzBm#Pk$*H`G)gz-T8_>cxU1np7o}jBZ5j$Yj@qx>R$gcZdMuGVzJGDZWBbda=gHQcoYBm#Twh5|=#__rnK*MXcO zMnM?Q5|oErAGDCP6d*sg+&h#jYD9U%ozPM)Ux}_z;=fDXQ_h>N0_;dJScqdnLbpXNa1=!>TxVA=DuxoIx8n>}W{-VMb}fBKm0jf+jXOeT2x5zB#cONVGdJ& zHvMW*F%#*3L>p!i*$R8b3(!;?+SrV&;v&DuSe9qof*Rr(AicH=l z*^4v8P_mAb>K3xw_r-^tYof`?%w)xJ@oY}u1uWxEUL_TI8(%}hMJ)Qe8la;}n)0rK z4Z<*M@tBexToY z;i9Y#Rz#oCq;A~?N-~qL*LJrEbms$@578gaLI}#BT}OALK3UMg>`*eKs`1EqyVE0Y zYg&b0HkZC*gC?rgcua$?1@2+AvM%5aNtI2HXu`0@&q|+RV2g9s=W(bj*yP1Z$W7Q} zq89Jm68E*Pxq}#Mz$|dL_lZTQZ^Me{Bbnn7HKe=^M%3Amyr|wqWSj%Rxsd$YbN z{J9A4smK7XzE6;|dor1r*j!l4WCoA1#-B?TMLlLZq_-X2o6JOP_Pj|@F8&j2{9x$`k^N{IwZQi{w(3Fx%b}C&EvVc=k{j1ANFiQ9gKX&b=J+fc)NE=17+3^$VTNTZN7(&sEHN+Frxg;d zix}U+W$T~7avp+N!vG3zFTjUB!ibc>#3@S`FA9!DMN)}Z{(k62%hq_s%0e_U<%P$a zrb6S1w`LQ??j5(H)*BL3E$qik z^pe1B2kblJn;5?sh#0QpVM0X6Z;qXtHd6Q9(lX zwvCe;4ZeWvK$w0t8cG*eaDs z%RMw*)@TTZy#E{$vAQC z6t{7CXSmG76vm&We4O){c_x(TN2-BXMk`56D-1Fhg7HGn$u3nM+0)bt zm+rmKnQ4v2{B$lkLc0&AN=3}s*rL&oBrQypQ9iAuFf$?B;^A`i*@c9@FODIz@!GJv znwnPqc3!M=r)Ieer9(dFQxt(Mais`-*>(-MN?t69LGFZUQj!nrNH5Or8p(&Xk4x55 zfNam`Uf7V=TdBwgSciUrX`NZo_kRW4cJXMRGl zGx0-Duv7tQCe#HnBw!qo+&%lhPgZF7 zBTcJyymPI9ZBTT0cuD%oiLZOJ3GBpNBUe}Y;GyfxddA=QhfUZt_usc zhoz2NMrSGAI^MbpVss^k){%a`F2<(yVtAk6mOAd`|G%>Q=BF~{@@lTPBl0jSJH^RB zOmOAz9bK%Cc-O^zc|_|lX^8~D;y@O^SJ*FD*^8r?pZG7P|9G}skce_Aaed?$*|b(3 zIa%G_i$CN*RYSw+YP&}qDg^ncuRGEqy@>fo92GrC2bPs-?p4@gPK z_DYgjrjO)mt^E&-&{@b0x+jWqw-Y1S1$-Do?NN#NI3dMv>Nkb!c!kp1q-%OvYE8 zK*OO4mZIY5Wi;-c*kG;H{N>MHTYnzL8B+UR39Z|N4}eh zMh}nBl9A6na^=*{1Z55_EkU^~)ZsSEL5bm@eV!F+$0O^7>=UwVEf42Mh{C{%*q2WMbZ+7t2I#bAh8JdE%WJ zu4Hl~XV`M|RT&FS)^mLV{~-dVsqi28CR;{(FcdU0Q)C;V%!_6Q2eaiNM_l7?WsN~7 zmTSrW-x1t3xv(J7o9Tn?1hxwR56HE6UK9~G0bAUg=*0@H2ttn&F7yM*2x^->Ve#wl z=i$d$L(ezpAp~*6Le7InhH9lj*X%?pk^N}b--R!QqTUP(n62gj+sz*^L}b_p5-z`p zzvmWOMOYH;eE>B60ePzf$#6Nc@iFASIMbvG0$V81;UJdcZ@`6373q~3z*#2#fdE_B zx9Nj^aGav=nzX*7B0FgMErn`xGN;!U?7nf07-oJW9P*XKSLvU0NPuPk)R6ur#y9u@ zw3aD?qyzBqWZby7bq|^sy1ATpE(?M_Vk%J2Gc>} z*0-v+A4?Rgel7${OQ?-;R}QTG4a>9aPd0I|%5?IU6N2&;zvPPso~>y!j!ez>C!c%w-I@ zID$xLMfrWZCU&D+fZCl6`bd%}-U#QX_)s5$(wBs6lm9!f5(T&9T8z2G21t&I z&WaLfVF?ETVF5tw`5QgA^b5}8AL4nvu7 zE`5-H!!H96>lftsh^hCqt1B`b_@Tgry|bmn^VmR+z@ziX4pjfLqnIlD^xrn+D;RLv zAoyJefN`R(MK7s_KDcP+bupCXdVr>M&XOpIe&L?K8ASIZNU_hxVoE%@&d2LoJW~o! z4Eri0TcNf(01So$m1n1i7~PfM05$#s>fY8wvWMHe3d<;n+O^CG=Q7OvLT7Cz$vF4N zx1!XACo79SxpVL`p5n~9KH~)!u z-!BV8LFmmoPUS(>pjEZ~mcs(5;G4>$_;+SgL6S@l^9YDbM-!&XQBmKw5xX zT%avJ?&%lo#P4*beLCmODyS`H2EWR=-!U6;nll_QQ}!mU<1PG9(iNN5cLa6;8(Ibn zWiy)JA0#NJSVM+&<&n}N9-!;N*g#{XV{wMFH z)LK(#Jl(Vn+BU`%?~Yl(sil~zoLvkgfth^H_iW%fS)RYuI+icO_Da&$v{GV4qi}bj zi1viwq_lxcWV=jQ;O?}OUT9j4X2R-vv$p)L+=FDC^#NcJ*u8itle!5Qm#r?ofA5t9 zv;x>49An64dPmu02!aEyfZG*lHGQ}*Krs8m_q4%M9uu`@LM8O(t`s$_MDY{w2JfOU zB6OC?2`4PWX{$&klL#~|JcEEfh_LvgyZCsn9ACBF~PLb;9m#7)GOpmO@o_`(V;dBeaI? zxVoW|1_<04To9|t-$Hw zJg%hj?rSIw%Y}Dxh@Q1F5p}+vFa;GV8Y@QHp7UHLAOGK#JkQtSyrH5X){}Ky&djWL z<5oSy{vIv+@_SNh{rRRstm}UO!ht&b*53Li`8^CDu8a8?>bMnv)e2)Ap#KHVXV*in zw>(RtFBL5j1kPh`xZc^!ZJ%=&WGD z38iMJ+5eW;JtZTaG&AXao+zGm(BkckscuoddSGjUe}U5y{ZXp z+m+KHnIGs3hqq9wHw~n0^8SyDcq1xWGI|BiN>UpNaS2&LJ3<1 zWT1VZN7}~!i^%|)baAX^?%4EO#o-&`OqHCo zANTdk9QgiKT)5HINB2_Flv1b6kJI8GHgr+#RZ4jjvFUov`xS;Z6|#O=8mon#VTW*( ze)?c%-#solYa$A&m3HogBYZg+m9bnf)01T&BJ}flQbFk56-tR-I+jF+#`1NBLcuQr zp`?0k&Q@#os``Xd!0RJExAUmS-= z0=^hL_2^td*rqhHW4OKc*Yo+A?^eUB{LS4w+6vW1E{s&vM@|#R8h5uG_;&BoFSj3z zz=6mIQ`N2UE2g}@;@&-cpT2Kv+xWx$r&F8!YJYYFc6Z8UiV8j3ZeP-Hr4OaT)J!CR zB)wm_)*j0M`fmW&mY&F55@hJ>u+C6MstQ{^wX$_nZfL_DC-Jo{szN^~+TN^lR5g8M z95N1vCI<9nc|&Tldg2Xo%L-jMVC>K}=XjsH%sbXkaJp@M{l?_2-Yia%j=bGe`f5#S z@bL$oSH;D2Hkb65K^QeJpU6IU4WmwN->tn}_Tpw$n(%`=xvLvg^Tz&VlO zLjfLZH3r5P#XkA!dBJ>g=E$M9u9`|%>R!La>c1a9tuM~pA{4ZWN4CaP0d#`?kgujy zJOR^o5%ORcT9NEy8Ll%tTRwh%cvDhQC?+#WJd(e={^@iJ&w?m(EMpz-`!_o;Ha4vS$sO3OwS4S6{#ovV}!lquTiEdQKoMujF$y)EPH^s5fk{=1Xj! z=7#9w#EqLD2VR@X`r1oD4*nj^dAf6C5pyrw=%uX2VVwA-D|VM;9wFy-3!mlyA<`!Z zk8dT9He~mm<`5VoUDsCHVyo&U2<%g7dOL0qI}4*ihefYXwg~&=@t$<`NM?<%l0(5v zUM|%K4W>atUPr&cQ5Bn?Xk*$Jz2#h5ZDl?4-S&|GkeK?br{gxC`(raZD`g`LBf9ze zvv$Jg4~`yqu6FdNRAu+tObOMgtNz{9OqJ4uZAl@Gwx5_uqw&o-0pnIP4=6`ErUP6) z{+)4co z)Vc^z4EJBdt*#!7)+v?$azb~hQlk2=sWqIk(D7$4h(m0H0i429;}^K)L2Cdq`hj$1 zsk`B3AO%7kPlp4=?#eU=RuAd?_^T&2^3d-k^R*K{ZRfbRAM*p0o!m#lf6v?5+Fco* zo_)8C^F^)p!iKJiYqxKwM!R`2h?DW5J3rqIvKBLpqIl0 zpQOBe``i7HrM|h&*zk2aE4T|cA_?sqy}TB+*RBMNX=^)>fHr#o3LF-iNuGO?j~#BO z*Q#WjnZG$&;dJ_!=k6@+nHxV#R;jLJr2jbkpzM+DvzcQ$ui|w_dz`LKmT_tf0^_!* ztNc2i6&;YnpAP%gWqaxL$H+aunggGGm9yWFT5~{#uy)k%$tf>>roWAB&t7-m%FYAF zW_Y1FU)#NfKCdA|gZ^VW?}|`S zoLv8vkZ5iE(?u!K*E{~C_}b5p=qrDDzmmxh#dIrlGUe3EgoIRp8)Oq$ySS<94IAA~ zXj*+KMjOnl1Q=c_cVfz01Vd?BZ7eoFKiy?c@Uz|Wdv8r+%H+%6{K>iNUjj2OpRp~L z%3WXd%Fb!^Fmy35#=gHcQE$_^;dsZ=2e~5booTV;khc#zYscnDvx{!k?^H0@H854K zKlwgy6d!Rpb|rVq3))&=Eg4ZdtA~K0;#j1?YAw$)|8v=em&yX4VXBn%aUg_UPqbjZI*G%e})}B_hjBAXDG5cgFuar=T*fDvuy!V zFj`_*E7aUtMtza!Guh4ZEMFeEm~#k4lr40$>3bT>$fE6CAQpaTKF#0SvcAG5RVA@h z?6l5laryvd#U_um(x`nN;wi8SLlX}saC))y$DxZ)4i%rJAXRaFMpYJ^0y#%$4do%2 zp*437TjwjZW654s-;EnqkKix1 zXklp~N9AU;#gnAj!}lL`kiSTOS3aA*4>PR2Mb`5IM&x0Rt4_e<=i}=cv=ukWV_nzF zWxSDITF9&4QzEpB(p5T3oD5PBA>vi=Eb~;&UyA53P@FZle43>%DI|{j5G`D6RDP zp}|c5X}ua*wN4{Govw0hn88%Fhm-yLwSA56jChbCDC0_?S=17Pp=fWUnB5D^pvm^X ziiY;EQgmAi1@Y7c{)h;~Y=s|xo#Cr@^ytYa73%}VD-Ae0-s0n@W4d%NMQsyON)!rR z)j;xW96%L+fF+s>4P>Be&z_Ltk@U&7X4X0JS$Y}Q4UjwMGkoKa+_qJ{py;Z4UpA+h3NDZ40!&Q%g)2uBt#-53kxUkayPqQ?iOB z<*e}v)bue3zDUn87<(}4FZHZTwpr{Yp5>d?WVdsR#_liNt)B%Fm)@^A8?xfmGV{rb zA(JIfZtpC?Rt4=gT{_^hBg6sjLnXbs_v)c zXaCd+30=8T)Cp+RwDp)4aKq3IzXKsq7YKuuPtf*|q4opKW2GZQYB`eEm086zPXnH8 z2>8c#e(7MOZsK^{EZF2j&!?+EB7iD`UTDzZ4jd!b*BTj>m_;%kQCaP%o){~5< zqs=V0?-4K( zxBIrnY~K^U8*bU#ZNwgc3J0G1usshwPP0A1U5qQmTh5%-_%#(9ps}?3SkKZdubXz& z-EtA9J?X=LdEo`l-Y(9MPhC7<^%7uptdrO2AVK9Z!1 zfgRn-C4VyqkmZed>k=@zK2UA0e|evfc*R_Arty}HKrTYMp41eIsp2!`TGZiwZ&89q zCv_KpI~6)tpS)Od9lHC_+Ffn!^O^&gW)iGm4~~IUNHNApb7FT=-BjTwDYA<5RLi!p zP8m=#e}B8Gh&wfQ@!Y32y){wo_6E|*5@M&8;Mwmx*@~)e5{z#a#!1DKMBC%_9-Z}d zewuVv^f-(#b@eZ6$20h5l#td!;aBc&pOHotYbRqf;zX^cMXgHAnJZ(+N}`mrDa~Ke zhK~XsEw4U1eDv=vzh6R3)KK{{n#lcb-@1t!sr@)E#!Pg^nv(O4a&GM2G8?CJbd4-? z$18zLbB>JVA3c3!SbdGY{6XDC&m3MSD0kr~3{m%dCO?J@%IO#)ZW&xV(COWZSs|!4 zH=(KlfA{g=My8zk_G{%+e&5xwt$WXeVnaE)$v1^2Fp-nCkg~>n z>;S7R0hw+&`(t`4R4-OImz5z5nNxHYP-v7;C<%>G@L(UDc;<}_PUOc$?h!eAu6TaY z`+sW%xy6^Ba~0{0^tA?&s==Lh_b(G)yz2Fz(6J*jh?jm;?4~uITG8p&KflBA&&ys)af zBZ;`HMPbMC+EW*rS-y9E+sur}TYnNxbC4DW0qr~Hm_d5lhM#JV9#Qts6AXT}zuH=Q z&H3P~YrYQ;T+Q@9t5;DR=1W)c{oSeGzH^(onZ|6%MPv~k+H5Mh?)jWUDNBK%5m}oh zcGgW=(U}>BD6t&wLLYxX9Ia(`{wf>$+M}E}X4{*&t+l$k`|1iy;-QJDSZDD{s|wtW z=K#OX{b?5(QvJCO!f1mQI>Z+Ew&Oa`;5v?C^&QTlR7CugHSe-Y+Qxz||C5W(-_W-k zk+f%Etj5Ik?3wyASDwdr-ukswN$l$igx$L`Lq-p&cK(@Sx0k84AG3XDGSL$#YdK&e zdw@CSUiyE_a|WiW-qMTpc%k?C!c4tCoi@45{UNAxu=S-}pGs%{w93z!vv%0t^4JFi zK7VplG1hr#4Q<&-c<}|itdj+&suy z{PTlx?P`$)u4)(ej#FeGL|YpCj*2xSSP7b+G0;tbvOU0WY@OlE^Ce=oxA=vji3w+w z5?@k@hNdf}85YD6oTiXaMe$jX9IO;T-@k$@kY$ni>^C4L2d4dD2zTPq7x$LtC<-lVeM|(7%sLwg=^0-ET?9lQ(bL#QIury^>&$|eQ7@f!nUVYl=zFd5v zU)-7-rt98>xn9z^nAx)&^n@Zy-Kj|sRf)Kla+oSZqBUZUF>nW+NG7K&_Kep)=b9{3 z^AU8jE@#N#?p@s*ue=I#dEbq5qs}>s`(pRoUzBLQSFuVv>yUMNy)4EahFeoVF?XIH zxfVMu|JG#{Jqwm~A*AW}u#zj6mTz?wWy3BhZhFKHBd~6h5H6Fbhtjy`cI>nvhVR1) zt0a!iO0|=k5c#qUx;+8Yzgq)W8pzQhD0z6LuO)dfpRKHubm(!u|YTOb-fJRg3 zC#AzU#wt*Z%SMRr?YSFGHQ4ekZqJ(5`#WZypX+`t7u;ia@DPJ|e?#E&o#ES6V~Cxi zQY+)spn1ggUg$FPQ;jGfY!64y%d-CHcnIuUkUZ0$xG!j$_Aye4oqcPjqX$ec;nvxv z9(HS0c;UnPIhq+8lA>L=`e%8&*Sau5bzM?mpmIwor%;ATtB`Zmgn#m(3&gS0&68ENHn6ikuX4e zy-)4MxmXa`IBUcZxr<>8UHz=K*1me(nkR&hKkLrw^4Grp<6Z4I8=Uy{G5MbtvGK0A#WH>!@?~@{WGohKI;;m8-M&(r69YdzP z+Wi+p*~Jf4U`%S=@~?Zu_3|q0+835NyXF;|tmTKbj`-1QSziNgYKEM(2+Xlh+0`N} z{CQ323V|Sfo4!tl8?*oZRtF2&lT&Qa`lgEr{X&UeW>NwjK-edqqR)EZeO07|Ps>)ROXCn(r20LB(S6 zim#sNN0Ae?i!oIt8dKIkvJQ1FYi_(Pdp%gVHqids=jMN{BaehloxEC8A-8H6IIPhu zWv3tF8d%jbqG#u7TD*M9eR-%EOkt;_db0%r~su7I$&^T@}ZlRP10oyEU{ zc73&=6C`-hxd7qVHRzpU>%;2RrEEef^J^c|3}UgSrR}1~|N(Y8E;?+O>#M*A$tF7c~dz1Q!hkF%x^ib0M03r2UrO=wb zIM>qS`Y~Z%DIkq2IS9mOB2h~R(?)72;E~bta{GC1=-tELPg)y1ES>Ay^gKt}Lwq-P z=6nX6LuKM+wimk^RDnhdySkuO)bHA+4^tdC%B+HA2x}?>`MS)#jld4k#!-e$ zD(#+;F!EEE-pS0!2Z%gj2Cu&PIaHx4bcgUyP~lQ9%`$$b_Se_V9jls6NS~_e`8hm> zVfa+9(+(hb1lwO+k&;Q<$l%j%b*XJVl^y#mY@wr)!J$HbK70_ga0*q)5aTyckZTqG z{a4l6K7DA=vhS4v73dkSN|2a6CqWE*-#O}#pZ(6o`qP^BS6iwM_f@yGJka=dU3<(= z?-jlAGygP}T5ITw6$x0ZTl!36Ftz^p?eBf<R&d-|>4kA0!W-x}^KltyipTHZ)TIJ(+YS!?Me4I@#f!-Y>Dd?cI) zpFm;RiJKVE%Iw-qVE2FeC-CDy$Eu0QBU@OT)lAuNGOh5y=}z56F)p+=Hxw*|F2b>w zWes7Ku^pwOob@wI0|VTCv&?G%|884VM!Br$+rNk^JU#Z+w!t>XK$~ML&T&yJmg?#< zSE;W-V~V8O@QQ;!2Py-~ldlIv6t`R`$QdfDHT_@egSBHhS7NK<;IeU&Kx% zeO#6nB)@TH-pzo5+v?lmWS*4y*v)#LnYkZ7)pEV2;`QG7$|K4VdT#`^wgqv?qDh~A zT!KO@m-BW1%=_tAiS&r}uihKyp9e9ZIRG9dMc{TD?6Fl&Nd^SaQdlcM9}lApqtlGy46hM`kKqItz9KHjII+}Q^&MRcO4ip_E#~nw5fk`u;oPm zl;Kluw=rV2^p&f7)h4^xa49FL(qsR8UIWYo$YDS*492jJ3Cg;X3}CKZ#x_$C5HSO` z4e*VI>hx}?OvqIG>_j~knQ2VpkR%RyYdsFTLTbwO*0=$%<9a1vF~cp4U~8m^2y`v~ z3>rKP5pqFA9E-=hKg3G|U7EcYOF=-qXM2*QMe7Qf{lG=&S9;K5A0-hd9vu$ z6`tIUrEul?1yx!=hZ7hGA64^Uc}WS%ZKTCm%GgQ9bSDM-@F26~`y@D^IH&_q*Y7~n z?rbs9Ws~X~FB~K$ulLyz7>vinnojt>z8>fMY4NeOp!uZon^syvFB}uAzQYGK zNId$ZQ3ZX{Gm##y_qoHJkLfSoaE72TDR%NJA9Au*IY%w^UmIh0o-?`s#wju)`{hDJ z=Xwwf+MaUF|dcOV5DPn$p zW#V-OYZyfi7$GD=cWFBTy2js8JpzBPGuneH(g8sNC|p1Q-T47eMp#$Q(u93Z_Wq2k zIkSHgQ()C7gcY|%yHE7TE7YDX%dXhbESjL@H*Yy~fdpx6ajxKh1dj>Ok zqlz8_p}O3m4<40gIehT9k6MI8FUVJ$NDYs9WTUQBVA`SSdr~g40jFmkU=8U@z7^;C zesERCb;HQ(N{Lg;R;@F9&U`c%QMS3u-yVKUByDt&&~2+XCRJSF(I2 zX(=BdI4?fn991x@&U>W0>%qQ|>@`!tJ=hG+SMk%7(j!@NzIu`#?X3o_FFNz~l`YbK zii>9gMjNGG!u~!VYWm0`n{o4HF7jaG(8SWuYgRQEf;uUc2-25F*APX{P}+Icdyto5 z8BMyNX4l71@*Dt%LGR;-t}XG`(D1K%Yn8+$m!{2YSNX@%R(yEzm=w)fQwA`i(~+B7 z>B!meGKm{HlX_qf3hj_zB0^Jq=!t-S?nZZY9;fUh#M=rsS>S)q*oSp{IkQ1`0F@uZ zm?#Dn*1msDlrHow*ntFPknglPTs-o^R-i-aPw zxf8w*W0W@N7lPs?u}_e~3=WVs)<=@rQP+^nrS6U!skyJbQt%Vyw{t=lF_r`gNu`jY zE&2kwGCMZz@%S*QbJ6=n8OsA}DAPVDO%qSaiT!Rb-c^RZPLdEh^&Eu>5|Wx$D2?fG zd#?k8Q4xFtph7&R7bm~b9#EVmf8LGyM3f&r7*_}okUd$pGltCfn2}ocm3rCt`jZQ9 zuH8<^?;k4i$;mb8_#7(T=VxGTQP-eV6T9ALRa{6Fs2Qh6;!QdEle1nj484_{}@WC)k@2J~I>hlg;*?yl}uHMZDB;80V0+QvC&{ zYJ2?Co?{wG8jjDDHwvkL;q#Z4gDUM7DwzUdnG)*UkVEr{+X+jna{3??sN0v%k?kC? zhMntmtcjAD4FC7avGsd99bYmZO|!`%mtp;qDm1N3T93`V&Zy5dM%CqDhEQ$USVVk* zD)3nNDR0eZNA`l&^GHPJ{Cv_}j!i&J(Av-`r8QQoIs*E;+jR{LB&@xp>==A(?#6(D z5fwiT0mGpC$_C?21NzviW8v0FW^)llqp{>`L`U~rCZdEIf3$p92Mg~2#%n?KX&_}? zs2w2F%RK8)_cuI}Y9HEW79bs=4e!0VnZIsq{t?tU zLbqvPA!DOHGFLZ{xgC3T*9Mmhay~{dN;r!`^bcF5oLDLv8T5qcEl$sh&+jU+Qt~}E zrzF#Pf*4Lec?!s*Bovw$EH=WGSRVOiS{DP>7AG${mSTYsar9=a)C(jIYOQDlt>wi2 ztq)Wf^6XS(MmlTi^pE*dl~$##y$=uf3y)lyT@(2nJG`9eCL1jhY9Q`@KFji+L93j$ zhG2Df-5T*s$&L>yjc!p+gR5JQZLxmD;BHG;4}m0jY zb)#L^N}EYW?vy}cOW~xMl@nEM69r05RJQ~O!S?bWu`~=o0RPbGrS7+YvIZ#sC=+yd zCX%JfEQtjfU_JCw8m3(@_+qPegY(A*Y}lwh4p@05R`Moq>a73tjy?gZ@?RYY6{qPL zLURg}sDKS0a@FUO^Ww^m_X#Rbic*ToVqL~e>SCy^@p3KyX_P@K3w|~b;@6qMV!5Bz z78PKw_6e#;nA%%^Fq^Xa~HNohD6)Sh0qRF4PJ3Pkd z(i_p*ZJ3p&s0?!6Y^S}AJswnlIW(+==FqYiIl3ES8S;O;x8R)m42C%)T-682SvV0e zIDzIjr<#P@LkM}#dM~LDL^BAkoZ-S5Jsj%6rRy{JS+oax86db*;raUqo_jUmIxKly zT!dbjwn;Ju#e}d5L4Gg}L=We37n(94_r_9M6mWOcotZpA{@|fp$3C1mZ;i}fanaAK zc$P^6Nrsw7ML>U)J)~Z>`C&1czenDYR@e@0Uy_Wxna9FokQ2G&Y9&zD0R5RMHFfJZGIh^fEExbKVM6WDke(>-sXoGplYosc~d#1lO6 z9tJm^eaure(BJC;WE_d>`=6=pT_DIAYXO&lbZ@yJ56^yg98}2+;>znpdtlWRsk;^w zx4WQ@1;woiM+*Z?9N3{|UYpS(moa7FI6@~9ARQ=(Krys79%eu2wAo}(w?V`A zk38w5O=y>%=(Jv$mDo@c_f8fL)K2`_^f=6E}N`&iFWYM}0u%|s)QP&`nWFKJLaO>$l ztQD)AF2Rfp_KNzJJcK&8FPw@cpl8iCQm~~8(pgMms+*;z z6}a{LT_b(#T2frQUzpj1K`UhljUQl(clEwG?wyC0nh+lUQ<<5z+N7YGwI(P zbQ^<20sd9Bc%qh79cm&2!+;^S>i;BzVjxu~=9!$~w73TbQxW?WG&kwY1@SG_U;CvW z9AyMFD3{h$dNz#2_j&(K-NPmzoAyU(!(xTb8VTR*-h?BNLp6mRi4G=rG1eSchew}rt` zNWg#v!UWp$BWra5vhBG~z})z0|5rU|8BK)S?d=L}6mSjTFe#DnaYu1}BRc=HU(p%g zZs1uK3Q#(?>su{wlj!A8f%_b%S8Abe4j8uqZ60hYdq^Ezv&@}7QH4S*HTy^?vj2M! zs0%z9;x8n9BqSBl7T50#Bi&3dMQqIn^Lu|V5u@KGTb$^|w(ss9|fT#yBe zu2%Gddi^P+X$zd80xDsFzuOuR)Y;_fYEq&Sawh~@R^AgW+HCT-blzeJ7)amcZm&`%_z9eoGX~+qGm>m zhd2J7PY{jDLrn5YDKR;l$(cBl>ey0fMM7rV6DPnB@`mFL9dBhY(q*6*c6#|=`{d?% z0;a;vEzNZtJgXLXJM=>aaG)rJ8_t3*0{FZ#kNY$i8dtZ-)6u9^jD|*_^3S8s1aZz7 zwfCUS{L_^c*TuxdJkGikRKr>igiI>i`$lUAG>G-V zz|K;je2ON=fD86c&ccKZaS$lGfkRI#Fr}#p&wlIF0Y^;-vvKe26Bz=!ytC9Lpe0IOj@6PU$rdh%ggIe zdVGEF7nOCryuN>9Nd4IFqT_NuMN4-qN#8#<(yKHbzo`9+dVsCGde$&AP&Y^8(WavZ z^fjiw^dF}P-Bv~CirgZyaacxi&l#^0CSM%lTL~OAOd}aMro2%w>`)>!@>cD)5dfR}n6(1jC{e|QDOfKB|Jw4GpX)uT^5(-F2$R_5- zD`diHk0!SW{(+xt9|NW*9O0SOwG6$-FyiuHI253WuBe6F1#ZLSF9Zxg3ka9q;jbk$ zt*mun85F>uqwL8-7UcFUP`{@$`2((L1UA>SRUOD87=aX);skD>@df8h(4FUdr_ToX z>d%+tsB3A@-LQRmvylp6>qOs%%O5e?9QYeS9d?p2b83* zU-9yMM__K+oikT%t;&_ZII;wI>xoHBTE9u{TA{xU_ z{%R34kYHFbmN9@!FGwb`bN-rL$3W+%iJ^En*R^a9bjTxM@g8tRQP!w!$ z5!hM)vx}L@g-=qz{T)k8Omj1&^4dw51=IP-n8(k)u$PVT#^A)zl8p~u8quB8HapC( z?Uns@*l+5`7kFgDxu3r**fv{iC@Sj>zZZK=ySLZGSvJ2i*uv`hEk43B?ltv@$?I<& z&mWtsl=k=8YIB5TZJ+POnd&YW;npW(e|(M|@%I~$&@1?*R%AAQY8VD?-N&Hrd`g=| zMmpD9o6ahLuC&UBPibLF9ni(~e377>9=VHKlkp$+0C)Vs&vYPl_?E3w_H`|(eXe`) zF!_`XM)(Ea5mI=0g+T8nc*c&%P|EV_0g>}swP2JKBQun*%xe08ex3+a5Vu7tln|xm zJ-t>+mwJpAGv()OM$N1XF%NnkB7WxZ9uG$360%ny(ut}1i*H)>jt=4M7|5rd)J?}0R>5iUr*5om;H9DJrUNa=+KZz4 zh#Lj~gV%h=hsDGC2g=*_=dFqV{O`f#+hHl5Y1J5!6gPlOW(UlG zMF5cGS|;PIM_?}i@-6J9WwR92PSKRi^=^C50hb7U&|H5oE&qdk!2E@+d6@qk>l}pO z)|JnD(h3uBQh?zhmXHPM7d8O}oS%GVSK#oY{%gI2$?G-}TK0>cPC+EvsM8PU* zlh$(UT`;WzU|=;UbsD&2n^MDrm-Z80p6;k3Qo&~EVW;?{MeTEzGK{OJzgmQ{j>S}$O`q83ToilP(x;$PlM?GLF zO6$Rx!cFlFEu>D@DA~(8n=@=8-{G!-`1?cYh4H{MQIk6^6LIQE<+T21Hfhc|LDZ@0 z&7I+Mi-*tZ#*(Mb9=I?qDs*zAL!H^fYE+a5OaeDE`*#(lijzURRL>^c9JE9eL?fwT z!K4d5on=ei@u0f}v;9WcQF>PXf}_~gt;2bE`i~zf=wIW(VLX~9KcObLpFOz!XSw82 zTFf=1Q3_N{htTGGW*ES{W76e6hx?x1K8*A5@b!%y>f@dG{OW*0?B-|CVXJe*b|f{6 z9@VLL-WEk(VqbGsOtq*~TE8Tba|MqH#I|=t5Ll1vzxTcVE(yU1d|D;IC-Dbxxi`qG zOg_f6kY0E|qm+FU!R%o_;&>~g;P~g-KWKK#%)!S9``a;km1XN0VfU2=ZFdn=&mNtZ zg8JtcYNXIDP|kUwc1tB7B?5^nss-E@0k8egzaTn2bh}Yh(8-;+1@hm#pvJSaa9OL>psEuA#wB7-<@q_ zA6ym-{VNIXq5GhfK9<@ngRRmztMTCzM0ovm^-rPHW6JMghe0gOK%hHBUML7c z)xjLlgHwfKV|k@L!vUn}2cGNTcX+V25eawniv4w${0K{M9@ zVnZ<-CXy{T1-!cbpAZTnI~ zgYk8(ynY>@%>5^^RRK%g*Zwz1rx6S|-oTGhVeAa}Q7qwU_a7`(yFuJ>L@D9z4f9d& z_}L+5MX;C(ILg|efC$fS=yjATFDbazJ%~8^V%T+iXG#NDzn^%=e7mGy~}wkIl1YnmSn%^FAy z;zl-_sDx~)f2t<2%x>x(dqcH-~{c@52le&_9#FfU8k-4VQv zE5ODn?Cx>`B;wLF=m;_BjGCZ=@!AEnD-`tTE7T$|pMrY{TQ#O>MPLxOT>w+^J|Xl7 zu09I83F9KcvFgo&`I$Pk(d1ny8w&!&`|;>^0W0WU$9+7M3OYA)ZqZD**m;ia%A4yg zlz!}1d+ZMBDKh)Rcj z#RaX>o-ipo>wYd+_DhJka`rWc!u(hlv0aShiUp3~_DVMqyR?6_omT7D7n3v`HiZ&& zdP-*mn`UyzI6GDN*-xT5zCALf2hyziTyIxqyGf=89`ozxjeneA=BBN=!BkSO&OP+Y z|7KXTub-`p@m(1{Fe7}yoN4av5qN(M9y7E{{8E;o`aYqPdN9fXohR3#m(OdFdPKnJ zwF!Lg=uTz!;x=gFSoiWwFnLj-xz@25#&;a5i-5mG2$o8IASa>G^cZ{zOW?K9K||1i z1#5c%ZwY$a5_LchQfvy!X7EVE2$p_>_LX19-Qy{H(W*NWwDny&l`o$&C+33^J! zczr}%#*G8A^IImm0!5$N%$E%R8~So16({1IBqXGD9nS_cBrXud2QbS3JTL!0s?Itt zs;+zc1|S`Sgh&oUOG-%!5(5&_4blzLZO|h*Ln9#FjYF4!gn)D^C@In)ARy?wM}26#~C=iKtt~oD6mgpe%FO5twc^BEDGpd0HOt`NG%u$ zNawe1-AK$!_|YID)he`YBlT0+_|v`Chh#>rL2WDDWi+RdN87s&vLvItKwSzJQTzDA zJGN09_2mKnv|_MFjY1+EUf}N!C#1RZMes|r_d`rnSV7+e7xp*A;2@TOQ5^1`ixEzB z6M>TE`0+o~gZrxoMDx&tu0(iOnPbsTBZhHn$T`q_BKNmpS1x}3K1Svqa39m>5V8h5 zgS-~_dS&IMCi?r1qd2H5R#DytRbj9hZtnQbMN*XRtqo!-Qn&Tv_PxBpLzMNYAhjM) z$*A=dh(|WO-f+QH*EzxZzSx49lnJbHRZ z%Bi!rje$)cx>R{$PD2SIU!WeFmd}A_GwmgwpJz@28HRoV2p|Rtv4^3@ zJh#&XfrJZa{070l9Z-6rLStb68w1N2sk^LyFj2}1;5wMJ0Z1rtz z;R&5@U41H8bSLK_Ahc&&93WZj>T&%cPfJ3l6Zz3<<9XlwuN?PL6_4aXxxM=`?<<_BW;Mw|fn&pC?ZbiWB;@8p#oq?)_P6!!J(7XP> z`r{lX8v^lsK~#@}(~kj%{;apO=3NsrSU3 zP|g^9)E`0t6c=P_&E9}U3`+U8!+{KHU}m{-ZhRWxJ47>-@)Lv%Ru+eqad^{3V5=CcN%pM z&>efGL7$3Y!`A#Cx|tOQCIPmlD#x$ACtC|4AgIa!P1v<xWjz()aY6=;Zc^}aitwF^aFyWxZMWdWhsRzZ#lrUeEZVQ?6C zT_tAzg8w2V!2bX&L@GQ$V2FonPfu58S780o*HM7YyycZvYmMWKKB-?H#l+fokaj!} zgFiWm?I3th;$hL8Ri z2pMn(ZiXm~a2$DO5L84RE`N*$~I z^0fcm)CRK&EQ}M|*#JZCy{Ex&fHzOG44vC}U(C}WHxBXzcdar<(7cR!G0@@bph~OM zgaML{^8#lX99W|;DiuiTHRymC475?aKOrn=bkuBm4{XC9FfE*RJSb3E?Ii(`de5{X zEe59!GjIhYtiQ!OQop|~*Gfr5m5#Ouxo^yXi~?M0-owq_G;=3ee?*~VOjkWdB*BP! z2VS6O0a6)d^l<>x=^vj<(V!o$?$w*w@G8p%DPbQXucO z;|wy)f2uh>pq4`bQ0D;j;{z^z0cyJz33LQ8kW6j;XM^)wYF~$fI4c@N5}0zrk{BS% z4ORm$ogCn10XDB3pbs0?2iF54J=#CQ1iZxY#hKe5A0Xj2qw*FsN`T`Mt~`eVv<*9g zzpr#1ABbH^HZyC`wEW7T8B3UkL)2ZnvKDREqW7v5|EaM@3KApoH@uO+yQj>8Cj%YZ zn!gRCK~S}w_?IQX(H$c)M&Pd&tpQ<9RzOk4NWgKB2?+#Wn1(&iO-FDRT4O?1%z}bp zymo*{Ukk865pbVpPKcgwEORuUkYq+C5puQ5-biiA!+&qX>+fD5w+Q%s7_=puMu;Ti z1gJw`%z2;~U;_JlPJx{a6a+z*l9&#Zeiu&;$E`#dir*Nv@(>1En_SI4V$4|;vrn*{ zOL$Pkpc@tnaEuF=bFcj{H}$**_|U-caKnf&AhR2wu5|1w9t~>&K?AU{Cz!x0+JQAU zU{D!qP&xo4qJK-11mNwM0SFsNT&urQ+cEsZ8W}Apzm*=QmF}p53nPM$) z*)8ZTC~_9~wEkof_ew7>^Fi6sSTJ8|84!{vQBt87K{bO|3tRX5!rSX8KV+qkCH`JK%JD>=0RPjPw+(Qn+>aak@VOMLs1GT#;|Xt zfBB0TC3U}Z4s-gHDJT;Dsh0pwLJXbtE#Pn9t`uFtCku5Zkc$?l6B_<|aM&Fkg<;a#AhR{Ig;WD%Ox zK;023jJ76(c(|EOdP#27*!hAbsMa0^IW)+XWxn9BY(?w_1B z2-M#}wTIw1N%O9jeZ`a*4Ft-Zv@DE%F44!5YDA6~Z0X}4O8W`LDj>Hf) zDB)|ise0`I;LCacfC&sFqw7E$0F}6k7p5~=m2iX=@NWOBSB`|_#ewsfc)oNHOj9Tx zm!0DTrv484`jxW(K;jT|Kw?ErIlKY|Rq!*b>AEvg01*EN>|%_uP;Ej1+4rE9j7$6T z=aR&KhLu%tq@m!zYsCY|&Lq%OQDe)!vNtCl|POG_Qn71I6vY*pvnU5 zW}1I0U_Ar?Z0`Gh+6v>hU;_iAy=_SQ{GTge1EW*AfC7B7GKjxicMvihMjnjF;$RfX z$?mV#nxDUEE<+pNG=TPLkN}(jp6B0TA0nt}rFf$wtb)iNGjKkB(|nRGhS@VDKLU;` zg%(SR56}w8FmC`FP#5K%7_P{XVNtKGDU`b_nnu6;$ zP3j`$2mr)VQs17CvQ&~^Q{ma4lP?&CG8300eSPBX{Fg+GDKHMp7y%IVCiL6O7yoXH z%6P`b2Prt5U4cG%evBMofdHyhAn0k_j^Z9{CNBehqxN7EqWf1DCI+RbMnHZ|dX*pd zXf!zuUC;~{BS2-u6BCkCFu7ZOiG^hDt$!WcLnpRlV^1C$Q~X2tuJ8xW?;?VoChV!10UoY)3miZ;N8R0m+TYunSESw(^#9zUL$*S6 zVBmklAmUH#`EQdUs0rjSEoXVh0_?5;014LlbzLP4lHCy~+J#Qw#8rscnx`U|!u}`z z9)j7@g#yuJMf0?LZaG5^mU9}Y(?F5u@NU9+_eQuo$eaP?wt8zmNlw;lr&-P&z>z4* zjzQ(&=E|{gkOB_`d|X4x9aDn==*6#9u&ntZjrV|v4OG5=H4bC4!KCFd&WAu#w!Y!) z1u&obufS=NrmJ2Gi`jK=ODGl8vi=*Zg9V<8+55m}Qve1l1we*DT?~|crsz#EMH6q6 zmcvreWvrwO>>LhIv+%#TbKzNamlUlg(BRkzLshIlr}=2`|K*aPrdG88`q411<3s>I z2kR90l*VgA>QPf*i>Bw&9t;WjzX(LXKgF6%X)c=w0?bETvi^=cGT@TGg`Jr`&aGg; zgq}V0@17>GFdzJ``%&28MK{y_rNj2Dd+TZB_vbeRM`zTo$0&%zFLgU-AM6W!!dZ;C zaTJpfxWP-cp+Xgzx$5u*_5sSGhJqs_zI%RP@*`%^bkFFihux;yC^gh6dy3ZG8Ge9( zu#^c?;yYFuq5<%7@K|eS{!>R&yT{R)8E*@0jYHkbcS9X zNh`730^g;VZh8{Adh!eDrhG%`69?)V68zyB$H?s;+mim<(r@1RAh!(ytt#hYNbv$4 zw{jU#PJC1Vk`V#_C2_tICKO=OA}%ZYc|KiCG)rtl?Ty&V&xky6=U{j}zMSTtt72|o z@$?20#D`2N0w{;11K5Ff1Rb?P9*Kc=Tge@R}aRfH>zXRiX^u3`-9S>T=Fn{QS z_9;B$GTP;V5I8i}!FZoh;a%nFE$3HbM=%A$dm9!wQ0UC{l@4QXoqxlMxr@y#HnTwR z>*)Hs?KO%%=m~k4FBKxEv}HaZ6nU`m@&KfzZb2QMgKY}FQWT)%gF;HVg|P&IIW!fXj{;eZAR3@*~XZs_8~`)B!zd@~T2Sg&#-le3V1!_r<$5gSh` zCotvj>Cxb5*XnoCD+{~*?Cj@u-Uy*VU?`xrNxhMuLBd4pNnE#|9v{zCHU0XtSpIGV zZ4xng5h647!)AJSHnsm-`&@}OEuE6kX?r#;ItDvV!G2>b}7pUW{+rMC?o3Is0kYhA zWVfEDMfmUa>3{0;1zCHP*GS&lb?9gdfEU5njru$)c<7j90z(aR*H+kEwOjy0MZXL@bL5#KUyTfI>>bK*$_jWR#e0+Eud6#dT}I;E973$*jI%qMHF zMN=@Mf(VeKWT+@fd8jMQ?UcY&5p2uQL@O(=fX138qhB~We;z*Ny!=fpI0K$p4>B;# z)sZ5kWyha-iWtiUf9WsCg!&;!oXo`h3)U7y0K&Db0GHVdN{S*YoAz;nop>5!j4>B1IGtD!rnGk?HklL3iakv z24$ogVEOY@*hJBS3G!fTL2)hW?RjI6kDGsm?N9J2sg^N_K$)I|5Wt9GG!e48%sasU(2M*o(Er$m zp39Gd+x!p@-+)2_USjb$%&-qUl!eXBa;hWwF2+8(K`us=O*2qwrmDWwcdD8A269ekw9 zIZTVw)4rvxrp?c)i`wV&Jk8vvmZo+~sGyr#YKM&E*+ngv-hU_H!q%N46b4TF3S_4-H?tzbhY*JznM)mwTsWF9WNz@TFZxmW3v~+IYTx#{PASFofEi ztM6z-FHX#rQpeJ)k*2x&80VGb&z%JuZ_RW`>b(M~Hg(;pF44W#*3QYvmR*xs%i_=N z$8nQtXWkXTq&6+HYAw^UF?}9sr3j|7(Oo9%jq^KiULTm<^=8QAVesyqY518kBPj)u zstKb)Z!yC>Tl|N~P*kFrWuH4O3XSY}=E!9{?=pgN5={harn=@{bt`{sv!72#+Z55W zkX$Uw+9r#v{4lWrZB&Z{-Z1&SS6*cYuyf~vuDZUg=@{p{gF4CwQuE|G@d-o4-t6*8 zh8Dl&I5P4J`Q{Ufd0FO;pP|09vua>nNhq+bsIU;FLNE<^Ki08~ zpXnHt&?7uE8@^XpO!KpAs&lE0x<@R-;LT#lWCE0SYBHx?%2d;O2Syq|==>AwreFg8 z3aNEY*!!ZAk_l=fPj11agPwQxoFna7HsO}mkV~iFrX{6}<8+~_h#jl!Hb^(VfG|yziVB8 z;Y^9qfaPUuSn!=0?2f-K`fWVM>6mIxBU^&y7?_%hwO|K#@Qf8Lc%6N2D5+ezsNjCU zT=p@U#)$O`n79d!AAbye&K8SP5#uQtA-*ts?f$(#YKeC1_sz`={E?bp9+vNF1Chti zXeI`5lFNTPpkdou1&$k~JPY4E%KD+?%9xNt^Td0*?)z7kbst-C07CJ&noR7UlAqrK6YU7GDhV+a!u>?$?+TzIb-OyKYG)l!USC1~i(p!>&%2ZM|~P zNJq>$rYM^=NQkeQm1!O(H8iH|YeHsOR+z`iQ4o*FP%tOlZtKcEGBt^}YMv_`PthWT zJUuR3o)7x%K>grZdrOZ=;bonf1c`pk>Tc3e+qJuP#!83o;wP1^1+@vrLiS=7Icp)m zUQ;Cp&X}lwa-^PkC~-HqbahM~P5dLbmRfT{r{EC3kj(E>lq7)jA{pCOgpg6cr<{hQNyaYX)XdeKj=@bhGvaL|AT5fzx7wF?2hp7`H#&td*~!f=a?B5Rh0NWbQZ39D-1g8kU}p~@kt5vBB(kx*qDA7~)x)bFaK+Spil7@! zeA`?+N4LDA|DZ_0!r4IUW?j1~!EIa86|D8EMTi3|$0*SzecKO_wlI;Es2Ptb8y{#3 z?LboJ1MT8QsgyUe)9+$@9$$V=jhPhr&6pFm_A6}dMGIFr&Ylp?o`?%i#Vr~)Mfk=A z?&oo-HjgI(KSrNgm*JVsxl;l2q|>E?+xPbj3WS$m9VcA3O<)F*RwrY&fiG82#y~8b z69NMaij!Bb0zy$oBK5QeiJ{LS4@q>Z$aO8|6Dte5%I?ucRf{g`DVSc6?h@@xjRtUU ziG0-IPd2H`+bVzUg~i<$NMSk`%iu^TrEh&%CI+kjVoVS>6K1CSq>8>^+^hQvCu`V4 ze~On+Oy-c4Ue=6S8p)|C227Q>ddKmT+d`3NrM2N{x)k3X3t}KYne4mHYutGp`GSVi z`JFUfu}_Fh2D6(oHhH63RWh_gC+%}dkhaSzD^*;qMcr<>Lb}8zL=-#j4n#%n2BJih z&ua`^*2?Q?q3-?Mx5nZ;n{`o{PGaWmIy7ZXI-x&u9hNU0}R7FdXV{V_e8*Tq>s zdv(3^a+#8jjo<3KpEV@yT|UF z@?b`w-YL0u<8Bn^dTsg2szxvRaHG$(BgGCis{ern*RN!`*zTS-emT>2{;_d*rM1C$ zKg-HQ_iZvaZ zc2$mq@F??aLu;79T|CyhWG+z!u0k}^HttNbz|cw}qSfwlMZ$to*O!FZ$CAjyC(S5- z>qj83w@Js~kb5?T;@};{wb3c~+TdFbhg!7tlHeoeXcJ^k;rphVF>F>@vU8>k?75DX z<&!qOu3y!*skJ6OTQ#j=YVLg^vUsMkEoW>Lza8h({q)g*b>Tw7e<2AGL`P6nT329wyev8-Yru4kDKbcD8E?OEu z=TO}jwy`v*+JqAf2Kmro$6c0x0}OKBvb5Kw3A5hjY3$0o;dX1lY}Cw@*68yhr9(@qldDy+=X$qQ+R6u-9A}s!KKc9*qr){%!8bY z#n^beNLW*Y$s&B*D+Se9_R)ug5W(w0*0ch9MaHg#@P3DQBuiNTf@uJUzc`vQlx_*? zNE<-soNXigSP&{$x9CL}3n2*hX>*)=0Znm|^a_=IJM>Vvi$+|OOlYeA13K&T-R??G zui@57qhekg-7L=R5*1&@7pY3iJJmvL=7y#_1P}}3kEF7F<>G}`4{-*}8RMM!j_*-D z7S_OR+Zq*f{P5V!)5_=YlJs!dGqvVIbHfDx{lhFsCQFJeX|C+H>RM2fp8Z|+$6WqO zv#y+J_f-{7J2=# zNvf3EIa{B?tEH&|8460ELpO=;Qjo1n^wQp|{?vL@wDvyS#K2*x*oPn%=TiqcJzSM6 zC&LfraSQFHc^ke!v}$o5V$SAx-_IO7pi{YtwNRRfdFxsp4SeUx`D(C`8zY4Cagy9) z3%IaWW>_V{_g$cuuPF2NrY}ED(sc&)TVLi{KbzlpSYEu{N|+BWR$+6Gqlz3N)46{9 zG$b^O4Jy=k`yQF6pRC_1f(aVr62jWxRA*L_lPCAVWXO?M#{99pYD=sVS%SBL)G&<@ z0>^mf%Gfx~fvCfk#FhBTy(`~8l|?*P6CkDF`y%N3)Oz@ZvG4UyYlibo>XGBxWGB2f zrkDHjvDHhYM7lPu&@>Vdw>B&+z-4Wfw%c}|BwG#9 zu_4%$KT&mGFlzAB{)&!yp zZt@FXnabRfsk&PSk4Lz;4ayd~G*75#s1=8Pd^Tc2pu?+rK7Swja;cNd=E?i!$1)ek z#5$jkA9FFugGi>mv6(iw!iHtbjhcm!7e8pk+*w`krYc{&l-p%fySv+{{Jx4<9Qk}+f*o%EiA zf}FEkuv0pexn{H0J3iK{{IjU5u1Q-FR&A{?F~(zS$i zmXhvzJ$tAZ-^dI*O5%2V_>)Ua{t!y4L=nWC_Ph2A6Y5!p!4fl!9?I`53Ks}E?I+EF zt*H7WTm61S%XVvi*18dv!BxZXWz*GZ{3^LcR~d}*(EcVZuKQcp{j!PA_~*Av-nR1g zxxVH4_~{Co$WDZ*T29NVXk1-(`2{WatfF|Akgg?{szaVlIlHA{rQK@pAx>fWW=9gu z=SPcqycvD_%}LWlZ2nO~@2oPL49B-y(SlkAtAbrtHeS<>F6Qs+$Elwvg)W6FHRoo& z(3wCpMTW&1u!V=_470D4XsN7Hwcewwwm{yw(u7RNzfyOWRdegzNdE_!lOG+-P!w z{3=$Slr(MIaN6}knu?c6`9oq7BLvd(Q7ZCCy>Z-{)~0g5=9+x%z|>)wn%RRI!%nr_ zY=L08)gHIugtIXGM=TSkcd-fUwy7YFT@r=I28hbFbF&W>zt^&+J9fkzF9R~yw8!^v zf2$PfPnqCrB=(+J=ymJMx7zCPlDf6&91$O_M(xB^m|u5Q(--d zRhL+DhxaX1h0@{)!%Xg;qiW+_8p7Bw+&h5;c=SvqH~F#EtNJY4qJxkC?@NxeLv1G0R}1!IsHtD%=Q`OHTe2`iavj0c(z#B} zvoyibwdI<5d!DSTIce#15OOA`T!VB`6O|-_GQ5@RVuV>oPM1x_2F!Em5lRfpNxDm1 zHRJ+x?ky=@WE7(#={)Npo+gs;v>QmAIz+qMO*ns=pe&{tz69?U$$ z8rF$s8&yzCCG|V%?5mwr_YZ& zRgc+P3Nar?|2S>lP7&emxVq;OL%bq4TrDFeC!1H@_}<-rO_xv3%~$QMXU;kS>5co- z4*v32=Bl^C45*G@;EA_Im&TQru4@l?G);VmvgSItqYL@CN)zc)kM-AR&S+L_!(-OO zJZfv{1MZBys{a)+D-{Mq5p}(aExMI|m)Vm|9Bmo1bAYC64wMTt1I2>5IFN?nqgpoc zAwcbalp?FxlEQCy@m-l)L5qQqFR?e-dh$q&rZ3! zDuz&hrK?ltw~Y)C)WNblYNrJnU9t5BoW?%L3vvi49L+zRLM^`a;$;vZU-i$l8r*+TU+l<7Hold- zC1k0@y-8SZhyycHgGOMPzrpc_u9(HhIQnTh`oHQW_N{r-ycQO_J=-~>K`r{_3bU}l zXnePl>0Ypc#=a4J^dz4h!nk0slZ#bO1vHE+C?daXQ+Q;w3TYAOxw>U?fRKw(n{NUd04%2uQ15S?{JF5?M_$SHAf4|*4md4V$cN2Cb zU&1uvI(7^Hy!R%9!sBo=x0{^$HmdmF9)<5Gp~>yJ-QK@$qY1_}_)ujiqgWj9&C$@) zDfBTJwDoo70oi%GZja)pvsn7L_|_hPcTs?xf11t=QT(L|xvhC$=~El*X1%I;x7nlR zY6wY6W8lua-3Kw;{^&{Egxyt*@mZ*V`{tpnh7rv>oZA{|S7IhZO^Ki1s_)e})0>{W zNeDr8DJ<`gvLZz4QPBV+p+(75!%P_cy(?PZZsytPd0MghokIs!I*l92J;!_D9{3yl zuY9-PeF`de>Om!F(OHZYZxvGc_ik+nbI$Hun%`}$k+0Zuki(wnGScTOuVP zhF!{`&T~!aqN88HV(j9ZTb~Fq#U_VXomF#{gF7*KS5&p+gnQ--a&fJrM1gQ}TB# zC(>)Idy_$i;-!&QIC_GbY1yaz#M<%kWX5kmqx71DLjs}ZviYPZvByM9-*%Ew?5B)Pl*ftsYp2Y@P4}D zUFXJvg}0QU(XIHAp-8G{89kZ$GKp9njqey11l~^gG$@$49r=Uh?y`I!f#9g8& zhn1J7SG+m01YkRj$diH{v`Mr>8DyzA z3J(Epq+Ny#MZ7kF?kdBpPRfoJ+4Nl~jo1Ct)%a+t+~Fk}W@t+}%|nHKZ3L*)M~Y?NA$heFol~OeQMQ5&n+}`% zloh{`6a&%sRIJKtoXtT!xqIIhy)kImAp9yiZuAFQP)d^odErzjLpt!A-~UI~9+ZrI zph+Ex^~+57)!wDww)o`)P>8=)Iq@sYrqqL+P(cZoy~b9l%MFFxVYOr_WN8c~CGSzi z6c zo!*g>8oSs2Woz*kMftP&-yIy3FrMd6T%eU$iW0_E&$OwDAt$og-A|f(XMa`m$?L_` zWo9R&hKV-$h>A9+IrK7pN@`wz9J#TN{T7PF|7DH&D#N|y@65gr1LCOA9n^A~$M3k$ zd-WO{7A!;>PPmmJ&r!lGvVLcIEL$gb0{}@ijHc_;`nFB9H#r}|HdIAc3c+JB_3#Q1 z-9g)QKQYJJ`8e#oG{)a;l`tiD#mX2PVRKh@IaBeou9f2Pz{e4Jp$r?k;qdKhDG{xo z-4rF}`(sZlqm__4rf#@C1(kCt#nK~;E!1wIQC6ape$<{4d6b>F`lL8{PrL#`d&O99 zx#*TNOUI|~zwDlav*K9GL?CzGuTxKi+9}SG<=?4W?=-$j9+!cvDOqMvSP^^5_lhjM ztM>EK%kApP@uxhcNWm>TVJkKpEfs5FAwsD-wI@W6!NnVegJEtvK^0=|ZQ*!PPj29~ zj&4k*S~_#g z&KM(;jiunJM zjhI4%xSqfU4%BFP;Mrr@{z=8PAm00ah=h40!zAId#j34s3qhpO zyHD84Ls5`OL@G@=Cq#{C()%I2b3QpMm`sp9!ijC4D27NYPJy;Vo;1#oUdcBj<;~}Q zIiY6GnQ?a88QiAo51S{cMkkeCvJvsIy_L?pwJIU0&K6D|XNhG$-yYbtVN17k>jyX4 z^CIR;+1qn*!~u?X4OP{>uHD%c2ZtggR&;kBY+%rt=3|W!!UoqUGy)MlFW}PT?}C)& z!M0~2SEzpoLnS+6<-IGdT(1l7tPjN!n14T6O%~Hl`sBS$ce)I7d-cs~V{mi&l5eC@ zF%Ck*V##(<9%S<5QG5wBIKNNIp9M=Ocx*kpbJP11Qu3}vD%yk~w$YL~;r7qaIF&tG z(xo%9_Gh8(wO&8=J+CrCt|ngmI6MAb;(8AB<6mwT2VLsORVI}8F@V@KBy3+EN7dv_ z%qhNRI%wPRac9R1a&z45TwMI{d7+j~`3jdg&Eh;;PpF^2JX3ouO)mF*Eah^Uw;^*m z4bQ0))S{73=WaEtuStfJhErdAz_aQmJP0|1Uhl0U|;df=hTC}a5Q-m)iwBtsXB=v@w#%{TM-G+tWS0B%^ zd#z1<68tK8YOg5>Em>j%tC*RoV5>t>OhW_;Wr(F*E^*ob`I*^z?FoZOjjo5neWf>R z56gd)YiYc2T8Lz?G8H`jG&Q2918ug@sWY>dlQZp*sC@_*uOQPUq6!p7Zu^hs`5XUc zUZP0jH_bKwozXCQi*eMXajx>mq8C-BHEG_dXLx;i+lIy*b?LR@L({cHKC)o>3p8^; z;CFbRMsVCLGwj+MXX z;a^4WQ~L%AIZw`sKA?^$N)Mjt)<6mA+#m-O1l zR68_&sY66A%|R!%8MjQR6jK@;#A?yQA5u1Q9c%|*Wunt>O>%63v66fCpr8(^WbPRh zC+J*dK7DD z_K19&_jPi(ZkUNcx`4N5hfh%}qYFAygQD6h7YIy#x;O?&Z&&W|GiyHAD6Z!+1^oaf z^ugEBv=udUIS5O1F!e*TVP(OwnZn=7Np0ReOw30H6_Ig*D-eGm7OEEJe zNKgMwyTy@1^E937Ek(!r%qJ$~TLE%IuS{JKOfRcG7}BP0535nx=;1zbKtyuRK`5;v!eLEFqx!~VNT&SgS|Pt z3c}jlhw}s6^vUXt&c913QZd6D$Tj^tRG*%jP?Y19d=J*d6yy0(d!*s z{V5M5CXP{ZL&{H;Vcy~O&j&`YpIxFm6<1?+o};Lj>tLQ4q0dnW-99uW%Po?x%KOjp z$iDYPCPyY2Bna=L>6k}0qx58C^@WsED^Pl2Ceph529Wm#RJNtxutv)Db$A8D)|`ff z0);0^Xh@aLzaE74oz^e%F=__;JyW`$rfqjbziS>H+wt4S_w6Pt=IbzEd$F8^l z0uDUu_-Nf(B*d4_w&_u42Eh_SWg+Y02`>wjNX#>N&!#mN@6%b7fUtGD6RIPs|6@a*^U-)@pCSLvvI z^q#UwD1Y$^UX#7rQk#gr51aJlo4UZdJ+>I8=sb57Iz-yuX*PXGinyY<`~xlFbfC-x zX-C4cSnzJ>lo5q zHK$>4q&ygwNz+vm{2KRw5pT^2Zd>|pQ^)G1$+3AJHW?E^fD+|a;f`IL!65K^SU_8& zI@Lw9ZWVIgJBcl*GGuae2)5Pbs0*e}LaX0CosUJ%^o7`rwfhdoju#Xwca(ZsPFZ5V zW--xmZZcJ+x){1uu5>GHo3m7j&#}U$S4ZL4zP?Z7RdW42lB(*(Yf>?o8$Nl71o0<9 zE^fbJ!ah@PnP}bn!=q}AR|NQ-(0#%ub+P3VxNPH2j)9Z^XQ^W@d$JZ5EU z32$R{>8ozNI!v&ViGPGM;Jc`10_E@GzGW-yYp<(6tLYuOdgrNoSy$|6Nwq{8x=Kig ziUFNnWj~gNydx^>llT3M?4n0^51hI~9FW!qx;+;2?9hbk_b zN9Fq;B;20tsYEVqUyqG^<$qd$4a2pqRKX2 zQLA#0>k$=u-WuNS@cf88%c)!{P2%BXW26~7EO7H-gjkx*i>r~;7xBlECJOW8acJcU zrCO~zRx|TSIR`nmsDz{uvfw_8+~ExosvKjARvN9k1SmZ_E9XWS+w#riGRiAFgDUU! zhf0snddr`w?CbLRa%_n(>JG}SquWm-h%uo&;k!M@0=+jgUzo$Q zE{@9xeveMe1N^Vu*}&&oMfj-#a{qqdBG%fh z5WRn2_pDow@$5Bn_6Z`6WX%psyO&9BxB`5_%CcgX_O8p<4%Y-Z-08-BU2f(*^c)%V zrSXP9Vl?H~?fT@rA6XrR;jt!RId(l|4RZ?46)hfEvQD|7^E}`IQG)z6%G#wILksD! zeb3`wPi@hPrtNW-p!oSjF27a|y~ezdQLk)&4U75fKL_XIs_bW&$f7Acafg^lWN-%X z4TkxM-`AK_9z*;WBqQ-(u-%U^y_8PS4b8K|#Y2>gf7K=!3BI=1R7!)5SnYLtzsaL4 z19H<5$;#gc+3KWMh|`|OvpyK|#d(1UOHgL=^P2IV{Z6%u+bg$!dJXgQ$wW#=u|?+5 zEn741o`?m?sEFPJ4!~e~LNe;NKk6d(95YYc<$uZpdq4qfDat4u7pn9em8`xr-Oi%s z;Xbmsxf}ImEa5sYq1BIG9}6ln&Pnnu+Z(m{?Rp)My_{PG29}}6{Ja%r9yZ!rSsW$!O0f|0 z{4MEn9?m_PahDeSfc5x~gwAMY$vyjy=q?EVXbrlZ-)$MYqjL(7h) zUA}U&1626!DM$in9Q4JthIE(X!d`Q}JF?s_h&}L)e0t5Ny*FqxdyAC(Sw<)?7hbl~1&k^vDJnH_ubMAN zNQI41{W&%C3wehf)~YG|_Hp*~lH-QFb~$VG$`ci1K2q4L7?faYPo6GL99|9WV3#*z zRcg8Wqy{3YJm^)pe<t z#in~G(W+!ZHz;^FT5nN$H5tC&TxJ^FM$FLNfHP}v1OL4c{j#?EzH)^vT}wU z8@2rcAFsGQg!SNx73V(rRWinOLT+a41lg+}bR&7RN4X&~Bz8BvN)-^kJ*4LOoba51 zc4+o!KEa&0C#~gqc2tBS;X&B9z|d9W)BeFv^3dm~GfO{SJbE^S*=J~Z#C?YHIHgY) zalhO99yxKix6;jS?>ok12ybd-5)U+450{fonm5@zy632SL#yDSM4VW>B}d=y>A{W#B_~zhZ*+`9O%taDQI?Na^fU8YL1#5qqg(4wcBey*ww!e z8x%|1N+BdnVerRXV{FFs(X1Pue~#A2x>c_e5H0H7I?B>xWb)=8Q3%cGv$>`HA${tt zHb>NRGzWNj<|7xQ1$z{cGIf>Ff<6)Dl(i>>;WTPIw7G8dQEfx<8RmDUZR2He{a#DU z1>Bd_&aPpXquU+NJFO=>P~~n;lMFcP4-_3epix6^M5)yR`!wEY&FXW=`4uV#?zbvl z&K_D%6q?@r{}(RV7U*n+Vb@Lc?9F=5SDAlaoGW6u#-DHFRp`TQAoV7F`-8)KQuWaE zhL|XARYwT3%9y@n{IHE;je&Va*W=9eXwTUp+mN@6Uih}C{+gE}4jIAJJgdiA@o3&? z+zuU;%TLxJC7P9`I`!55rlmNW!bZ*87wz{Sr?men@*&1OY>YXibA1^bQQfuk=&G!O zOTd%-2W*PK*uT7Dm`n}5xAoIdZn*DR3s&T+N+4{i$>;FiTWHWuL}VQ4gHzm0_N6-5 zc`)SsoRWb%O)MLP8VkF-=&krfo{nG}k+Mz)nb6}rbfUAtCZD#vL?xnOI^Qjs z$d-z=D55pDB7ONXwPUz+tql}Xw_=X_zIY%!&qC}=!v(bX=}48jwyNidm+W>|oMg3z zWS3*dL^7hbGb~{KJffdHhjA}^oGPmk?k>ra&juS7jLiGF;cwdv-2=bs#>aPY^B%QY zioJ+adGwH4UUAfGHS#!)6Q?%)GE2I-WlC)M#iCk#LapbfcakeQwlnziNXE5Scz%uw zISoSw7TctxJm6{&i-;;cdxm;NDIy9_bv z_^Ra!Ds|o6_fj}=K3`MboO|&lu5ff-CZ$g{EJz4tEPFw#ZXv<(O#^cM|8ez}VNrHp zyf7^-4Bapc-6<(B3@}4?N_U4yiF9{JD&5`P9nu|wbfYu^0%xB8m-jvA+r)M6z4CYO zy{;7tsuNq9?4PhnDOGFY)#c2?A&Mq$_m*F$SdAByqsT|MaOd1rK7r66j9*mj`^OBlFS(pl<1_E#@v`oB^-0hZ3n3%AW+o9Sx~+p! zV)Jhd6=!t1Eh8C$3-c)pK$cXodG!UcE99!oaN(eCqB+R*E3_ zCM5E15u_n~ zCrz;=ogct5dJJXE6!?g0DyliLzC98OV`#uj#o;2F3e^ZuXLI|z;P^vm^EZNLX9#h+ z4qwu5chzg(qy9jP8O+FE_r*aZZxy{lbCa>LrJcfiouqqt#7F?EgXz1HgumYiG&`?7 z51u(bmfU7X=8?bPdeEJR`^Wwv{Mr2R{?4zF_@&J+Jj8P)S|WIh<7Z^Cy4;f~8wEWC zGjPMTsC9DItygVzJ>HLwh2(BF3j)}=jC2o%BMeU8PXgoZ3Gm-R0zyo$mq!h;uZXvF znVS-d{14yMXfeEp=mD3ND8At$p1UH$s4Gd0*51zEJ1?Hlq7z}U@nQQ{WupV zL+h~0W+0Tj$d?ueH;~e`l<}4jo8tl0FtKF|Gc8tt-DHHos=A!B3 zqUD)RmEIm6U{0!SH7(w6#S0V41fUhQq(XL6n5R>Tz=WlbCJ(9{%j;6jt7uGQK!OuR z+rWry=G`8;@l@Ov`Y#Ffk0BQ2&k+ys`ny$lQ3=-*yx?#vX)5iGcFf;k?cdvFrq}7! zFj?51UeZm6K}?Eb#%teOm&o>}L20J#=6iF-5FI@0z)jAI$hv;qEtZVUaqC#$VbtJ}Ad`gjx!It~r)^GAkG7nOX0e2aP zYLOuHSzC6s1il0w9O6bx-y*ttA^isgOw=m_QwMBzDu$}EwMTEU0GRN_8Q9UMEvJz@*?J01jOAIJdLND2{{_GG;)M>YBv4p0>IEl+#O;Z$$2D263;Yv?%4wo^&*j75If>^0)}{P22R=Meh-XUH<2t9S+`F>DJCAR z4D;G)v3PlqRD|-EJz8tpT|wQM)XS8x(H$F0o?SfT*w{cdvG>M0rJxs!-%g(+dFB{^ zFUsql-mo9gIOk-)6}9+{NJEzys0#6%)v-eZR< z)Qzl>z`M8h-y`Cl3@4G_|Mb&_6N=PUqsXTd%V;B*R}`oeLOBjZsoD-9B%EXOP8d zNX<-rk8Rowi(Q9Fy^XY9xY)~Be?no)$9S^ILiwJKB7#iQlkjL;8JclR8_iUEv@QbcctTdZ0n47i=Uhqna}nO z-LtZ)DGpM!1g$=;_;^PY{)M~jPK`W@eM%OsxDu)NGrJB4vQe*3+~&otM8(pp!v|~( z@_wDzi%|OC7o)Cj9HQIwZER3}`Kw=t%QgQ@_j0VXar{@V@sobERa4C*!z*b&|Cu(2 zNVIh*GmrfoJ0xd@RWrI`fAPeM?CBdCQM~BHFk{}qi^8+Qxc}G0^3|FLsfy98;vHMe zeZFsT=Lj&OIx{J%^3$XBFnwi~9Qiwbfl&v$+zrZXf@am{L+0JDcd;BQ>z(6R=D<#!=|MLsFh_-I z0e!pEH#<$CEP0QVU0pJ3=k9VZ-+hzx$m+L+%3sDii*hF82&C+9Lj^J)Zr-+&_Q+xO z;%vh4C%&LaRZgPOPG2=EwXra%l?$*QQKx7Eswybjvp(Ih6a`js9GhsQxhyR`Fv8Fq zJxS-J2cgLg)m4(!#Rv&DSN*#n555IWL|tqNfI)~WqyTYWhFLp0u}us) z`%a1+h9`k?t4;$5Ww(h1#8>Y}V~qUPB<-OL3|@!X$K|x$1;S@Q%nga)0}$bbf{X2p z<{p3OAOWyDZ#TCC@42YxULfD*HM0|ZgjEYSTzw0?#LOCP zt#Yf`T@XWl+7tjdIu1K+`pCV<)^>so+gz2hE*rg3^d_0C#+8j3s(K=ITzf<^6QMM% z;I)TUrB_}saFhsvdF3bLYAh zvgmuaO$`tdgSS)!ip}YD&udBFIyr-s3rc+I-x_Ce-+oC9AY;V0?~!@6nbgslzS>2@ zmCY>eAy}GQRabnICpsW=jr%C*1)rr>q^5AWE60gOP9itM3FCNmLofgBice2JZX#() zRm@cNW@2?`Gd<}E@M*P7Y~IQQ@HK(KlTvRtk0D=)&n)JEsz`W#ds$97mXI3t%2%~^ z&%HG*7UFH9Y_oNkvojBq`ERMsrFvem3SByIbS# zKk(-oPAsVt5$n6g6K~$Esok|^qWXWfPdEP~_(`jRQEef10&~|4=)NcLv0Mp*q*T>d zaaOA!gJTV~+8;^Ii;K!zOjl|-$a-4O#KoY>Ay;AhzRhKD z0Js7abanFGW1veqa|QV9tHSR$^KEgT#TDnp#3D%(b{!)reawvCQp8TqCmof~@(X^di5M(C22rZV`<)t^bA`?p)K^o`lapp|c}Gwi{LxvVgJ*K2 z%&snqUfo5yLa@(uC^A2F@kzyY#Qfx5mI-@)4?on|fgxdLkF7qU+hBk-0X z)zj!lWxWu5$*^i5%hT9k18!Rg7g9ejbr9c{O*4yX08#O?w;K31qm50&p)upyveqQw zjWi63>+@%Q7}ts+ktSSx3zkMW(pA((&II9jHL*5rbug z0!1d)gkk`NRd78mT!yv|Cq^EFH6WhM{EAKIF8i}j9s6JLPZiJ<8QMN#a(0%|fN#^0 z-eMTVr5N93U$|T#-rpsw^?l+c#>e@|T09-lV{$ zN7qD#u`6W%9+e2LxW6st&jd*Qr@sp55XnqkLR|3t9ri93evSRUz(&52}$EPvB z!ENN!f$1hW-}6DX^E&NdOWAKkz9v@gVss1RoP&|QWH7(LOGPB$5pIo+T$A&IzO7N>0MLYWaeS5|2_E{pOv^fBXc!XmZrOT z+fIs2;6*woyloU@<=cxpZyFIE@GW=Z3PKZJh^!Kdx4(veVgbV@K}2uRPp3-90SGkk zSQIQ4)ZaB(DKRt@Rj_8pjZ8V;*U^dh=>5?;K1HvnT*QV5he0MB{yL~Fe!W$H*S9?Q z(Mm_F=~mr)>~=aWo{yP(zzqraf=^>+XB*Xj0h}JSoXLco@z3QV1zmKEgMtsJ86lW` z3k}`L#?1m_*ANiQ;%ie;w?QHxCJd|2E<^FIRKh2N$c!JU9tG2qb+H+?SZFaYBgvZ@ z;xfcBA3@d_*MS*CnA@LVrrbjxH>wDq(q*;o-|| zm6oX$+c0PxPm=HgzT=|^39u5w95-EV4WAyVf`Vq?7eilU7(C;1psk=@5#BHTs&1dYk@%V%gd%B| zm9tgdb!L;d%E-76UAQHuA1`X?HDS-et$FUu^g~PckAHZj;)*ua&!b}--PIfP;--_R zW@~xNEGS{v*%x6KNSCyQ{-INtu3qJBl8Sapas7e3Ny*;(nZ_izDmX*%D`^nqLZtuZ z6P>+YVVE2CSlY8Y;wQJzsBxlC26&yBp`pkbGL|~}j>7S#XF;S$;~8ad9>7a#ljN!b zk(;x$nV9GOfvk*GIOn*bKDQ@Cf30d>QFULjzVm+I1uNjkM6s~BhmF}A2P$580=2;gEW9=P-6~mTH-*^nH`Hcgz z)>8{Kmjv{|Lc!UH85lPqHPUcs0zDz}E*?~MIKeL{W*}V#9YcC(;p={RIU?iSd+jp#_nV(5RgH$7sWpox3gv0S{m6DdRE3cT{A)wXX@~g}r`|4WZKKAh9 ztbf)bCk*(ewSHS4l=&1sTC-@jo${1rs(!|w`>91FS4noR&o=SNc>8fgmF#7U0F!xd z9#aVa5#FH;vDCs!t<6qwb@`vGnVz?pQY_Tow-#8KP?#J}Lk^s+D`Li= zHOp)%y`y=cE1&SX%yQdRkmIGYUhrG92o*c+ zFc&3*S`jg+ak{j|zi~-exuTfe+^O&V<%c!4cZ&mf1uV@!Q5ktjVz{SMBXblSqfAtp z`c&us$|O)WH_d!uM>C`H?amFT4n^8$%g@v(n`HT+_eCuubeGA2ELzfy-MN`iEY-jx zN-tVKRf|k7%E?U6i!k|pN#$fwmGT=bQU{R_15yaeJ3BWCat`9U2!FvxUnW)pt$S&M z@YUzLrsVA7S5ez{>8|@2F^fW;8C~Bq`f)a~1W8dH@Wgm)29&1j3HdmzJwzGpsF_l? zhXm!JroQpDcpqa%e?9JIL_^P$+M#klr?~_Y-lo0gb}=eC6I@i0rU(Yn2Jc>`rAV6~ z@@(TgXn4r=qt=|Azrm6MbbY^Iu06P~I}{FOF8MM3+=hXM+R1f%1ZwgKG8%lq`eK68 z7m*goXG8_bXE|2?G)gR7hB0X<7Y7K?u;GEN?uI2y8mDSg!@%0I)nGpBb!nlDFifIO`mxxw|x&gl>TQApJ?YMlm-?}DPi zSFXaVLan&QroZHb#Jx@YacJ|jBy)kDtNKTi79`zLp#PKuyhi=e?t@i^pO#!w^F#;}umKzYoRfn-uDyNz zb^C1WOtoo4b>Bpt>9Oz+hfmzlY;;syfT}5OM8x$+*1N8ncO47%q(3O^!D;4hx015S0|%2IcfYdN+Dm(? z3rNFE;$#&w?Q(JyT{WwlnIbk+McxJB$Kh1;QQR&pE=TPzZpC3BZ)~_cw(+Yt7Z&?w zvV7(Ca3Aklt|Mm|H?fOm`RQ_rMLOCzi(caGmA_qeYHM0X-s(5nq-W(YIm;tV#GMe| zL$<48!c_vh+`Xa|KqQ?7^xvA_3_bSDiwkJ{3|APPosdR?P@n*YoPz~o} z3e%p3VY`Ai@i)KUb)3>aKgYr3|L9|BysKQJ*ZhX1EbL~+dr7nQmj%^>qq$E>RDKc4 zx43@5sPD{lL^>BSrdzv2;yw%(;1&Xg+g>ws(AC11r~w*L zl$PP+7{^+*{Q75cmz)xoEOSbXWp-mt^qp?!F#kAZ=?&lSs5_``0l({}Ee1vi773`D zA5oSR!+M$K#(G!hTj$l_EX;qjPNLE!(3O;2!q;N&`6&x=ImybWaohc6r8EmvOj(zy zM*A(V<%eCdO+?iUwVyKyOofS@^Y%uld8%h$g>uA@OCFd5wcYJ4wmhkqTw@g)87uGtIOVx7kM4 zdzyH4f%x5AWZm!1pv8Ap2vmxqOMWYdgwR;85KX9K=krX_7LhKFK$m_5>)?`1NdFr& zS*YXA7GwbBeP6Ea@^ByhAUS$&qTOez9W7q8_z9V5R01eA`cZNXJ$D`(-~_RK#XkUd;;8&^qTJIA(96{ z8rr$q$asv{Zigv`Y?5!J8L^uM@qmP_1D)THJgjYIn#@Eu8k56IG^Y{eI49-$ztWvF zc}zIZXJiTqWoWRNv_U6B@=S3nkqriVZNhsbLiq78g91=_KHz8VRfD<`$SL38@(9deUHT}BeJuGj^U}&N8+dWJ zC>h}|$Wf{EG5$ny;rQ3NSM9(6bMAo~Kjy*|Cf?qWtLmwbKuKgT%CQ{kGC8@k_}AW% z*N}ez?&&T$G;Q; z^fYS{jP}7(`eHoz2&e>TpX%c1a6TpoX!G&U`ivf-A(K&(vaQ49O8bu+=&j(De1iBX zrZ$+AlJtu!P4P6fZwn;wcbWF-4H|7uLMr;YV~S0~?%E^1&17Fg(vjwPmaysM!AG)3 zCqkZ_lO94#h$c~|BH&CLs*&^Otqqw?)BQg2S~Q!W#J6pV;oxo$%(>69jBl00&eo3B z1QUkYJJ*bg$fZEbemsxI({k9)m&+~2!{jnY1#TQ9vB5o`|Ap}G+oABXoeN2+f3S?n zQfJw-)v0;< zjs5#_6Quz5C2}vypLKPKb70P1-IMWjooqgm!x8IMN+H;`U+S0jJj@V87w~KacNGaB9EBp@PC{k z$@piPJ+IlbXvqk91^lbBPy36b zz{DR;!_5&cH#&xR3Dz4Fun+tS0+IOBE5S

    =Px~q_gcl|_URxp;#j-Q<2$o6q-}~-Glib;hky+B+@q=|)+hoohdxo=l z#%>9{U3mB{$>>Wo|8{M~;GWjsNI!=a??TKHf_PdKpz2r8F-auoCom6!Q{7?(y(73+ zom-(3nui&_9BKypai*3oOMI}~(ms3m-vL)pzu>*8TAUht`I(A=YCZ;vPYvBe8og$y z#ZltgD3YzYf%sFA278=ecRWnYs)keD4p*}RuRzfselc=)|GZ3IzQuC9wzus^SRx;P z*H8%bsiX{O;~gEaP+K0N9?qi8d0nSCayISmk(J5V^VYvWI%iJCoN+gGiV$}z*oi@6 z9Bi7U;-4>}KmVp%ztz}Rpbozx`63B1*|{^jG(<*J+b{Q>I%a?T`NZIvVMX~7h-7c6 z5Vqjf#ER0@l12IW1@(vUd)3QMW}5_AmA%McFAU-K4F*Mb14 zUD7Zt8F|6yCo0y{-$Ft*JU>dIZUKAdHk)I%0mf}KSHD{O45}mA>-tAmRuDID?gWFO zeHt{2(2U}fM~TxHz)=GierL_txoP8Tb1`O4%HQ(CugH>|ekvv#vBNK(VJly#?GX~s zV??bp51AbVoIZ%_LYZKScZ34K%PGk)zuY=&xEHkK+3?f?d88mMexV9(ARAb!JTZ_Z zY+Q*+IDvrg298@VMTVrNwvc zjFsbA7Lq^F%wdgwNbd?|x)ETk zrR$I-DOY*wTwhC@-`7jE*|-I@XzGmW?Js|Z)3jI^$&x7dJ(hClQQ3%5X6-~1=jK@7Ji*YE_-Hw4T}3V<=IX2T;x?lFa9S;}k;< ze~jD0)JTLsJx4^YG{#%UT6IN-%DvW#`?rm?J}mI1lb zPb~zy;8|D8VAZy3d-%}61+#+ud;PyIuaPmXbSjB<#P*6IUFUaxIo%dROf4FcU<)hx zMhNl^rhTger$Vgoz5MUW{JI1PI0r#0!MFd}#jBVP(!97HAV3dYwftzE#I$>$;_yYM zoWLz>Ez5eUW1op^=NecVGajIwdVA^c8UUG&U)bpm!+Xh|Bp??C*Cr)8fw&N;t~Dy? z&0a*GDUSSfn0im6E!eZFY|4*-7ZZsPPw&b0r$eSUOP(octVhW{ux$Y9;sKmYva*&_ z^29hZEgPWK<-pkY)W4m_Ip72heD|(Phja$^cw!(VIWGg_pUmGL>!mMoJ z7tj$$a6JJo$2h+srV@Ub3T&dN0JPGRtRGwpJtW^XCAY$YADG~0$a75y*pcSjq zU{D(XA_Si}$Es0%#5E65?Ywd8a0V>^JGs|&;!bwD%V?OFQ4OuJHcal=0#gvz0)A&2 zR1^LgNR*Dz^4n+m!&n394!FZZKCRUYaZm*S`=%|6ByMF<0T1Hbu3FK_eEPTv`M+KT zO+Sid!6$x3QIuBz0TgNc1@6idb z9Q^6WHk!bZQkH1cbt+3ec0*GL?h4AQO_r58D}NR)F3&$N>>PqR7!5@}m7}p6fv$xj z*#?nHG@DMn3ibf0akt-Vu?}P-6XJjYLGZy>SB%bG#b7a^SL?tQ0|Bz~FAv#41I#I5L1UA2Gii1`FBiCo3w}t4I9*q+&y5cqXJx2TtKgpfL2N^3JCWPwR{@T zOOc5@o|AqVYI*SN>q=kZ@}SS73ac{TMKh0{6d_}jJ7p=)jA1K1)~Vlk0Je92gK|wK z(eU#8gXkt$$P4pcIOaWfU-b7>NLB3(_|S*dD{SU+bYWX#XGwI`8t=Ri;P727U`{*M z^4L*zz_yEsCYIvytN_K|qhxx26Ti?}mn=tHc zV#%!310ns2Rs{bFISp8NLPu5EQV4=*nZ=ClaYvth^pEi)p(Ol~Bz%7;VUBl^5gl&3 z&b3G3<{V;tPf!CqhA9$%e?SIG%!eqRRGLLQvPjVbjJcR{H-k>sB64mjD(iKd7hwDe z+d*;y?I<$7qnW7L<~Ii(48d6ba{9e214^#+!Eyi^y{42ZvPy8L-RS0|#hdxJiiCxd zP=p}mrTI6o4V0{mBpG#30$krO)L`qx?pz|6xm0VYXT+Wp>MbaSKN1;E4=BfAXj$ye zz{v>5VSYS}pJW^Meux2?KNI336| z=~IY*xTCerT&rXiLGH&!T|h#(R+SqcT|SNlZfwDCkKk(3-Ron;l_?Ynuh}k1xB=#p zalf;rBtHz${M`&Ny8%ix=1l3_%eUK#^0?4=!P;M0B^(fudDp)Y2tK4FyrcpIllAOV zJF!k3>Z8GLTg;jNM#d6LS&F`1XYA_^82k2`_1jAu^r&wtbMdTxm4c_*eJ5(?fB@>^ zJK(CbF*7Ywe5b=i+jJzJ2K$27ZMBb|y$t&&`2Nq?48YKLdnJ{z$ z@3FKBQ@dX@bA?X8cuJdFkzSf37r7Sw@kd10Jz_!LpPf*rl$Z`MJF@CrYJ2!XG3Y-m^mg5@#$q^oR8>vpm%3WjF z#IB}}@neQMM=1)krA?s!uhPUsz(8PcWCg{;^FLhF|E)AJv$C`P&$s_gNini8vj4Xw z1w}7rY2#w*L_jZQW9VWkVrpz}VhY8_2j%SIWNK&&^=I>6U)6=w28kAD%S~?kUz+JE ze`z4X*{I5Rt92&URvUNgVtvBL{B(Bvx#qd%On#+Sx619htbDxqN?;c2U!zG)OpOeU z&%ZOdlZzS~`acyW+<-`_ZA6P>8%yv+1}Crwz~+Eb0M~q8{}k9e_z=_pC<43xB$_Pk z4q)EQgg)&N@=c9RtSqfBAm$sJ8k}2L8UP^LJ3AxWxjGm)J0Tdqmx|#){#`Ko129Wt z6A0*No^(|wvg~IyCz1(ZK>%@KZ2+j~MBCEH0zjpb3B)7EqZyc;LDav?12HrJXK4LM zCm}EOf%@wN#LoUgFgrIlfl^3Wg-cOVTLO@bWUvkciV-OL2Tt=}6PT0t`mGBflb89~ zjsZCQ=$jZn^^L#zE&Nu--uymZp-;0vP9akU|8!>-SCsPG14&{07MCUj1r+ zh{rGSe*o{S0P z$9G4d^z*K$7k`iu8IOZSUER#jC~QCKGQ+e`iCs)1r`Xlen?1X;%QYg86rc>e3> zo2n8;^Xn-1i~jhZvZ3y$S9^YJeSQHiZ*<_P7RTUy_0!h)?pNK=(B(!qs;X-XNYn+O z3PcS_PVN_)x_J6aygD>Ij|}DT(|Y-P^|1T3y9x%@0V;#El5#Em7FeaIB{<WiiH{*8D;yhu zOM%Xbq@|!4ya}ihk2r z-Uf>p3^rz^C1F$J*%8Ip$&koi3-kjUHvQg2;v%7Q+@|e3p4S3jVRc= zYwu%utmDk_Q6mxUR?O{7%E}(-v19cZ)H@NVz{ZhNV+h@eBt{v_djHO)1&@W=(x!e7 zWFdbg|CmnEY1+Bd=aig(7SOOQ+zEYGwsZt`m`Uf}f$h%m+Iug^a#8!Ic~=y+?{!XR zfB5ph03ZfdmK4_37gxy;#r5QLH%yO<5HduX0G3M|)fw`1;X2M4l2A3sh~wI%3(e2T z6>wwsBC|hK; z;8DSemC;9+NOk}*xJ411CpM&|x{fzuI{01@;*5?BdLljthimdmgJM_qC!Zq496}S= zqhl?I)$pn27;M)_NJ}$=j0Q#$L1Q4I9zyLzKT7PK(B+dV`bk@mOqKfHQ&G&_a)E;j zjFV5Ae<}BV2s&df&!GbOo+D>J-tMI}E%A*6QbEoATcR7H=<{{+Du;m72t?P?l7I$Z z=*IFf8fx?d1oG2HnV`;CWS5G2Yp+BT$DR5kRE?v1V?|`brMV`Q;~lFmYW@1}OffU{=Zr zSYCypyEPotL!H8k2v4ygxw93E@)IRod1lYig|fy;Iqw?kPV&RUyMHH3*39;2ZjOu9 z%*~h9aEfrBr4s$%rI{(qV+ma-eXq{p|7O;-T`d|f$)FckHce#u!DaT4F|Rn8x&$OH z>LEX>W#uoKXo^`**dOD-|37dD<$2r(W0BMtU{c+;ib1O~=H zk^g~hmiPVJcRHmvbrp=&bxt|8E7cW1N(<&ZI5;tj(=cIcrm*F?D2gbGdhVUiWUDlT z=2)(MsmbJ6`z|39QtPb|wg6j6ed>JZZk+#h1MzDVTCm9dO*EKM?@#qjo{o`_Q0oy; zB`sSeIc$Ekhrky*=o)7}0$+MGu5TP)52S_z`%$v$eh;C}C6U>H!x{P}bj#D#hQd4x zV*m3IAMnrQMbN;xVP!KaN7j0936-)i6i2Fgi#j^ePE4lHS=v+KF5kPc@sswa<)xke*se5n71%ysu zx3WJG`f8n;{SY3*Y~=oglpk z8#_~7U~ZjWayff;N}`+@s7E1*D;M;S&@cmVtEEAayt<{8MRi##m;GSw1|GV6OEVQL zMxgXL6cIb5w%VO8?oEX%f<}0b-LQ#}5`8M-qqK*OHCsyV!M;yeKRqeXq07kHgHAAE zaB?5LSY6EA&soJ$wdoNpDzljl^3WmBJF@vFLDyBKIV!FCwPdl{SZY?{%$NLcpJpSx zZ$DGUXhd<}z}}AW+h$bTiMDT#Uw&+cR8&e+s`XkttKB@2OY4`Nar`fn`raLmKJ>4r zU6_7?_B4ikfjRtf6X!Ji!=%Trr6@N-v1vHWCA00>XT%Yo>2NHuZLmJaOcs-`^^^vc z9Xu(SzLziZW7uf}6hxHhmLBEUvIppY-f>mDnGsrkG}ezo^q7kXmv1UOwzyn548Gu01K`b zjm}f%4oIFN8z0SuuMJolxTY3iF$i0MJ8aTTLn7bqGp@M6G$fg=7&2!<&bFng5`v8K z8|nuKM~z{f&_Rz>SIKJ&o@)cXVw9o=xOC_UnvkD&V812s;@mR)dL}7~cbcxQzqk)` zCH1dNZtSD6lg~XcD(BjX1|njXifRahr&)>;S@F;?D60W1$M2|~)Vkfq&2{&(=7Ko@ zov0VoeId6GqW)s8MAP7;l#7!XbLr|d&%yxoq0bds_nn-=jwVH5A65$`_*e;xU9`N@ zWt3UZV;-l4y{4AFh#A_9jRQ5%9*I}RH7wD%#RW!=gLOo*$o~G^^X`WgMID~)r`$bp zBV^_qKT>4=25hWlc#I4-oO*H;e&uex6w=$mlj*%1uP;NgJowsT_rs*0<9}W~UHTx( zB-&9bG`av*4WC&f=8`TKkF}ZXPaNIU!u$~c(QR@fOqTCQOFgQ^G9vmz(|<AGfrTX1_^Y*_616Pd7=xEXtl zUD$R~tMe{3ok;3StOSugpwM;soguqdg`j9vwl*QxgWz*!6r>MG(mc^fHq-(hP^yTe zZ(3XqM%fO1XO3~)056$o%=n}&uxE=^MH0DNyp`T7w-r#xCPf&u&A}!({jwh?6C|GS zJ;=X=dYP2ZXp|O3Cg=3OET*Rs+m$)iC7;yeh6LZHGdT_06=hhwAqm35Vq2B74@3(x zK!sQCWBl=yvK985O$R8@%OCca$&C?^3TS{Cf;0Qwpf9tBCWMjm+yPHc@IN7sWVREw z?&qk~?r2i4jnYG_w_@hm{@0qqe@yc|u#W*K73A%41c4Wpj1LNWtqC_?To~iuVoJN9 zZmmb%jm^(fJLUC%Nj!0XFlc#VNsg$%7P`i_J_kYho(qwk@aUHY!Y%OYP=*y2KS%er z%008%GP5YKOC3L<&_EY;vq~G@!4SO61322^Nq|OO%pCc9-bP1iYL;LLieOSUxSxv1 z3(^wjc9Nn{xHR|Ue&GS1pYFcE zv9bQK&hjfPK9S^$6 z`LNnNVvQiOVLYh83+J6@$M+9feQ}>S_%&kB?C#d$#*f5EO==u`k{$<6B7e~KhpUxR zT?UdLIzD;lOV4d;{xZz{VxRG8m%u!dC@KB>Z|FUD>5WmlL8#9eyJ$4lfD$ZMu^c`+ zr%bnAq4*1|Hy>q-OIBKc-k!Aw=Osu)HW-vwi=O*Cg{mwlsaZmbziY`w8?kuYmeG15 zBvYrsP7(n@O8c5(MxdZVRtXi=)Y(f$^DjnIH~70x!<6VdkTB4$r2oUGR;g8xSJ(G! zJ1=W1wco4-r!!T5m#hLIS^Y4p6t%zNi+7O*|8G6n7nf~KUVHn&PFBH)nKm;vNc6h# z7@t@}wbryR$O}wBU`ZCorSNP|@2`Y{GO&u^MI7oqjzVxV89WN1+hcqVjpRo}{z*(4 zs4>AfSX*o1LHRS|YVv|tIYWO13LTo~Muij3rDh!)--?sqyrd6ZbP&^1$ZIgILATWb z*M_8Op6yh;;{JuMgG?@hQeqi^(bncnrb;ROmD~{vns@p5Rg>$Bk~)*dOEu}0;Hpg$ zBh87=@Mpph))uAivUm~(wLY}O!b2fLJoHK11fv3n?M5I=tBQ3;K}a~GR%?Yg)lpYR zlj{8%uO>Z!d^q(3tHTRzZ(s#C&FHk@l98y`05zH@;N{i(d54ziF#jU1>S}tE%?Xfj zgFjB?x%dYAx(8oRPcH@Zg2LzQ=gzV0U!=@K*jfc8TVzzJ>4F3eU~>+aH_5z8E2g5z z9$l)X5kLaY)3lKDnbB1#J1|_* z>xD?-X~#v|sm-9!rn<+RH$_1>dJ0p??OF%XLVz90p%NY6%e||2E1#N7i>g+oe-A$LP@A0&9_t;RP@Wc!Lxsy9B`P-K zQ4pHy2wJf!p9plw8Va22zeIcOqPe>+MrLxil|@ndvwbe;A(D0Sc7={jdzg~Ii=2P_ z>^Y$^&#xUu)oFObQ4PtsWe&XLNS*o=k@rc=mDIyktO;(rd8Hrc1-B5>vgeVCS|wOW zuDY}j!xT+>HFukWRbdW~T2@r&|HLnXY>Vw>xzWK(HIqK|9~ax4CQBzfu=mik-!Yv_ zF`Z+K%SIQ*T{n=jDlU5;jytT2Czd)@{%~Tgu~-4_oRfbzpG2@u(~xhNJ-B&OO<~zg z&x;W%to1dygncU*K|G|)uwS_kAId2-@I|LzjjNO* z)c6c!)Ix&=m8f;}mmyjb0gb0Z(H=wbfhA%0pnxl_6a%bfCuGJaD?Iey`SUjbpQ>xB zw`@LB($^CE=168OQT5FfF-+1uvA4;sbl>r zkzCa@e3k(oA`AJiS5E(L?FBta{K=3AM~3}rdhk8c z-VG8+^zldXK}wave}br)DibjY(jwC#!S^{0dv?djLQ>;~Y+8sMz&&K7EcG?%UtdJi z_YjE%<(&sjagFmfBxojktx9SQZrf8QW>^-acr#Jvma7X4$>+aK7hO4f8LW4$ny)ik z1MIKZZM4KhcIQ{8Z_W&~nKL}({(mfgx~mn7bRSGgn`6v58BVScLfod~A=k@`)Gbjl zcybmC5hyZ+xxlUgUZ*QQL&agHQ=K~_l?Y5IS)?`^BCIp7B{; zOkP_8czF!g*1QTpqHPmg^QN({&X*9LVq_C*`=#TH&6r!%4me6zG^6m7C)l||mDu_g zWH?8ct!mLf$>Ud!e&&#t8OL-O zU#5HX&Y%#W3PbAE+_nf60V7va78G+EaUt!gprW&6_rO6Kcm|i#10!m3>6BKypM9m! zcZm+E#sw|3GKKyy_dCzFm{dE(O{#6U80oeYx2~@^0l;k-IR%U}^X>0?32}j*Eg;J2 zGcK5@N?!rgG)@qI9yNT$rDNMIizgFggGwG+V(7KjoB?V*0lnwG6Sxw@PSJAw%5eJ%p2^e`KC#RYmD;6fzEVKD*5*L9T7qX{6OwQ|RZs9uXU z^!1y{W2i;^L!MDwvC+Fjm-+0TSEbu?SYwM9hlFVU!{c@Im5&sZrt@82_|ad5xZK+I z8T6%2OIH|wIk>B?wH)Z4-w3%jhzD^*dig78^tiyxQ9)+?$MPC& zMtH#~ER}Wgu?z>W{TFEKkfqX3nl>cl%t!dXe)(8mHu~o-#-}@Zt9AU%n4G2f6R6tc zUPrKS+;WSb(#i7oR*;bXyxzS27($GOMd`WfB#nHeL!T+TT>`1T8rw=kZ8P=BWzU`F zGfe^+B%`&c%zH9-9F=h@Q%eSNHx@5;^0;$DQSH+Va%!n1iL}z07&JS-?BYiXW3i#Z z`My)JYK(Hq0VR6F6PPrpK@tvTrdCM;kg@)HHmD~jbS7!k5Nj4%yxA15pe$Ey%bU0yNs z$jwZH<|L5=!*~zP=aQ`ff5N$nA>@{~EL4!u&0gf1sKecDe|PoD&5^ty`Cwi6=H6n` z!i)gRc>#7SpYAUy;Jh+FrMSo_5CO#6JSLu=Nmq&&#GbdSohBA_5B$DOD#Q)Na@T^W z)Z!dLqwj}>>*c1b+#{EZ-3|VxUcx)H(=MQ;pA7u4J(++Ql@4=i%8|~Ua7uE}6!X@3 zMe4U8vMgD2b#}k>N2Ehirzaj9m|4VUBb9h9ULew2I!6MX2@V}Ch3g3Xg>{bjU#m@{ zS<_>4I4s}$pLS##TyVKT`d?sCaz3CjVDmPP-*i=<`^ZtY>AEYb8`MH4XI*#<{fG`Z zmR6piH-!pkiKBlxf2a+HbzdJ}^W~PWw&wDmgH(b8m_b>9pYeLOiI6Ee<8l5Q{{q5w zv@5bb9T)==?|~+AB7D0wKTuezH`GtwAz%RTQZYXeubk1cjJuXDwWNJepN~Qxu`7wj z^|?C}AJ3uP?O5ZOr$ zb0aCHijr--;a8-NT1aU7)oUZ@^|*he(Y|Rr?ny5=8MM#dFue)#uq2p=JZ^3mazIH! z90scjc0ucv_h>iDp1gTrVCooIU!8|~0NFC`m2ZeGZVpG<> zDj`m(1}Dp7Ps{E|>5%8$&|~9F1&yFki=x~p1aT9~E94J-4hS8If+#vC^?Gn$1jk7m zn^X7&Jk3{YrWdh)=SKYDMmyIUu^LOMD#%HJr5bUmLwJLpY=^8D#DT$~-wtveb4a|V z5tGGDw8$EAd1AG%uv#IF+9zW3td1TNOluiK;s;9of|8;;La*UAZtPJS>ye61Bu4(d zTdNQK13uWpL+!@w=&vTfh%lFx1w$Bah?c$OFZNHqgMfK5(URXX6P>0gzOA~><=9YP zA3Jcp@YnWbDAh~OqH5tFa$y;ehs5h6&q(By;kiE{&%b(>oX~5Ys5LMy0cKQYyrfUu z&qrO${WGRIP3PVg)l2D1)K05d*tIrfmYg2PeMM@awFIe4;g3J{n)GxtDXQ2v?zJ^j z)op=HWk!`8r34_~-4yGDrMpHSq9ag^nk8uJgr&@EH+hm! z7mFH2Kwg4xzD?(1t}f75AW_gzya0eL=Lul))t~rUiyj+&NQ$VkENOjYXYq1o%$z+r zs}Fi+``IWjpQ+jwfs7~I!uCti0D@3Fv6mOoeZCM^qj$WF*JaklEWQX6I z`RQ|Eq66yN5$r&i_fYqrcf7+)b7G8=*$D$P6*!@;-Kb-X@8twB@ZsLweuk5$P(7z% z^vTG>#}Ex>u#V^B#=#)BQ^;v?ChJmHLAt;2fx7Ik>@|m{;idco(GXZ_n^0?zbBwzK z`E)Om?(T7@L&9SJS4yfoC!D>w$T)jz9z>+*;7d?nPe~_0(l~p&6{yIY%VB>o3-wwR zS5C3<9;DABB$<3)-&F>p-VpQKUf`J;k=<>)bx1P)&jw+ku0R*qcm-Dy26XIZE<}Jd zDIQ=%9qdO4wmhzbhqo?p!raI+hWQd{vU3m1tM?jr{?@}p75jqHtpev>R|pKPpF(P^ zH;Ht7N{SLXrpf~##w7#N0U6ewaam`yWp?a1nFPJHOwoYA==JCKq&6WzoL#xi;ZF& zYXm}+pE@986ugXmfJ|GqRbYn^l4em0uWqQ2bsEgOYj9gUE;0@5zbSgbjcu z6%E~O!BXtr)96~MCQRmB7#sIoIs3x`)t!dcXX^#T9g_6^Kf=O_2|6)zipY|RU8jt( zzi{zyX~s{CqdL`=liS}x1kbAY*MXfMUQ5?HlNujCLDMnG!d-N>k;4?FbSNXcQu>idOyW4_#HIQ~P_WG>KeJG}u;1OEO?)YhI(d#Q+^`OXg* zsr2Y7wk(wQM1{7~w%OTr7?}*&t9!QB3T?`jjeccH#e_cFldIB(DvNyQ^sUdschg@8 zUp!BjhNj`7dH5tS&Xb6^#8<^&%~rE2PDnFC%8%UOtgG~h1?8W%m779r?-m0#BdAwb z>0vLiE>>$I%G3ZJO(eflH3qj<;FJ-K7Pc5qGz~rgW((Y1bQ8B8RZj47>v=2@(;g#Vm%x_$g&x#{y9~x|8pZ``+~KB<3soU zom~cmqr;irI(jSBLOuJCKjF-R_I&zZw^ee-5r>Had73pC-n9aJp}Tw=qQKEt1uG;$ z?}A4me+POQd}kzRUZh`|#~fig0GTwJD(lihJT~Bohn;(<71p ztmi!rFK5xPrXO6dv4&d5BB)pN3~czPC~TDs#Xz(KY0xKi`LS07n$z*#TqeE}RwL#x zn*BAtVbXPA{0omgfQz|)@;%Tc?`ytAu%og!`?(20@SIS(6`YG_mRSp7=qp*>P5Z{w zm?k)}cj9b7Gwj(gQ1{LJSX`rhO{ixG2X0!(3hiu1H$AZ^bW?^B>)=tNl!W_0wBt>u zwzJp)gffgE#@Pgds#-k$MyN-FmGR9TW^Nqt!B}WQi;&2`lrTS4pvd3DMO@YHrthnXgv%Sn!VAvhfkl{vGFppvZ1vn;c}7+-~`nxtniP1pdH=e=wAM= z#K|?rmR~Y#h;<$ucWcCZO(0(tCxm?R&x9H>SrbTi>So83ow0A`PBz;Jl9~`_#*nr# zAHDuaoQ_XkTu$a?ASW+f2TC+5}1TxsP&Miy&Cy5 zsorgtM1vid+{E!S&AKx{UGXrC5H0RwZo)_QL0M79pS_>)vGEzH%f{asq_&7TiUIei zVzs|lD>acv=Jf;!n_p1o$dz(gk<( zkxzEE#={~TM>}vc>%k`_N{kv=*hw?Vi~R5a&#V+;#74sYyOLkIH<{h|)M{ zQPLg6*6$ur$}fg&mKCqzEE0{$`r!>5T!WjrtdrIJ7dv`_ws|*ii!MFKP^T@z`znf; z%3%BRb6<%H&Fz`&RqxhIG!Hgjb_-9L>O61(_u+ZYRPLzrY<>IZ*gkt4T^X_wJVXd| zud$yaK5R^_9Ea%>j2zwW;;UITMG6{I9w3@WJQ7EQ zZ!Fs76G!y5%)tXrB~RW4W7!B0fow~l5zgaE45@-VEkAPQUO}2 z6PxF!Ez~IxM}N5uC{g1VX*yZkfW=`F^Mp`a{X9hT{Q0B{)lGD=LlD{tEhZ1=l`#ow zXYaBuq$%51O?$U9m=Ch!QB)znJUcGQKVguI`u;v0jqPLTwd<7?R##*U;-J1Pp^|>+ zL1wmpZ^@$)}Y@Oblznvu7XewM8*LUeMqCh>04-x-| z*Lo8I8;)bc7|(Y>>Ub|#u9Moo1XZYi z$+EM3Lhz*XPFdr~Z29tI(TK^BJ&IiLTO+1t?9swXFwg*RqH^hcbRu}GX6#I&oYt@L zmK7OLR>LJ!j8PL+c^c*fUwezgHx!G?3oluiNfRF0|f){yaaui0TH zA>OWAg_v8Dfdz5nPgl|xIAG1w$19#sgaBaa51=e1Z`e`H?#}X8tPOUU5vySU>7 zvR3c%z$5T-NK7$8nK0PX?;mBI2Ar@xVO{J)3_pqf=78>yBjhI=4z^UoM7tuitrz1#zw2%+dJ(fu@1^dME!~f6c!2WrayI6&AuRo)LJWq_?N=PQ*yAjkH#T z8%QcJy0S5+jiJk?*j*jfV3R#CZ>ZkJGH zIbQ}Zp<*cZjQ0W=tT$fC+k6sb6=D>*+&~zmqgRCiq~1SOj9P#_7832}#6HCBOihlSzxVaE z@R9d7I@Zx3ouD2LhE#U1kD<{YAnu?~;b@+d$$^+G{7%;KqZr=Tc$gNA=W0#y4pZXt zWS4KgFfW`J;|ss04ijYahST#n(~oCUWo5B|b=U~Ts3Lr_buO3`2q>6{b3-2KcLV&v z{lIw*_44bTejOj@jJy|FE1s%kB7hdVBfjiS!G{hN)yM)__Gh~;Ds5n<rRQ9f9;9YNrQgO*h}bJU#N^aTejjl4<gxUG`4iP<9jCi#zbW_)Z|MIezW| zA!9~f5u!GIe4UPJ`IQhdjK2H{@UiW3VL*f!jHoS#Mefw_H(8C?s+onrO&nv^qLliI ziKCDuBA%O;H)DR+b?hyzMO#Y>tD=Dn3`3HVpVn$ha^<5stC=i#FzJS>QpIK^;msKj zFk|9pW4T8J6Ml6EzQ{T!8)N8)OU?XK)MtK}N{5lOx9HWW6ONVg?PdzbuP9XW&GMgf zq1Il3*t{qZ!R-)-9!d|M=4seQoZ;g;o>i8aesdNesq@z9?C-jM6JCzKp-@{R^(h@Sbni zB+-0SpIwST>ob83PF&x+DX#kS?4FicC<8%&J#<1cvdJahzz?{d6RfrJ+8R_RO@}5E zrA8DasYXq-Ew1Ei0{Ru#T%{!0KEhUgh{h`MA3c;^^A*~o=9 zDnQhMz}W_$A-2~2RR_vknW|<{_t>6H#!wyv&*H2PxrtP`%wHsv%Se&!+d-E*0-$uu zohXxkAMhg(Zi2Z|Nh?ZF1>6(Pb{&ikBlp(Zk1R`Dgrm70HGE!FnMp%#nllhsauV zisGJR;)8Jy+r{Z)U8gmfF4ygHeOB4FOPkmNYv)dbP#{%(RV{pi$7v)#tuYk0omT&0 zJ-yX?SSJVb4cHu`JCF6>WbNe`4_fyufkPIlt?qw?vMAl+m9ATC<+5|fxodQm?NP*l zSrc9xkj6L#r^TB4@t6|NpbhGo+tq`ukmzj!99P2)vg(7_xI3}p;luD9aFbG8)(fbR z+vJ$I5Z1;>W?Z~vjT?)ju2hgRE4%iT-n9@Fmad{@4M$p~!wiD>_9uAT0Y$m4y1K}9 z&{Fo3NuC|*=~x>y`P%a;u?AFsX%&|YPH6?t8*PdOcR~i{d-!~z$+F->AkQ4Ftay6g zYR?7m6nSub!1ns6Tz;MHmrUKjMmaakYb$yxu;;w0-rBoul2P$k@0etyUd&Q7$Y~g% zmABvBy0{h7f3ugsSjeKR#L88dyum(LYKtdZEK&zzQyPNT3qG4^FD@WoR zHYF7{fv9K&sag$ku3NJ|=M{V0t~otj4b?{0O5|6Nue`M@52ac{zq8iSV4(@oD!>Fd z{YcfC=!g&^^F_cZdarE^=?C`30FBI}W7W+-LbuX~MvT?8Y76>`QD%2f<4aCgfVvy# z;3smB^b1YIA)Eiwx>j-l@vP}MHcSmO?h?8R8Tvch=ry@@*9B~{ElfVB*k!}7jSp06 zjqNW5rZQ^qRdIX9<__*FKfhIt-4w}AVDdO4^bOP;JdGaw}bn;sE| z&YTS5voPRV`i*l%=S>K8D9jNJ;w|PP4J^ye5JpMUJrs(Oj!%Xd$M~&v0~UC?(3OiZ z!?t&z)(PmrS-gyd7bIE!t(Ocp8Urlq9lS}pOyz*@Z#HjQbFJFoEg1j)Ja&|^FYz+r_OVdBWyxcBJz^vsyJXBzS56rP!jw(iH3@srwN=4}lJW1G1fhV@^m8nuN6p+#ID2H}FzN>F6NaLR$sgTD93A6Y2b<$5&BCb2Jqk=uHc_dc2-zdz?E zd=0P*YxQI=7pan~$O*9TiOwv6oaey4=ci7t_lk2(1z6XLegTXh2nib@sR_;8h9rSi zF*`d<*t|kB6F8vwUWl=*mpV5*tX`b^|K@^ha?ekxt8bxaA<+a`wHZ1X@d(R^0a|ju zl4v)^Os}E3e9E*oo6wFV<_&5?nO4;N_tp!9mk0TMYLnD*C%k}6NcJ~^(a`^h+52Wj zUj8y~Gv0KaHEd?$?Hw5y!i{=xx+?v6nL#ypq2|wx&fcDJ?p~{N!Rrt>p52$Y>2&cs zRx0P(K&Y;)=B0zb_Gcy{2w;vaGHp9f;?qP59EKc(Xy%k(_Rs0S$zxRkHxBe@1>?1@ z{nJ+Ti2pu8DSVMmut3|DJz^TaQBFlXoS~!;@*DnhTcNWKDe`hv70|iwPD3xD^bK0I zZpy`wP)QqVg$E1VJPcX{i1CIFr>=E8`S^Qz)?;!}20~Q{(C_4yCecs3TwgC5wX1;5 zZriZ3gem4$X(VZ(mRBNZpqCz)HXSdi8bkD3L~4sZHkD^IQNw{bKw2P}hP{Go+CKZ> zj>-fmZV>f59)@Sr}Qj!a%)a9 z3G9QN`~2z1>6reoX+4SY{Ui-}8MzfV2t0xfpJyg)a~kY8FX3vm_OE#JoJcZ}{ z3uU2XAtk1ioPXTwZO2QEI{F>yY?tWOD9zM7D6@Esga(6~gsDow@Em)OZ*T zd5$B_j~^^r1<7oLN(`s8?#F)%;wnutWaYrZmwQ9Q5@vh!%0X%UJ&hpi3S_5|fP_IN{|!#+157_uCe+Mt7?N3kU* zh(+OrD#M~eO8=tH{C}G6mdxi|Vi~?Xf+r;8dU`e9$4e3=ps>cyKLK!sCNKPDzWtKE zY8==`4~zf8RfXe}P6RcdPR+TAeX~2OmzLcRol^+*|D`1_JG{!?qo&qLknd*(N23no zF9ue!UZh}foCQtHQ*)adKlo{M;*^Ln^p9zv`Brj1sYD|fz)j6_2iO2s%=NK_KC0%v{BYaR!l=ix5os}%{O!K z>^e8Kd_{_8Rywbg6=UX;NL6Gq*v4$q{a?Kzew&Ns_sU{Z6VdFFnV*|du3#O^eFu>e z`2j&_H7W@LZ*gE3E8O(qq5`%OHt;wfFi*iV9}Uu5ka(SdH-^dPt(-BpyKqaX zrXhTc(R(l~=S+wu7jw0{&k~5X;4#gvpi|5pFtke(tT+UKS@j+to{+2o@8=6r{Xofg zwCbt;`3!>dhYwb<&VlMyO8_q5HrrP9Gz|c=S42R1S8i~*UMhnga4?{a{Se&-Ej~g; zh_BhKWjNh4w_m72Nv2WBr`sEVL9jw*Ts~O_izo5aQ86%ooZWDCOS9&xQQNF94QMX7 z#pITqC;Bd)y2b2Rav+z*Liig{w}vmTI`2^wGC-z?6cF<2quul?AgqW<_~!7|=XCZ!nfo%bGdv>kH-c2>;3D9qQO1^zW`8`NoJlfk5sT7kQ#$(NsOY3O@l++lk zVzMkhqX0z#;I@sp-ri*B#d8>9iQ4(!@DZl(7~I0-rwUH{!x30z>OJoCsIdQB7DY8?%+t)DmF)=;<+>a~p@) zrm!)}%yT6KJL;0mI9!=E<_s{Q3Wn=3GALHSE4Z*|L};>ZY$n>ATW>`iKIS){ia(TY zTtb3FX{aC{Km3(19G`K}U1*9^Na52A)<_zLcF)HWi=#irr+DhqioHSqWmYGDL6e-u zEWe=2VUGr|6+M7R`4@=bF{Q%CZhf({7FOa4z_AItv)_A#^nACiyhFB21h_5U9KU$BpfnThfL7wog@aI`bI zU7*7?GUReM+{}@-+H^DAY$0p0-gIHAx0bf@?d^VDzb$`VQoGDGd0tj?-EO{7iOf=; znpx2p9>gD$o}KC&0+q*5TG2N-Fo9%Xto!*(j_Cr1&8fAv9)ZOP>JD_lkLt%Xhu=2^ zqHkbm_#=RT)YABB*Tlf=3L*bT>30)Kz7fDuUsrDjR<^FO*{+F|3Hqk3qvPB0AKJ&> z0mbl@SOoVU+BfYFqy%gEmtS31KuJ*+m!Fib6b1=$0|XDg8W@I7bOmDs=nt$>UNvgm ze;KU*(7vBo5QdgU*7`S0GV%~#&^l*uPR?J@sipZDh`-boL?mSNr65S?Cd$YVSQ{BY z#w0%ytaD5NYaIT%b{YCKxSz zSii%WMb+haeusP}sF9Y4TFPl&ug%Y3+spwfONzrvmBT9bb^fPj?;TmUb0GyGzH zRoT#U^B8$nW|vQh#4#8petIq||J@B&)4Xcvxuf3j5CFys{%>#jFS+2t`W=Bqkk#}L zVd6O-87w&?tZQC)K=32qRVKFP@8Cx7^+n%r)P-K~PvW;6Wgj0gpuVyB<&6*g_xy7A z7%N%1Sh={^{MVHD=NhA#wS~F9jun)G>sP2Izi|8)>*rdPq3Law^BZ%*cNMnp%hy>$ z$W#p0)enF=*!vQEt~cvTy8Vmue3_cviOB;C%jTDpoDAMKHQtY~XJYdBu4fmmgNx_i zGV`0$$JhO(_WNoA?0>_5NMJeXGSbzbQcjzH+*1(Th#uF}$P7`@G&z+=y~wk=L4hH3 zLiQ1w+U82t=5BKb<_i+_=K6ahzQdY`^#d_LASWw=8hS~0*n^h%U*CMis+;npcO~>v zN1$wf4QoA2S-lr9wuOw7Fd zL0`=)<4vc9U}~bk^j=o_1|9-j_G`!OpQd3aK(7!7S#Ho#deT zXo?^pzP+k|H&ya|+NKZ70F2=-Z#Zq%8aIW~%SfjSd09F;LR7uYJT zzbt93lystKpoPIvpytQfWt(+twNLp#I9DK2QGChrrR?y_&zmCg-p_bq#Oa^41un&W z%X6-bIf}5*sT+4$zc@TZClkJ%_g*v}@%CRluy2kgHE;tp9h|I$j+N~%g8vU@ndQ6k z*`NKuUlHndfBu7nPcaJ7DFB~(iXGC(>^n2NNBV9nb!iwNN?AF^%?q{t3s~_eA6Nur z`>59SQThv6vD$YT%KTN?rcg&J4q-6E%+8O(Fw3TJhj0AuJMP`l0rV#-9?wvk(Uzw5 zYe`)@-y@`B<}6Z=$>;(ur#@X?EAU@j|Ds~MVOD+$wF2n5m zUZff6g^BO(g60>-M+UjV@a95dx(o65uOX5YCJTvp)S)@sk>& z632c#RtKnoTb2$ z(UdjqMkVRxBzHT?A?gDKpE@^Z#&{$h8JnB@n4Ib3|0eE+P1BDma2uxSD_Umsb|e`O zR8#wEib&cX<%(Qka)tr>sK2vqOpAF0n7luY$}%0qZvm7PT%A~uTUi|t!(EGrEBnya zt1TShu<(SDIc;x~oYn}WRq6Ha)0c=$HY14>#6|zjA~0(fFfhc2R^qfH+;7iwa?pxr z=y>d;j&XBL#7wHynFr{2*%_85i8Y0 zXJne}=6+w`CU1{MHBG>g=g5fUy%3((P4C=~0fy-W2URbu_HI)hhir(h%mVklm1IG| z&2f&v%Hk@zq#6J7dxk3WzJcNue-0vEOf<*(iai$eKBMC91JkZ#NI zK!BL>`Ny&*fBCCu(?z>!9w*vra`6c8OiIs+&S%D}bw)Gh>{_0m@NMq(b9(Fb2&b6@c5tbX>;VCxB&1!E7sud~@f{#2q=?s-E(h8SDL}wg`jk7z$m&hBKvGHw?!>+sv%Mdl(x)heEXU29@q255RJ!} zE-JSI&u+inCXZ4{da4K;XQ$-nn5LD~KCFVV;vYf_OjM}onOFJ*|5N&jfMzTBaUZ1p3HX36g`8AS zw&(dvFj+1WTvvgGcMBn>Hdmf*i!-9J5G~|Tm*Cna1!kul z8C^fiV7JU}1_yaKcO$f>UAF~ij>^S217+7oxN|rr{f>9?O%kH5f6|hj6^8G^frB*7 zp=QfJqGLH=3<`y&fc)*|lI^|R8@C=)9y8TfpHdjvyq&McVZSBYlI2e?XLCKzqw4C_ zKp88K7_r_{{*p3UF*nfod_F2An<9#@!@dCdqDYvHpm5QK5#lj(APHjY#L!Am{NGXl zcdcgjs1bOm`LW*Ov3^iCwty<-TY1|?v!u`};uXfPD{|16K_zE~R9H6b(SNcyx&$QPb6Exi zw#VXfDd^tzXFrh=)<(DavGu*CrJ^BaVx{o>&k~D?d6Y^j?77Rhil*_EdvqL7#9s&8 zX^A*dpuDaH_QxtNF{lC~_byN#tRyq05^Us-5m}`ix}!G#L>oYOF0|^)Ue3gm9N*6( z!MJCYF%8c{phdZ z&GhJ_>zJ`xEf`>ZO4AZL;=;U-@dSGS&Q*(uMmu}rW~*l%n*0(Ri8MYL{c?+%VwGZU8KUl+8GAJ^GU23Og(_T4^ss$zZ) z`q!_A^b`f#N0GjoFrLShE+L_SzQjb)gIbYqlOCdem^)0;sK7D>?1ub@%0`KKYZIcFs+ zACKB}M4efBj>dx0YGPeopPKtL8~LAWIk$`p)A1L?JP9huDg(UaHf=)O=O+pW5QM#u zBK`PkSv+M>kEmy^2a1M*q^HP-^8(7G?I6R!jKrzLhj~g~wZ>X#iVT6DL&Cx#4K8AH zFB;J|8IVVQR& zngSYZWG6Vr!r^>OzK*m~&W5z1AvaDoNoH7T8Xk=aIJ*m;i~OJfymAL8sKApGDl;ZK z)cynETpB>m?PiDOi?Vn4Uf{DMme4y^f>>OYh!K&ECmx6!JP9M>!N^#<<#Tnd9dnPN zhj`rV0->@>3VWw*67vHPKF_+I&S$(dRYA=st>DZ?i$_;jyW4CVF#BPWd( z@uE_*b=@#_y)XKUYyYL-p3P4uEU|}t)9A#mBF}Y2a*pBR)doqer-^!I+zPr6%I_|F zch%r>koYPuHLft;Ab)E3sU6PWnfcjA7kY9~L1sQ)hEl=maw&F~I0nK%{u_g<^#OgI zIEP+KCyA)6XqK=&{sB8*xmbh+NjSOm7z_gPi6G<$tFGV6~i)8UKLWB7(B`tk}bCNA?$hn{(2ZLtsz0I5K zH>bIG$p-;O|5{<7Ap}z-&-nis@Q3tfaM=pent^DMrWyX!Zyb0El&sbe!^hpxbCSDy zCG-=H6FwXee26KbUnlVI6c;KT zQ2I%0l91x_8EfQ7a7reB7>&N+as<>@Uxb98b#H$77N z7oz}m_H5~WY(yQUedir|u^-@~!4Y6qfz-{7{rp;q;KUU|<~xO|elf@k>NwPvAx!+v zE_vbee4N`+bWw){C(w1*8gq`OrN z&MUGZAea#mL(C9Y!!l#HOOeusLQmTc9w7z9r3EyCWP`%7 z+j2paAfnt2NhH?{Lurs2+APgMs21B{Qd9v}7cD=>3+S49-df!dF9{ zg6BF%-|#qN5Oera+Y~4u&0H9s}lnHec&s-wIO_epp`Xhmz=ui zvP!kM$eE?YF_n7QfX8T+*n59;nKy6{FmLM(bvmVi^Yryzh+PurtIk)&AlPxuSXiVH zNTUaO{#37@J&)vAo2La31yYQIR-jpSYZLBGce$ysW>u=VeA+{uiT=p!$kp+wm)Bgt z){_D4Cctzyc-K#%P1^RQ+J&Qm-aIshJJB(U`uj@bh~fCzJ5NdyN;7=lAUrpP5kyRie zQC0&DA`IZO>hCFDdh5L>B@3Vtn%1T z_%vWKxF109=y#+bsn%?1V{Jg{$#ZWzYdf;|DHKnk2ObjSL|fwT%Cu78bVHSk^NPPu z-EO<7I&J4pJ4R9Cf`yxBXW-8$%`*=j(p5*<&4Ja}bnGx@D56I*AYxW>wkui$o?S=| zlfsNVvc1B;u~i5$vCjDVqqx6|?GnA?=$u@1(bOc%B4!nihV*TXQn44=$&|hQph+9=r80ATTAyMTW77|9O55jE zLk;_?Rkz<9E946mWsgTcTfyg2|KEo}s1?hf7O9ORuQ>gAYc$dXd2 ziO53ih(d<}>t&Os%Ml_tbH99FT(*>XJ+bt{`dexIK&)Iv&Zj_KHgOK5_RkM~6vJaR zPMU`qEg;G_tK%ZO4W>4Rbf*UN7gfY_D5=j`^5?ZZafm}?tDNgM(7D5CLhHpSjv+AU zT)OJ&X^Sz~$_Ntr;WrBq^?I+JA0gd~w*b}Q1@HG@nelgo*@5=!>HofSKNchk$6;z_ zERU=lRSYqyZ{L;JmbE*O5)5wRH0etKdjz<@vA@zioY41a7rPpgVQAf(}ijAzGNC)`r#Vzs2e1#x8Mmyx(_d& z?zg-up_WM|u8fCHP3|F^A#hO+6r%=%_*ch?MdE`$dSUqdPf^lZ09OTWN*=1DoK=BI z7F*5xoc4VBPJIc~uouiqLRPIyk#Ap> zKBvZM?z-9h2g}W2rCOhbMAb+U!ttw-*6w{5hY9+uhnF{h&t$Ka1T&#|2UcjTv5o6^s7N^2A>pKFIu;OQ-lK z4jCcZz>1<|3bgJ%%+l@4TQ>9dmOqv6#Ei|nK6eX-lw5oHmM<~4wSVyUW7h@vbC)^C zqlzpI4PR^SZ^>~7sq1PHTf=2z&ITnn4=l*~sBUB&Yb=&utcUP+yXH*pNi!p34v5k_ z3`Dm0rdSXYy+q;6%7dR~?36MhBtZYx{E!~M6{l&B7U1~a@TGo-t;bW!UP~x!w_jB5 zk=!HY9vm~S~+^@80lp9@*z^-9kT<1@v;@0KGQ-0{BizOr-#~oT;*(1-v@^1>SFZ3LTWgB{YC?=(@as?~gt`h9EU)SGk0}luW zrKR3#)hC|BvIqrhYxUhPM8ii?NRjk(!=6i^gC zwp5=C$9jCnaR7-FFR)X8P`d#t_kk&geb>(a`%?pl88FL~fgFXd*EB?nDV5 zRw-r&Zxk}c>p>)9N2$HmGQG0E-9OK?Cx$9a)F9x|_0DzU@V-S@#HrO2OOxTAg2b=d z>z*Mi7E@(zU|r8f{}~DHF(|oXw~#1+hDRx zd3W6Y0NJfrcw1GKZLbZIRBvw;(%>hPK3VX{2fpnCN(*#c7vjp?FtA&T{;k1tT+h@2 zpr*go75msueR4WQrVw%rYYGO3yF?%K8uI~UtfE7Knd7^2K>9%7(7xMb+jI2=sT5ZR zdsFHGXHXo1RO4{CZ5nyjt>L4}5X*bDnNCV9fU^ z=Pw{dK3FeWJCLx*dTgs{Yd`1*dY_9vPAIZV*)j2pG(j{XOls<%O6T!&1DnMySc<Gzj5w&%bNS(jHWW*yL_QKbEX<0Hus&ir6&Ss)33st*6-vuQ66ZIXjlsVze zP=4F(7D}RB%E36$S#xl4m~RL+8%GsU-~8g-kto?ag?Z--8b3*%x6Ay19^s6b)T6aR zHA7Tn8-1(=r}mk3phty(9O4uB(>_3bA!p&Gf3UuxBhfRSZWc&awg)Z{Wbm*Ie0s; zNp(Epg#tP7^T#st{O-CjSG3BW7Zm@cSYW%aj!${?%-HWT%E}>;Tj$K-LwidHK^@Vv!n;eTbgsQcSh#c6mG_WIQcf!E(MHw zA;;A*hMU?J2rxC4M@umzM5OupK(OC*nzUV~wfoXv^loXaXNyG~%|p8o?Dl}aHk(F_ zHbUc0OwBI5@Y@vU*SNxg!c?pivG9YTw7C(w6@tYJ zbBK2P>|Msf(CL~!yz}O!k$)CNjPQx}O*yVwpVM0NpCxYg=%5#} zCZ4&~F?4R#a$d@J?moA3Xs^;B2*OZoW1buPU9ul@p9?=D<|FcSpe`ZN={&^MM`TVe z#ZoE+kbir6LMb1PR@h0r-@L*oR~>=JJdYYqOA%jHu&Fr`~Wd8BTEdoW6~UC1o`-yU$|F zhns()lt*bIOog|qGW$n5rG$~FLtJc(vW1h=_8BK(qHKk6uozDSlua>n)F-i-k4!~O zRx|zaw~>_5i~NpC=NlbTA$r~hmp8&0t48x3l;070x`N0Y^njw1!Zh1@NM=91=(8BI z64Sq(RWn3$jjsE?XHzn_t`j<;c0E6{;dG@hogYXTd>o9^81wUZK`^f!)S4-#z|LP@ zVp|fAl@cC+X0H%LA-FBZbQA^n^x~V7XV!OyA4~7luutoei%?eHahr=-YPjI@GjLid z?u$y*{$5I6Gr;Cu=a;sch$6CV68O4ywT#OWA4PFGsEY=%)6~lQX-pf%p;<|`^VH?F z3%(v8cXU)krwoIre>84A&Kv8vfv{{I=?_Sx=SsD&YK1ZBJx0AS8QR3uULKJVd5{v$ zqIbtG*M*Gi3YR+(eKz2%Yha04nR#n|W{tvwygR0DHL%pki5mBDvJ^}cSILh4>&Z*RzuvZiBW;077 zhM#S5^a}<=QfVLADe7a5;mDy#;7=1)h0dqNo53tTI`202S^k(etiZrE{J4ubQ$FV@ zk1)-*sfW2#%(IQj9Z8irnCI-NffSIOK-(W21`hslseuR0#6+#J@rNsr!TP@Da^4w+ zk%3GZ-{`7&Oon{Dj|}k=!*@Mft*mmSG1>K~R%yvKZH$+RH;m^{i!f`ALL|SZa_njQ zI9yKr%uZ7&HFuu9k>{E=8LI2LkV7!n{R#+zb~J1tKoh9%(hS1LA4 zX(>(Bgd=6#ux@%Uyr3+d)Y{CH4FL~D?EOr#b9MJ6dF(w z<}T|ctcWOnKA~Wd3l{t_{yG$>narfM zJ_mt352D`)ZvOfi=^N1c;#20R>gd>61xXH=Fzb};`nh-@vxP3o&(T;)S@PEtSVB@! z3qlJFll3mYewO5Rt%t-&h5GQRlKoA7@pbfBF=Mb)0+Q8lB0b$+n$7O*QMf}Y0_Ty7*eq_o-}Unb z{EP%GnuqK^k#JxIK=h{FkZwFwMCY6Pzi8-8t^0h|5moj%| znonk>cZ^x~Z&}hvm7zb%nMAy$p}KlONL~CDB%4MIBFpt4biOJNJ|xPV3d(`K!q-h6 z2?zrJPc)$or)-WD{HAi-(%MH^Ytzyqqx_@$AL(2c$!NjEtF7oU?zEr&f4 zUB;udCUV#cDHCYHp+fCU9Q_Jip&WPxfB1j zIP_CJWQi5;_N}C;Q-S|)gTDONrr}|&3M_LX{hLhMC$O`N!H(Oh1vEuuweWYRDA?Q5 zon3m8>CM>Y7Ki9T+_5Rhi~MF@%IQ=HtA4w&>iRRpIgO3cfdmXm_(RJpLljwwG2E@KEk`QZxfCqBGe zqG*#}hrsQLCPBdef`*o6HH4EAVnM-1#k{`Rob44uj^U4Mj~JV(3JKg$@;wO7Aw}fD z;F=5TBYZ}QoWkd4!?>qL2NJLz{X$L<8V)y5XStsN!=(>1tZ-%dt#(I^sG=s{15Poj zZ*)iBHhrQ?k8@p?Xy0aoq1J`kGSHb3T#`^nmGX+pPiOGDt@*J#WBPUfs#7J06=iq$ z2%BB5Ir$*ksSj&55i9>CQ#Qq8q$xsxt1PK=di`YD%LCSSJ`o~$Z(+_ynhG+ekzw%L zXbw9i#vQUqAtHi&`;Bzp#|J|LPw>DzNywJ}b_rKzUq@iLLnq-HSQ=`U^{yGSr{&M) zh2)wXT(gJ9F=$l&w~vS(8&QC5Dpe6;!cRDK#l0V2cG8vxU7&9~vsGntCzQ9?V?|KW zIO*y&_u#-j)gxQ5rW~;9(%+CxCD!Yu_L&;|12(09RlrB-@YglM6D~w66)77#6n0p3 zemb#=P0Ap-01Y+9uBep6c67Ac^>;!fh=@qFV<~0}OQ}?lq7)`sz;b)59Y=Cq!;_Us z5Z!&o(a6Z%rX<-zkbq9jw<5$$Qc2?G%17zB)7~ZWwi7v%wY(5N0Q#|!{gY^)#yIGY zWjQecFDi4h*&|S&mfG25>y`5lvqrx0z5yR&7F3fNHYOuwb`*-RLNXQyey&6}AiVGz zO1pu8mc+o9h`A4^--l!)xRWLdJYG6<9-8+#;|M)UQx$}=%@Yai zI?>^2W43elOEs-2S*qP5zGGm0xXq1gSpS1bJf*T1wjp_>P$S>&*kvz@4ZBg1 zIMb|-+N=DXuTYuQt~Ns=G+IR5r&TZ_Vjke+Vm)0`!LFQjmQ>7OS(`+@fyM;_j)DHp1^bgCGVu z9|Xy;i6aT=iGWfLUCAS`=fwcx$IAkxn?8DP{KmP(7L_XUtc%&OlYKiL^+mFuvW`k} ziC+|<>3W+5(?8bBI%pP5&ji%reS=P?#(z)9;`GrWcF3p79ZXAJkf2jOIgqPFdFl2-$t~wcTdLabI1UM)&pO2+=^VixvF&Fh1cX z40>ZERT5JJ$rY4tKG;>&>)JyJ$*BDd;Y%mhZxW{O=7{~2%j?b(sbPl2SEw4X?GhUt zPEu*Es`~EXGiG6XL4UKyh5bR-i==vmk~l9ZHfks(gic@O&x%*n8ar#9Rg}n{E2T@W zOzr&X`(sL#+fJaHaB4_l?_gTa8?{@r03F5IX&~JA+`Ktkw*BbHCPZJ36S5cSv{#QP z=Y-PW`i}fJMD>g*;(pR%3XXA;`FR9OYu~RwqNcV&_vZU(I0u2xDuiTP-tD6>xfen;)T77;=nuA>ooU0J6MM6>&#Vk$7M2p^t2iG{8!FZM$L)k zpV)Y=OJNoXvRvMJC_6=ab>&uMOu{6y^@GNG0o4x!g(AlMYfSL!JupE|A-FKAPea%Z zN?PqL!rV@brzm2thrG~$FVIHlc(AQg{OD(>0KO<|aV3)oAMs1M^>-DL)5agKyZG0; zN0vN2VJr;q3ZKm9b!m<`f6UzKJ@gIyvXp%7YOIufewEs0X+W$8lE7|N>A6Nh(%Fm4 z6J&&<_mOG9nC@sRone38u9xs<@UG7@AYlylGD;jn3Zq#d1>p{SD2gzDhMwMm*mVs0 zx6@3f=gPqL^;hKK+rxUO91$FT4Q7e|q)Kq|&2GZeS;#v_>v=SQ_X{8Eei7AMx$GFQ z_UBR`Swe|;>Q9ryQ5HZ6A`eujUqVt)2}>by^hz{*_)P;tIy&_}V8z~fy+yL^kM1z% zFwxNTHEV2)Z*bIXG|giKH%5jrO~E=sgcd*h-z2uib>qocadd4%v1d3}aoIp_*Xrj!eA9MH4G%!9*`sXYU zSKOBt1Tg@(Q|Yj5l?Jz7TQBjk{~7JBQ0E{Jxdg499<<*$Y|rYTm8lQQ3qUZwpkt;0 zmhDjN_Js$8L9%pr=bj~wLsQk$dei>IuMtn(s5oB_N4#X?&TO5EYhKqX)TgeakNYL# z#l5a2-!?buMo~gwPQwcga{ov5_pb|MByV*%+DjCzkka8;D2}JN=jk3C5^yQCJ~DT< zCS{6vy88H2QR8GQP_gI~C%D%m?$rmorH*HHrly)7ySvI;v#Iwj@p_9?eK6FoSa4*`Gt_tY+|Gp-Or~XDKiMgR4}n zC@KYdi^FLH(5GdR2@{nr)MMj%A-OX}zz(?I8?Hv3nxWTpL^Zh?o&$5qbAk@UiImQ@ zytz(iF-KvT7pU~R72+^av#bj6!a(T_eSZA^`TJ!;C-F7`MALNMi>{$sE+;qaZU`bW})x>eZ>cAu&5k4j1 z1Z#|3i)1~Dsqs8knoSBIJ%OMJ$=yFp@W5&nYNs?N?Oy50g=s^lv*ai{aJ|jOFUe6Y zU9nl%N5gkD{ZFx2{R^THGA5Txab|7k;elXZmI=&M>)2h*!&ds1$MzaJNTjXuM3sFj zriHFnV-5szSoMjgxY{|SaLXYA--#6SO%C<-2CeN!<@_GEC%Qgk0&RlOoQWm|L(pN z5EfwygYZeOxlBsk3>5b$OSx z)eUf}^2dPOLhtNhd!*kGXlH+IZ%W4kzFume62}uG^)vyb7&Rwtj8nl9iaoDrwfmX)ETZtA+#y`f$~4dX5^>Lg9hN>x;Ui^LbG zOSyUZ0W}Px|CRYxmDh7ZxA41|&+0WnldYp_`^22F%-$~n4fpSsN-Fguq1ncx47=K=9pC{Y(o%`nS9LGEEmbv(%ITOfJO1bJx3#@q-@=t<7Uo1#c{m zVF7v4!Wu$P95ghid854|7t#GJQEpK`YAb|EEYwH@pEJ%j04(l> z)S8#>`Kt$4Me{QJFRjdcqdqK&Z*{P(!A84P_33Zt?1cjmHDtwkaAWS>Fd&|?PiR61 zO!l7M^3QWoh+IXrBVPh?Vup%W$)yCYsEZ1?Sr;C)%M}9i5n~~GL_OoI-1DcAmK>gu@btXQTKFffX-7C}vR(YptV@73)6Jdz;h&E3zV9V~s3#jWHvNi?a3$Dc4X4*#R1$m~N zsHij}a#923|#|9S`dg-F?aL~ZZvPudrHm;r?mu2Ie+~!R;^7m z;c8I`)({wW5r4ySf@Rb+|Ech>>>`h6 z3VUEBRgx0*!^#%ngIpx%8Nz|HT-K;UV64O_2gl-4iSgl*!8hQEX_Hs{?tlhbMF9)d zuV|{GR`lu8tr`7zDhAx(`{J1)oV-3QB<|1O0upp1@mzqcB|XMnE4(b3Ew#@nMohmp zi>Q=WT+4e4zWfFtckK3dq$!|IG8{MR5JVkLkAYK>{zhXV%U}QdksF?8!Z76P+S--b zA5E69k{VOgIS6_i6Zt!FfFSkWbv0iu?UZDm3A|wDk|LNL zlxP~8&w1$+{CCKOe9yENz%Ysp$fLj4I+%!@GP^FF%Im>rJklz2jVpAien9ETImkUVI6@nWR}Tl6C)YC5$_=Je9-%&j&LrPx5x11|1qUgu(_7ArZ1Jb|#M3#7 zO5ok5$r2zBCvk)QqGbkww@tM<>G%;q58P?8HY#vWM3Fftaz>TXW|3KHBomMcR<5_9 zw^ztT3u10UF`*Gv$X~c1&VwTsNoeh8>}Y{=A08+ZbCJHCH~Q0&-|7?sd~WJaQ-1Zx zsxx1vUu^=I@SfPv30a-YsI{lO2Qvdh&)8Jz-xU1zylK3Ncv7kXlZzpBFB5?rEJR7% z?Ov}lys+tiYigjbeT7X&=qcyp-{gPqQ`H=1=XNz%E=k<@d^km3svR2l7cMPR$0-M~ z5TXTSJ>_Zm=i0AU3~iQhh#YbJb<6Y0KzE&MH*_E z2H{Ff8$5EQY*8*+Tjv}_tgnOD$HvJum)8OvC1iKypbc&!LCn(2Uq)-qIZ; z3aD&06TCqCeWR1o9xfvKnF)5Tfbw>fwN#WUR(|=DO1@Ph^n2(PJ!8^?L%#B=*ar)S zwDL>;xLD#kH3~}7K^eleP_trKn|04iMsEV`;L;8v|4VT6Vlp}BHyAYIsva#|ikvUe zwH%3~ckO6$j7o#KgmpTq1pSMCjye&_pJqb@rT|x{U^nyEX8Y5xkqiZ_Ti8sWzg!Ou zd4v!L`H}LdBrj=8ub)DetDv%~BxeCC+eLmN;BZAZd+e9wIAt%9k9J-al=8 ztv|Y$`RTH4m<|A1OkXoau^p=j((jC9&s`$N7BO{%#Sm7$o*`7rWczZb4NEuk7p>Bw z*z19c(y7}-Y97O&M(;+OaFRADcRFF`SSu?svorI^Es+w%!~D_L0%}pP6kLZgd$nAy zRBq2-EizPF3Kb19zCY&lSj~wx6SY-ZLp8EXI`A%cgrrNyhJ_yFYtRONO2-=LF_z$93HIsF>*nHc5 zN#pqi!gHCbCeEwkYFNy{lf4Ng*V~t7fZfyk%GJOA_DqW~w;c0}mzj>QE5uNLH`qT4 z<}cYI^JgxowFu6u5T=qZrJ?pF@AF3*v*`C1{`BZB5AnzO6*Hv5c9RjJdH<(CeM*v3 zRm;sOFoCrlxoOO$PNhueZ>z<+4~g>&q;(;VBXuIbdbRIMN%MYVmBsKgAqW9F?nJ^z z$42q{v?oe7o;J--Ma>Wc*YucqkQNxesSv zYJUO`6FqUyB>+G5Fl9+lDkjie)T?`svweU&uQg*KFb25R5Vb~fxG$dh8cxI!ng;qKk> zzBi8<9lIg1z`<_nePa3>z6DO~QNccRcu)2(0mzBCsUIqYXF9jKHwjXR1LRH(IIx*g zH8J22`*{B1fEAO8?|al7@;cn`Q}mg1_gdp&PLwaO@Y&`cE7kh^V~~pN0z!Sk&d|-s zlVMW?f6aJxL0x`5-4HlmmaTHk7gZ1?n)_Mq9TX_;Y-klKzPq|9W9dFJmK|iU$m!0f zEDC5&VsFm4W1Ws~4G-FV)IDAnUj=BhW17q_XK=%ICc`>02fcaq)vVW#D@L@}^U@ZQ#goq%?>nA-J^UlkB7;?;Vnay!b}=@Nhxp zyrkaGNm~b(+w&6Th%cH#b0TH*fFL^G{MV&ConXS$xF8m8<)vb=pSc^zc;bMaaBlL- z6W;V2+Ik0{L0G^kYu7A>A^$JVh?oDz+s`Kt|YB#iccMzf3BF6G|~c%d?2|EnQyV0PP{wo}MRI#o@cfA8v%b zCNVjw0VYry#|W<|s3jrRgtgX&Gr*$S%Hm2IZGIF?M^U7S=Z)r4xw6qXOt9PL<5Bh5 z>1ax^P80EAoWpHWSSN^2_R}9PX zHEk`4tXq_u5}o}Y1i|-BK6w(LBMO%1)C&zUO{?)&a(TD4gff`_kDq)PnO7H8y-kZ9 zhOtf^M%v93C9EKKB-9?(rh*{g^^3847Np41MgGVUpy6Q%QwttlryofQ0ue0BXb zb)eTwU$>Ki_DoNLro;U0pXqBwj)78SiRWoRy`thkpX>4G_MYPGXA$U13!3{c=iW{Z z8EnfK(9@DAkX|ZZN5AN4a1<|v>%KPE=DDMdaxsno8vdx;TeKiH10?uw+jcrE<2{;I z5`D2eWTXb+!cvmAnkpn#d?K)04p^}*W!KseeT%sTO+BV*)2*djsdxk2-(96(xiQ;q zDW6_;7)~PW8s_xQh6cKwLVQhDVl8I5XSu#TJj4nFxS@`Q zLT2pC;-L!|K=3@kA;#v^NSS%NbtdKpcGoyM7i-x|3ni0?c!$y8wUo>3Q$XAcx_m*` z6e-HnpU6%kdP26^zfMlG*Q1H5H4)UVaj5{_+Fw`6cbfqe?%($JYNz+O^|LtD3dZIW zKBmh-y^wZ;m0ms>iaJl=mL-~*Tg7w*k*p!Q>*x=>!(AOVM^0xeAb>DNCtP_3>wr%r~YA8a-{z47AzjLKMSTDPVec!oOj`mr{+zXb(~>1t4dkvXt+ zP8z3RqGwg-9`?ZP(6M4zxJxgn5pa_hN+*e^D#TL;V}il3rC2{mz~kcZutOrBlZKR* zP`ngnlLih)*6OGrOZU)^{yJ?y-ME2H({dl`6dbP1D*UtES{}96%PzJ9Ww$Xd3_3xP z{x>|%JcEUmi!#lNMgMvH##qd=^}#n z3AOP=>9Y({AnjxddCe88w)6;^Zl+Ho{5!8A7e3MIK={#K3Fg)D=;?X!5P3*rwI3Xn zNGgcOl5gK?ODkZstT$Mg$&@Q4p|c)tMq+T* z&`(@dX)_{%lY`iXVa`@>o!7$7l`vnr<0%1h|I0r$pGiD`B+JmuUzR{2ZE=?N>4wO3HZ^R+Q8i^W?=Q}j#UiH5 zV3{hX)|?{O{vWNwALsq{|6c(A835+T+I;k9zY*wjS&gpg)u?XP#KVf^?os~Bwyicc zyZ}!g7-RPCc7a$3IXgRP0TNI=(t)S1kJls#cY!BH6GlF}$+uO3L$~1_^+hiU-^OP* z={#_#EXPhHi=XC;;t)+rEpu`G;Pi;+{q*5F!yP>aof9P{3697#gHQGr>&6axLq9lY z%9$AS2DcwiP}6vyn~r|9HSMiq%qkOEXR?U^EF`+7SLodOMVYwJclH;DtYi)rc?Kc0 z)DhZn<)u$uR=teYJ_%yIrg0)~i*DJ!jNZHwz!2njqj zv;ItlTBi{#0NUdo@{Kc`W>C{p@r6KQ-!LEcmb5Kb(NGYzcm+NUq&4qq;>%VXTRDpv z2L~7&y|3%d#WX+%xe}HaIF0l%b&<_UrI|-jb7As0x8vb5lA%>m*ry8teBnO({b+bM zDFK%5(F9TFz*YLnoPUq6;nQa_>?_Go1)x%fRUVvh-)JHDotRvN7!3mc-nqph02((H z9+&BtvPs}6{AC^5{ZqQS$CsO1idgi3zi5|Avfn)%&L@fQOew9`eLgNw&Q*H$y~hO4 z%?*vSFIp8wEUJ6Av}djWyS+tzF%w3^6G^GIv<~kc_#Z^6)HJ#;nsR;@&ykXBU z7HZ^%hfHMNs~meUZ71DJn`nD06>lB$HUe^BFn)EoEEbW$UE#VWXm4xGXC6P~J_*tV zGutc(YpsB}47EhEs}@GAFs^)T%rDSo-FOKhf-z0Ca8_KJ#L5J6EZ9M~zyjmVYZBW8 zOr}YtNoDC{89L6b&IJXEuaKKlY&Q&i$Oy>2(tnT*dG*i~54YD*(1_w+YQw6Eo)~El z)smNWiQmt8S~8u$##OU&l;06CfSgOhPF;2NXkRj?6e`KO3q$e9i$^8d?1H_3DCV>is} zSfYYhIF2njkO!Jx0OF%XKock7PmXFN`4`X|aEq#WnRuy>4-Em>`sl-XVMqm#=%#b> zX{l1-bllRR;q@C41no)&)s$qG&#IwUR_j#Y0M0k)Ok641R4$>hbWeIE0`4g(Xj8r` z1p@DR@RcguY}Rogsl*7|PKS)*CqR{CC9pQeU1IvT?bnd6N7Cc*iIg_=7b?F_MikM8 zMmQpCOya<9uu-r_3xPFgcqxw%g^z&#!Go1%Wr-sLYl@#g8hmERecLc;cbYfj49mP^ zjsKtb)6>cpUCx!VRt(;#CzDFI*DzKm9}|Exu`V@#yFgh)G{QC*n*!_l=;Sf;x5RDE zn>(_FLNR;8?m(w>w@=d(u?I-gK_~CYwagvUdf9cgAyPtxRkc*ke}pEolYX67%-aj` zz$TFA&_G-!`0VWcgN~Cpoi_nF$!V{TEP!4MkQs@nm&JM7U`!8o`w^Yisn}?Yzsjv| z`+;eRgEB)KU#VwZ)f41X^qK^=`jk^P!}I=1s;~^fKK{LA8=^w8y9_lWukhB(UP^(i zk$ngKE-6+RZ5Nx<%ibIDYCb@`KN~D?IJLFrJ&J@yAInG*5fliReG%kLA;$akPJa9q z;wsRWb39+vK~%S<^fUy0bP*z_9w*# zWQ83iX}M-cG8B#Eb6K8uPCT^R_AWN+66jz7Nm@H2iE%1n%pcG&3srG69rTeMDPv_^ zjL2f@8I2$_!Yck#&n}MLGB5Lr_;5VCePO%?EA_W;^8{VpYDM(Q*B<C7^5CeNcJMs#x&OgPGzkFiu;Lej19Bjs)oA( zSWyd0=`)Z}D-28{r7jFWY#&ynK%XVDOg)=v;GMHX;~VHH4=Az~JbBX1D;+q0_-#*d z$2R6?`hjyX|08*o@~DAPgxYLr|F9Nrotl1#PP3#X2kyQFa^(#g;M&CGmJ~TakV|uf z&+ZjjTfYg0d8kb`h^B0T!LTOC>h3hewkLQOjTx1VTpvcWo`w(D{0*)*1V!0<8H;pt z8B8#0zEnYMQ3=WJm;pY72smP5xP5YmZ}x)?OgOk^i9L-+g{f?wq_n9dT(d5$dGf&{ zE;ZbeZ~N+^N2bRdt#LU@-)R1401sLU1O|> zj9qvopYOIK%xKmJ_-0Vokf{27rMV0)3npLgXMbnek_1ceLaK~qc_b@_Fbxy}Uguin zlqYmxNq)aec5&X>oP&)hMD*XBSul^B`UPa*){wXB0D*|zE<@N=^BEAsAjQrS%0!?# zwwk-MI&LH%G(bMjNdtJh^Tzie751as-YjW;gw2m`D_PI6cmf+_ zD!~?oXIbDU05;(jC0CON@5DcfD*)!D5BhE}JsL87qWQN-jFn=1uG2VqoGQIJ%c%>E zFz?P%z{_murz*4zqOuXg>XKd{OL62Taw0K`q>dRp^(d|7`F@(w@RWqzQg!}MR-M(hO3X%C*6zooLodT4)TXpfPh^GJC&+jx7m*lNZ14fWMmrMtIA9@QsklJuR(i$}q1aE@M!geA z>NO~6d49D?_d+qH7lSRkbeR8iN0PQTyb7XAt<%0}=#z#dIVEbK3jGxfYaT6_grcqZ z$wDapL6VPEwoS#J_YRqaoR=iEYGq{&$L^VD;5ZFBq3~vfcgLCaYSk1mwhJYsxdMGT z(^dNDVyBmMDGifsGWHoW) zJSCfJMW5`96gIDkM=2afU#=EiUKD4TsU=rjJczw^uu#JuW@K`u!hH6qi&dyH-5=Dc zceKHogyuom`!U84(+S#bSpkX_(=d0h9?G$7XO}l{u$!}!)G_f@l8 zcw9$We#`DWpc1SalLAsO8_(>;o<7g2I%-?OITdg_-@Q01#}uBkh`{dJ_hilIbx@7u zQgV~fJMm)7vsf&0_CrH}*wFITQvURCsr0g%{^#{$0oX+D^aVKWam=(rqRoDUPYZh^ zM74F6o&R6RBmu&HCx@f7=bYgMl%j4GT5I=Gkw-TLa zg0@N}L?xi(zl@7-q2v*04-T0sI%C}X>+k#)+L6qPgUdJRp!r$p{tq@$PqP8(sPCr| z;KjF2brrTvK@JMY&7#njW{~0&V!t6h+#{rjaPP#A*{#)7@@ri8^2vMFfbs}mDSbv$k(S@c1#JIo5aFjRcQ5GGEZu`y7P6s&;T&F@)Iv& zm!-o?IlHf?-)Hqu`N$Q{3iO`D3%#wf6AW<3)z&MA_PR$JqQ|i-ubF(+*>S5y)Rn%i5y8tGCV!aTJ1?Mu?O{n_qkIgdQ}o zW}W0_VZ@LELkeNcpzqjOyUV*+lFktJ6C>_{pe^Z7XH^Cs*vzylD|o{6>M-NjANK+> z7;e*P;a1|me}98|sy_ZLREQz9=O{!SyJkbbsrt3BEe(mvOdZ@V^wXEfr)^i{+Ww#? z7Dxko)@l6ffJAZDNjtrkPlG-os6#9_+Am3f6H9HbVY2ttzHCp6 z)W*ItO5_JWtEAz~Q?fsKktPY=)?+F{rp%;r(8>*|U5s1c5wBN8ZWJ~ipMzr=mosTD z9NGt%2$@Ng!oXIMD;|H8&sc@Nx~li1`dcY5G-fj8)M$!$f~s8^=L4@41}FRV$^4Kz zrg@gL7T~j#4`$4>$^`Cs<+;JYp^ZQKh@8D=fqKYOT8XoO>o^MmYnN5DbMS=7@984Nz^mX~#5IR62W08r(lpJ_iG{SkYR)Qpgeyj6 zf7#m!q%(%zJwJ$el#Ga*0m;aD{{2vx39m*CZZadPCQayNQi#{bNNI=rO4@2YWTs&I zt4+5W-`jjt$~JLCCwa)k2Es%qi(8^zFc?4-O$6^sE?2jpL|yM4X(nMZ3V z3`w_R);R@nb06NPiNb90FJF3Iu{171TSwOo46XE4x4otAOt&6K|D}r3#MyDI8hcCS zH=*^;!$rK^JupYOx$oQRT1l+<^8AMk)U4qPxj|!=RZS2b4~1gj(~Xx!nN(0xbTOvo zCo;@3u8XT{Fo?>YO_H8aF>jgJA7>7#d=@UQ-6!bBT9kpW!*qpnf>f&(4P2+YpnJ6{ zWD@F290F54scpzClmqDOn;ERIjZ?32H}VcN(THy>)Fs+0HMU3(xFPnqAsHhHe^7UQ zWp8aJb12stv}TfluB<59QRa?cutxYhgEnQ_*b%I3OQW9d!kHqC`4}7E)Y(&vyYPb? zar;IYYU3}i5w6f$t6%0BPdO$T^pIcsh|caP4Iku@;lFvS=oWw!Z*$jWe43isl(#hz z=Qa(H!M64Ql&>)(9&Rs1I5|?&2UrP2v?+l5VL{5Xbllykpk_2Q*dbIHhb|b7YME{& zwhlG5sZpn}Y3Mj&VtAjdzmx!rc|@EqOXfH& z&~|$ds8Vez85i`XhbiUfkHe%5mwir zg;D(W!GyNL_3Pw%ksmTfu=Y%^*Lvvy)%(By{Mvi-|I9IhPY5QKsA9O2RMPOAcslx_14^u*-L37LUlnp`f6~(y8I@RNC5Qv7`AjS^#G{ems+^pe*Yim^L zeXqj>+}p-n`f?Rfw^D?CmnW~pAaPxUHg}UkCV=onMMf-_^|ykd4`9o%y3>Y8^Zv*kGN_%}eid6Jr-I^6aYRcv{ zb38aLJRJY%gZ{Yid&8>%61pZK(?gIIUotiMq38<$@>s;E7}UZsag9y>G3WN`pyj}s zMNQd)lyCpfShaMy!SWwnX(zx`=Ueh<$A3(}4nmy* z$>8nwTMVCjCldX9PeC~}Vt(l@gqcpkDS0onT-O&AQXtNVV&E>GTuao-_ z-k3wZ&5LsepWkh;*u`mM8y=dy6DSVqe8)rk@nXXi-g?pml{4MfUve7jt*sz(t{cMN2kppr(Ala>K7+A~z^@CO%6 zbqHJ&)O)VN%wVKB{90jp<$=wkUAxO=!Pxi|kf6Yb4CJvE@0n=uX^2y3h>s2Vohs2i z6IsA#MYCqOC}uO4m7!>)U{0NGR?tC8qVju49CUYIk4pI;UPFG)C!vhjXl}FC4R){2 z^EBOYPlI$drd?=c@Ef$G6rBvS1L(|a+NAi0Ig26HdhQ%FQNOnN4rUReAfLD?Pp~Z; zLZF-gJSJDZ1Hv96Vc8HfdtVUb7Bhv^jrsQJC%EnD#LM>V1L|`o?b=kZWuA=M8{P4` zxj4cDSH^y3#$%6eZD=(rImV~f`+g<#kD<0ni-b0M&nx7xU-p0}jBIw?^3p!^7d;k= zkC>*(-)XsvfS2U$k{57f!3%VkQd1XnxnAXKZx(2}2~8V)n1^ ziJ=sj8Ui&pgJSu%D@dp*i8=kXJO3SzcVzqs%gl2<`Hdfc!cQw{YA*qwQ=VTq#($ZP zw*E1=-t~pu^HY7U6aB6DDMQ`ML(SUQTzCJ;3;msXzIBa0xUe)tx@i7Y8txl1bR~N! zO?5p1Kuz--V|8Tu&O6*S5FwuY9Xs!n|DmP_c>Lv^#O&bE@C0y9$M`8hFZJ{JZF%~! zORcZ(31jDlriT8fWQSn?SILI_r)0mr`wg%5ICPK>>jGjEol~N=_+QTXgF6HpiX~S zqUwB&i=TWwC@r{&|4$4q4I?&C*aedh?!b5*$*(Guqwgz&icQ5KXMC_K+MYsy<{PbV z!|1V*8}tU(VvU!e3B1aKf#h4wa`#2Kzkd?>nZLj8mnLRSy|54XH*^`w7H|~vz36sh zqUW{^~xcf*2xT^Ty-G|_q4iiO0?}LB#{{3h*g>P-9Hl8Y&!z&dZ(r1 zESfU*Z}A{f5>>HW5Ee2N%-6ieXfdgQH}~#TPkU~}wHxDF!G21_ZwL3A!e^JO?68YH zgXja3P1OSt<})%v4bX$>4ag=`fU?`&_W$bA!BqJ+bE+}l_Qsy01$S=P*#Gi;O! zO}{tX7;V90dxFX7%BFCe`t$jXbzmQP5G^+yLkJ^Z(Z~z#Wpd!(@4q*7F9-|5SI6fW z4BFr>n&=Z>VLrKWRq1_W7xpmk}2jy zKz(BftMx>5L}2JXw?!?9^PTxFk$Qu@_*^;m10~+1$}V>=@w>@fgU5*wVdX@{!EuxH zi2b8lItX834fntRXxfTYjjP#^oN#gUsOuP~V%B}|Rw?Atak=@u=?c#SYZU4<*<8~4 z*Y5qY9p=ZM@q-&B%Fb;ri?hMPceBatHlV;goB{{hmo)`g^~gKr2y#!AXCSkU?pT_~ zrIy#N%Q<*TIp|syp&)Cr5~`)ZBlvwXl&zCEI8!d8-S6g{#fITnp8WAIPRXC(KcNlJ;(C%fusPVUNNKC@Nr7X2hs+bz?(!iX1)<~=>0SLsX95qZ0*%s zhAH%Jnrv!ac47{^c$~7w-2H(|_*e=0$Vk+A9U}9a$nTC6!~m2R7Ls8&4hSVZ_U**+ zzS|?y5@be|BS|LplBmd7wvJVfYHdeL)xB#%j3+}VL(mE@t`QK_?#wOV0GiG^AnYsP zgU_1UAx^cJ$+NeGc!&vNq}9L9rSm}q7JEDmgcbgjd1dJF{oGR^irNiL# zBV3TaP(O5EPLZoAWgXL@b*7=Of*%mOk+8DbAzCjSV&TLS;m3qmfd~Ekl!jN|WrAmf zs18!Oh3@Y5<)_Koemf^6~{k-YXh!vXWm|*5Ac0R-ea2^ zHP>CU>hR{&798kV$2X9}lL3sdDAN~0mHaw-`O9VHUN=2dhhx0Sv7~Dw7tT+tKHx%`Yx)M@Os<7#;2Z! zs^Jn&KW)WcSSSKcG^}-``>?SG9W^WQ$cGWUPqa$A-tqO;8_XKi510I*uyEWq-IJ)T zk_~B|^V-c*eH{#PG0p3X9ge}*N1J9>I;I)rjkZo{*2~5umpawF;?}s<&iO}{-+l{Z zpnr{iSIBoDGLrGO5Dvy1c;h_i54Uq+9H^breM_aKrw3x4x_ZiFTMVEt50l}6kGYEI z)F89I#FPq%oI8i=CAR<$_%pt|4txD1CG-V1WkVgKt~HHj|2$2e+hT<|{?IWsf+`hV zUA?s}CDuz$c@Dt%M8usX+p|?w4}$qs7JpO>Br9bXHg@eQR=byg*|HEA3<*!-#LsV> zNf%k4H2!wjN^J69pOs3G%p3ycmbS<1D`#B@_dtm~kOCyE*iRnu@x7Zr)^`rSC>B$# zCMmQJo|~A>xK=0p9T_=e%mOs1m!9cz!gF+$JNbOziYpP%OU>6cm=QD2 z1{tbQ2oG*sCL!&IIGGfbZ^$&1CiPK%7_T6yyk|2JY3FsZq}Vw;Z5_AM{CLSv-nY6K zAo}h1Q4c|04^E1LbvgQSpKXd!|6@ZBNLb`94r~s^bbrl-CtxwtcE;+F|DkbcQg|V= zQ(p3{AQjW~2Z8dFO(#iayuC*KcbSq^KuZ6b;tQz_zG^$u%+wJP;j=i+2lA&QqPG`= zKFq$r&xc#T-DL%K0^`FaMzN;vFDA*u3YuD7HFB@}Ud#@P=REHF}}zl+rnCZ&h$ z)QS|s!Z6%#i8VfRhC(T-kLt1iZhs0%OXD*2lqKBTGhVJ>deRfVcx>iK4Xig#^AAsVtQ zM>~5W(jie2Wg%2E#e$lb!fG!riPlFn-QUb1>YL)DyNgtYZvv{2dQB{yS|r)p>#0vA zPrj%n$W)5@STVJ(_&5u#q>x&%43LF!URIYlyfo)WqtN16~T`LIC+E zu6B(Sv}D${Y2>ZVLvYuOfU3$|`&>+T@>x>~GKtu~SV7g&ucm({E_hO@&8i9~$py0` z&7c@VYu~$~;z^Op4ijWt;*Pfu?HK%Qds4qLC~d^Kgl2orbdhSmhK^vZ4V(MDr}0ay z!`iY7mbQu|M+f%{o63H|Lg871z92f<2iDcUS+hR*cuFkPCQOU3Qc8`@rlJ)F_w=JBGTU^^0y6aLGK(JuA*ka4QPCH z9d5kS=OT;f3@{CGVRM*`bm&SR6oCi=Ia_5awTN=*cy2|UKHTY`7yBP!0xe1lS&uw7 zU!lmJXXRik3L6ZB1duF`K49X>;z+}xpX-FTrdjL`BExH`xnmrs<8}`q1NygKT8#F$ zvG#S|3K3Z5KuMZp`HVN-ww9N!S%45~b6(nvfaHWE986pTzG;8}7D=+q)$b4uVZRmwEWj|`-y#16b)j5%)Lmsz1J?9KX0{8>G?b4>4LhSzH<;t-w4w*76jcFj z{+1L)*NkSXBHleb(sb<4yz16( z7W(c?XHK8!KI05Qb*_hYt*1CqEdU{9Q8BqczYnug9>UD!CNF&7s7d4RbWqBf0sO&; zQr~yi2o}rbB{1sC)p<=e%<@y{Juxz_UkO=?=fsTx+O6C%#Y1p>ZrCH?Xy+z+|vzYF30YDQ>!XskZF=M{QC%T#$3_M9&+INp4-mJKF zEjKce ztSUGvg6dJC^F*|te7a8**LZ+Z#=)k_@K1K8x%$S*%38i+V>btNx$PhY-Fj`s<4-{8cpjSuP(F5Xy z_TVWciSRH%^q$GFxn9r7kBLvef?nVaC4mh>=C_@ER=FQS!Rg4%`@GOdVzkro_9Koo zZ#TeDmBIS9QlNZ&|cSVF=OoKwYrBBmJj)wFT9=S zpU6Ujq8j3gr9R*q-?*k4b{sAeoMEq7O&&w_T0Ml(qg2mf6~PwgbPMyD?7Z@`}+APA-?~mvLlwVWLGg#5`qjr*oBe$SnVbR#V!1LA8 zSN{A9aG3Sz?W#faFMPBU6sKu=Sk$dtS9K_)F(4j`G@QnJQ_yG~<2O|2AY2_Wiuz=D zDSgrNABY)Xc<=;?eoe0Kftj}^n zFu39G6dI&Ek4?qTMYN{5h~`Qku$h$*r}>;Dy3oFmY_T-{iEcWUb+O54ncLP^yGjXi zg$Hh>O#1KfYLta7-X-eO85wh828kp-6Tz$V9DR&S^|0%`$yD)ECG=7av=gEYpD8xE zDK9Ob-9zj@KaG~3l31hDpV#+uIFam?ULkp}68@xdIzWk#eNK~gp9t-CmNY|rvmCa6 zJO+R$>gm5#*F|2xQT&mhU`G@b8Ez!ct|AH;g*^;N7k)6I=-*yTKZ6r=Wtqwp9S{t0 zdNL6;fns9VcaRZ3A*sZhPhA3WN;P7}lK*-=G8>w$Ea9N{)==RDDUgWHPW#`xbp#~) z>i>&8>-w7EAnwiRvj`pJ@;u7@jvBWcG}tq9?HG$!={5@$Pbwp>TI3(#AJ&+)VMKRG zME0a-5O3+E|Lr&zYUp=0!f>#AX+N`S;d_ z!3R85X$P2qJ6_NumFruQ75o8dMKX4`m;6(WJ9lDl3)IqF(%T$#gYXu01CYc>%m{<9 zcgi`q)sgjW9yARj6T|Z62~sGtIXd(wpv5!sunWG_k&!o&w{vgQrfwZnh}=VOK3_5H zINWk@RUP+i(3!^1bu+|FF?k+!7V{;6mxymeKUE=U-Gl{rb1dKPGjH6xHn;T; zXa!7D5W{Orqfrx3#wkJXwvnQa;$Bl=i9S_$2-;^jCZt zLDI6zTWKW7)z_a6D$z@x9NCTgb?j`{IoZL5@3`i(=Xgf#BKPD{CSp`6Xw{Qw6=0?f z^8#etUhVl|HW|14?|Qa$yzOCau0Cx0OmJp*rEHyZq;~ZI^evsm@#Hi|g64&PA&>0U zVc;#6IY^t9$i+d_^Fm4q79b>LZr=wIi|bHkrT&iL6t4cjuLy7`=`twdMP);Fb#MTn)T2$BA%CL#**fia^QTv%)*`-MBsBNRTBk#2qTj(!;>)^-&519ok z7U`6`%-%jTXWavxiBep#iQP`j35c8byK>kD|B%HZtIHx0H?~yPKQ?ANpzhq_w~b7q zFlHliXmLtEME5`0e#XH|UTPdic$$>^e3Fou@FE(0<(rBm|H5Vhp(;nnB7I;hon4!M z<-~Wlkna9KDs*bfr)c@IL09n_dG6fIkQ|bpcGz>H&*RV{#x2f(Ug(OT8Vig(vJ(4o z@=W>tQGD`Ut3Thy7W{%yHWed*y0?s@$hro{+T1~Q!lK#V(-{3Cc(9P->la*-M^4Yu zK@}F>LH4Zjb*kIjN}n}}n2T?vf^arrOrkuQf3OMUwV``$gHiU*@o)LOa1Jjj)>U^j zA#SD!P42+=9wcTTX;z_zj*2x3tH2k}0%v*`VF?ri52Dr|Qz(s~5J=^mO?=``?iJEs z*3B{~N`vk+`csHxL3@Syp#6)INOY+`OM;K>K2CBNoE+WTR0@Hw_>>c#`I*fTWe#S6 zcJ12?V?8Y!8d*1pLo=d7>C9kt@gtNz79h;b(gct` z3oTlLAgTW!PL$6S{ByiQy5ZstXGt9{H!S>;rRu{~;JP z=}952AAC|%Y3B{(-XVo z@Q(D#*t@ab;XGS^0NO;kGWw7olGcY?j&eHee)ma0W$RTqeM+vg1U5OhTlZ;^)M%0x z?P+S4>Lf&9V^`O%K;vkFar?q6Bi%E28e;!l7Ey;}Q$t_!SUN~Fzk=l`w|&hE%bj&f z#%@uCXpuTSx3-0{)z>D#-|D4tQVJ4aC|`Wejx3;eq5zxv)*sw?sZ{e-lt03e_5$=l z7I=zTGFzfI*bWc~Kj^T?#s_09$sX>jw{Kd%EGpdXkFIZfrt{W_+)2QzYQ-jWR#+IpS zDgWc?+OQk%-g6b+gG^hjogVWpWY|B^*Jiy%zSqgeLnRp7v^Z6M^xTrEF&Pq^`Hj2G zWL5~#63yA+gDX1kBb&j6JdvRth)L!wkD$YN+b<9PC=pmiqg@uxZqqY;9E8^)h&T=3 z*Wg@7aFWAAouw5%#wUO!x47NIiz1t*v^W^00O@!Nt-{a8mTZx@GL93?ZD!}wB`c0M zAT2ODG(+R4d!{&theqfQe9ewDC!AKl&wQKU__AXqvSCx^RNqMXgW zqU^<)sQ6>rIE$kFWD^o1u#XF`UagfErGT<-GF8OuWYeuNuDH37C&Ci-7Fkyjq|laJ z{iF+``Hkw8N=x*kH8DhYk;qi%E_G$&w-IHC$SWLPB?IHl^!PKO;si+;C?<49qy=OG z&4}aAmT}s=wXCb+bO)^Y^J6j2ure zaG(3jbQ=3U}(7D*y4840! zBoB)arPojNm_gd06^al4vJ8RlJA59RVJqo*kWd3D&6-h20jhMoS zTaY(R85@%>-o+PJIUJ+@!{Os3Py9~jDv~t424gyr*Ngx&;>ciHwnMLiq8NBhe%G$d z+F;+49Tkle=70rVb_eVma&;xLquAUP=`^>-(*YEw)#SF@J&0Yi>X90}qi^B~Dp05L zx%>2XDpELwWqJYtHyX3sh|t8x>~#Igp?CVOqRV{`<(}*)=)He~0ScTlaBD^x z$Qn8{SK5{c<;bm^rmu1x4v>@#a7fs{EA42+o0j5Th?_Fyd0RNhZdl2I$}Y`jmL345 z9!tT&6B!6-k=X7H$VggjNr}qkpTe^WerwvR;M%I|sPG0GRraI>y52NL)3cUQ0Q5&= z8wB9B8SLtCknkpX1xm0#s+!sy?zKlrT@(66OOZ*&{#M9?@ z#1n@gg-P0|%YEz*q8%oUbUXdsrRhc-2(ASD*(5u_-5u=AzmS$LZy3JqR0$J2Dj#I) z?(A}VR`dAr>yUAO%xN{KCyw0bl^D>NrYI;2-sm+uAI^jJ8_3Q}0r;(S_Ixk<-)ydG?2LdxABueOi z2trhGEu_Ff(+pEj_b5c)W+o-eg=7d@cybtfUo?k+YK?VqcQ+M`l8QV-$a>w;+ITg> zPGhZ1fqGRE@@@)!sgzdop-GRtay<#-MKPMt1Vz;fDtmrRI$3;59vXWHA_i+b1o1}} z`YVLSdOeA>hO?91L901ek05s1v&%>m4=u6l4!eR3gdo3htl7-NA_#BUP+W5__l5B^ z3LOhg)HU{}0PoPXA2oZx{AwS^3)VaBjM>uQ3ZGLkf+Y=RAA(zM6$R4fys)Wvdb1(| zn{1W@xM4OB`r;QzIH(5`BVM}>{@L7>h~L00WcN*a52sXir`Psd1G1NAxds#s@l-g) zqVQ0RDE0j&8>wZ!j6f_XwM)sJNV?l9yc0^I*hz`v5rQZJ;_@Nq3>ndI{)9Z?J3Xbt z1=chRRW&duYE&JLme*D0WnE^MCIFH^Mg9-6`SE&R&d#JSg; zg-OHN2OE7plAHSSy1A0adYD}kX>0j762cUe)&A7eNEOU!&>vG`p?X?T#~%n)*NVGO z!B6%^nEI0n>$X%V)})J0dqTKaN=&~Xi83sP)Osakt(dame@U(O*qk{-s(^%Iqo#$~ z`W+yUzD5wN|^6nl20rQ|L2j288^k z=WiJPISo#R%wPmq*MOLY3?!0#rw;F+(M`{)D3j-z?!J7mvMHo;kdDYpd2;eZ_kI^6 z)DNV44q^;}&_k4in={D@%VT9J4n-Yw>oZbzw% z&_6I1N%?3vw8gI*Z`G5r`MUCpB|Nspt@cu;J?EK-RpF;2NIw(h`C$93AG4}+Ub`C( zNIIBDqlD;~#eQqRQg=(QVXB9u2KX-s%aoe7NIp~93)e}9pdCii3KjkKEs^0bAV@qV%nf0uvL{pX+Qce0-dxjhQU&|4o5==Wz6nF|{oWt@tZ_ zR!@!8T7>=0u)kergDCs@*?*#g;E)1Ok7(9Z^pEiKj9w7!u(@kVqZnm%%IFrRTeEk9 z2pybhzr2Qoly0tNa&r54nu~itep!%hjWo;lh5ucGbjS^e?E| zYE=pC@Oc)-cj}=y2I*KU={k8=_Q2?nW0>IKcsj16#tu^)&<9JckWbSaSXdZ1*W5BV z=PYT7ByHHTMKe}|=(_Vr`F*V9#H3+jt98z2`i;Nq2N zc&&3WI^eJDs)x_a%hk;&5Ked!VFmJQMR$odcIyQzrxs&@J1N^j(@AMuZ*3@RqM&}CyPc&-XPpn7!rU{bH(PiO z30<;REjye4Nj$U%bsX8@iUsn}EU__c{gfAgfEjXEy$NR2-ww$tUEkgD`*p-he4qgpC&)~7Cx zrpW#!7ig>dpl3#!9OSnr2ATzJ&6&(wJ#UbU5b-k90b;2#<=Apn9#Wr|uJTxYIvuN^ zH>&>4!biOItYcc^VdC|i9liJWgKBt@duCBx_X``8&5hy`DH7dTZ;9Ot;f`lP-16*S zzirxY&0QQq@RD&^gKTVJFZ=3|0rB7|5#J|-AR^~*##2kjx=ENd2FuISF`nBAe84*# zT4yU)fyhWg9Qy~(Sqrjb$&F5hC+e_D!7`I;rAcxm~622ioZSZdz1WIyUzNj zQ;NkbF7!$A07_XbHmK?25Wf-&vyEp`WgWH1t4m0^D42K$knD*fWzsP8A=sKWWGCoE zO5L-E%VPJby(w$DD;GO*-FfuwY%Yt&-!_r_UngkIVU<~0XHH(JE_ro0bRtr^T+fDMf=VIn9gkpbkuwby$h9} z^m6EiwIO*znWB*N<-U&YFHV#nUGA(F>AY|&ZZKpej(J}ueQBp2SwC?O`aBtzW8u4i z+)2SA=xuX7gg=e+%bdqrLekwpaEcW53av3|Kku6SNY!y)^#R7s&-l;7L@*<SJlCrp3}CD-yC;ZT8>g3w%XjD0JQv~RnG7qiCt|>JxgVy* zE4wNZve^21ZufSsan4s6^U<+~$BLr~4XD|pcXyU_~i0pn@n0w^# zscs*EwX9j~3h*3C2(T^P7ee&6!X8S4yob$sXu|K915y#4@w-#`)8gE5iX;-^+b`;4 z8ZQGy1Cr}umoHCSBCq~16QK={j;pDJudy5S#u}V@ZH>M&I`iwt-Q~9zbGgmGo-WLU zJ3=>mVr1NSJ4({i$N5@!b9NsIk(5q2GQtv)k)4St86-$O_JD5V2aBzVHlkSVAiC3B zDuPyR)Ve58IEk9ao}%1nR?;QpS33|N&+M%9YXc}$aOid~YL(PW3D*FT_=SsUTyx)bAqR><&cA|2C}ExvWcGbi+_KTyqG5W>)ctcMpcere zqai6jlv4F)dP$xYykTh6Mk&+ap*HeT$_$XK0Tp;Xg_>1yHMgOvCDLjSVJpxzYUj!(5$5Y%AdCOaZd)D@!t9n|E^HywPvloe+# z?=)ZfTx+a<_JuC@hG zMcyqPkWF~_tlFjFjw&89gt2e5EsrZ9|L*+C7?Iq2lR}NtluT;l7J>>d*Gupuh~x83 z=MJm6FFi_&4Tdo3j-CEo{JFI;U=8ISgsl#-gK*IEhx!!(dZqKb_1UjyGnu~7cJ_lO zS#*DaxA3ffA3fHKOzbH@6pLOs^+6KMPG4>>!@_p87m5`et()n^91?| zN0t7z97YKxSYR|wQfzF3^V2J}Tpa0QxG^v666D0UsY$RP+X8Uewr$(&vTfV8 ztIM`++qP}nwmCiT6LIgu`3D&pXJ@Yb7Q}+pkrVt_SKjz`eyD9OQtL*GRqp!pZu0>Z6znS?{zXF#trY}! zF`&=1^8j8XJ5)67^+C3?ToaTAAyFPt(S}7dJ($y;BWJ4eV3PvT_ZA%|j@cz{$t=6y zs9me-&x1{m`VGcsvW~rE@7ZyXNtEHD!&ufO1^471dl5TV6Go%~qF$| z1vGVrqtd{b8}z#)!j%Y*ar>H_gASxk@f=?iqDYO7*E!V01=W>)XaJcJIhf9^r2{P} z_bbGPjk&WCo5WZ{@P}Jt=h)xBLV1bvwByovBR5i!5|bKWjtjRA#FD}_Ub?IEb-NpU zT@+5HAvX1m|88`%t9|sd$U)DwWsL=>2GH8&BA?{XWjbns$xw0cq5dfVAm77{Iw~y% zJRILX4n6wGA6Dw}3GKd5PtjrAw#!go18le^V}AV*O0;6>u9|Y!tRmZzd@JcDh5&3K zu6FF2NOd3HQ;3*IvXeLbN2V{?h!=vj4$BYJL2}=sO_J) zzW8YV%M+z|QXJSdwOr7}AAuh6LmS+xzkCK}z{5CNhO5J3&$WC3~CXcZj948h75 zpWsIsLYGkLEV*A1e;P<7>#*|nS546LniBn(LOQ}nE*MACa=P-gUE`5-E^^LMRwde+ zr-9H{oW=^t!Xe}S(!MlKoh!%*tF4subtazd9T~d-$pCRULR%LiUPF0Vw;T0Ni^8{< zdEk3S8wAIJcJhI+cBS{)1ziEeuDom?@$#S4__6%`-UA`O!w%=e3qd|Nb2kPlC-w|a z@)P)}TRYgeG$=yvHWg)Dtt3;9Tvh@9_y0%XvXJ3kEF|`_a(+dgBb*Th;h7<5Q^nQR zPHI{h1~X+E*MW$~NFQZX5rWaqg&kFGt6=k1Jl#zIk2Z>@EITe}#PI5!gLyW{b*^K9 zFyf2TAI+Ta7!pTZQdukt+nmvgP+2Q2OKdsf>ZxnIK>yrFJpR5IPt|o10(DT?-y6vB zCEv8!b2vaK^MEZK;VLAfA@WNus+YmT@@j^$U)3uy9?aDIG=F$c}wfPcCbsy{Q3w$ z$N8q|)VRHi(R5D)O{Q2D&Obk6d*jpFdaRZ!1X4hxBWTb#7(xf$#Q;PWznT9RV!wzP zm2#yyN#3tMnQCWv4G;D5jxINY%VIi}SM*dEJwHofA(VoxUIzIF zArhxG-8Umhf!yhHF>Y6!QKoPFI;;Pzuzund^0&nh)s-ByIM(VzRn2zAL6aN z*INjZ8zqt#2^tusNYX}ifc$QYNj4h6x?|$44@2*+|kH+ z*O5pNAATqBXdx{}U3zw#3`q|~J@pLG#7|UD)|zNL40{x`(VTXLcoMQs_iMwwtcHsi zo!8DWP1aoE;Ng|}BEXrVG_PTS`ibI~5?dj2f3)%!GYD@A)Xg&=;lrU?gilOeFkc}c zreZC%-Ste1K-&B&#<9@~^sjmXp=MgsXHD}@Wra52xg8s?I}}{fBWqq1M%QQ*{Xp_? z3f1E0acc7IC@*!V?#~~M&p3@mVC_!JI+T{EcKBAvjcs$5%}$cTaq?>$_F+z0ns{FbLk7A42q9wp7C`=-_LpBSNgX=ov4(&kJ-a;OoCNV$5r6cDw6Ax6 z#&?ofS}AQ!v&*$Zk|CA1A>0*O=srSR1etGN=El({N%fjENa~A&;!O7(F~e?&cAp+E zkt(lnqRCpf(HVrEpPNswm!L;ui)s{C;2>MD$GcR$*S3k_TY_v4Mul9RO2R*lx-R7; zg3V>?hio%ZNGU5E&A%Q2lM^%GlKM+`(5z1KUuGk(sXzWEXDfQ2qT{6|?c1?l$!hdx zt_jq!4lFIwtm6e`Q%HN6vGm;FNzNDzK({1K%}GIKZb!cl)Mo$q2U(hwIuN7O=psLFy}@+ z5fIv*D~&c5*iNL9=ZawmW&Jq5)e#q3vJY2AU(qa4#$n0jB_(Bmh93vIDQe#_ zC3kx`nY8ZCR1miSqhvI_6ezA4E8A5Tb3=A$ZoC(V8@JubI-QlLpeVQUFSwwOp{?n7 zCAIQ<2R?V7Dhjw4ckw?G(kfW07S5|s=Zw2Eh9`8_m1y>4ZK@!CdRB)ytdv?A#q51( zR~dQYPZURr#cuHBQN$copz}?n5Q1Jk751#nLPT6>eSeS_m836GLFZ%qxL7&(b$%2P z;eoWWv!yhrhR07ud=rd2M@el(C59IV=2XJ3S+L8X*y6yO=L@T}nf!!F_zKg38Ubla5|e@qdZ&OADEZGIz0fX!GX z8Rf>GnwAfj8rGS(6Cz%0Du)q~d7qR-Anj387_@V54;qEUy2~b@-_s}BY3r%R-6Vtr zG{u(D&%z36f_YEliR4Nq3>MJTQQTu{-jmW}9$GVlunrV6 zcwhats1u5PEu4L+dS{N;tx%<-b8pHb)4NyO|FISE{EWD@%2v)!Vv}n=QWj9@Rj0Z7 zCIGK#4sll2CC*rRG)AN`VRu>J+G`UFvzU4xP4^GYb z#6Du*{yvsERi9aN=PDksYJ6ur>%!2G1fV{TM z@oAB}VHl)2KLQp{+zrlVuDaesN7AmVR+;3`(66&+N*a5to`bjq+0ZMQ!zU!9N<}Y9 z1JjOhFi3-+PL2s;=~*YZA$1G{gm1U=N6{UUoM4Lm6Ei31`35-UZtIHwYgy5(g`ogB z+_qGbQ=q-O>jq7F|029X4tvW{P*$`f#JxUV9V{xpL+HJG6zLr#iUL&VKh~eRP{2^; zkGxyC>0XTv2cvuMY*dJ`ePg~pt}0?`0+rH)f(@7*Z0KW*MZ+Y7iz~fmr`MU0n(!?Y zel#_woUT|Y4LXUMBi0YLEr%fNs!J+;ea-CIDWz{VG(iW(0$E#;T zjqr>>2LTaO5k&%Jlhe-joc=(a=2@A5&$F?kKQ|VgN@~i*)=yOV1xA7za4UvpafPKF z&&)*k={u?3si}VI7yxi3yCk;(*rI33eni!8IMVBTI+nmv}DWR2_y%*R5;$(X&7w&Vf>Ic$H4sj z7EBvI`vuJEC0IENn4i7nO(^l``$9cTLG6Q~po!bQWN>R-rLb+yHi#u=UEE!ZX18Pp zj!yNn&9%Ua{LeDdD+S&yz{fbmg`gyRHRnHH!^Yi72P{#Z7y%Szx+d!e+x|~zot`9( z%W6nTTTuX%&1^JABM3-y2uc&iU-ijRH^t^hOzW7>V|p(AIXfh1HVmW*zTR38{k+5l zXnsP`n}Z1<@ETl4IUEN52c3^KpG{$CbSX2hSw{VCVb?nT2z&{>uniOhP13Ud`12H^ z!D5p^S?GnBfj{#tJEp&$gOCp~3ZX>NH(3>?Ow!Lk&)jWMfb|lWPog@NPgvl0Q%h~T zs)I$L8LMKJF`za7imwu8kFbxwY#y3PkOLmsvc!u}$MpJ9!P$S4ojBhVJ>=B4-b4ym z31F+aC!niCGBs-o%B9R#MF;ou3l??vkrgvve3+M4%M01JP0>I+NC^Mlwdnz~Zs+pE zUl9*tR~D}>lX26buSJyMa_osGl6)#@riCc9aTn!t|3x1T=u$14SX0I6W?)5Bg0Yk4 z^94!KX@_jm8FpDX1(~s6^4xLNcphL&4qcwjNbvdm!ybV`Dq=eP@<>Hcf6eYI8px0u zP~x-AGv(C$J1`qx9QX#yvbn2>sr3!F;_fiV=c__(M|M$n1hjX^;b9=XvHx*KIQYc# zSBj{o95bOww&nH;UPWf4E9rqh{djV@r0bg%b-d=1HGjZ=={s;n1;Lkw(1;EPCfcDqN-&ZvIZ)eVnE&&N z%(yCEA|Tqb_je9x?o(e%IDUS-L2G$QjT)eLIc}&x-3NIuslS`{Hy6MPI_ZhJ7yEKf zPcx8!H1$JVE<~&sCCGI%XVMrtIs&y33;pjTr^UU;kQP$SCRexlX#Y3PQr5rV*xjiH1Xx0>x2aO{ z+VOhgxQEAcAnJo?WC^&dfvas5kbM#IX`YJ@iYA-VV~QsK7AFH`msPjxw13U)M~V@) z-frjZ9{g;~pp-s>z&r`PV)ZVGmAxT20VCUphigkz$(;-#XWQ12yD3Utcey@!PT7wW zJ+kO38i%O}bV3;|noZRAXaDx7^>+5Ggl!j61+ud%AXpXV)us{ot@tpaslz&;0So6T zM@U5#k93|T-Lk3jdRiMNV8YOy1*akMweoLEFM%sGVr->3MWSBb34bJ;}hh+rB!#=Rtk!5hUeFVUU>PM(Aafs4b=3^N1vi1(MB|=NwOQ z=1SG%RJK|Eeo4OD2096rNiu}61)rP4zb=%?4cab8@Ol-laSL?9hNI|>DeIj`6#VJ9 zJ0n0D_TP5%^BO2j(=_~oJ=M@j71_fEr56x7gGCKzmRSwCWc8NJ)oLx<(ARt-e(hm8PQ>Sn!;@#GHYR>To ztRGoffY<{bUUGxtVX43)1K#^Z%7nxZA(*|^j4-PxAS+I{pYW?@R%vx*^SxBABTfE) z%SdMW0AbBKPeqCA^ijBei!#R>@X&49bQYp9%XW^pl65=eN9v=R;fD)6$qeG0(XZP86F)7 z-^zhQyzIw%eiA60hc2WoM%1YPy6Mt+wzF{ZELWRMs_1Tfu|$O*hozR&K1L$o4D>&C zEyZMaK9Jr|t3#4+WBNg{Im&%bWr-*%7?!wvK@_g`Z$FdTPTLv&J1?)z*m2SAe)y6* zX<0^B3vk;5kHx01_aCCNVyO+{peTRInU2hiERXk`t*StvARddD1k)^XNf!DfUo-(^ zS!3MmYsg-*W5vWcH&;u6^H4IDY^H35?mv6#hwPe45kANVa)|H~y+=c}K?UeN^A;%B zPpg#tbVmwSMuT-xgcMh3j!6ep^NpqWndtS0d!x@xskpu}kq|QnRxz&IZ?gHD`An{> z4*`H0xtHI7wt-+^6z&S#f{J=IZe#=G*6p&Q6Io$5&2JrbuY z(z3TDB+7NO2df4xCy|K$GGBv~8lK<$uI&eG%hBqZ@X95rgq%zJfoX2dk~~Phyvkpy z;nu%7sI2rZAnMx?AM27cLUxYu*W-^jjoV=$it#$v)`Ux( z7T7BBnq=3Eyct4GFJLG0LOF$s5s5ZtW<=u}c%Cp*U7I!ruMk@ulNTC;ypMt`gj5J{ zQVD*;Gba5vWnN>>q?F%=6Rs#Cw~beB|CZP+Mbse7L%&Aib8PeT;!nErSxbIBroRix zxOUYI`tI)n-B`T+T)hjX-H`DcuuOR7*b7L>(oj$|y8y4af0AiOYFT52LOEI4szPig zJHw}HM2(-tY<8f*xY#F;G#Csp@naQIulnX z`3RmHSfOAi*8y40P?edN7b;cPXA>53@a;iog|7~BlY{~}(60MQSvo{tTFh`|OmJK_ z7x0N+fn_}SH#-8vs|HiS2)0PW;=;er>}0-lhc1qO7A0?Tzq5siDUm6c^}`Y9Cx{#E zVziTllVyrRE+EyaL-w26CwqE3plFOCk9|QcO9CI%;aAJp!_p}U0R_P%!ht+Z^BQ(ghMN4r(VEJ z(F`_Z5-^|BZgl?)7y9tCUq)!Y+($H4LlAbv&7v9rQ|x$DnI0>S0u#SPRCHm#&Z;Kw zpj}RrD4&WSC;-bs+N2ITzbMIo#QlJhQ`R*B!EH=zy6#2oH1z^4}1 zEVEy_C&xwdauYG=NM;uP{66{|Nan97&NNen|9MeI*c$KUu2^5v;k&9z#ECo@#o|?q zG0WqqvE%qdk}s`5Nt#8xDar#`qwMT`{CBWz=_=u<-=lgTFrcu~%`nngtGMM31H&7n zrOA2qF^IclX=k5=WHMtRO+L9~2mr#4(EgRJ9=~X0oF9W|mQPthI*J^KX&m~`$oUc7 zHsN*CtP%X~H0(xS`vOllXh5#okXJ=gH?=^$oZ$5s4khZ9K;z3U^umoZ-2_qbMVO-i z<0AxS(=9zAR3hA$Kl^_B`c2|CeOX{E?l9BU;TVY6Qw@K3(`Ca7RjN7l7b2;HL69Wa zZ~2lNvFEcjt=P;K}&m{{5V-9-LBIkFZb=NcU(TC7dioi$lk z>&^duEs41QD6-9w7#r@_%bP`?k?zBo=TZ*Kl`73kkFl_!E9-0(o-3KOv$QkJc7O@P z2`uTVsweuB1a z;PLRET>xtx8Jz52K+_9zGvGK>6-1Q8R3*SLDCRNNIYKqjQ$qD?Mthi_yX!=t00 z+8cAgncu`J*dKDtAGwd*)%kCJBwiR~{cm`y-gLg3$~QT^U%F8O%E~+N~$(GS0C=)>L_ zKho`AY*G^A(;Jb|sR6(|BZD7M{R4dyP9z(MsTXGvV*$ z4wtyP?i}3~EM`lNhoFc5w?Ue!M5n}D6Oe&$>RDOItTZ@WKFBSMPUbpW;Q?LKR8FXc zX(HK>q9+lH9?*C=4i5(YTc*fR(&*)W_?2ULXFhXvVOef6oie~N^9b{z>D?U=6u4D0 zLv*nT#F&M00E%gENTIRS$qJjcs!-GR=~<`(Ujk$#WtWTg{iMU>x!H3wB_<9qcFeQK zX`U)XS@V-e(37!)Js(AmwA!cxyqvbhR`2zYQy8uwI86|*tWY=e^m*ow1+=6o+&s0338DN z*fF8M@kR$1&7I>G%;2dt-<_y~E)-`Jl!`Rl7PX$O5yw|j0c6+OOWBs&N9<9vh~udF z=eH{YGXXhuNI6tQbk)zr12OyQ*DLH;MjW+@&adU^aW~z9*E~;XD}*|R(A15_qo-;7 z>hgmvW)ECt@|@$1d#ZBl>t)Y^Bi=lseCwpWo-2OM6zJ7;#H6VyKWRUN=e%e`0@UtSh&Mqe5&b}1{me4QJDJRjYnynX0j+?Rv+H^2GIJrnP$m~}9wrwNkZ*4xN z^=eX%aVQ!BZRYMUW{nUK(y)Y6gDVUust>5#Dn4~Snj5b28+{``+;Y_9s%3v|9IG=w zk}WKE2JR9ct1`k+NA@L#2S&9qc36s)L0{Xjm)nD4^){5QDZx7uRGLLB99`^2IjhtA zC~y@P`*p#HLA_R>>0!@lH{X{LVy7wDh5ssCudn6dGAxkcCPbbUQ&3ONW^1Mm7tB=8 zq+5Mc20e*1eQc_6$l%|igi8BrGFCs<&*2P{t*TMp=6TW2aFRzlQ|9yVCL;*`iUTLP zwje&mi6;!iONRvK$EVM#DgC3&ON@y`BYt91H5d3rY8C7A#v4fbKRecDvA)s9b|WoGee{(jTyNbJInf&#AR4kdO3y7YD1V(C5tV{m(mV zB+ef{$fut!xSZJV*A#c-L51(wkI&R5w@gx>4A;6gPLdTvJgBER5UO^E45hUNaR3+B z`61(bK5rm^ozBL+t_4sDec1U*(XeJ7m!Pm%UN}13ySnXlF!jwerMb&adK9Rv`Uzi! z=K3&IjXD7N6i?^W;@=ZPpyu(&JsiKhEqcERFuafS-*Poi36maR&M7T!;Xk(+y!0f^ zE0@puyWDymMfBEyo}{D)WCW3R)A^omHnM15mk-8kr}m{0lWa^`w#dChE7pf{=|YpH zcenv}BXiq-VNN91;+#=Hd&pBeHAL*Hi?=cT^Nk`kviXYUAP0Fn@fz1#3zV=d)=o(a zKEw7EGccc=MHeVoKTxQm?&raF5CfoF^+w@vh|6=i{vt%L`2omkXE-Ar$P!1LxK-qO zS!;Jy-G@k3)hvBy*dvot>g8vbm3S~TAFdQ2Dxip%uCkDtZV?O4A%Zueq@7cmE{F1q zYs3i=rPo5#RQ=td3R)|2FPtTE2fd5qsx)wiXTVN~Dpl1eTl|LO-A7ym6RgarppP)` z3c`7+EL`!7;%ro@X`$(X$I?1)jgsy6v3H`T0LjShETxo`a`y- z`(ZC(k+ya)VXe_`yqD?ZNf;K^y4^zWO1p!*LsFhW<2f4dVuO3Er+KV!%Lzo@P=`{$ zc$x9x_$Ta`A4mn2K_TUDrxzN=zG3cZu|lmPHqjJkmU(Y{ay>T6(A}`U-^Yu+U;tgr z4W1V`^qg^+Uz?$L$3)8@fBGvojcUG+3G($kewI{9;jdJK#0gc4=bl{nqnOMmL`)H; zf<}G+fW^K~EVkJR1zoKvTUJ;3qiG96FB{5wA}OkGJM71?d;wco-mfs@^Ms$&5y(hu zdQI9#qTaNHs-eF)IH=?PV~EA>LA6tu(ySJ^MnQE$LXB!eYqZPtiLiiB$_x0d4Bxa5-K=evaRJg)9w#bxfAWBEkLH#N zi!uZ@(kZa%qa&a!h6aj6cx_^LO%flOyF&wckQWE4!G+5mnj1*XK5$9 z(rAw<+OJpEbU3LH7+J@5_0&Se9B(z^87*D3TEf-Vi-xp)JhdAzhK9qug|K|rb~vqJ3&2VXZRf#3&rUb|V6yWui*hl)(d9cM00Y-Uso0|1?OAJLP%?c%XBR2f(gvwe zM%&VzC1pc$`90a<-R6Dtz|D2)?~HUb>b@?;uW@6w&wG=^fgZ6u9#!n=HjNTFxd&`B z<{ayBcw1agxKJ&0EzvTWuj~oX4<+C@o~3F2X?1sF2+Y-x6kGP+N}R7QIb- z>!1E)XA+11a|3`eeQYZZg(@1J;;2bU}KnQwah-bAAC=s8t7AS zaHBb#OY;iY>zc_1q4O34RoRVu3{3;*4yir9GeoEeP{E$}yypC%fS4soz%)oYZkR6* zZf<80o83>@&RI5e$OFX)_)Z&GRYJ6~_u?(mF_6-f#H5&KEpQ@B3CWbRg2q!cC(z$l z(T^Hy<=p0HXvr!r=9G8LVaR#NLwlTAOrA?`xIgdJsq@zD*Mtz+ltjJJq1B<0sue)g{AH-qLilS1<#d{GwKd(3w3;=Cy%n&6`xV2aAZ&hp&vJNo@GCT8F}OCg;jw< zSnS-UhwG)rdaL1)PoF@;dQN8Ro1C|HA5}FPhYhZAseosxUHQ9P?$)+s$*&FT=N#74iXI8L6TIV_?`e>uNl09fo$u#lb?tq1e;)MjlG}nmG|F0Fy&QtWm9uEUAl}e=Zt^i(Pi5;R85Y<$V7b_j!brz^N zrwD(@27BJ0V}J}hv0d+>#g!lsDa;DQw0GKRfeqjZNBl>DoD0H$1KdmVrSP@9b5#QA zIbh?M?=wb?w1g$*wfNdWI2YDqvC^s}Wc=%f;1~&7Q1>l-^k-Y*5uzksv?6b5oTt5bcj{uo zhf@*jXKDs$kZK0r_Tyw~7iY*^4q+kkMm}zg88`5ebU@@S9=LpG`A?)IoBxj7roMfR zSoT@7VzkO_l<0^PEm9HT{1-@pI9g{m35`G$SO_@uK-B<9WI~WvTIzb88#)(7aEBK$P_PZ z0WF0(`kQ6_by<1o(0K5m-`Sv#zZmMJ-#!XF6HA5ca~U`gk|XdUf4kCum+yipbnKyA z)7~-!_s*L)44NOf5CBiN&;QD-mZ9cK1%~4LbjFM@N3iKRaBPDRX#37wdJKf~?Fm>`Y$&-D!P_E$U`0=Q8d*y+86~bWl4LD6F ztE@3HlQ`vWMLc_D-qcyb3p6PKCt#!0&j_10B1Hl6ZA5gDN~Z^ZCeaN-NK6&bBUvkV zeN#-SolQofjT>cTYC6-hR)l%b@AwI>U79i)E1zUW)SqmGCE9>yKH~Sj=NTo4dtTkm zEFEPTbGl`TjKiNvGPZe4F|bm;njW$ILz%f+6YQ+AkpcH2K0f0yKX*Tq?PRX0fnP=N z?q_(AGEbGx{o+zt)^0geosxB|H^H7vcW2w>g_ln@b2NlMu&tn~@MAJL_pRd|s<(+8 zUGnz~c2BUmnkX!sqxn<1pp9*f8nP+TWzqlz^-3GfiSP2unzqdtAl@lF~-%Y>u1*nyx|i7#!yqq>3o%EWD-Sic2KQ zu2q71XQrKj(!MnDPN}d8v)t3aN>1X0Fpi~j5@j7l!lA^AYM(i>7+}UO*u26js&|!v z{jbGz)rGdtJYk4A@aEr`gq>+EOsAGmq078+7Xr}oT<=a(`op$QZ92?%JgJ6-_eFr3 z)U|tx+3+b&7Q5o8>9ysBP8cVGbhGxVGwg3xtqnyYZ&xe%_tQ!r&flmU`hIG*zVVg} z!x=M2)`q!D;2FIV?NNoU))CT%1=^GHqxV&Q-;B!DgZ!U}i5swD2|%)0e!V2|t!)%~$<&I=W!Ls3i!TjKQl zt_78W0mGF(;esj>obv0NTrJ_t9naN@>D!GKu?J_un-l}?Gty5M?2d1RVhJW9V4@U_ z&C=pg99Tl`L_NnaTLn`!KhZa=$r|gp4+_uD*h`7%Jjbe1!lG<4)Rahk- zGK($CTCecwqDJ@0Eh|tnuq_i3*{SxEr-epcBYr3av?#8PKxehWnB?avjG=r|@ZBs` zTn+NgSiHfs9)mTs6Y+}I#c-?`>$8uBn5ix=*8(#SjFh8V)&mDGJ#x3+alcs?( zeoDHmc~WDl-DY^05?w!w{A7NtV;tuosDFU zC7q3Z)U+#*; zB1O`S6Kj!;9iJGY1@Bkv?X5?m0z`AWKQF~`ef-yHRt7Wn9A-5fLqw_^#A7-Vl;O@@ z#J6)Vo$Ep6c}Gz&UabO?de*HXrH^eWkj$g(xZW#Sk6!i)gnC4xyS;#sY=Q;51oG`HRyuP{N?g@A_kJGd;3q%8mtDH=P#{Z6YRM(pc+M zGb&+kAb3{Is;JeHJpji8+v8z2;8`;;ra6D4TC~)Blzt&8fXv!@tt}`pTCDnDb zZ6Ph0e$SKg99HQ`9e67YU2>9j82DC*r=hkgR^5a57$2C1>newEn)7$KdTE~GJxm9d zz0&LRt=ATBrU`p((8J4;Nxk*Aa>Fs;j}G$4K1$sS_+cqQDTS~v2M0x#ZrC5cgX{?@ zww99(^bRqoUHZE98AF(3?{=8=(`#(JUI+^eL~S85D@iVblAnvw(5R6&xz!#M$jvT? zMz;>~-f)SaM-e!L$%GN8I%9z8WZ>nK=LPqX_7se}y_@X=TtNm;+am!{|N1y$XQJZ=0ZL;aTOalh)Ty%n+qcwZ@tD ze8}^jyepELIP=kcOxhPQ9C6w5+N|O^;%07c8|(ERjaq-Y?C{?%F0JGg*`vd`s&hjO=QF(Y-(D za{2I~RK5???51hn0~N@y7~y~O?SbnmcQUQ0+WkrI$t8bKqO0YWDhj~jNxmDYjP(mi zK3xb)Ly%0)!u$X};F|EA_b`qao1myAPKw<+C(? zdq^HY>F=SqLrbI6F1!Pm&&yc=@Z+dBCokh^2n5R|jV>Iy=8tGbe@4v3`^O~mFE7R4 z={1XX+EP#=9R*R$6r5{?iw~U~b86L30|BJg5E*iBw2<|0V1XP5u8YH2!7GGvTJ^C! zpMJHEIDt@)J;Gj=2`7lj(XDiFO6kzNP{#CX z3Q1xzeU}PaL7!lHgZMB|?{C+|GmjtkNX~s#OYc$Ln)1OwX+J=mpUBXvMsk)Y ztZ>jn-Bgkx|ACq^5Jdn7cg>wmSP%Ka@n&H~no>RK7a4h<-eCXY-_#Bjk?(Uf>|*sX z&y+&m8A3jMrbN0fNOKFyP|}{W+*x6h`yAWvo%jjdmEt?HGJ=Qrn?}2lV_#BC7!NFo94?p1_1w?gOzEQV>sL{9zzytMzz=v9CnkkYA%|Pa=T8y9Qg{@>uWK`of ziE!qM3}f2M?)b|V?Zj1l{9pT$K8)}9JPOkfM5;r~F6`2sFvddvuaOlg6=r?()|eEV ziX~xjbUw*8ZA{T0FwcLjqLly}!J$&cRi+ zxVeAz=!CyT&V>}5^;>C5C5VOhWF3lx_SR|!7Qu;z!!a;au^Yb4h!wZSn^bVndYvhp z&HnA8#y)LOPebBY_K52VD^Ymz-kOwsH@^E|$4VzaaGVQ>(sq_f2Oc2dvpt!VBSjx> zhB?Eoairbi7n;0KBkZXYgb((FIVAA#tl&J2mACmGe|p`38{Vo+Bx8FupXo)xER#mF z!=P7`DuhwkZ*{_Fk^0?&0#<0hc9vcjvQNOHn32CzZF`hM88k4m4LNrOOZ4r2wlcOW z;ULpZXN!i=5V4G=)Kw6e2q-j<^TkKTJP#l|1+TT@lv@*qtkjcSQp}XE*%D>dzyJ82 ztLEL2#>d?KKo{z0#5{6@3$f%+S+cT~c;BD?6v97&DhZ4}0Do!$&310xFVSQch7bfZ z0>={`y-;C+z+ssgyvKhu@B*ZqlLB!fmFKZHlEm=dBbnbIDe{pFsoAV*%mMbS$3c0) zysvym+%@HDU3t=D?XFOa1~<)u%a=&0(~TFWe;tAB8h3``8PrlqhDJzLn=Hk}d zXe)@9T3VqtFb*I|`^g(wy&p2Gn-g!L5z;O9iW2W!3Dr_1>rZ65^h`<{;BECmzB-^- z>#8KQ=a3XIDU?re5iTBSLg#{1_o;}f`*bw}dMh2Qd{?{F2bF0LZwZ6)v35{X&%z1o zn_xsXM;FKg2T44HPmx|I?Jli$eb>n}Tsz<8;6oifF{rq6w_*KCtchxe7%J=PjYU|* zEFEV22ti!`Hg`B`{bW^yp3BJFstL2fz&4NHlkQr(!K}Nc%N?!A`3WFeNOq?vRHcBh zj~2ha(TaT5MDT1npjLorF{^WG-cF=H8vH9;;d0wnED`hzvJCKRQyOVhNhV=ZkC%?0 zC=$;ctR-baJ?>T7!!ym6tcvfUImz>u@Ql+o!jVgDY@lzR#?NoB(omB1&WnkhSk@Pu z(wa_Vg)F!9{Tan7wqvA&l%ODVQU#ho0mGRW{|;5SGyjXpzuid1T{iYoEp?ts&2bbY znLY&a0;147p2xMK>Y*;*xC%r2kT~sQgY~Mpkz08ijZoX0W_U3uVb*um@NNFH?PWyb zW`zrir(m0@Da_%a9Q*8+pJV8ZZb*7jOn7BngK#(Rrw z7U~zmU-SkfMMQO>bCdGk>ws<55#>(bF_qhF1*GF&vSI1vj|d^|tCuV=3h`iEYW-*B zL9{~UZU^4ev!+`>EL!uFzab?fcQ9fHVvOc0)hBnBwjdSn@yanWqG(QyzJr+jbQRrH z?OG$9RzKWia{B7g;B8e9>ug zDkgfBDPi^`an^(5YC^<$e_Yh#5jvHlwAZX;VrKD~2l=4cuey?wo6hNa@$e|IWe#_` z4IydI7mkgbQ5J~&78}B4r`ziZP+mVkW$2!6$CcZm)(0X9Jg>-jQ%E+Fi)ESQ#3IR; zS%?{XA8I<#I%F0`9~g3sc6fVUu|6hMQQAe$;VI@@{e0q0{+)sghR4S*%Z0;K{92Fk zDl!W%!^qBkK%F*PgQvOLusCJ#T+^NNSv9xg0rJZ1vML!p63u@h#8Ew~{dqx>*W{LL zW$ezo9mLrV(ZXjCrdE`C`%-t;-pj^i(ozs#i3Y28awr$(CZQHhO+qUbJ zZQHhO+jHl=Bf5WKKkdlKl`AB7-aqzsp6KFGxv;?p2sZg$m^X^$OOx0YR1KzL`ahB6 z9I|gTlD-#`J~%I4U0$8!)C{=m=9;s`LIUJx@wNE$;>ebnsqGgto4p^);>=KqqLaGQ z!ZH45_ODonCCwLUDCgu0;J50pnqA3Tq}|>(lk2k8XY)Kt+E~&qja%0`QDLzHUS1$+ zMPw7EFzhkP(MDWeYN7uD@%h?Wv1O<9K_qTtU+aT3435V5LHcvP{?J16NC5}84e(el z^R^uJDE+HngE#`6|3@y%N~xtA+VcGOH3r9RE|M%yROq@;rtWf%XQ<+(=UJvM(IH-z zd6nAE3Iv={__x;4O)b@yQ>GWKkRr1$Q|WaVHtn{WNQB2i7RA>i*x*o`IzpimmLkLY zbzAPtslt2%-`E0m-e=ETXKzUTf?P$-Mk+D911)s(s1TS2f(ARcx!{ogeOt>mH)$Rw zt|ULNW3xuaOy;}sEc7zp3l$o>vwym~%qNXASfNOUsYJr{Z$Mjs7v?Z4EN++oC5l^X+>Y0cL?|4fROy8*vM*!pR?jr zW&G2D2D#>O{b$MT--alm>?p*cu9jPHZ1wtF_9sR1p-z~N<2{!04M@D)w|$Vh1J;C! zAWMkQ06MdPVng&DO_yLrTw7t;pv*s1;c8_;rCt^j8%sFyWHb}=jB+e(QqVK+p1#+v zoO|?D3floxL|Cj}lv>R*W(;W@Z4u8`=4+ZSCnfG5E{9nZ{|&;@rKr39rQ`FipFKK} zBGwzx31=szzW{vgvm{|X)022ZD2B-f^11Id*ryfYOA1v#`k@0uNq*}1vl2h84-S-G z8v+vd_Hv)4{Ppq~BqZzoQU|K5AA|p_GraL^?~9jQQhIIV2@_Xt6}4S0brIVYeR9Wb z6a6`ME})#SKIjIhmY z^djx@+`^*ubhK9x86i>V>Y3*(HMZ(K9Kh7Ld>_NaG(L4uc<=teG8aXUn+qNb%sn@S z9U2@3)}*@yAj~(6r+IVZycb=I%eZb&$3qm>6|1(sg2i_@HSh11Art<5hb)_5v~1R?@iv~)$d{J)teDP7k>B|B#C;BooY7TV zOapIJd+oNe5r!I%4Z;H(TY-)JrZVF}FIeWFRf>8YO#Gsnm--+>=Y*t|%FlYMz23I9 z7$JgRP51*Ge);n`r3dO#hLK2gUddC~ zQu#a8oux_X(?F08pVxE#3vEWaP0mv}{2nOnzv3S`hO?$(_qhADnm1J1-2A{ywbu7R`?f!>AU5_Ku*cK(%OG8}K2rv%<{Q`T`(2n*{4MSTt_yu zaY;6z8&jXWStp&d3XK?an9M*78*or+yYD`>!NFkRg5Y4?*J6bIHmEQGz6VE_mU}dB zeCAmR`-KQ8D`f=~iL@*)3zT}taFOxsX7cr5h7ZVF8Yal-eUCwfjNT2QZq+gyDs7=Q z6Mc`W1k(?=r!9;W#{sZOPTVy2gZmwwsN~f`If98Po*#QT8VP*zTX*yPhN(|q=5TAZh7AR%z zS30l}Q4r>lHhRlcifSCwQ5kK-y$~09#!qk&)s)f2#xnNqu5D2ufbRk2K*TnA397vb*lN;#Lwuyi5}!zZT8`TdyIpGO z1Z3b5N(3=6>NN^(h&^L^Wx`^81p`G^A8`0$Kn_HANK?8-EB3%BeA5_{1QiUhilf-gv(1s6 z%yFMwC3Jv+=%ujKSgrm(os*o9$VOoZHBE@|7Fl}%|5Lo>j)fp`{WACI3XFWgiU~#x zs;=Uk4&w8HQKqcccteK;{4CN1@q+h+x^KR`E(<)5w%TkC86w#tHivz}LGo~>tgpm@Z+ zE2sty{nh-db~9^ljg|DXP*mv(UxPV#l$rc_wW+BUMyc4+T}{!W6DlKkGBH2Xb?$*@ zvIyFHKN$&j5XCZO!IvK~C|!;Ln((nMUidB8vglarz&!{8Y<1^d%Y1#`aaM0M@0p{C zwrWofdihUYSuQlN6WMT~xpZBe7Z-r$2lm^ro&>o@zgx5yZb1sYb@I0)y%67g&g`JjHDD{-p26fP zE{C@$7?af^DOv@t3dSHhUQ9)Bqnrm$0b}8G+?h?v0R9g{oUhp~(!FnMW3_7D+Elth zRf}5858OQn+)3(9CBHc0-c*wcWBLh3LNjy(|JeM z(d?t{-aWqU9Sf85D0wWTak$au)1A0juMB|=sH;L{E0i5^bQx}M^iv_i$a6{Zx8msB z5LR3Yk=uEOPEbnDh{Z4DrY@tZB%hs)CsSS!{kA;HM6<%DVS0kvFmec`_iWp*gI{m` z5#YxjO0>WvW)FiD3b&9awE(N{Mu`($=YMw}FO$}oSxT`PCfKl;nSmZ=FYx9B`ajeo z`iQ@|*0r+(*-o`PUtgYxzR@*lwxTbQ=otf6R=!EFGSe}#N)%#jOiR>eDLTCfM4pDE z21zT_cMJ-3mG#suK=CYgh?&Eq_u|`7=q1W*-Ky94Q!L1km0Fr64UXbX*>X+Z*nOP} z4j)puuC48U{!HS8#+~#a1(KJ)p5S&2Ds8y!yP55;44GzItjobXebz^VnBVg`Z@8sV z_!_v;e?CT=!Tsb!WXe6Cn27wbrEk`MtKnP4v3NAGof5meO-L7^NW{ zC^Q^=X~la;wcLnA_LqN9mP9bKq5j(%SO`WzloJbua;w|~tb+nNZB2xUC*V>MmLcU0 z>MDeN?LqaY&4`e*X;jO=x+UdU!*5;2J9&B?E7H!fs8 zQ(CC2&i}Z#V<7bT-sL8y!;^4K16CTgSG*%dBZcP)O~iicNX^`taW}HHVf%qrm>+{f zfXlEBP3*(wo@^l5pF*4fjV47boy|<2mYWttN0U<6{1trOG)AO7+-=gH(S>tH3J_n- z1ABrUBXx&Y;|7>qR}lt@s8f?J!SVz0g46NsHxRuy*0@`PR^Y>ibAHiUnfw!w9SlD# zs@m9vyvm_!py$A5Z@ za8b%_7B*jW%Dxi@wisLh zNcQm|pw{f0Wh%G8Y*|t5)jg9vD-t4iH!&0}?VHU;U0f;!H7I1aC8KL)Sc|?xw;WY% z*UyPG8Q2ay7AR{)3Q_@olyIq>QCYlDh&!P~m%dnvgYdtRrj&VWW-e16wljlnIS# zV0`WQiD0ib@<^Q5{NkzTQh?JJTnKH1_pGWqK=sR8B3nUfO$YxVP0Vk!p8yM%-=7HL zLeVpv$8`U~!%<88jKk_z*2cuRsV`z!k_c8xuu@b{&Qfn!#mJz5h~@adEe_$x?;fwR z-UuDczK3e|UAMd~wW1ZwD}V`QTPNtRqR4~IqZ99d$#;Wy)lG;Lm{4&bW9yp;E)UE@ z>5TpNp5SXJfh1ZnY=W}YP)X^sWOGIw?4eDh0y0nKg7pt3##JBP|;$)D&bG=Pl-O7zm#MTN?JTzYaShzp)M_rLZ zx129uSLyeWh#*>^Z9|YK5kwY3Z5lC1h+bB@k5M%G#hiFSY?7f(Mq*9gTY_fiI2n!b z*y<8eZOLpHJ6?vNo@q3T>nx$@Wr0S7wp%=C=Ncc}qhyBLs{HlCy#E^S!-)Au`*b3b zxQ4S0fLo)6INv?=mU)$xb(DUDbWp6Nz+j2A!2Bqk za{5_D!;B9kN?GX8EI70osQ?1lYU91LBOmH|N+RU{1l*5d#}`UyGo-v z^UzURUy-wbq$`uC1a2nIiR}e~zxtDuD2cAAa>eqL8enFELDMyz*s^+e>;;X6(9hl7 zv&7;~GGcsJ9|=~czSw9OB(nSO1~7{IY$@}|W>5!P^#j9zG1aSFn+A5PAUuI&{+67}e zdwX9R&dBXY?dE{Flsgl8m2wknmi7!j6Ij=XB_pJ8RQ#1w*#^exgO|5?_vCgP;)Nb_ zv2rt)x_2CJ^~t`f>p*b^YWm3?ISjzI-`5QY0*YCnO=Gt8>e8(@rxKTWi3|f-C>x7P zSM0UnlzeGyACvwIZXq8VQ%AmhMxHMlLRAw*UK@_x^WJDPTdffo2T&d`!lw>uDwpoh z&A+`w3s;4o^>&$i8?(21W|>HO04OtP=y7&}pnsi}NEWCScAaCmw&;v1D>==oxkn$@ z!tmZiFG}OJgeFe$xY{KidmSMxidk)?pQ2!Z&yUjZy!zW*3OLM~)qeMHe{rO9_o z74l?K^p?LF#E*D*_FJ*^?eg{cNxFJTGu`n8{$m^mLmCVe)F5|84&9ZRNx3ff(Qm+ek;-g&AmO8+ z#Q-QeygQCf>h$qnLhot9rR$uDcFpK=WB@(ywf;%+1mG;2JUTq~B&Mv5)&KCY)_+HQ z6YyzhT{>goL;8-7k0s3R-G0U&5!V9iSKP0IDt(wD`Az3pi$oD`{b?jVg_dmV*W*iR zt=9oNS1gi(Af!=p`PUR1cw71kFvy)}2(O?j2*$3_jk%fPn1Y>=({xju1)5IZM*!x? z<`F1_`N>7cLBo!#G|DZiEsav6fV&4yZKtf`0_W_Xa-r$g9m@i}Hv2{;SPl0n6*nu$ zVTNm1)W@d1FlsF>pL>;o&eNeSAfKrj?+fk_oSfXkq>ZoSl>R)-oHN|;yMgVYH!{K05jf}5fFQs8}JpS-^SBh<#2u<*-huE%B7L~ zG%eZ?p)lgQ;|e+xReO_pt#Dr(NhxR$7S;w{lL<@PLJQ`4f<(N%vVvK*;)Dig{2n!Y ziA>H&pqaS#dyh!?PSL1Velki{fjaxZtPUHi*o#90Zr67L6d}vm- zV^%N1Lp$9552tZnNra0Kx>^3k)XB>hFr?f*jH_=sm8CICP56qc)`qkKVGK{*naMMbldP6pnSw!5#*ES<(^H4Vt z4bercvMBaSX-LO&A7KVHF_)&e;A)~G2h@+{K3|l&i*ImR&naXrUz@jRXVkmm6vCjgP>siovn9h1fAS%2yaQ`Hb_u&d;IbA~N zB%NN}bf*-|v>n1JXbEdKZgC5xAsNWhkVq=MPOtrlZfy(3c`8DkgE9|s3lkJ{(sO(T zLC=jeW9R4aMIs^4aD9XxqH#e{;G!w3qqf^zyMYx)F8Msgu-&l**RmttTUsmxf(F@p zYfL@YGi7NE@yCH1G|nVv8W2?H_}TA<^*QI9Vy!kX&Hw!C9GH_BX zbB<+$%x*5e?(O&K)+SOu9U(Jfi@1!PZXj$72(3xqi^tnF`|85`Rcm-0p7~MGI_=@a z&&fd$;waVnMO)~t&oKVDgaX~A*JotGBp<-hglU^# zA8Ef&HkMnmkgO%kSe3_Oh_-qb-#F+8HHj@t=x3|7dkF*}^B4Mc+L`*gO zYm;|4RuJy9K=srp5Cmv93&_rE&bKb%E0hLJWqDTX$~AR1Ge&bo@&Zccg(?C((I;Ln zD}pK(rgm!OIge=?UC)WJ}(D4eLS9R?+V(^3q7GU}=pS6dxcFff5x6mUI%Ig*rVQvo1S z4rUQ`t8iv8YR!B}T506!;ND}D{XOA!d0S*~18(>w;9eVO?AAL0oKqTa&WDvq^0E0vGGs4TwFSl`gw>3GjD1GN| zF_|)YP5*XQcUWI0wl@;x5)3brP<_cJ^G1DNQZMbU{lrNa2etBt=p+ud!8FN3$}z!6 z1cn8hpb)(BSC2b&MvKCm3GHp+ErgJ>KU$i%qOq6EfPseXWCfMu4uwXtVakt%g=wF8 ziLKz7XXv)fz(vHFu^Vox5&6dRisRQC+lB+$PdT>5y?LO-!G=G!YuWIom{hgK3pT8e zfn^qbtMBAd)RfDP?gj;SVcOb!2%6s~U>yNM^}wKcmJ9wfzjah+Im!v-2S?lbNaC+< z?!{Br)q}Vr+2v&FslAf3LIRj4&*Uvaaf}RZkF^#glF24C{%1cI#*BXLzXfgSa1|Yq zJV4{TrqSH5At(yX}1dpfQy`0p=-VXZrRL`0~Rx%HRJu zvN%K}PDQjqyDZ`s4^ZDcs(Bxm|Nb9hTNMv@xgGgn7FdMrR?N zYLJdJ+4h(cI@Pw#i?nCg0Ox#voY3XgRb?zwPwJ~&Ae3}^Db*Bxfl=FQs8a(7y|~)t z_0`D19kHL+1Sc9Z>b3N8kplIT&6*A_iKGYIcdeAwCy`p3ihz}HILu7zhKm9?y4%>?Xn{0kIkuw>9B*CNyf$K3*sVzi zDq;}m;Kr*yWmw?gw8>D2Gl$76VFZpgqSA^=4d03g5){Erdf7J}G5uO-r(Y)MhU;>0 zL<+f(xMB6<(tm_5ymEb&jlmB(@X%@!u>UNFoPJY+=lc$8_JMW!nnMzuRusX_KhE9X z*tr#g)U0HxFECGZK3k~?(Amipvr*qSZL{^~!#Kur=BKwCyg10-^NZgjdHeb&c9cBJ znvCi1-+ItPZ`DCpEeMr=jzROTBbTmqv~?j`>L?XhB=%5mLz`dp)`s(G2{Vkp)|h&Y z#C%2vgVbw*X-2^_CVWmS#nYkAUvVdBJ~RU_tQtoH%-S_u++7Xma6BkV5;j2VJ8LJw z=>mEi-OE#3ZG-YuTEPLrkzw=XwxgqhiH6lxfjli&tF zIZ(48F5yQKt{Abl_7d-fi>gMx&ZNaxfCn70?Qi~$vL?uUc|9BAcJNQ`G^fA|xA!T`JS%oOlv*&ZAJ_<|hLstP(ZuyReJ)cYXEHV?U@ed+y?Yr) zT3OKjvZP`Tty#CsM2xz$DTS!Fw3#yi>xVC50ed0BzUZzdqyV^;zs6@6Q83BgWatyL zS|K^}R_#mb>TJ&hXZ#+_Ix83)5tA<#io$K_FySJQgWBiVNrxc$OBBpykx6h4mZ=mt z3H;G4(&=1|!biBGaBH|6NIhVvS+U-f9=J(yI9*^<;nHcw1a~5Dh9bvd`Q15hnN3CRV zqjqF}`@Y1Y`4-6R;#6fRuTI!|em5C1>$oAO?>do9q1Gssi9{;2eIt+jh@R0smo-UE z^N35;6Y)0vM~P)g z;8N-nzGeO^WX}S^(j=!Y{}E^#$YH0T1;Ep_Ahz{rTMeTUfYVI~sEg2hs{{Y&=^cg! zFVrW&%F;w9G+2vMv#Q)9nuO3D0lVAmJxDFk{)scJ%CDEtw-Pkr(*LnpjPrWk9YG-2 zSU_4ng>>Z8F0EK4)^6_PJiZ)V%NTu8q!kYz#%?N`K1nNYs_B`2!Vt@>M$|vX+Y}F7C@#|5BaPqa)r1pOGOVpDLwQA79u~+cbZ)-E93=_Ga`coMxg8F)Tn7YahAntDNE)< z0KKMg1=$5kciOmO_NlUfO)L!*&o!{IbB4py=SLJM;rJxAiS?_hn1y8u%j6J_Ns@#Q zb%)$WV~^xGHbb>;5J6(~_oiV9$Iml?@?N1x^T#6fzU6dm_vx-q$JO{xZ85aJ62IpM z|GHUvb}_oyD7Q~yE*%He_vbif1~eH@LC*F3ALsAD@?GvS*TOv{i!9q{%M5ewS9Q3^ zePAaBYwkM81&n_~Je!RN%fC}n(Lf)2Mk&+_ken}RsZiCaEin^az-|Sh5RjDZ)Kfg0?C0L!s1g#Bho}g%l5oJV_(_A!%-?bUjFBhrA+);F z7uBGq1M&B)t5b0jPC~JOx#}BRNe`HISFIjdE2R7_?N~RHtRk22#Zh$3$Vqo-@i)k< zf$*&dv(^q}D6aw+2<;oQ@vf}c$aT9|hkJ*)tg$Y2OPr1)Cxv|*1wPh2zSE_p&$-KC z)iae1bXJ*~jfC|{%yFm%z)53KiwmYse4~$kV17o>i{N;%n6X}u9K$dYp1~;8D+iYX zQBNL&QJDVg!DT7d8%}_HC3ja}vHT_1X0G^U)W~hMgW+rdg^SWb2`CJ%%h%ukvPQ=J zeJHH8mFxR0Nqm7gix=HZ^vy56-<G;$ zM9BFV#~#;al>m$RUL^Bj<4n&SUL^Y<0n5J*w25(t|M3jZ+Jz^XR)Gl%4-}3_=UyE? zpL6x|=bOnu!$4_*N3T_X!Xt5P#Omn|BA}_%UW6Am=A%|zs-fI$Lb)Bdp>`;}_m34A z8L3uGR7SATi2W5MeR?Umy#juhT&=7dxCM8=osa?3^|6Ctw5IND*N{fSovmn0 zS#-r{|HUqzY4YlawLiDl;9knF;wh{g4!O0gDso8~LXj8ndL#4A1Kic;n((wDPp~8K z1^tNx9 z^~+R49Z%IvQ>ca$cC}FFyWk3*G7};^9Rg8CZA_t_m?Qwo*d-q))=oEMF-~8gXe4_> z+V2bimKa8`C$CQapvd2U48Mgn^nRx^{7gy!y_a-oKl=ot4Wu25_@k6Xl|KI=%h7HN z{o)>?KhjgJoe7p-?kebdcWfLvvgy@0!Gd>9X>J{M*i4Au zz;ru9Z>n3nUl?q?e?aF<@okx&$1H#N>@S1(Cfw)tN7WBS?=n-|6Dz@Cq#J}@}gLDZXm^0+rZa+)3C*pK%=1$LoXDLbIknQ1}O zCuZPmGkWIs#noUuc;{i=K+vM@&my-}U_f!sR?LDA@FBaJ{lpqM`iZY_@z1Mrje2cvwkaiYqGCuw823Gs z-Wgx*bzJuMS02=QV?SMqhELFr+3yp=;#pN4251RbtEA(U>#foAhUgtzu)d#=4Vhz- z>NHh=J6DX&lLwk$p?e_v*ah^YGtkoAdzs+F9nRPd4-sdNS&6cE!^r83^1d(hgQ5v2 zmc7ki%Zk!QHK*oEfDWO_NwYGI#TgiV;mafW3J2`QzoBNxMI8j_-2jf)C#zd$GkQn* zT^epBf$H5F$>vxx6+f>$o8sV0yJHYjKJ+(jQZeRG^i8nmPqU9`UEeB26n9NYQXU(tkwtlU<6Er+#?z;JlK53s>lh;R z+%3p$46o_H!@Z&zF5M`xjfof=UnoqN$Fqd&nDU17VjG>yd%^b12of;3(2<& zKFKUwo;p>PEFw>(K^Kg@k9Wph3qUMsd9p~cq@4W801-zT7w$?8u|Vl+Y@YS8+6F*- zM}~Gs2gy?#KEx9V!M6AYymGhNivWvfcVHDvMs|HxT~SMB<3k3wC&r;yATk9=g6Fk2 z`>9tn#^1SUw~_k}fi&5)iJ#LA3;tWD6XZ#8weOIe31)5k6)*-3SU2_cAn@{2STg`o z3V!g`S{sUjj*ctEKwDK$3F=3$yLYWeT80L1(3;Y5sFUrRO>P|8rA%hGF8_sTVD010 zOhauEM=M4?zqraSCL)tS?SD2ILB1R|GL7jGj3ex&L23;QEcMo`)Ck<6FSVh{{=~-x zz(owa_$CI4RfZpxY0&t?KYSr!{KJ#4LwO9n?WlD-BbZUXgy-7arAM^sHTC@nl%h`q z$r4K`9hk{dV;fVPo!Ce=12ttm{EoPx4Xad&-Y%f#G@!<{Zw#&svQNzs&Bu+i%=a#1 z@`|UV$-AxcU>oXMOv>brYx06!p1~|9suNH+n@tL>QCX78pV6KrT|QqsvAEV|H1n8) z++HtsrQ}fffYFd+RWcVssOFv1cDnM{f*sujjHd8a)t6bHUR8hkrGHiKQwZT&G*^bs zq+m|3Jmmuu=}v6vPaQWHdIZ6Q zX#l$sCU7n`F&M_q&pRK&YBnNvp%ZhXm@b^+@YB;-fCIAMg)p>91Mi|I@wDG{H+yDD z|6Zchi#Y4kS9I2d2xU^sbDLo>H~RUc_dvA*XmL=#751Sn+2S9OO-^$t~K4t zV9kJEx2+~9@z-HDPXf@ygfda20Tk-~$Q*YhN$o~Ck;6XUmlZx!(}bexsf7fBwLxe@ zDQ3}#r9nIL^wjOLq_d!PRtx5a`Vrj_wjOnn4&}t*yKG2aY(abr4A&7mEFgg?E}@ou zltwu!--t_stmaXZ;07)*-5-rAkQkthIwOOmk-}#M4dr~&0Sc#8I5iuQIGZ~weCP_D zkEVz0lD6^=z%z230n-%hAi0^~Xd_F%#__En`#M5Z>um52tT>$MnJy+UgA_Vv%;Ih? zX8gnEL>HxPv|_9inUt9hj@7r^YKgYzZ_#5);ZjKA7<%mEJ;s%Gd(N>p!@?P>(9N=Y z+#w#|FNX2JVzXZGyar=~ScG?@5`%|V_wxG;s~<^g2^1~**5{mAho%5byIRKf_2>EB z1)80o*IqiDMKy zN9uxP!9FG{+vdc(Xm@SY>_#?FTz%TC1pL)SeQXAE?1Q-mkXuw=zWdKDpfy^~>gf@BSxEe2R0&KZ)2@)^ zl-OdyldjqdXfgf&1gGqfc`sG+-#mXJee0b(j48Aa#eo^X9)?zb!q-0|uptk5^bx7J z<4hz`n$rnbh9Nsu`aeBe952%Ea|reKb*}(aXyCP{a~XMtS5uF4>J0u;DUOb?tOolP zuq6wUWK-|ufQ(*VnxHvG{?GqRhPn5+(=g*vMO}k>_X#QCJu?(m9W#1SC|7a zxfY^3yZF@5uI?RNm_JqdXmG6nhzg#|aG>9ie@1D5!wlPq z+PnG%#s>}Bu@co;kwAtr<;;7#tl}P=8ibf3ZTPqlUtfC9D!e#eU&z(2H0~Qg_6S!6 zn-cjR)k*KckDYO=pB%c%jd^A(^5_ny0Y_9U6>k6#GA0XK84Z4up{OJ49i|FHAO;@t zE$1~YcK{>!9c;8v{+&_KoGgmo2`oHcwvX2_*~!mR5qtIi7!`#aDg8o9hPg?l!BtZ< zhN9zp58|AhBRw#T|Ed(S?4Vf?IF?$h>pN@yy~S#eb)QSRg&VK{NDIB;hM;+mb0m^qrX+~tHAAhuRi84P{Q6bOu_58 z_(oqhh)imV-jy>=CyN$Pei%bW(`K~wBa?()+-nIii8;kuPsuD-moKd~_}>*AZbAOB zF>RkFR#UqUa2nw@@Wp$hhUDhgMnMKQ)GmdsQ@XulfakV$D!vynDR=}DA*gIjHz*_` zE{KvG?@uIk&}ZZlJ?ObALoJI9K^vQ5JcfFYAO@e+P(0sleve}0Pyy+N`Tt^ElkGC5 zzdCL0D5?uFh7y(u>OwE7yk6WG$q4J!=C$`#Tph8SOTC!D{J5Ikm6Yd&)YO0bA4Sd% zCr+{s;Xik`=Kj{cWfoCs3W^44WO2+Eyw}@#sc8SUJCn9$!@SQ zhO3E%I`S2>iA^kwCLE!ac`w!=yW!eKNsZgusc0G9ZN0`F$?ghVNd-Nf{+yLbekI@u z0c2({j}hwp0C5M%Vr0YZv-5>nDCEA@8&X~mZ=LK4s<&zx`}*dG;&}W!=5Jy2mH-z( z!B9(eEuy3y|LC{5z4?-#(h&`U+Gr$o4kF?iHq;*eapTyTxYJI2d-s|!#Dq@P_jfsc zWX`)(vy$bF(Ru9Z_0iA-0vVVoTh;>WZZNsxLD6JF-w?&W!Bkk{`(%)fdD^$Xh%sDa z)O8s`Q!J3~ zmS3|sdqjf;9057738!T*SfXss!-KG$W^jG?Tv8bE8r=%6I%B3$Z1Pv-=phn@h%yP; zhiJ8rbr$pt8vqe9y3_XQ0Sthla|@W?napD3F?#+Bbkw_&l?4C$0>@x|dAn+mYj9=e zH&>_qor$&K;`2RXDKH0912|Fk>kj=#_sK6x!#}I?1p_Hip3yf0Pi}Edb7%5tN5W(; zDBie#sT%XFdFuL;fbZCygwmI>t^${L-HCIc){^1i<8E=oa5ijZ zO@f{v$tfmyxpZDURfo1g;aFzNY_~oOisNrk{ax~q>>|nhRh0!IJ8$Wir66MY4FJQr zzb#ZB%2$*83((a66Gx6krSk&~J&!?x@%xrB0* z&~UN01_}47@efKig+R2kq@2SAw@Pu4DPoKqxjsQI6Ji@^Qw;&1cKX6)ohFq+V3PD(pf0U8|lfqZua$eQ4$WuEgXajr`sY zUMMx1;iDv7y(`ZRKYTXqUpt|jmX=>5rniFru&XF8a+kE|v{*5ln*Av1Q&(2hfuo?d zv^=e1XX(hID_9r&uli!is$`M!~utfmx?Pb8G zFe7 zOWNoqHis|;9vOrJS{}^wuW> zIrLJ4AcW1H5bRwxl%x;)w0oqbeTaZ|1%IhSX0};-n>Zc-SIe+m4Dmd(RX%GUI_6gz(l;M}M`n2t#`i;P@H5rLFYsuy# zKHJEoe)!@b(5s)e2Sr1hZ(R#LLNfn?6YadHY6^ zOGxG$wG}iAnvm&iWBF5VR_q$*Y68ZwAbLu7#U%kBb@iEOvT@f^46JwMgbp`R<&U+> zeOxQiBBcSQlMl(~Aw6jD9X-Ro%&Yhn#1_Potzf5pejJ#RqB3u&pc=P{CHVe(bgz}@ zLsAZIX)Vv+a<`9?pZ=YRt~t3AjL$ZGLw|a#ap~8nYQd7IU{%b&X7rE8aeeds_<4m{ zlKl&%FYp&y$5B2BG^bG)31;^QL5?)Ta?>A#Y+_(~fBb78?YnHM=bT@;&TXX6+Mq{Z z*+eodx8;WQJ_f3MAck66x?sLeR4_8hTS=KtqJav+TKv;v43dJ zUY-PNz_B%POk!J#v~V#sklK`o*L)n8uJ3RQxYe=lK9GaW(Xy zUv-nyY824bBRx<+zd-zDMy28j@xVO>O`PBC)Bsavf-qpvmvQhA*(8)e->ZzCjqYu zva}t7rC2pOVe;}&NBCA{ZhfTzoyU8fcX`D-1NW)hQB3GaXI)s<&wdE$TrL<%f;7nF zRb}DSNzc#oyp!JzCS4LVIiY+N^ey{~AEfPCu_kw5)x5XA3y;#t?I@h4e@gWcV$~eh zc^)s-Ihol)APR z(D%PL!h9low9{=j&Tx61^NpRFRFcfi!rQ$+#tu4dEh?eLdV|4<`HZ2^QaoDY7GKKT zR`--qM|3PUOcP6VoGZeL|0>mzOQ@FOQK>p#WYfG9ONiV@r1-LuPq+#m&)3$ex3|UW zxuKt{A{%~pcleZm=>UkW`3$tU5t^K=xH?a=73I3a(9v}$$NeP>E7_-5D5#c19#|Cm zEq8VH|AT&nh2ekGk1#T@GO_H~_#k0XZNRw|{nWGE4+C!NKM6|1owC z%DE^}7Jy^hwyhJ}wr$(CZQFMK*w%?{h5o^<=g~l1p&33z4&1U zX}yvST76k%0HT-Rk?^o_p$#nT?(VMauEA}I$zgijBXdK70s?>l)74%J0zspz>2aB1 z1J%VgQwTyF135FdfmU{9ZD{3yqSeg`A=DFb2Zoiv4&3a)3~Vm|TYfXj*3bL`IXXgi z2L6JyI6AdLQb}1wO4U%=0F{zyvXKFmBM1f-U+uXEv9klsZ{oo*fof^<5H)?paBxAwN&vm~&kAx>{C50+IDf|=3VvpY za04Nk-g9iu{*~WYCIBl;b8Pi+1`W{#l8zTli~$wgSsr|5BxP8|0CJMxArhQIg>wc9 z4*Zp3YikEQe*BjID1_pzKQaC>Mo15sH2rR$+*I4#L4*8|`E;Nj*h2=z$G__Nso3A^`=K5$uBa!ctQ)=Ci+dZVKQX+4YISb}s|@)~wz&lP zYB(TludaITU%L=c{Atk#0{pI|$qq8C<^%bupZ?c8^6$Uq5whXmI225erza!hvwbio zr^b8Wbx%$$;2z(rzF)}t&YT$73E;0eu%DL)!ta7vkRV>6Q%RY}_*0NUcIti+nXgiR zxwIh`S-DJ0mYEhIhFA~Xa}(`XE#NqhIjDv|P%gZRk`$n`q3jAA$Mv`qawdXQpCu+r zrU&7Vp$Xt?ukOs+f zAAWlHx@XWOQ4F=Oi0<_GtT?@~ig0w>yL?1UdhLRUa2)-R-sxUy)LS(OCak(zHHQ9c zKdxH~wV2r@Vvp%_COZ^*dK}Ogz;Qw4_%JqVAk34lkyepzG}AZGDHJF8ysXAT$gp9U z68mG6QZPkPc3|Vx`Ojd>OK(MT)@kH(W!#&>U5gu7W9}Q#AGBHZhH@P^^dE0=6&O62 z*&g1Hsy+G+by2NciLDBUQWMtED8+C4@e@m`k@j@xfhGC}li6y*%XV;9o8szyTR5D( za3PMp zHCsuJx$nm@(#a^}<$q5qdUl$ZyLBdX*n};N;GqRESEuPPR-w;2LF31*A>9(^m6;{2 zcil6wt%ovUvMAw0ub|+0B1c5;KGF%|<(t$9>Wwwf8+vA}ZWEw{WL(lR*jhGR?ix*p zfz5g-#B*U+FanN|73mRUB2AF!qiL>5*gHz%C~=vu8Ez2bBVr6Ogb=R51MmaJ{BYq$ z>laj8FEyEzplU8wI#UDxHmk-6sm5Wn7gL&_Q6CZ^TlRgB=`6bgqxw)NxaxsyGiC@~ z+OSDEnAgbNQeNWAd4o1qaKgRKb15aH*JUCQ6?~5P`kaVO>JCkPZ6Nv^!fMF_6~|_c zfi}=NA-16S?N$d$%qQzN!tL{bQ+Ny5EJFwF1@cNQ4Sm z^|lcM$_;DV<#6OVB&*%J{VG=nBsD)XmPYZPl$U8mYZGEQjgu7$JZEgDU9v^NY&=cx zEc-f$!O0wgo2d|E2J&sttSCSWq&9&{JXPGk;?v&x$xXMeGziRQDGmsdF9Q zsJ2X%#fi#a!cYR#`NZy|>v$woB3|T(xHqvEWlw1Y9ClM)=5fipmp=IHgRN+t$7&OW zTU~TJ{dkKKi|sdEmj^a3b^Oe9-x;ipFD=}=pTke1fh8&LPA7;~N<)$a$qbWg`+td$TT^c}Wo zI-M}V^$ud{TkLT^lg4W?tN%D8Bw70bm8R8sgbRqzCp(*8m*?ZK#L`uS6~LkYMU4Kxf0{ zTC?%Oqj!PX%F()xiz3KoKtkrc%-{vHMkr-(%LCqzQj3n#S+3ZyV9KZ4=~&PKNeW-1 zXtWIV%DBhmPa^YjU~)WE0+bh$>+K-B8`>+FYbYLCd;Fp%`xWDdgYWZ`?TfE>GE+A$ zWP`DUR<-TSHfrxC?gAo}0u0@1(zzm$2nf=}x!kW0$p{7kCAVH+&Uine3vm~`{WxfR2@(n#OecFmb>*T5g`{t zD`R*VBjQHPoc;7MmH{g3o);|dXqoyEDF}rsAPvgB&?N6ltq(ieJ4*WaN>G-8ux(2B z@49bZOul?(eqJr6$wMW7;t#!;3JC{Ff&L)dy-IqC=-yZ{2_lV62>CD+sRw!F%sta!42Zu`K z=h^?NPY_;7>KU+xRF8ES z#A?`pI9IT)Hu_F##cpYLz{R-wHgl#*{sdL$ZQ+~3X-)sl+e%}8wN$b3$}~RJF1_0^ zvq%A%Vk3&Vkg(?DBvGWy>J4^EoFJVcQivprmyU2}m2qxWZ5$gEkiXOXx9}l8wEva+ zWbjs!qfrh+s2%mvd??e;58gZ@TeK!=vJw|X=QGUoJ}SPjyVxS+)8Zy%)DrUvtxGFm zlVanDMKOqwk?D8$DedP;iQ>iXw6Bz~OWf$oWjKz&adW^PoXNCoZvYYP2k(#8-cdBu z{E*cmvk$diOnzF$2z{^QeICb~jdFffk}SF#RvQeUA}r3G%YN3`o$G82Pa9vFt=~sye_BQX3w(|MGA{l zk!^N4XRoJ0T@JlmsT?Xu7V-5hp<@sFC-t%1Y9KmNqmb0kAx_kZF-fXUvGR`ckGoxD zWdD|pu>@#manfe@5QSDz%6Gn@^IY~b0qsGXdGz3`}YwX-(>c*bj3fe z^}l%TV5^J-DQ!Lf5#lRF)w{_Z6wc~bTqzF1lktCe@nBI2nZDH5PXVDdFg^K_E9j0f zT%9~|O3bzu&W!Di34>7oJlQJ8_|KjADevwHMN4@5JBi+-Vn@`Eva{9lkI5N)be%$X zLSrFE%tuYc%bk{o6!IsvBc6OKj;;Kj_sAGL&h^bTLaB~LC3Gar`1R93xKg*VCnDsi z7H&k$o(4zbOtle)#dw3i7Fl8?4|vo`ExHa@1(rPJa3Lvw<}C@aKRX(*bgzd$%ZAQN z_JsVsQ2A){y36dVCS?nR_~R0=OD|t07r5O5)V`mFsC1rtz1PydG-3l<12j}Z@sfD) zI5!hk>5zH1r!1P-SLLghdJy6J{F((;&>T#Rn>~$byemg?RwY)!xEeaMn?L#foe(;= zrv4ZU1b|ZeFvE=-+S(u&2K8pyK3ayeebuuEBp zRlLT;IvI99523Ds5GIj_dt^~CcaJuQYi|pr5-IRVH-B5e&K1;-A<~+)I-_J@6P0&z z{PS$2@K>$AtQ3Z0O|f24pDTJf*7k^}? zDO)w%yturhaZVzOqh1I!@n=bx6**UOo*EIaUzIZkP$_i+#$y!iDLMpvtakPL`hK{2 zj&9g>6JP0n01Sz;>!2RlmukSJuE{YRpk^f7xJa5Iml%u5!&vaq%;+BI3Tye`)*UDZj zNOrO$l-4t=tQoid!%Gg>*3~H0ikP-(ck3N}aQ~_v4R3`K)Q+ED3bk5Lj?ptmxAT)f zjOTK&^yA!f$NzwYpFZbvAS270K{_hLc3;!13#TFI=s6T|Iu7rA;WFm_QiYW!D?QF1 zON%Zru*902cj-S>EG&3xgDi(z{ZbwVu5b*bym$Sh714Zu%_$DU?`Ij({G)tHX)U7w z5>k&EwNvP$YC^LZeXWizi~n>B(1>+qn1j{iOWK$|5McN-ghff1JqHyswN}s77J~cf zR{drwhSa=JUl1*dZc%JO5D&7-C_VZKBb#=h`Qg|h8}uRKH(O4^BzE$`i0|N2keXN% z6r#3c@FDHo{jOwO{r2B|F)6oIdMzu8&}=l57$LGGv8Pg|jVzks$a&xVXs&mxDaZd? zT5~R1wlLIY0sG@`%AKM@D6V6Pe+`Ok&E559?L$73$Y+`UcOxncz-&kQgq!HeEx~ZB zpbJZ4L1Qb{o#Y5iaEsT-U;_>y{jFSllM!-lPDq)l=7dT-%9_MOr?CqjYt1@2lx$l$ zY0Yq@xH2{z%1`1$m$9$7_j8MEBn@%Oj})+!cRTXRX;S(B`bSIa_bp3ELGT&WLQ!6Y;?%MBqjgongkuXygatZE2@*l8qGhhb9Sq(6et zkGOx%!bu2Hz!K*8ugRb)FM<8k6#uuCnP<_B%2c-WH)vU=bJq}N;RUcFCoUfby)7p{ ze)_(9?_V67u-mPE_m0K*b|worXC3Cd!=m?!(ywc;`L>ZBa%5;z@QaLS9-TTwho^Xp zDp48j-o1^{+j!G6%ALYfJz4qwK7hsT->G^pYoIcK70ScBy`k`+MKW%XkF(W~=IRlV zM&}{pFy*pImVu&~a2!l`Dcca=J4ukGPd@}Cmjw{BfcAN$eaBhlY`!em{?;Fj_beYs zb=b*AdH?#J7p_S&$jdRBz+mpT4WdZ(w?B1?Ev5-TbGbecJjC)#C9x+huhGSr-%M^V z-eD+ff{bpb3a%veYngG)`M*iq@+`3~5-FAmQcgqXZ0tF$q2&*#2N6Rt5Hju_7gfgN zRs6C3Q%3NohoEo9l*Q!v+us8_t!@A|DD8!)*swkZwF7C1k=T* zYC;ok%~AT3U^%?FSAa!@EfqIOjf(I1UI2Cv zN@nWHf%64EbR9u;DkY?Lr5`u5Nx| zQk>nnixoEBP{LB;mzL>l=NW(W?;4e5F0}^-*y~Zq`@?Ab6bl6*h5Ev&(K9o~V=2U8 zdZhzqdm(;=S_^b7lH;O?^?U2cmRzA&X63;` zk|Q6?8~1SS^@)_t+cMTI%^?tno0}VEorlq9q4vd#{v(L$Mg@%|6}|^!X5+-FQ49&| zEMn`i#>7AoSEy)#FP($`QokogoYL)%NIaq8tPOdmx+_%%7pFGyMfn*$wGQI8Bs7)E zBti!{DQ`z3Tbio4EcR&3l}HsT|286$ptGV);hjYa+(jzulGc8R^t#d;gS?>~N;#Y- zj3{5z0f+k8{Y+SOPY$t@u9teJ>wieQ9s~LGOKo%=55&*q1XpINahNUg9#$ED3J9)T z16X^gt`0Rbejbar;3Th?`*FsH+S3_2GVhIww%m!_G>q}GE< zcB}12`hxnC28RLCO?Wz|wU8{u^fdK_`9Iu>k>g)%ipQp{J%@PPqj4T2?WgujJdJvC@E3T^S>BPatn zX6I-b{i_QuT$MKzX^Bpi?W{q;i^n{K0U;%ur#_L7$0*ZwGYyOn$2sodaM z2mey&?^#!4QnYjvqtS=--Px^)^CCh>=P-UYFb>4*_<_O}(G%ki|N4$B`9pxcC$sU^ z5f&N(mwPU>-;*~52|9B4qH`DDJl#BL#}{(Snw-6_*O7@GQWLsEp#{b29vzeT_#bA{ z%Mz!6uJs#~t~V9h6W%K~PMINx=K3>lbmo4>DUZ?{eGJY4Ttim#`U-9r z-}`n8(wHlh(M=1cQ=lyY1ccKx6b2&wg`$rkFc{%Z&e=a#Fyx_xTP#zfmo1iJ>oqW} z8bc_)>xx}Z$p)_ zH@s|9Nh{q&fl-(=${b#>1Ek*Rls5PuWWP{np1eKUwZh)R!WL;eycQ$3yHBn`8$E9p zZ3R)~$B;&P3VD(%(S9h_HS}sX4WYFjSs_5475(BTs3`wfij?@f!rEBga&JvTaS1e_Yz_6P(AN_?lqmA%j1UENePoTx^0POm3+(|4Z=osw=%O=Ar2 z47-(qeVo(4ETY!33vXJ3@#YKVuX*Q20=Uj_QS6_CBe`zyAV-|TC;lYGwWlpX)JDb| z-(U(rK+c?-p!J;@kk2G==f9{42?=K_;1oi?7NtY~FgShOgjYW3!C9%fm|Lt^QXK(H z->sHc&(w&p-|}s{V9~s$hO7tCJ1FE7yV2JP#hTM6A3o}5%bg>&Tw((@7G>A-%~+vg z+x#x%092oH9`}dCsZUe z$OJTY(tF=e*)azdxt@afO#I(N7u?PTjnhs|G6N5gQw57knl04xwZc)Smpmv~_KgEX zE$*>1dPCmKe)|u;RU?X8qgQM~BqGH~YeMwH{Lpg4PWv~gn1AaOSN)dExk*I+@N66< zn>PLN1(&{6HJ8`#1(Q5Mx~++LK5sk`(;%M9;{72mm7D#H04}4<|M45n$+Z!*AH8tf%vhK%p~ssriJbsYpTg{raIkYrKO_|R2QjBYGN$JNTtmTyr1lI zaB^QYF5Mb>rBZ@3WK7?IVIfG=XUUN*Z`lfDOD_(bM3=^%M)@V5WN+nUNd4AMoYE9w zYv`5!{^;C;J@rNd*>9}-=^*G`QoTK~ixs^t_W-vB6bh z8s9rM&DTD6u1}|-=%?Hoxe1+Q;`41Z8p?-!KN<6HfBYgLHCHDj0fP|oC*94zk{R?= zHeK9sABPjo7h>|GR2bc4^|-1PZ_6cKy;DEb!aMknzzU1Trrk)V?W`gYbB_Y#2s z5>PKD9?0z9vc~P4SHrrb*`7*7O-FPh>?b8C3jgD>m>107)$*ZlN7l-(cGwh>4ZbQ4 zD}1_muayTS@Yl3m@ly?~JRQ|D-2cpmmr#zCbGQ%3IA7TQ>5`-jPW5ZfdN1KzPA&7X z_G6x_S85x9ZI|YVEyq}N(E{hUg_tZ)%7r~zy5)s4z}-0XOX&NVtGmedfk;s**_S8j zRq0+M{>F=Hu0CPI`RXjM*!L4yg{rt;4_s_S`82;c*RrJADq7o^<0m&|O<&=F;-V+E zQnXGypT3dq9gXd*zhqSFM;g#0%5i5M3Vl3t*f0_7NPwmzR`;2<%1KB?bXdmmer=4F zNbhFNnuQ+wc|@@0r2`xboI8JDD|%aa&Olc!M`tQ}O6z3GDjz~|9+o3IS5}wkhBypbdEsIAc!tKZMYIIPG)N3yn}|_0Xd-2-hhz*74+yH3;cBq zRncknJKw=?Of$x(Wj`o zJzq|{#+Dp;(MRWVj5UD`UwJCX{j?=2jy0XQhwztgo+q?~WpEXE+RYmJWVyC)$;3>j z482?8Qe^ya-VShQr)GA(yDo9xhy=fYM9x3tE-vTcThV2HA?#J!X?=d*qFu!iZ^n}=>R^L?!%j8j06@27;@L{Fa*ev4a{^B9MK}ZS>RNTOCA`|Sx;S7-5?2A3 z`g>e>)C;Mc3ek(k(7K}_5J-2Y7PRucey+;Mj<&24u!VeX54HAduJ_--FWzUEC$9z> zGoJQPj(-7L$or=BomfdBcB>iH0jGF|$umsPG7DB_7$Sm+%YM$VP28?#Izf$0l=kHl zzl+=@?1)>Y+P*U50xX>UlGmzEO4NNPKdOCWs|l*Afe|d$bUD29xn7Dkir5YVwGKrp zk$Uf8lU+R&FHu_g}@-Mo~gEuN!x%U4%WO zqHR6@p&Rlhe&$G+=Q#tn0}xW#f%(Kc0^4*j1SwUF;wCd=KS9zJ2>;xjXacbwt|nn` zQ5gWgUpE$!w=4!*RvUnVy%u&)h#t?+rgm-rN6i3vs^A*;a3lF+xV={04v8>h&DG(? z1^bHz^{M5Er9n5X@p8>Wj(sunLS_X%Vh(HF&dZ(sh@-@cCCLo(tCL*PT;M>QG*h`t~>k7T)*wl5l*-11W^!>GM1(o1~*5|ci7mRl&MYw<6!!7Ub!-$pW~idD zFB5=>_HEK>4{9tba{BX=H>t(kr+oH6=FXxCdZa3=xY0W?3~uH^uL2!g^+(RZF_ zbjKRBt`Y-!c-?yzwcd=QLGKU;vbM%A?q-9V3;9#G>jS;cH#6xGKadu$Hpd2Citf(0 zE+6csk&n+kcWo1P2)lz7udKbxElj=3OPjH8@x;jbH(!p)FGiJO$w`!-7osiChd%xy8t(Ir^#Izc*{EXD}26G`H|I7;CQd#6w#!q>Aw z@b^(gP~u$H4hzzCEi;5B)77#YyweITC&y%xAE_C9ElmItzov!XRMN(r+5 z@mA4Pv0WUu1RKYt;^#5hTIpbHjr~E+`DjXKQ_N16XM{K3Oi9`u>?YWC`JW@-mZSyM z$`5ge-_HL&MY{bc!sD4&?~tZk5+l{gd1U?9X(6h!Pi7VSMII!1Xw=-Afe#G5)Wo$w zaEVFFcKPoIKQ<`U?p)hM?pqj64c`*z)V4GAW5QPQUq;}#e#FHTioK35jzk+luTM}o zhfueg--${VZeIZn%)c1bxM%0DJXdwyivQ#o_MRe>`RJ{M!dQu>J}M99U~fqbJsl^Y zE#|yUNLDaF-HF1H-Y*a{#5a=)*jj@2-FFrjvwcM|h&?LP6)Phqv-T!ca8Iy=_DIh! z{IbRRo}c`UKZ=A*EK%JAqdw^K9!Ke*qEb|PBW0D@L9HvG3(j1!b#TGBk1dINMUed2 zOF)#2#+McP;oN+M2`BK(oqa@o9Fx%E{5Q7b#-YG^!(Z!>I!aSBL_#9Y%?B@ppcIKo z*ra1E?MOTq!w6TP*^FSCM6VYa4_1Z4TkVYaA2U$bIZ2|X+)qi+`@uLZiaz2)g7e_U zC^faZ7rXcZH=Y-xl!b^DbTIDz055D!o&cPuauY5CmdTaEi^gf8it z)swvS(N4!o;^Z3-1P_|`4LT#a?gs-lk6`Z`jqZBYk2HigF%tdd8toLxwXF!*B;NEK z4ca|=Z_fuq(ym8P*ifmg!?R=u4g1bsQOc>^K~qlQRN(&gn5P<^wqMHUHu@&5N?PMp zv0GFOI)+!zvx77I!Hd_d$iQQ;y|4T#YGYEL@s$^@2eP{9DCrMlUp!?_GJMMU*%<7y zWghm>Hyjt5wCVOaHc$HZ<&x)#ETYyQ2mA>?&HV(};mX4{9|Q|15sOBvUVliilY-Y$1=+E2_Wx31dI-SNSreump)c}UGyn4M;*gH@(QiBjqG+o zWO0gD-TF(tI``K=ZECmn(MSC$56s)x2uGWvVdA$rEn`lPd)8Aw*LV(?>W<7;iINNm zjYV59mmJ_wHIt-}E|0VOz45)hj+L{JMHj&H&gduu_d~6=<7z&5N40L<*L_Jq5P>C_ zT|-&WuOmoOm-J&a5ccXg`mE3+C`$NO#B01_Fp1vUhz~LQBIiIi3u{Tb^P+_95`a|; zRl?hlDzY5-W?bb5hVjLl9f5#9g!EDSj->&)(1xYKc~*`8+6~bZwl24QY?R^6@@CXoOUM z&*$K1$HPx>?yScKPz?>2K$~Ikuc4LXL*%Qnonu7#xJ6ev7*8TxLd)nT^<(u*mv}V| zS)N|~h%9fCws}*>F*pktFN05BYl0flbCmLsf@L6raKGerGD6#Ut4CmA<)iHM^51{$ z8%td45GO~7mMHh|wNkLWHnjIyE2o;v;WMJaMZxd6&>N6aGv>W7afeztevgqKFFyLn z&I>yHx&4}9;~5A1*T0EoEu*nbFd^bOrlVml3#1^^WUf> z2+Uu$Jv6FiHdhw@9924)2|F~(ohT}uV}~#0_@_FYCg~4JZAi`mQgsA8YsS-A%C~d8 zrUP!s{p%O0G7J?ht8S$NSHH~)HAW6vq@0X4!7t-JIu|D_FEb`-ZMZC3US9b9#vtMz zyD|Hl1{}d_Xl1e0M)&CXqE+hbcDa&i3mpNwZ-URL?k)n}9HeAu=R^M0XS2;@!#!RX zP(OWb5i>Uy(ztQ#!!W&uVv>fBK`+$NV;eZs4fL4*#tlgf!%KbNeR{(`QGfGtoi41P zBvNdv;Hznb-!mxvS{A`H+^MbelJf}M;*j%&>6AUh1hYjDqr$d`z~Wa1tg<*daF7|% zEM&Ao@7KOPoQT{1@TGeYE& zJ}^Ew-GZWKHy&jBa?%f^uySNFcAk5G(m#Zkt{SCcbd9}lrXiNJ5qrx*-CG^m#WAwX`pq$)BxGL(T`y>Y!cWl`XPbF;H@6SEs>gOh532L&YPL`eI_ zz+jnLn?S(D0_bg}=w!gE$uQPHQib^QlM@hy=hn6+Rv?KjY`~jbpjE);FY-V+znnm* zK0GSZ0Zz{5Zydlp9EB;<0wXiIS9ZV;ht)$U0_dv1hsCkg#XzJyDuKDn0w?Yae|djR zLFID!e*WO&51a&~$1VKQ9sO$k#&COmjT;A=nL}i1XLkU_2A!t6H^%-h%5DCgAsDzP zTwh)}=r0O@;`$v%6nstyUj|Ys+z{BPXJ>~I2M7YCRrc0})WFU|6FE4*xHf}UVr_8! zmPDqMVGEAzj-e6V9Dua4f@lA<&rhr_jy?XiKmD3Zc4K{$#x>@>3mCI}LpHmnH$DMn z(`a{nmGosL%?eb15c=vPx)=J^p=LQf(OKYrs1rtVvlCn7&nCM0{K`eX4nEp6F|0~RiOn{o+BUC; zXYhug$xm;M-bI8tN{J@X*W|G(np5U3%#97RRamFN>`S-ukB(pF4}2(hd|edCh}~PS z%*U8_BFQY8j`?4)xL6ZvfoL+9R3j}30kQ}A?ajlKJhC>U0eiK?g)l6Li2G3liU0&WftA;svf%lj*+=u&uuAL-jxI3f!`h^=+ zQuLCNn}ssKVAvhaqC-KsZuLt`q*dwZwnQtHRUxQx!4UXSvN5%A+o@VD-F5CI8IgF6RSNG(BaBcxNrRbztKfYU@>GWS?ZSiKs&e*6+rBsA zFyBN?j<46fUncVFfQtr>b};iv_Mk1T?T?4A>y<+aeaPRtdJN41gqV~zd~xBW)t5XV_d4W6FtzzEsZx8wF%dR zCW5Z}Eu1HE?96D@>aBR(C*p0}_R#s+~v zmDOgg()7J4N&E^7Q9@YYp@xIMJ2MtfOZq^S~nIxWm~)~N#@Xq*5jMIumjLk%15>k(p9NJs%A`$ncZ9j zoFbTbui>7jL=6ofJhZpU9#)Xxz^5CF z%OWG+*6l+y5WFTwZ2;_y)px5azEjuvqXNu=bykpAJ@GqDO`J!3Cy)BLrx%{^ozaJy zbkDm|;CQ|^h)p#;11pcb)v{nVu7W>8fpTt8!IRI_w6ejU@S2^#v>oadfQ=W#p0L3+zwC z%+!v*_GFn}e#0;Y;o`it5L&QFa zcD!{f%NV0(5+V#Z?-8_3e~?S3h0f4=rrS8w%VrqS6y$c*=q~|{H53FQvpO*Z36++^ zPAz=IR`#r3Y9Da2u8TiEwTUUAkUN#@NywY9u2+ef%}@0*+U+1S^2(AwzFbJ!wqM5x z`R`AJEo+0FsOj&XNW~Pq7kgv`K61fQ>_(zck2usxusDO?H-!$Tyx`9Y2d0Xhp{S&7aMT1hi4tA9L7iKng$N78E zrQC20k{?qU?6UNnsw*DCh1U}302KL^+Fd$_r+#WR{R!R( zfBer^is^e8`y-7KRX!K;!MqNO!Lg~~m?Pk=jK$Tfj?yWq3GoCaUvsw8kif0GS1Pbc z)`}gbqT2s(bFXNE$kn3)+iCe zi+F~>i%ET748{v;`W3G%2pD+6X$^h^M?A!42MWX7RA`G}&8(z;CLX@}MJttl45a?_ zgM$h{qJoUFj|d-(bYaY5vfYzD6hzB!bpXS=bdthhP!N;3LG|_GzUW!Xch)~#p&1Pr z6^Laa+^3|KLB?Z^^FbVT;tyLrAe@s*4~qo?ndX5|7BUfM=(c;8Y+Eyx80tnDA^P$} zBmMYhk02F(PgqwS)oT@8pif&E+hejW?icF$GlT;hZppwmdLUE{=}Y%?=azu>aAGb8ln0jP$NP?=?1cJkW$m=N z%;lE+!V#Gcl?TT2FNrJ(qEPVjdd+c06kG*k9^13}5Gy94U7BMg{(lPrXPx|PEM$F^ zEKB+8;1K?2*O&P{KH-@0QK9{jPutaa_PVtmrv)R zAi?_tvZaYhgZG90sdtk9$|sp9$d1x>glot>2DDXVTqlqe0MNC~F{B?_ z2v-4g_TC4Km;`bbJ*hHg(wyZy4~4tH=F6!K87j8TtR$|4O-C_wWPkX+x+qY{$2XfU&O6- zB*{Rl3(ycd|IOd2jz|vEus?3A%mWV6ecabgS%+|Qf1*4A)G3u@a-fLx8vOwp?ttw5 zS^je$Y0YgUYN8qe()MXxe33ciO)JtRr=*iVgBhU)BAw*4$fDqt(=Wsh-f>?hx*^aM zw;rmQme9h#@q8JKRP}w~1M-Ntw;KP@2>M%2Cl-wK6Z=KrPKRf+zv!%XvIK!x+GZFT z*4lk|VuJG3x53vX?~!}`!fJ!qcQKOSS;1IBa}{gXaEI6KD9$%nwjkZ*z;yZHCRW=q zQrStzTW!U13wSr8iNxK#26Fm#RxI@ngRy_pfHG$I7?0?jKaI7awXv^nJWE4+Sv-m* z83V0940b&r2iDNPX%^pJ>;;la5E!hYoT607e~f2qRA7P*{S^0{fs)_AZ*tpLP7q{F zA2XXAYC630>ef;*jhg>$w)>STJ*QMgy~a~uuT)iEwxBoZfMb|H!smxM zRCJIQ9xFOBabf4C!&T<|xX?4$pQAf+q@1Y3Q@E$GVeB1}y=M(JGK~AxBV3;AW)#&= zo3VU?uT-2T?*VaYBFk58uN4hS_os2$yZ@ckO?3ntXgKujkHFtoFV`_^^X&qvU~}aAv|P%kO>yPcsBdBmd#DY}kjmV;f1XybaoS#i#(!O*}pCnD}7= zHr6~vXJo6ZOI(U(_p9P-mSIupxA4?0ctDOqqW7;M;|!Qir!7HqPAHb>O3|?tei5`_ z&DgUz!W98o8H+lGPtR7zx7urX&zc>{Ue5q+)3rLFZ9XY@OLz|AvNx5t-F^L$oN&$} z7Z|dLWDxDN6Ts9nM{(TgGDr({RRuc>%J|RVO9oAw0?r=~V?R%OnfQ}OMKq(t;a0Vs z$CuxPQ9|6`z~=|F@2tno?1|E;5tN==s0xM+{^QJ<@C?8#eh#NnP~ zYs!3WG=PR;W$7yBhny1=8J}w6FN2qSlECC|ljn5C@6ISgsZ{{3HX_9Q)9Xo3 zs6f5*K{bK!1o3Coe^XoY!y0PMkI)lgy)-CSFx>1N)d#W3E@S7fZ;l-p;+I~q!Y;5; z7)SUIYNdJ~>C8+RuB9K~fo{PI_JW6I^FdD6<=wfijYWVazyy|J-{R}*YTSy!Z`1OE zo4ueOALt|R@)j6C`xP@P(TG_V;{^WA?aSwbW_qfQ#KmWs8c2b&XTeSH|+e*Eysy%$jjqfJ-Qr=3gui{WLtI)dQAs@>#j1B-l z#ElTrWNPPwvd=WAwM%vQRZ@Wae~*es8gka3$-_U}mbpRA)#$H=xG#baIe~F`=#@Z{ zZzJe~wrE)Ia#VxI%$bUKu9! zs;;Q&dq+untj<2$(RqYN+F}uuP$UG5|5v>GDz84Fl zh-#~M66c1uQx{FvF*8ywJm;TM1qzwbB!+t)=aq-d4s8gR(1*b^hwLz#&NbPAz^@6y z1l8r&7x4XARD1#-W-FRTS_PEmOyb*x42+q)I5v*%&`KMbT%55I+?1ItPvSV{-DiWRIC6S?p8OD(~0hQ1w?H}Ah6tl@t9EG zP($CHCAE-WG>xB_>hrY%*wUbI#oFMHu(@JCCTLMdy5Wzwnns)p-N`XiXrN8#&3|ls z)`co<8PxO&ZaT6&oY0}P9i-)%5WQ`;tDy^e%H~uNZ6bXi)&>B}I-1*#)5EGkFfO1C z@m(B1tPK=v+B=WU`19ZTPWXu@P6Yl_P<^p@&ZD@j0*7LTrGTQNC@A6VxR*rOU$bas z@*P|9_IQd=W%gH^su)Jt-(fKt4#OvQ){x(MQn3=LDwmO2o&VX&7_t$zJPGPJ8%&)? zNb&FIdE}`q8>xk25Kttx?n(6yeh`e`3b;_qA}kDyP{bzvu+Mt2QrF(RQ`G)*BZkKQ z%6Mn~9qNLptm5%nQywkU)fU9NkqyOggDH)sF};p-7RZS5znq~N)5f+Lz6(f~)u_?& zd;Mv?%0NO(RH2{u$TxNUu$8TyI)iA~=PbBg7;r^+TKyzA_3)gkhGx3HysHDjuieFk zMX{bbB`Osbdrj9|?Zmys8Z5H&2gfhNqKQ&_U0}9;SP{Z><$reY?8}m5EkF26k{CV} zFKGIVH0jx)5_SQ9lnGGou%>rM0wbzcBlAW*FKJwuADM5HV@8O=%oQXy-pTD{t2n_Buli{^U>JpBBzL53@uLbl?(s9JmaITo6(|eMCyRpcS&`+9Sq-1oL@QpIM_XFrcr zBUP!rFLBPk*ES8`&W9&V)6-sfUbH>x;=%RIK@(q|5C2(=2`sB%!l9L}MfSMdZV$}d zvlK&&E^NJZC?@y2l_VUJ+wM`#w$;2;O`i5u%`_gP21=(woi`Hb2Jujw+d{7PblrN^ zNUBD{VK@{B4bjmES!F-41Hls6t=1oi>V1kL@;ZH;Ld=Re8>Gzsumn&kx|hs)-nzbg z9&-1IMb%<$SQUm37+uWTG$D!6YjXINcM>Gs(J>TaObXv5Kr@C@(L=FZ;efkEWSSU9 zI45}afui(lU29?4PC`H%CdU;wrq-wuV1n=>WPe_APK!!48(S6){{3@TcNxWg3o)!x zbGIR`+L6Fkz8FIHUsSAIjc>@1D`Pwx5&c*#STD||YW6;OP_L0c3;R!e*G_6Nr@{A8 z59AK+8Mr=&9QbQBRon5A51V86Dkh)3S-B6v>d!kRFQ6&$C;ak+clC?{)mQ%&v`ov^ zX?`KW$1b&4uLqV$wpmaF{}hwWlU@w}G?>9;$*#8*pF0NgjyXlRf@xHVSh}(sHrR?# zEZ_|xs0^Cv$pb9DBCRq6j3mRJ6`Y$i-q4*bCT5$DqgV+1J5uR1wTTY-8laE3Y}GWC z&fw`k=8yPrODBpn6!;}g8nmQebWx$k1IjLjLTHA^Y*RR+3_e9p zRxWhcm9qvONUFmkFCh?4+L4E+8=@nPYHw{>(yx53m(`aDp^jLJRT95>c^oN1X|96M z{3FPiCn(9DOcl7@cp5%P*6y;l#)~Q~d5;1-y-*2@{(7N9JbRA5ZUTJ~NpWGoA$@XP zGt~x1luF@deNZBQbSA+N>8#4FCpP2FtD&Sxe@x--WoXudLg~Fgy+rCP1px(Fgx}5+ zwZR}a7FTDB-UTY+b1edrCAO}U05mH#)^*c0F$AV}Hfa;tPg#CFH7ULU^~r(rfd{vl z`GBoMa;f_he&k9%-h@CmRX}O{IHK$?C7UN_pD!=h;o32p-=Y^#U$v83%It;9?h@Y! zN9y*1LdsQ9z1LGbb8w^r0d1x0z=22hxbS7HXyZQ_7#3h$j8iENcyo z6&#&oMm{^jGGr~^E;Y@&13@4SO0pX{$?e>?@Xc^OI`Q(F7ionO#5CmWa4qyWV(Tan zqdl4b{N!3RDcdTlY6*3TYm1h zA<8a8i!b6}S#WFG=aBfGatWz#!;azPUB6Ed%#03>DOJH~(7A%DjyY*qr)Zzx#+V*_ z4_%j;?=shBl`GxinNMMZ^~hq{!d7g=E4-Z~X`hWCB-`5<##d?Xi@ILkf|s6|H2>I7cPYuodCrK)*r}68bLokSP%HxQ*zro9 zlY3es*PTY{LUkH&SpxqHPu#1BJbk^6X@1vH(HOt(%1kV)^yfO105b@4t{sz(_2$u} zAH`d$WtCY)dfTm&Ih+3Bj*hUje|Rou&ewXn!pirNp#DIBWpf`u6k=MeeGnljbxgb) z>_dkpEVlcGUl#M@wY>8)dclJes;^FJTSPj!#mOz#8$l~;zWo%HG>zqU(RL@FK=Urt z&!2n=wcxy(Qc0aeEuj!eo#}oDBDtNbRlZEZ1yrhnXEJV~;6%4D(NjgVhR;<)TiHl` zvV!9V1#7+*S5t*?lY(8f4En?D+8|JjLRHGbzUw8@CCdO~s)1*qhLtrTJ6K(G+cB69 z@uo$M4_d>gD2Lp-=j&wj}X zo+IbO1mZltRbTP>%~{IiAZN)m13iowl_BuzRL@1Jf!eB-7?eOJ?b zE}m(bNvjdQ#5D; zZ%K6yRsdR1DC-%+SeaQoc})zp6Vu`i#i#EQBev8WOwReVGLgaC1|`LzRP?|hyn^@2 z2Af70hQ$74AIYN}dM3^RdwN2WJ#4K-qHCD-wHKcJ@Zl9|Fx&0@e zGs1=1Jux#p`OmK1R0Lfng8IZ7HYV&~n4e$PFov~guA@79pnTpWrqS%w(Yefev$Jr3 z{aBFh&WAUwh^RL;!yhSQr<|vV{yUS9S1@GmJYJ8>G9Z_&IoO1BJaZtO7taTz?lz;y zN9#W9Gl?ZYn;sU(ZT@j5bWAr7_!@p*rM8=&5Z=eNk6zB3plA9k_%s*d>p1(a999+$ z4Pf4)@Z;c=Hu*|Ki1nO#Pp}JmzjZ|TStiZ1AjcHIQ}JEs@?464A~9P8)W)t$Rebxn z7FG_9NQ1E|o(_!q%vh-e(EOsW)}3CtJY2!|Nx%7CLqyXUDoRuHRkv!qgH%jj8qsf0 z7rRGuM29()a)Grs*T)8u@9SuG2I-)2cUd#cv98)DL_wCPBypIj8pO2d)%4P2Gs-^M zr_12sydW~53@6Dgll13NWxf3U(cZf(6!%T@<&esPZP4|yUH<4V#%%&BnZVl z0d#ow<-jgc;V_AhHt5h0I>2l#+Y&44Hfrmusm4zY3(x)I?e&WBn=aG!H2Ws)soArU z(t65qhy6)wgx$*VbM-z}{A>1MX0&oKLp|73KlP<05p{%B9(ZH2t@vKj(y@JHfSM+Z z0&NM3O~%>&Mpu5~+mIQ|!Z@325^J3cB0tb%EyzopfzVQPZGjA)RiZoecHgDX0zsy_ zFnFQzS^8%AO&uA3xyO9s*}j1dIC$EI3TorPBwZs#rETr041X?>0WU<$#*M>`9Ff%M zM(v54CEm>NAfY#~Y0O_Njv@mj^fPR2ff}CcMrvuu98I4lwzZrksSf<-B6O$?PkL%DrFKfVH@%iH zh+?jiGU;LL-qS^z2sCiV{+8GD9;@I<)&!YiHQclon+nyyzgbfJKrsEsX<42;ITJhH zmPWYziRs6ze$LI6_+Yx}p>}qluD=C2%-cD*Prt=GjO$LATf<>-(8bJESkGHcUS zsuYBw>q*(0BbW4QtvhSrH`da-lR>;zX*_Xz0Vd$z`X1^|cPSDiurw+t$a$bJZ0q;| zcPU25X>zkdT!9%L!Z}0KXbr>zgo%Wri0*D0j0Z`|M_x30n3&>(!*04D-i$nJ`<|wS zO9QZ00HQb~`(?}~OmcIkd-S)noaMDZ3uzyq)&&cBGx&Ph@su;bNs8;v; zA*u5FEa+C*Mv^e%gyRL$pu~;L9PT=!xW~~BJ?3fInf~l(KZrr;+e4XHKu7k09>`4< zKWTjp9Snr|sCclj3A{x+P4#9Lx|W;!{EWMw(hA4ElhJ=QUFYo6)ROkHaC$m|mh%bQ zOq|?ciTw@a=Ho5((gL1m(YCO;^i-<#O>+<@By7Xri3onaTS0mYo5vP0@n$1t`SxPyhcM(68o)nZ3~oq+}Qn8{7(=;u@cAnEHt6GoO!*&=0JJ-LEx zM@3pwjgBwlYP@M#=5nb^dyga+)rt?Ec{NKor1cnXb`c3LyCY_qI@wt>^CtGu3}&V` z0Tb5q@6%GLm$Q`V63{3fE4?i8MOc<@Xsa2M^z zpW(KhE3(JU{8$18u{!=4`}VAm&8Ak$$Z8Ar=&0(qqJf6}9NOk4bRb$jznqr*dkS-n0{JPpQA}uC)j%y`#T4))R$jpE%~&=n@@Kq}d4U z5^Kcx7pfdnFWZk!ekGtjQ!PLcniFJ+rX=^_D>-W@7EGpGnKl|_nUb5mDE?$OyLS-o zkkS^9Y6pRlUFywYWNi(t0zH*LqPbTvwtWfu?O0=mSpi=y5aec(zGwoh7G1lu{Tq`l zYXOo=^E%0W75#osdq!9!>K%9%@F)Rr3Oi%>Qb>uZJaj;{0PRm`u!u0_v*`qT zO!2?sR2F3ixT@$+A}t1NIg?Ss;5L%Q40$z=Zw-gr94x5lR$jL)CBU}MP~fsv zopJBs#9GZ6UDO#<`(lUPu(1RgNq3o)VtHGYO~AJgCRpHD>cFj#nd!CbkhXADaj1L1=Z{3O)H5+A-KF0OO%rMoIkuL$#+?yPLKDM`J+R3|oGHnbczN3ogdo+Wt-o6M&iY12>p*CG?W z!>FglNXd4_xyq(jvV0yD>NuHFV#8xur`Dp+VXY4-%3X-6waB~VE~ONZTcRTP9wX** z!e=aK`Ns8q2~d4)hm*kC9aKOvQarcTIOLdS%#SG1Nthu>sxDuX>_f;a z>|d(S%{G}ro`L7qEA&Q=-aUi_f&PQKqtAuxu&wVy75gzq-bt(?cRf}wFAXlEzXZBS zh>XHKHFmDaq%9f~4z>nFU&Jp3!u(7Fvm?8I24r?#(onL6M!zi3DjG~^Sc@Q<#Y@h3fwI+n!QC%;_Rk8=+1Adgiv{T zolNFrmA7|pc#t408To1>nn!+I&~s#fKf)BpxVwsN6Lm4#W&7GW>PeZnFH*m_bJ!DuTI-A^*_zTc#P;rDF8hWE3Ny66ynhYml3^%i({IWv#_u=nU|Oh-ATbT#)Zw-FVP*dF` z?qLp#gz1Nj|4K+X{9^bExRj0+XN_RjP`WCVM*=fVz$oRG$OmG5dmIu1SZYXIo-u`{ zX|>HI8*A|jKS=yIU%;w?-@_dFe|kr2eQos%ungy-Jbp=rQl~8S2V^<@`sDQFqn?^f zt|>cuR?0qg&||8d-IwUQ<#fW9EAI6X6RYvx?S^UzYXV!@@$~dMR|=zFoaI|+dPwTW zUK&X_R5(Ee{H%w@5KYttaIgrUwh-!-muzuns*YI?XBTn1OJt!zE+0P$POj%ZuC~?Qi)^;x0-A7hrW?cqE0i_MgLFfsPSL6DWTOofzl5& z0Y%&`){H%+W+8!MUci^-2~|OSek!DLG=NT&8uTM&V6|`J*PPD3?9DRb zu5iGFL~W4g-z#)RZ$@PLP>9OS%{g_Ivm7O9WFCt)jNe3gbJZlKlMXjW;3SrTRo5nz zgDQSiFhEK2$BUnKZb+{8c#q!K)+|}s%lV$W?*f(%LiU>^7SB57Jxykii-HRS<4bek z-9yUg)J&ELWVX3lt|KOLKNsi19i=W;)3B2wB&j2kg^xYTXnUjpR~!$xZf5%{)Rw+v z^$^Hw#eZGiU*wAjh=9!S5uR=#jJnIT39q{ud;%FBC@ zR-%>F*&8O77#9?r4X_q z%EQE}T@hfTPAS~P2q)xNJMw-J%Ja>n5Yb);K6Z*D@ zsR1CLHu}24p~T!xu=KSx{K9j)gEWWNFzZidkXQO;cyPBM-9@z%4ow`qnhd`8l)90ijCCJg)1z$#Vz|z3EQ#Q}fU5ssg zwa9wru=s`rI2;DeEd7^TOkHD?S(g}b@#W;zzNDUBx4-o^9|K~njRzIVquwusYU7UH zId`8myDn)5R>)%*%sJ^%3J}n7l1XxHZJfVw4j@NWnxSy#Vf-M0II01)_aQ9t*M0VA z{LL>!-+K+Fdx7M!&sO8HG8AxPq@Ln9C(Q4-#J^0<3BD?-80b&P;#O zX)`>;?_@H3wV0FKle5=Mi4Qqlc>B+-S|k5Kie0@)+}LL@yEfvJj#T+j%gSn-y6Nkc z_B|%=E#ClH`y!e04odo(3Ksm@5?k>g^E=LRAzr}q1A2@|j@2`~)DY3fzV;!V9X}v3#49kLF?bI&waRzgPsOV_K;o_{Cw!fgvpqoe{l%VTl zhHMx0f?-5?D(q$Hn-uiKH^+@L|KcipDaniMXm*~>R(`~+`JdWCsJQ4$P5raMGBs1P z)bIRH=!2?|yPQB1UKgbWm}LDu^lZGg99<2AsBUV&yts$*kl3yOb5cOUbC`%rU!=l# z3o~=_+JghegTjIyv4P>*iKt-5f>I@v#qp z+>|fqOy!?fae2*GaQi&9>MRguW?!Lna5cDE) zNJ5=y{sA#-YvHzw@pe*>cnirn7M<%~kd(|?;$7ir+95VzNl;f7{xNkW{Wp9Yb-A%_ z5sJ7Qo~HVl(tby{lvI61-w^_t9~EG;!rc{2^1{bPX;~}`;zJX$&dzJW{_ z^}{>K)R2nf<;u%gN?ipi4y(M@6uK(SvToXuk(_V^yQ+-((QDF%CUVF6%3NMCujPH4 zgXZa+{`0Kkt`@QyH#Y=41PU)^O+%*MP8=g~sBels?l$1WGB#~HZg+b@K!^g+^1lmN z1=$uy)uGEe0W0WBE%%zAjBXqoSchAxt(zbsLVH!wZgE)*o~7lDP9^`?J3Em zvAj&`W(U^7p5f@1X?D0|z(#>IXy)}5ZtNfba=O%Y5nPZJP297X2`&i>AENkg_Lk>q z+-O8|v7_@dF@0wbs~9}v`cE_w9B6pNiD8x*13vb10#J!eo4@bV*fz)9{QFs^Q z$hc`0(U7b0Yt*e0wZCjdcUHL;he0g$z|QRvQ2}vm0QtO}r&}k|42MYgKwwh?DDJZ{~ifg7#Uev{y)Ja zn@(c~yO~xtod4mFT5ZYQy8r7C*gBDFHrQ^ts$F}}?SAooEmwS6{bF8TTI=whUSD!% zW@`)%?267TEo5ipW&}ipNvI0R#zaI#M1)5KpoV7aEKh8&gYFy9n_U~t3Kv`2i4|Mj zN(@g64G#_v!wAcfT<)J=fYdktBP?Vp`E5&(7+PJ2F#vZUT6Cy)aR5%&LVW1x=z#3t z>|)~RfMWP&mRQ-&9v_*^9tSe8mLsVwFQ%;_kQ5=U$d@Crw6ni8v5_u5wlacdAWZ~L z&)nk9QbyL~;6U8?6(?kJsb>fNhE8H0>H}Qw%HZz!2A&?A7>Je7(~;E>QWT7l&`DO5 zO&(w0jh2wR%sY7fA2>-QE332po0^-8DD6+Gb@VSq=9l_s?dtdeKLRi`BV!!K;8MuM z$PThT%Ms~;3($u5&oAgtKe##Sf!_pTOZ!(Cf5}et;2g$0NJ;fde`C`Ey?J^sRMbEGUG7fCpAZ1NwI3GuglimWQctXA{e^?*1Bsc zltEj9pDq*oYEZI8>3ZW6-KB|d$`i3P(-?-T^K%gK4M{aE-=?(Em2#oUh4)Yf{`@M@ zjAjVhPC7*IZCy|>I>_C?PNFfk7OE;37hXseL^bK(zH}NSTY?4Do=ocTztWMzTEa?q zeOu<;vgHul@v(ivQQfBH=N>b(mCdLvv-kSPS66s#mu2inh*pgzGp~lv^?i?0LIxts zHf5CQo`uVdw{6p=(zR&RNkp6Bxa1!I*tL|991FV=W2=JYzxnEpU9IVEDTY7Ws?90%hsH~5^36kRIf8fIn`bdRSf5OODXMmt z+T+SE(sORZJ#B!tq(vwBlGn}GFCfg1ho$#8SWq_Ca;#I`8rm~`%REThXZVQB{$pzN z;&W)GEhu?{-qd%BJTOkoqy}B0 zyow8afa5PI=9>wSQoKla{(EjGhP-mqDrPsMwt?AGRyJEBvoWKnHsMChb6^YhR5&XHWl3P?8;Vt_1Q2ta_w85yXe-$_@=6C8{aW@{><3 zRNp4nTNJ(xM`42XW3CAVnd{@fP=S4V(bIkOa+$l}Fg`>3?}rS5oe`~PU1RiT(0Jpm zSj)i#MX8sXFO3v8f>?|?!d!xX*ef^;k#=E&Go(AnX7yf)HnkPl!YW4wTN)iuoXZ`? zSIxZep;j5oITv2M2+C#*pwzVGQq$T4VVAFOK>sZXy|g7nGkVlzG|G>WOO}1{h3qA^ z^x4MO=|On3Q-rFBQFPJcbF}AHAmf78z42ZA-c`D@-rjZ2U>B@R<@ICf?&w$ zYm{yZ3qHXTa$bm{M~TkJk)d5sqzGZ|KrXL1jAwQ_ z%Jz)kN4(U0Ky6FPdjtlI7CCy&C;0ii{!|uWukR1V+orQij$o~Jy85nAC9wL&kn_Kh zW?uxL85YBc%`fwvdz!U~wzx41syKek@XKiQJZjZqO4WUw47} zYFJp>f>EC{bd@O?Y0t?C3)_#Ncz_*C(>js9`nqZ&C5N{Z{k$=)vXMIyu4Q*WMNykC z>K)bZy`DLoA4ecuIQFtRD~m6E_It&Ab|mH|P~ZhQGnQe0N_0aG<)4QrU5DA5&GE@U z1*Kzz5y2``^@huY(5YA`&HBiQz!N=Od62htt;%i!@8kqLE6^LD&NWZktgBvpciB^= zJb`M;Op6mi&7`C9;8e!_4FrSlrb{NHFeS62Bh8GE)DB{D zddLtf&T>$qfO1dFGK>tEH1Wc5|XiG z*yKF^B6Q*5uR4n&`td_e$_14-l(aX#B%V4R_|bM1+7YkQ8Z)msZblAl2}P{gGHJ4c z`m!t!QG!YOJ_|sHQIz&9+R4@aWey}#14BI4z)@f_e>xv>S4*bG3`ZnuyC9R~#FpBJ zdDC*@n)C<-lf$7PI=3f0aS{zXe-M0HymMJfr|>z^4N$`-^@7B&Q$oK!W@hTnNHk9_ zRN}td936Gy|vl(O_?`g5aF`4Z2woVJVI>KRWdd0h4GSoP7- z6{mwP7gRtmGrOm~ms2!9-q|~v2VkqdjGN~3ZlzWjX1?;RGDU=;Az&}3MTRnTo~C-D z$33rBhyjBfnMMv985Sgx-xI=38$wn@B$$%D zd*17>m+ED56v}HL%t6-`K7&xvH>Ox`S)q0Y|0N-LZh|&Z)&@8ms*abZKMwBRH60DF z=#7URPn;LoG-5r^J{6etFbJ-yc~*LaZm{TUj$Hsn57T_VYz`5{w9eWdV`QLM>bMsY z6tUQ=HaEy+(A^WRDy!u<1KhkQ$clkhPBwyiF($ZuW({3O<*~`>#6K)&3ACcYFnN7#ovR zict@%v--u>68=0F$9SxRi&<2tiI&f$4p{p?@d^;NBCF%l?Zkd7iA;+}IRHL%s1^pq z+PCh7bVTM z{T@a4WRUpZt8Y%LY7kI+Zgxqh6AOkBLp+H4%V6a|i))w!v zoJs!jwo+l){%ggLFC^j^Yya^i1`a0oKGI4ScL}l91luxe9^-{~u@9BlqiXg@N5%>H z#Z6bUApMmBqVy!x=l~nOaJmO*h+uoRzePb{5Y2WAi1Bc(51=ET1ms&AycaWBN2`}3 zBx}R(OBGU@7Sp^=JgLaz+NPI44IPVL(Qd<)Ep{_Xj?@U1jE3LK8;K=zm96k~Yu;>+ zs^MP)`a!vwM_5fF%vvqN{3+SO+61j8SE)fzvN&nzK<7L}o&vB-VAJ6Gmi7N zSK@0P0qtyIbWaBkCbdx4h60b(*7%`eT7RhjHxju>2cE=NU)CWz$}f`fD5>CxgAQG7 z%y$(fUchEn1Zv8{Ms>hL7e5)3|8NJINVNa(rBOs`@)2?OGz$(A1?mYwN(1hruCX~? zq@BTw2FQVu<)(MR4EXlU#6aFX<56F;Q}ZL7kx)H&FA>=|4O~iga4Li_vwA5EnJx?= zuvV;`@a(NV^p3vAcDIM-4d;x-yCXkBGh-8QxWhBmso((JW?rJ~V~Ct$55J0)r!B35 z9jq?GCB7R@IK<_U^AVJg<|h?-HPXh~@G&5Bg`s2SOKnshOcW-kzLCl$xZCIfBIbHU z>9ol&BonZi$gyj}xXOnvdX=G3L!@ zH}xchJBrJ_XqxTbKH_dgcU0?mJtW3r-bBt2m0GZx??)0(h;}53KF?&If$;1~PDD_1 zLfY*~$l(LKlv9T&E$p)m`nsdk5e)+z2+M?|Unv4??^XzVpzN+T<;?AViSDaMHeh!c+6~isa0Yqd zxfOqRDNLX)-#DzM2BH-@BQK>B<~X-|qEtLkmoRd0ttqjY@6 z3Kpl1xIU!Kr>cUnl4bOHMm4Usd*i{$Aw#=Oo_5*E=evAX&o2Yxm)l;hy?XQ$3rbAvzAU2c>KUPoef6(OIxphAZgc;6$hUzND`2fxa7PZ{drg(vjip{?cNU<2$Pn6Bv%1>cGS zMp$zR5!delHaS-F?)b?P=Qq%hpxqW3h56N=a;+)CJ8Zv1J`{QUa^({i41jK+XD+w) zMZ*t5orN|6Ccqgs2LW(vZsVu!ns<~&T|LYPG*R;tdbmyItr0G*T& zF71MLf~p~&T_tP3ap+uX?lkbSygacO2x*{$=ZBWHxj*YbpZ9*IpT8_wd6a$no?~WD zlO%~DTaH9bo&EvOSDuWc!@`VF65<Jfv1KgAZB%UfQX$v)sxYjP>-dx6Z3&Y(*1!o%*&PWYk=_+&i= z!S}wQ5GZ1%uwp^I8W-k!cG7AC$Y_zy@%#XEDVN!JJZv)2mJReYt(9HS>3kQ<@Sg;> zM`tg+6JrYf5G2LS_8SGfLeia2X@C?qsVpQmP3#B=iEf=# zy96XPm358#fkc!4ktQp){DUcK7Kr6`*n!n;tr^N+PlS|S;=LPS zgg}d9dY+8(=3Op}He?{JDbelSM=5)t)f>D&a7^^tvBW-mz zDmZc`QAy5v_?hDAt`(|AW+M8G%AeE+*r>LKRnl)jpI!c06c!F#55z}}Ml)hyHYg>` zM@3V(Kz2RTPBAfZD2g9l8m`PMsIpjA<+}ueLc!|U0o}!FSqKIP(^me1Yoxf_*ul>~ zGO=cE6!P~z9(kcE-b<~M(l^h7xNC0Y{z$`OO%M`5 zwOJv0bizzxw@sk79naZfG6nv3|0hE#&42}d=sS2Fp~21I44fU%T0vy~sn)p@frL|Ccf*(EcA3pd{k;-qU9SV-(a2s6to|xoJ*b^pqw~u{ z^?}`W%Xu;$2^0EH;y^Zr3x}D)aXvOomt~=tVa*A$6oW02G>5_3jU`X$ZPyaPjTf{* zuGgavHH>wZ*MXCK@ia<|nf579LR$N_7vhGfT<>SD!)?M3;hT0xfcjv&YDe8L>U1x! z>K;zihxZh3?5K)EQ=}rDEyZZ4k=)me@9W@)iTLp;FRL{*@$utuP%(|xc(`udN?#|p zyt{XEncWx#^oP~FiDerw2Bh~iu+j=EVv0DP8Quhp%sHtarJRa+&@PHn(mdYRn0`5f z-)Y2ThaMN0>L|^wy-qVpjenh#yn5hDLpEYWT1+=eS+lV1{HFys_h5Z`_l2$69NO`< z?C17p{ay8cPdHZN1za#xS-ih5QY>Xx&X(>H zPkSq8(18F*Ok%Q2M8l4I-x2(@1?kvg3YyGR*s^t=JRzx4JHugXMSAa1B_{F)QCQo5 z@%J3MpMllY^piQ&*tzhorwR zgu4hkoE(`U2+C>K1y*XGnhct`PV6}8DX2{^9Jq+hHUN+pRqs|(U6!o^>ZbcTqg5OI zu<9zpH=B<7kt~(uwb|YsQV!gixY+jEJbk-<@epPcO<}XWsSPhwbs|EAm4G-h2;)zV z1KFk6BZeHjn;0ckS@lFZ)!A*ZfbJ!fTLaNE&j~f>pjTF@nnr~hq)=##kqzK{VBpC8 zx!_R!)e7{48#j&SNk?Beju&vpj9BkUXxAyOm8GlWX;Z2Hcf|JG~21YgJjD#UUxr20S|5 zdSx5eqYpn`Uw1c{pT-}>4J;HDuX@=EqsHf8Vl;*u38X9D!TfQZ>jSR2gED>TMnmD@ zK@91FP8EunsQ~}PbIaK=FpK2)UJ}*GdTVhRd^!tu0ti%S#>vWiywSl-eklGC<7U2g zHj7Eh9U7Cxzy*t&DpGN+W^5L5YJ7~=tni@F{rOkAh*wAO!sLDI$l)&Wx^Fj;{3o3+ zp-Q()M*F@|POx20PWl++dj5gs&{pM!Cb&cJj=CgT-rOSlAMmC-&XcV;H<&5b=J(fv zoX?S2hrA;*fFt|Svo_h&tJ#rE!mIt00X!10Lbp@_CKdeJTP!RUs#TR1lKjVYYTTn; zf+Ii6yQ;oNih?#Q^f|iu5{~5lWQVCmI&gyiu{z+qA)#%091~{Yrt9}x+VjyQrbtRR z$K;Q6?1pt~oJ}1ie92)g^fs>vKK{2K<{hDdGE ztrJSW^D8TYTe}6|9ee$4PSd@P7x#lOh{GWHqWt7|TXFottd)f1vFb}MLYg~h+(T-^$y^XJ^iUT+c9g^f{d#b5HPtImv) zPd0Ndw@9Kp9Io|zn}9wHUj#`XPTgd{k-Q{SQB$M=bLjX?@DB9KEXgLq@?1Le%vLQi zi1R;-jP!rCyu^g+?GJrcBu!=gfRv*5^pYYhGE(KAre)Tt)off&VX#>wbj+s~Q{V?; z8RIjR8S%l~1^`T-;gxoVhu`u62H|R7RDbweSpMf5lJ}{l z;XiY7?7oYf4H3CpK7IpuIK^C9Ib9G>G+Pk~?N5s)7;%AIWN6QLoVLW`Uq-NAu7#G9 zIqoo08ZpntG?%;`dGK{n*>CK9TJqVGxh9h9I@#)W7yK3h(otds@lTZyZd`oZI2}Cd zsghP9dGg5p<8w5G6V@Z-XGd|B)dM78pwG#=$gwp(&iZzPQ)}0Q0;4H3<5ie_$KfU` z<9de$`)%s~=(f_g!uEB;M+!~9%WeD{JZecIwums($(RlKbsGR>M^wkIzBAl?WUZwY=#7<8?&AV-Bvu!!mB*KF(8mImyRaI>HQ6N(VM(Rt_{!>3fsq_ z?0@TE;^DRq>BZ2uYKpB8O`l8`2Zyw2+!8uI-xw?L9DJ28buM|OJ0p=97wj#_FW?3r zLyT-8d+F&38UQCy6&CyTxN|yGWJg~JKR)WmWON(}p0%q=L z`3#I+QZH@|KC^sO+;gL7aJ>01O(m5ezb5BOH0jjCL^&H3 zcqW13E>S^z=AkbE_l{M&ZRE7FB-D`pvehLhOT-D?S1U{g41iq8w7Uwct| z2WzN$@N6R;-mRz4kB{X(0$VJ&tM>2jksAR&S)vTJGeX2V=ykEN|0Gl4d z&SBoedtf{Sr3UW?EFKNF`Uh-}2~YAz&gHyzCD zyz}BekYC(mzuW-3pjPrC8a1)oe&((>S8SnJBK)OOT>t+8OF*>0=l*_28_&Q%Z2v2K zB+TCbRbM{zdt4nZYfu}%OG@|TN$HK7OeE=alsC3uRa0(>(MfX={mc!sF>O$=jY*DS zQb%s8pT1=W_~Xf2J;>zzcW=xD=1O&lARY0H;%sn0uV92GzIv1*uIM=;tld8!5yQ)+ zWpc;4g-S`~^{6>W4G+9a@03r6-_U(6k*vdLp-CuHKTqYkc;9XGG!l}ljMH!w?i+8_ zRLot|`F6Z`6$cevsI`c-*9GOUBGF;*!_sv%j#{N1%mw$L*zXTCh($W@eB;B>`2v z61d7e?WS=nSttn=3d2KT5PNKu8jRk7m*j=Fe^=JsiojGf)sNcuCFsTNB^Jd?fev)AmT*nrWZF^xE=P#0 zRCbtoP*!Q1Qv%c<$Y2ktX+6-5o6ev>r5qtG(U6#brA{BO&1W0@dQ=gfLaoRhLv^`= z@!60Z(Hm~ZzTMQD16 zN1%fx?n=T@Mh)@8f^~17Tc;`<^9`W0dLyCmcJ(Y2O(-dV@A@Eqp|2&2CbPd9W zB5ZOYn_|egdfvT#q%2L!X|#$YdZ$R(q+;h8@xXc$ zV5;IJ9FI|eTiCIr--x#xl4}G9HE1h#bI~=a+Vf=H;b0VZROn<6eEjt`@?vzju66r) z_p6Jj2+rU}n3|~<$N5UpDJ1TurSREiL9f2`|3$S^qsPFvhJ~FQ=E=-mg*CzIxAMy_ z9K*XktTk|i$G_=@h@v(yjHP2ah!FoXTbTw0@*C#&<|&28fq33C70>S$4oIJQ%6a0fuNOB@)rH>-tJuD z^|~0OgFv~}p1~RZ+MeJy_)n9;$uY7qk$d}3e~fiSYKz!)U&=7Q_V)uY&+9-pugxN+ znS!Sl1WX!Mu9JY}$STrfiJ>P~BPoNoBp!aF57`; zw*dXik;=*xk&e@l>JafQZ=~{7O$}B!GE;q9&`60S%HTX0X~Yon+Sc$l0Yab3ey9aw zEPFo7U5s(^6~pR7d85+^M9&Qo)7TJl)B^Dwz~3&A>Gf7ZH5uOWs%h3(|TX#B|DwC>q?AfcH!MSA3}9% z9Ua5$b%tUL5Y1F8LCOX5-ohRcU}ZewG%3EXK5;IPk6>8#-%AT%2k^9V(SRbEC;AKS zD@REXL9z2cvMri}gc|TFX%*xbuQYme#Ay@>Z?XCmX*zxu=oTZVo9+x5gMR%FWTkG! zO4iV{ilQ%TrKlB$vsJ?0Y8ALpEgvWBcfK|Rp%5Mz3V@=EK~{kyjG^6 zco1AtHzM$NbX`P~CXg+Mwv44EH>Z7%6Pp5po-5&zQ6Qglcu>M8i}hx;&j{rfF>t5v zlYEwNc&;@O>uZU6Kv3P2KHcMepFs98a)R_Ioc<&NF$i!=OcrmFOE?DM`HeCv%h|QqDe*vIC-kK2SeD(y3}Mf*is%uUlTfy(rK4=Mqj`4cX#&5!%(!Ux zC2SOS4O>K1`kR|7$+v5~tKeq)sRITs+#2gAX|APrAi|fHL!FT;;GCcNFpv$_%5#E8 zD`5_~3Cq(fQ8+9*8*go7gbr`&49dx8G?wBPo{J5fVK%xc)?--wQflXb?9ShT{fEZqff?D-L!QbghtbZ~; z_n#{}AKc0kWaBh(X2Bo+(U*py8eV3-3Kwj&l{6B!KR}^RnigEx7qc6K_jbb z+@bw;XNH8{7~NI=0{ErWS4o6OSiSuf-W|-WL1!$a0rb7(-aTV`T|GKbN>jy1fognC zp0MP|e1jT|?J8lrMLFLUwo9aEZYBt>|Fck5fl!(X%yEsghy&GaSso0$OkO%!>!`M86EwC8b-*ThglEE*Xkuyp((i7 z{`?TIR=%AJEZi?e*RMiO!{*dK<_7!(XH*qPSED@iIc1jP@c-&w_NL6S#e?!57% zjgg3Ua!jH*w1g6c#kaPifhUG7y(BaVrD`>F1haN&_C8?)#=}Vz9SdTAy5q2swiNrB2J%PoAbrcAa-UQ+cJy9}b7KO+x=_7bB`zR5^Tk~CL zP_!Jb?zU!r7DpCnBu=#E+GcPPxc2}TnU#@f`&1$binM#gymn~X$mZP9o#(b&-eNk| z_CAPwr?C_BN76;XPW3yY2;C_PeVcn&@YbEut)BcH;T z?N2=nwjN?r>y!y3REn&lZF8bDi0dv1!Gj%?12yrMh7LF?squey>9Oia2@5+53kIrV z2MRaqKdVd9OstHSOFm8cLw8&u%e0KTM;-$8E@4>#!3($qtBkUJ5&dxlY z6Y-UhhbJ+lG^c^29tDGZp19x`YDqopc4p32mux+5IVy&{5y-NSA6yi{mU=kC_b`WE zCynh*1F3nEDN4a{hGv6CHpq?NnbjtgH$EnMii7}7@SX@6m zTTm7rPc=tT2l!*mL&M*$dUEk7+Ep}vl0{+|5L8=)OEV;_Oi8)@J)9C&Z;!=4N&Qg* zY10!4*{A6iac|-d4aR-iZ4l33NJWv$23s1E1acCKN&{p%y~TX7eaZ7Y|CIK&6=KgO zCu3*NzID^sltyWF$2ynW>mz~CO4tK(COX+gq8Jh({;u$|Zjg~LTQ8w&NJmwfWK7)1 ziXcQ5kqsOI*gZ}tqS3z8!U)N%ppjhCi`|~Mz+46GIGQb+_R9Luar}<`I(=Dt)2uXU zpcP^3-=nBsZ&?Ed1Q$e!;9_pr3yc*DF{FVo`-poSik)`0445E`V@($4;`kb8VPzF- zs#b{&2LgrSjTyG6^uA66aj+1kaJPHE&G15J<4oq)tvFQaHvHO^v91m*qCx{+iQzg^uZO>Zx78$uH-M~nUxe2hU^8U>dK;yiDxljHl#&V!nBY1Szn014KA#1OFbgU1ADLN3anCd zGZB7u)Xh996-n8`Dd2~aVUSFg%|3rkg5e)glM~WC-U<_2XfY|XGw8#sYDm{H>#A0SM6dO^G69WG>yMmuyQX33I zf~g$M1ZmP)_YAqc5;%w!MHdR0>V;x&v_cXWY)|;RXM(BWC&F5;vx7gKuYUHxEx{nD zK;%`hVDUhL6I=xP$Wr##vGmJ#C@x6~o48nA1S3rTxpPCeLLSyH5`jn=ebLinXpd>L zN@M^Q6&<*%qU%E>G$#n=9has(B_hMo+OjNbbqs?@SBe(&$Fgb2wIjL@AiC&H)vO?sZgSN3ZV#i5Ct^ibGvyMMEy#aL1S+ft0_mn<4KklJ$o3!q5GQ_xf4Tn%^uFonQ17hhG zYuc!J73!E6iFHv#i+H1|i|K>>v!?K8pP5eoxm--}ZRtnCm)ym&~BU-#6#< zFlC97@P`mVD_l?~tf4R;AmsXDs2qNf#pV3K>6CC00v^QTzyF0oL;{p@6ZmlMap8$-rit4_G)&2W%zr zVxgMw;W&1%dAlx4*@=xI&IH1%-9yVlzQzgCV%A7>CQ=xpXpvL!!UzTQn&R$zFE?B` zd65xCq&y??pBzqKv{Kl;so`*ECsEjT>NjgTVqv*xGg5%qrUvoQN z*`7^n>&}Xu6Hj{1@c;KmqV1@w3Y+e8$}5C1{ib+2D<|GBzrUbKC&NXBn}^0XA+YxM z*Sujs!=rZ&#Ec9?D!Wx;@~rryPwE;6(0m2{MwcrT{7-9R`(HS{LH=hU>pjzn)dV@s zFYnt}=T|7=!RxTO1p+1LQ{Cl?I7ige@Hlfy3X%NRNW=ILmN7`aXY@&(+f1w0vt_5T zPujE5U+TLvfnD%YGrnwFL7PbqU3B`UO~P*DSc68)rHA(+nYhzy|Xw4p7kv$M8q{CkOB!l%c%|x;Uf&7)=l4ftXA76%NIN3`<+@ z3!IltT|d9b`^=!kY||+Kw6UX~8XTVj_w`LT0b`Lz{5h@tepTwy zPbCzxYx4d*jbWiYZ*t|wkU4oWkSpn2D94Z>!GGv^o0#K}r@^_3HD+qlE$HNrG>KUp zo{8ci)D_1!1#uf}34Fru{tSS-6uvWFSQ$jMHz)Z9fW-E*MvbL! zhg|0hV`rnnsje4&05Xbk?qaK-5v!w16}4+rq;jTi6q%G@0^$mS%-X97|Io({b+(N> zPC%)|7?}Jm4)s!T(%DfHXB<8aVF9qfeizCzIDQPq+VPZz2Vf(j>VAmk`VYMgBS?X7 zXK)P?dHj{qDEWvC=BFPPB?Y3u;C&Fibed_nV%Z71G1iwM$oc&)KbqRgD% z_n6G|Hl6QP-SS;kMcFh7dTkyiPrT8NXblN}Qx`JO6Uz+<+_7%vne)(!2Y)~7fB`7~ ze&|Jme29f+f9th}>zHE+G&-l>Nt2yThPx;!B!oMMB7&Tyf_}>D1uVGb8Efe0}EI4ESP0v$GI>a{pErIb`FuU`nVlkx!^T zCg`H~u=8}o{XWW5iP*Vc?qR(-BlW3p7ueZldcE1w=5OiQU@!=jdqf?7cGh%m+|yxY zlKai37g87wA`;6{HndUY9zQFdS-Ihdw1kr(c7ix0Q`5NB(b!dkYj4Zy@`{it*zm24f|M09`^6-KJ|I3 zdahdL2myAGu@b$^)$w=fiC%6Z0w57uv)-qp8xbob#Ly{(en;`Wh{UQVzN77d&;u=DpWN)e|F`84=ex5SvI0HxjSE=a&79noJE+?Ek*L ziS3#B?IQzcuh}`SZTVaEZ+8u_&)??nq9P<;YpIF@?oR8#M%6M6!(zDuv3#nZ?wNHdyQt>UDxu?oo$g)S{@Y7XIdOL)`Mi0BdwM#~99dA+fl_Q(g(dZ-2|S zb_t6F+eUTZYzP8Z@|(vn;Gi?96J$D~Tf5YK10g-4-95TcuF*`c(|e^%u$WiyN{NmI zSUzF=8z<4~ilL6~RA}95L!djK26DW{So)D=4u?#hP58o~EgvFXA;%GcP;MWLau+z;WDZJFjuXp;9( z)rPCWC-RpPGG8GoUxEfw$jdRAYe>#^&!4RjNi?i55K(mNp$7ia@=Ln+@m-txcB8jK-Cn+cG3!FiB#5jSy{>Th8$&dlh)LQo`g>Gz4ZK!U9{AHZKA zk#=*^n*5DCKL~tXT8E`c3L-%NphfVjrUIamjdqvnX*+9$4Q1J?Cq8Q!r&zzkQRZ1; z@&*i@M?%*L-dN)^QI1>^uU8}-|EL~nY%Tyi#P;4cK<4tm!rY7xC5GgsJ0wGFaKcR0 ziRb<}=&vw)*#+WRjQAy^?IeJQi_y5h_-PoJCE&5Cutpq7Huh$q6s>8?mv;5zy zw*rLqUO9?{2xXG|2yVOAl; zm#{QkAJ=Q2V)C~@^;%4MuEM&A=t0{QZM{}rKQe_RmzCv9Gn2~%rqS#3koaeGn?%Jy z(cFa)tD@cyiMC(6fw5jbBY^3jbO--~uL}Gw{s*(E~%7&T@t~yoNvjME$NJ ziG`xks3DczKzrge7j-0^Aj~w@}QlgZ$3zD(NJ6~kp z(*vqB|1Go51lPDZcv!gimy@}m2_EZVxQ6CrQ^o}4QMS^WvU`$vtuP2tLB!aot6Ru! z`g!Y-WR;Y`718}B8WxadCjF(m3GNF%Z>)4w@sj9ig0+l_@+;ut__2!EOE-q#8Amt) z^X|dSRZiRC9GA(8^prx~r6a=QI6iGNgAe7!&P?Jn??(8kP{z$!R4(Y#(n0}}plxOW zEb~yLOFDP89?B0haKsM$0TnB!MZfa24 zFGd)ybVT(sf45deom*N~1k~)-v9^{0-1?vhJ*kH2 zuxFw?_bQ%h9Ht+lwD!_1#Bblgn}vLT-%Rl%w^6mr)I>UnKTU2qC?~(rjhP3k@D_sj zb70{~Su|e0PISNSp>eZh`&#i$zXURIcb{~E{`7gkeIkB|CNtffL*RaZD2#dD$&D@+ zdh>U7TfeT>c0$H(Z=k)*k436c<{5TWGM12rO+BfX)R@t40vedD*_TLa^DP@kx&t z)H-Lq@;C^L_jkJrQU2AjPVg!zSmqw=4|6oXrtpjtM0Ck8>>O+!jk5LyM8V`-abS}X zz~P8~V^d_xsFX`}KDC{taRA>99L%LWcqMk2hqAXSn<+vH*uCbxlfzpj5rM z_@r!JhE{ZMjQ{h2CvWf>8_Jo{fO&KOQxZHlPT2-mh*&$M)i!LBO{5CklpieUJypy< zX4fGWkRd{#aC}XKjce_-QlWng+Hdrx6xA!(s|iSqE(|rUaf$w(bCwO}Od>?{V;c+~ zRYoYzFX{IumMNx^R|B#l(BY}3^wnW*jRDGXIUY=zTU@FvP@ttxsWHmXBKXB=;sO_h zD}NvfPtVtYQy7NdD=StOA2yS;kgboN?M?+E;IOx4Y=ifI->JR|N#e{sORwiJpmU(| zo!T^xgBd3Fx|Hi6O%h^G9*vQ2SNNM!($KSlWdv!vm*<;}1-LP7$oE6ln=V)+q+Q?JaEL8) z2CUq0D2|1gI>lAkNj=YwJ1%~&dt1%rNf-cU8XeoVZQHhO+qP}n zwr$(C&1dYHZ{IrSX7>-|BB@l;=}x<=$qN82*8y2{e+BI8+BfmLorKlaR@5uvjs9{3 z9NsK|yWOXzU-2O5-^BLQ4$AZ)T6LtpgCDU)B$I|WL$leI$mR4N+ecX0%Cr+VD;PvV z&pXw+;_m3g|FXNV(0T-i8iDEHTW4NS$COU*Ld?c(loc~kN)n^hYe8hoUU0`POj$v( zOBI~PwS**HPg6=tMsYrw9chjf!~QG}@XsN&8^NYjcw(HfkZK7G*C2Js*R#$B*K(C2 zpJjL-6inCv+ta}*fcQo2O_wa3Ki8%&+t)qJCgPIJot7VQ%IyL$_HF!=`a@vRj35)`Pm+BR0HVX~?rvc{0L91TcDMSMM~w3AaJd)qfg9?t)V#_J#i8 z*glS_39;j0U4!A$%aB1hx0gCeM7TO!%fb-t8h(mSuGQwqUffmtd4C6SSa=3jQc$qi zlB|ARgn0Wk;Z*Y6g9!0HE|qQAb&>|OM?mbGu9HS1WA`l%i_mMZQI!6+UiA$&5f`CX zP@sT4iQXXeNw z-^av55HV?#J7&m;NAJ)J{H3+|&7PK0VGc1mh$>>t%AGjl)!Kp|Tt(en3zYBbXl3rV9cD;G?LD_Z zoq|9U8o@RO;9;y}jLn#O`AsX#wQ(p z#~HJkW1TOzYhAD`y%4Puc7@H$CrexjKW=#UBgxJxC=irY*r`gqrN2WaI`2$`cJEA{l_j8Ic9&mFddKcN9TI_5KEJ!WBb%m{3Wf) ziPAcG1=bgazRH8X=MSnMp=#T1Elm^j5G$C1NUig(>vu8D>fv(Y6`BbA2CVJVUD~ky zfb$U>GTU4K3wf=%MmYm017CtoZ+gRZfbk?keLqwb*oJA9EJ&%r{-M1HUM@u`cE`Kj zVU)c`=y#rx<1!bL>H6H6EmKpTKWJc8;0)bUQuGPjrjflI?$>Ds!C)Oh(UCrN=$47J zezEzQd2m!YD+p?QG{`mrnaOU@WOJro&vJ?4U5X-7q?8rU6qm^Zb@D3#QU3y)L?>{L zavYO0-9(F%4D^YD8vy@wBKd*Q5u!s|I5sTjV*I_qeQ04ZoL`qI!&pfri@V4(@54Lf z^&PSelF10{K#f}U?(7AsVRgdPB#NqI$ESA4$@zv8m(56bjQCue<|KMcH#MF&pz@Bx zdY4&GEy#V+a^5C`T%4-XJKU|{z3mycBmagFeHcCJLhnAmuC`3@pvvLkIu#zEEu@ zB*Uk7lhk;6%7(^TAwegJsDrIMQ)V*RbFzqBOXT2&2F(EHp~|2Izne-1)$RcL*jVX( zC&_5;L4)hCYF#_NN*%#@nW?=VAj-3Q!q5XnA_ZUcsv^=qPvmw@_P?LFGfSq%L;2`J z{KhQ_*vPBTyZh9xV9uw-i6D_+uFtG5QYNG{sz75&_=;noTBvdF56wemz&(0;Mjg@} zKO(#yWXODQdWTo{jHv1W=1)L+%);A`sF^S+M+$}3Dy8*8xNW~j zrqoyZqZl{{=&DjEXV#v3Z-By4$*GtU&=&%_|ETI{KJ#gx$iY8t77ri)TYSAsb7T93 z9kd#uycV3+qJf8#uctNF1>QA!(64r3r*)q1(h2*m1HQH&?M)8-hS_yd9POO_M#T_x zMr4z`nA@Pt^t=4`p++g*GmJ=<#Tc7`%FQZ?4fZ9`^Qu3qV{#qLjD>4?(b6t84)IGs zO}uiz75M=k;1YZ$L+~PqPzaM;GTH}H!Pa@ zguprfLM*%vbCa*z)SFma!w#C5=B$D7!JkU8htzPHWh#d1p@59mk`Kb^w?*NSG}$t* zHPw9a1Sm>6Lp-(x4@@aWOVWhqScgn}^`TrCmqi~vFs&jFVRIYb*E&P%xbj^8F3EA= zeLjWflv(sFl9>5^k->YoQj*U?ABJkT&{LI(c2@+Gs>NBA7@f}{sH z*4^66NOBY`M!St3un5#_Kq_`+1hMs7d&Ur3lKhkh2xKr)N6@6)?=M%XXauPvO=(S$3pF58 zZP&?Ut3Mi3JJ}vy6svk{ABYUL(V`smbauxlG40ycz~Mlyzrn$On-RW;<2tL$Q9_t# zm$Xpl;_S(b(}z8xQEgz6l@*iq$-3qLi{9&&j}BL38Nb*Z_(0uxdr$YG*hdB1+BOT2 z^$WlE6N6r-Lq_9vwU_b`=c8wGl^;$XZrN>?8wYl))0dL>H4y>r^C=7$$d=nf+$c?(xAd zC8Jx|)Wz_~qAb(!rB(YL;SjE*lv-HT&wf1Ew!DQN^c@9k7lxo;7p2B)W5@p6QD)|^ zVJKpdEfJYW)@c4m;AOQzfx}TcPrU_i@Ro9dYcSH3{PCwni%tIW{~ur$@qOXi!?m!H zl*~6n+X%loe>3A3Qy|ho#M>A>U+ZC=eaYF&GtRJ(lZV)U!BRn1eC2?P%XoxHwG@Cazai`h51IQQixrCgg-AD7=R%GsrUsT+}ySXy@28Q;(LFhRa{ zbhXvfZ)>!U67N{%7}sM#{T@a6-bxOVR?7S@5yK@{Ttf_;^!=XrSz^g#f)$nnB5k^B zDJrvO82l5wT~e=179XTib$LiWy?+u2qAFjr^wiWR?&TaO$WH&FuD1SUHY~ZAq=Um3 z;~hMtUK!l0RJlhjWvbcA@tt9=cz%-HnsEBamb>g$RFHztAw9mfP_P9vJ5xW1+sV~6 zd)cq2Kb-~c71i|tBl&}osM-<9);>cia{SxW1!`{e&PHB z`L1A$5ymuY;@#>CwwMQMjA~SzwT5|Ay@ejTYQw0aL&ocYnCq(+kEEi*r`pqlAD!vH#N~pX_UUjvSB&c|>gY=W7CF3XozDk| zU_%63!bkO+K7m#XqiIxd8IQ(M>N2xFTY+S&=j>3ElEtK{f$}zd9IZV1K{n38Es^_G z*|+E}e!N_1(PR~$UO0a1X%b0|RIKyAiLL2&o)_?1RX%17?fHP-GyzPkeR=#3a+L4g zibU0_;MSWEv|M0V5Ng(59^9E(!)hDw_u+L$j!A?UW=$4-LfC`VjP{giAeTltL z6T8LH1TM<0ffy;kWrOU81at|gDXyp>k+XO8E$)-tmlzFZ`z&r%k2`gsx6JV#N=7%E zBV+w$M~s;HFPvl9s$&oQ$pwEvjA>V)Y_56;gJi=uT4qm7p%IPIK?5?dQyi%a@=~v7G+k&_lF{{}@-X(_^?Nj@N{>3>hY{l~q zO*)xB8S)|9-LKwm(z}RP6zzwXgjtKW7^k4xf{5vJZm8w1qrYHuB-jXW@Z_dxur#k_ z#-hqD`;W2K$Ma0@{2G}=SL|n zbfRbAyT(AriDUE_kgp=>`$9?+D+NIx{Iqo96KoTuJHG68LUyYi8mR_t6Ad}YPraBT zvw|^)Qe9#YOYgS-fq6VaQ>u_u1?a(K0~Kt?$<)+rv$dfv&frk;5u&Rj>}d)Jj=c ztrZyA7s@Uhm;T6Np~ZNQ25e@p&?R%k##|7q%x+_)JIP75xUd47=G`##{n zH)TEAWJ9ZFEAOV-p!2R}S^Pahb*l!6R}^Sj8r390iQ??k7!c5Y{Zlbuh?m|H1gwU= z;)*_Q3o?YP7gx{-J}n=h_*li;Yeq>aZW5{bR0Z$r@54*AAdqEQ^B*{O;ICtq=y@+% zR^{KK02iohlxns$@gShCfAY>T3BVP9#%A-U7pC39;F5rWm({)&m0yxD zN>pvcLG?nUek{zYHZ$6X<}+fxTB1}O$`Mq4nDe2_!5FpOblAX^ON_>XJ5YU|xBwY} zJc!kSS_B*T^P@$lq>>cZG@%y#V^3$5g9Y$Fr*`RJnF1C7&vd8NP^Roopdgw%1gR*a zHY6;(T2^4HX_PuOxmZ&gMvqHM$KP((9;({%kAdPCIn@aG&Xo{B>}`AogF@Z}D)p`4DO`|2xGtV-LjOZLb%o}j@25#_*{ z28oM35@Tx=HH-?MZT_K#-M0nrT~|ZQVvrl|FiyZ1Q&9C6g?6M_T4I*`38umbgd_A$ ze#{YzOw}1XYV+QjBA3&xa7NPhL@Jnr-PO8X_}q@Hk>heyu4*C|qVJft z$PbvNNsGd^xe5{eWmNtbBt@>fZ56qZuMqg~3*Y~sOoj>qJwFvVckTp!YUen7{%3V%4#Jgj1UhQ<`^C{V}4hrL9ES5!Vu93tc|%15)SYdp-umkJ!! zTd(8|jTRX6gImQRgg>;wzL50-{BT6)JGez%2=H?bgkAfz@4v-jdCS7u|4osyMV@w8 z;N$7Czj4GH?5vuuz`PV;<|JO4#wpKwsHuEW|C=b~54Z6@2X?Nvek2cZ&?#Ecv51$vSG#s>6&~zUGcT*Y_bxjJ%KA zlUYG*hf^s>C5c2R$8Mg6{4cLM=^>({mP)pc5a+`rB-3}2w0V1MY_L#;Z8Xufd&o}+ zna^??AIyvWzCnSRYR*pi51f1-30?iGH7kmMF#9rfnF;S5jif(ZTniyK%y`Yl{ycft zH%&?ppoOC^Vj}aj!z(qQiNdX|b48>D17!8=0lpVOH z6x8Eoh<<4EiWR>1P304wZ2qwK16Xkzm8WbL(+1E`8hbxj>Ddt3c7Fk~m|?D9>ut0N z5|^fRCNo5JKq0vDq0i=z&&k8&svTdEVCEkXfxV zDsFKBy)4EnU%e31=y=-qp~o3dWU_36nvdgBPotdC%HC7D9l< zRA6;D{&$u#(sK|1VR2YV-ahia>v!I^VXDNKF+=tgu^yreVTBcwI2p%fn7#pbg~0dt zM_s~SCjnE{tCpJQJ>p+3yg&(hmSN3qm?)^^)rQS=A+d5FsFFK( ztQSc&jRPOGO|HlPc|H=flhU~4)km0ohKCqX>iG7{;vJT}9R;-KWMBC;N|SrNC~vPi zahbM}G#?mN0G!(}(DJ^#2(6I{AVQF!ph53CEQ_JzNQK`0MWXhBOHg3Lit69ug`&@&I2ygv=UYFG}z5hc>-p8m^ z0mYIkn%o=^u{7DAZTsW&)99U4i_1rUe88a+a-4_w-3$MTKx8bM5ZA|sO)C%Wm7h== zJ(yAC$NRk))XH^?=kq_+WIVEER1deNK?Qp;QL|2t58@D-Ql@)ZMJTPd4|lyz>K6lc zG)IpP7Z+TU^-T`?Ro}8@*0`VxU`o8?_u&8uI$+ASDjaNbUHI$x^(Qi0vdZ|g7C z*+oUJwHsyP;&^;mJM?|tzS{>bNA{0N?nZN*?~}hP{8 zmAxJJx=$ZeswXUcqSVRyWYvR5D%y!`o?!UfvL_$_&R89Bk>NFn*S}M=+b71O56Y|& zq)et!@qX$H=NLK~j8nko_#np}uD8JkGPNvQfCkF{g<2aD_;ky}^(vfMe@H*N?HQvw zt&6+L;L&r8H?F*ceVTxz@3SI-*8k#FW9p^&Vze2ABMo`?XoAIdeW}sRwTtqZFq0Wr z4WOy|T2}RqA1)T3F|ye@+44Uwx@*z?DHT>c__&gISdBw+G8GWm%P2MK>z7|GX3Dh_ ziCJ|ilry-0A_>FYEBFvtUZOozLao)D82sQL44MTDJs(kD5|`*$P z$wlqkjUZ6o75WME^>MISjEyq zSBir;dOlF6M+Tq`boDLf@!b@bM&S%zY5H+j!Zz zjSxwA#bwK{8EPk~%`1mv8e!?^We{D=gSmkCC^^`|+l-L015Ji!Nah(%dl5@4Fs`cF z)gPzV40dGf_zt3-y%x{3q45Z^kc9QR$(USV(g#2wa`h&&0bG=3C zN!r@oWz}PK`}!L62vk&z!{c=JpvNOa^Lj7bq|k3LROYy0C0(MV5{(r+X9kI zw|i@#9{_=N-i9uwM>Jq87yrnbQ053W+2!@l;NCiWn<^LTYe1gIZTFL?*3dz2)ht7W zRVC74=*Z<<=rHrELuakCv2u-^`PPawXRR@jBW8y3>yLNnM0T=51*q-!VsythFDM-y zAfVW^UIa4P5Q*t$nVw8u3RCkoGnc~O_MxA#Le??O&yhqip)vH}cywsJ;bJp^l=Fh} ztj&!?QFI5zB$>_qvJ1&TC~em5ou%L$UrD-Nq4zn|*x=V5+L{yC_@dKzdq#_^j}Mb6 zOH8M%e|s2CKz0iAenu?#sdF_%ZM{COZ$5dR013BC=x2Tp=u7xEG3S!@f~Qh%cA}x&Gkd<%=gf>>({Eh zYIfh}VD>C;B4gz!nB)1rX})m8@=YtV6htt~sV!L%A~0WTjJ?sr9yBssqkfUfuyYT5 zPL`QsLwyGbx};&f<3w=MLe;bY|IpyPS*Jhc4H$-IEz2Q?Oh#d0ak6-!IoPn(nY3!9Rv>7%s#~eiiKU5oNHK4#FXN&cb`I`Xj)v zzrO+fX*iAXM<@HoLA2Nl?ccUx!|A+2%fX&v-LzWNDeaZ}GH*{(%A#Lh?{S4}8;pw| z`Djh7X_Sc9Vk;dqHfjy<+bG?YkpeOw{Crj<8@CE^lV)LU`S5G4&oVbUq}V2$N9pJOC_F*@~t`CaQmv0g^_num4+9OX*pxuUB_Df~H@l2vt$ku3pzvoDe~cE&`0= zWI?O254RO9C9o93x%%jah_n^PH5 zgCG0>EW)|~3MnI#_s#FVVhUbk{a^GvED(8vFVY*?#Jk;w7#W(!l9 z^GZXR6n6<6E3ZYdrjKg20EnSOXC}qjl&#}#>jr*qWVHc$BrNXOzl!s*z@ZR$a;Xy= z46aA@t*(#0Vk74KizW>KX+W00=r>mJJ3eXuo3SEr9ZN4e{e|9=ENw(Rv7MDM>v8#7 z@O@W1S+9)AmxA*UEe7#4mh zfJUlr$!_2NO!j~Uoedc#RZ!tmWxqz{zTeGOwjXroLP)iLhx%`ycBAwFU2JYJS*i=c zrFz*^k-!a0K(&!@4$xVkts+Ldo7kDEp0^0Zj+X;_YALDvT6vFp2}W==Dk@pur|H9w zv>K8(###r(gFZo6e=8u~!zkW~^#KzK4mQFw9UYu)wS}`FCaGiH(+05Y6kYYBeLU4r z@w{`N!O&?fsyDyw7EkR#;Ih%1oj;KTPWI?}^qh$HGi6Equdr9>srp=4b4P<0>!u;Y zR1TUKn+T!;A>V}T@#?$N&e+TMbtgnOYf|IgTM*Z{{D%edkJ0y+fPWJa{n;->Q?$2S z!Jo>{h;z8z=dROch3&CEqF;T=e{MPT`I=$ z!LQe3TP#CsyGzQ94d5#}aEOjUb_>QAVX7ZeX(!G`;Fkw(5Zg3{?%@e^Acv_X=PVPL z;CC?si)oXj($NpN)QoDgnwgk)fv(5-6Grs-y+MA~I?!RBPKzI@T0%`>|T*ld{Gqr;9KxBSj$lBnZwC<@pJd zBy+$aHP89A^P<(wW^eM6F|VZ%6oax2dZts_p7)x9p@$s<#BT>dqUmU&r?UBZbXfRq zAQ=;`S7&S|qY~2=*zz#HFac54UhBEv9*>qG`MbUenK$hVTR90PAb{ZK-N~`ZEOzx= z7hfJZu8i+5oT~M%z&FU>tyHUM7@AsbOSSMFnY9K)pONPVa*rsE^Z;l$8ZuX_qIOLM zshOvo^-outouiDip}Jk#ur2N##Ealp?r&qS(E%#~0q*srJo9nMW=pM8;7sxOt;WA7KJ%F5w;b>{aT7Qxj5L{-aS+uKYO4sWr|&<6 zeFFxz5x(BlC12ibF}f1B0>jjJJQXaWm-tJv>II-K!{|n3$0lXbqC&DXQo)svWLtU; z%-T$E)j3e(N(SS}TrK4J!{J;6ij*L~f7#@2Sbs%IfDSByBD}?!MvyZtT&byNRUt;7 zCvQJ;cMP;0D5_PM)nPzNpHaNV=;mIdC_Vm6(72MMsY$d!Sx`&R4}{%a6DaN)jYD2Y zFpxQ-=%;$IbE0E_*9oUVM?QF@KG7V?4hC8|@GH1_>k78v;lR;5ANv_(@rRgogBcys z1MlNn6cx<(INL+c48?Esh%S74EJ?!h=f?-Dzz(4<|63E-vU6uld%AP)94E-g6S)A? zH~*Y8Kts}c&~0!>9bw>KEyLbcb#Re7|J3g~UPX;due8HBm>VTI+Kl|UpACeD%BX_6 z(S_5T4}dZ9Ip^cgf$n~CJ^t$w(TU#M#D~I6_hQ{<_^p{e<8QyB1?sV~Y+CXsJcv!D zzxmY7I6UTn2s{1r2fy}F$O%Bs?p%nc{*FF#gDI>{zw0})d)XNK9mYLtHXO?Q{uh`i zAz6+#S7PYjNwjEXt}dZ}Of5!wQd3ZUb=uEs?v3@Dxcr(_x+Btx;L@kPD}&UR|A^X0 zR*e#3GAkME)!ZA^GDenrnBg{yDxEJ4nja%FxH|)xf(&P z>B=Yc>KOzr=pzs=QklMPzU(KhT#RXys2sTR$YIsIYHag0WhBMN`?s_IiB`5hW~>-yt@17Vvd!pGomELVofSBI)7!{VUHw^;Rkr7r~W%2_`jY^Vea zpn?`hkzfx~@v2dz9OO{YC9SJFq#R95gvdq|0sB%WZv6W_tQK~t@MOBe`@jDpsoC}u zLqh|BzykmMvoWE|Txiwd6D`xzm=65~33gipc`|qc4T!nUUc11v-Kp1ld#+kh^uR+J zR4W+d9VF9o1Afh~7p@dXr&`rlUk@H98Yvh`T~vhH1;l03J{rYywVx9Ch>^-Z>n&Gi zGe7tay(vZFUqXF*zz8l)f{UNw0 zYy8iWk=~hDXAfeic?Y5#g5^-sN^a+n*)*Y$H|F0=N$x&Od%qAGm6kx(E@Rrf9Rm8p z@$R>%ueSGnd1wXsChPCBXZvmj-;6__m~;u?_IJVke0U;k)QHP=8B|Wps=YZssm{jZ z;n0nUiGG~ba$MX9x&Bgdo3nm?Qk&3N(jTm&Us)sySp~~ebjfZ9cE`iA+nl&T9e~Gb z@uDO(V{YHfz!fy3;-#JqZ&~U)I~@~!41Xfx*O02$A{oMI^FT)hgs0rI$g}`Q=RyfW z4rtufTk5l>G4v~wI@f&{D8yaIn9pTV>O-e9kvZ)VIS3qWpYs;;x|OUFXRobcw^}I{ z0wRt+pk)-)R;s+%K*RHAadyOgeZdHi8IT)8E5h9MwrK;GEp;;Sy~#Ziyg&NpCf1jfxIY-v96G8L;m zNm;{Lo#tgjTHo!+&2!Q16|EO4VlB25J7`}R=s{Xx z1xE*r=AU;?>XJlV<%I^Z@n=rE`h;!KXNTTA{gsmu`LAW*F-UWYTI$r{t`k|iA+^;} z#dgR?+>hFx9{4^9N}^%kMQv&YcNqj81o5@Dlx9?csXy056apfv9O_|BCgEm{aTKpU zGEuSJ#98Q7uZ?`GKUMtPG3y-=}kjZS!CIEhSHrVYa z4H{ogINsLmv%-Auf;AZS@be%)jm48^WBo8baKeP8ufV1~>(Z)zI2qjGY0rzTSNk?} zQ0$qfDQf;N#L53Tn@B($fkrwDsDS)Q2?k5xEBYp`kl4IO#Jc?P!ytAJio|6VEc|^| zSgJ46ptC>`qF*fCrAD;1$Aj6#m%iB7V4L>Hj!YFMWNej){4Ap>#;QaL8E|5B%nUgz zGN%a6iugD}8p(vaJ{y{!^FR}sfj4#y`|GPHA=^4L#;nN`NB|6x!MHNs4nhXcZnmfQ z+z;t4Otp)3q-)z%MI8_yA&5h{z4*b59Clzfym*&5C*p3@8G5v~-iD_irK&ROOj6n^ z|EKwe#pN)m0-=G_KvG*z<|1vY{-shaHPqQ}Xfdn*9uhf0 zuxPe6g8{CIUee~_0tb6{HbumcBqMZn@YyE}57FCYh)H_vyJeTY|AUD%-XQR9F)9Iv^cJ!_*tV(2W+PZ^CQX&Usp#T^3jAB^fHFIt#C=HG3=$AYiTelJ zO!~0N&Bdg8g)7db-4cU5m+w{y=ipM(TyNl0;)1YtQnmbYhGiR1777x7FdL|>#}mUL z?;wH&NWlU1p!RlUBG(-CcHnj3PC~x2)i2H--M&I)0usYc#pkQ06Gn%E3*UD-WDsIg zO25d9a^z1whyp+6Zl%VYb(#DoXQW|SF+~c5O@1LP0Ji3re#^y4k^`~l>#+FS@4=f?83?e-|F zgb#eeD_w&B?_6)*ig7kc^`6aW?E;$nSiM$KP|^#G-+%T_K}&%F1NFn*rud|8{TV+z7H~r=xL6?yi)%8AX?i z?p;Hwg4a`HwUbPvi+-n#76BDsh_WmrH{oni{fv~x5W6DE(SE=Q*Ymzw3y?m8l z^UODSu^1Nf+UGa>ibu-7w&C;^85t$9H7v0qz@c@z`~lhXy(-#gIj6b1_>>-P?bz9n zyu7S>}qQ>lO;3MOU+Gc!J$7OQZ7}m@!blA=+1E_?8kO5s^ah1Ig`tO19fD*O9S@847;2lciQY79gt6(ZYd@1Q*3ia$I{;J^(P04a{ zzAh0z8M=wYEOH6AgRW+Kim|BxmZ#bG*`N>=ZhO}#ycIfo@yC*`p8z=|lZ1PqZQYjW zhbWYkDx|Ox)08JZ?WEF@9hm7H76E)?l5;)kM`3U;wDo0v*IzY^JLS$PI=tZHG3Bk)gDDS!Nv zAVH+%o@6-h=F>GNEGN~8uzKID_E0$G^!=Qx?BP<2J)D~ugYBY3l?TBSPk~}ZGgc#8 z^-4l;(56Dw&`nvq?s1(9#0wvb9Jttb6xVLHpz+qQv@)pr88(y5N3X@}p-EkjIPl?p z4bYHWK-*z%t?KFyisJ`8LtqJg&St}s@*yau{YT|RV_oO1%tf+TI?FTRKJ5GE=$@QW zh}6d$X5cCY+#LbU!6z~Pr2ejnmaD6lpZt;i$0$;+2p_P2KJ158+`dA7@=Q3t5tID< z(7c2mxf2mk%~W1;G>2ck6fT3>sQxtj+|@r~-q2pI+0chN+FM>o9_N829Nsr_=Xdrh zrrAZArC|P5P()08m24^`3ACnD0TG3a61sPKF;7uFYEKCbUb|(?B8E4|*}6@>EHp%7Vnd6Elw^Rl@uWA^Or@@>V#{;^)X9m$ z1yDTz3-$ci=;0=v44?r{+TX;<7ovy!luIUUM3~Pr5iLf-szrDYa_+{&d#LN-qqzVF zd=>+WIpW1Jsz$BZm{=Xubg_O>)6=(2C^9>h-=#}D-MsWmxa8y@jAv+5yeJe7O40pbCQI;?}t@Xk@FNeR`<{_g3{bz0}m?Gbd z-SG<=k>be1F42<1K5Hoxw-M%?42iR;(dCF%_ z_d>dIsL)PCtcoCbf>$gmJTOBBH28#MUd4@1r7y(ZbYU9u=-aNcxm|cJMSZwW8J%jT z2s{vZds$-f7@O=lk&_EIJR5GXTmh_B$b;~L4%fh-LZ*ze|B#_+l@+X;WH(p~^`zop zEX{gB32p_q{LzJ;u)cIHLD!h%rZ56>`9dUqgKh)~tIOU0vw+rvq#-i>J9Hkp%rJbJ zUC~HXJL8|<@fM7^JfUuhrB)~6vd095W13vIi?2k#h-^=jajl#T=W}!(lDTvRGK3vF z3nG)6q7Cb+_UHlo90G1hpq;DwlreU%MbQ5PpOlkGiVEjm1*Y3D4@nWSI$yuK6l3>y zfSlQ;+v~zzC1WY;u`xTY02O~WOGGm^p4su`5?Fxum%v0k;IK;n@|xG|{qfF`+Z(); z2%fqk2q`#{q|yeOE%mF6!@nz_0(0j&ufZ_AmL}eqqD`sLmxCC-r0KpqDP59 zr4l6dn4SmvLbMO-xFMW2Wq6Z#lpYoyIF4aAYngztwKYYcYw?l&yG!}=gTv@U@2+EC4=ph<|q!T&HDO?G)Qy~p>I94Q z|1sZFm6Am#SI-f&^`ksR%@&NT!xRmm^*Fwa9Q4qFLUU!z(!o7U~K(WF311%uf2J7X2xYr4h5M-r&B75t!D!7yqruiM;H@Z(bTI|`F6 zlIop7#=YgNx=^~T#E>dnem=Xi>`cwn7F?-Z`WU0DK7h%a`)&DtBzv@hRRvdAaM$#; z+^w_NEw_e%4(DPhmLsUSk{e^DquJKi6QcKMMX*xBNxk<(T^gX*rm~}# zD~B-*Oc4#7s<6e|jVW769x2?Ei#`+wp?=RZMx$NgnE2(HM3QvL0DNaiBNQAjET`rv%IsLOJTuXciQE z4?S1uIkF!icq%y-)Rrooa;4kjzwxM5NCpMx&hP?a4rx+h4f85cxU4B6Dut`R(X~wA#|2)BX-h4a5c*!<)jK# z;q6G>Y>6OW#fI4Fz^!My|0+Yj)R)A`f$QS{HT_$(=qNZb3M-63C+{>{J9fLyteH$V zSAL->Vr#`e%}4S_sd31sDb%%sb?YyxXo&c<GTubSEd z$!awr3H-IMmTMq2I(~QVJCm2eO-&b5+XY6oZN>99uXr`^Kz)2I84+umv@Yg=f0wE{ zG?XZHVIGFjCKnjB+WPjg)x-d)9iMouX2g(&pp}PGRq#$R^}cl2$QR8b=))wsfnExb zMzTb`JL!F31~~tPm8kMl@nVAm5eRt8H>%0iLg9~$SG|cA=?PXefy;_gm3uXO`5swQ=^EFZtF0K6L zj=YW{#N*yjIRM?1KOVsO&`JY^S6%iksx2O!O;>y71``~;&QcnMdO{EujQt`VK_$!nLZ{b zFx1M8gB_}rSF`a2d3sjJND zG*TQj&6vS4+oW$OHRuhTt5IjfUwQ38oAJ%$Ve+%ZSqe|j8xxf9wHvxkk3(8kgTPOo zZj8!4n6w6m6)z8R2E!15)*O`Rt|gwUHBD2ux5 zcwuXR$~j-=_g}`Q?YoR83cQm<$qYiMs=wv#Z{*+pMYWaP{ixOB~))>qD7Hq~{VW)c*^oA6VdGG+GI}dtx5X-gtw{ z&+>EGnd>?A*&x0w1xvVeg^D>Fx~`mB2Q>(*@)gS+jEF1KOQ0HJOc-1Riey(Yv7H1Z zcx}>Ar>I9rJW0fr<=&m(ksNiany3$b!fG zooOd6f(-C{1S8u0R3#KAh+5~hn0we?^VNUh86ukiqF&sNdRCOmdd*`F-pywHcCeZt z)x1&50>^R=9u(_us)GAA4vIW3(L+$DQXwY6!Hh`NF(|B1ENrFlTTAPI{LxvNYmR@M zX<#=(!}8)pm<^QuzMB8DWWPz`^>1kNhg0$5{-xsQ7*a|GX}w#so( zO`baQDni1N{$R=hO07p*NSB!UL-KrzMyEHt8lm0g5`sUCyhqU3S?}}3jg#9H!O$yr z@@zG{G0R?qAv{0japo3eYn{xv7HT1a6 zWGq>U2UJpZ^CLb?DV%{#PISdT-GKxifrQ3%1n9QVR#Cex_f5DFF7FivsUn zz^7c@^@T3Sx%Y>lhTwKrdO$5!EI>T94zu0X%rdU0fTd3ptZxFFW2-=TC>Y%gW5t7?!^ z>&9B_zV02x<{yAaLT9?m0uEE%H6LRrG|_iY+YkrMVO=7o5!tr(U(2LZVqJ0OVzBZZ zBtpU883JPmNfVsc;ZCpumDv6qyM^niCSdI`CE9?=5uUkoQ{5X$F*&L+j|wfL7M;Zj zcjqQ{dq7DGnbrhy7@G<`_I@1x_|gS3jb3r(u7KczbN!b1007%nopy_UUmqZCyxOS z(>0J56o3zZc_HOiyYURC4`6Ln)IKnEMJvv64~N}=zY=eA)kE#>Y!q!R7t8pYyobP+ zG1QRYULZy#0csea5%r|}+z9B?eyp;r@j4NAWA}_1$6?WpchlJcA#+&aWBE;lC8bI` zkP@I*LO0wy9vm9xdpel5C;sBjlmLM#G;D+Zc)kjgAV?`2s`KrBxa5R==@w;#N)rS? zrZ{zDUw#9LThneAC|U&hp6F`|sXMUV3#iZ4fiDZ@lI10M$Az zI2jx{KJi4bt}$Xr>j0%&?K(YjkyY|v8QlCq&<$qGA$@?+%sDT#y$f%txASO3H%e%% zl+=)?gFJl%`I2h|?qw1^aZ)Hm>5Z$U-J{e;_5LiyZh*q7 z;!<2tzGCA$nN)yb3GD0syRS0Vm;ajupLG>2RU1j9;pPq*1^^IFR>nvPd$erQ?mSuz8-gD4q-J}K zC@c=$G%<)7iuqH2!a2A}r6S0V*7*Kh>`Sh;qM$d1b{z~P7n^i&qp4v)4ba*RT~<_I zE~1fMOh)}fc>gg^uDhv}+?H*+*&rh_{vz67F*a&1lUb4LGmEA`5>&W9H1G(v^C($m zBFu+H>~Vb1V^;TKJiTtc3{Y_wTBqVY|`{n zZHgbZ$?NfMmTv;sMq%5hj+Z@aHtX{mnS4*LK@o;7{(&o4G*-g=i2MvYQu&BfX_g05 zk;VWFh2xg+)m|r{dp|&tf+J*eJg!T+qX=-#dfK89??7l^Ory;gvS8-g0BC`ip>KNF zG*3)c!$#nK$6J#Kh=fk23lBF3&$#Pz4Cf+r|8< z3cGp?Lb82C9u%M;Q8LV30Hrc^jCG#P%Cw`!0!7SeMA(+;MJpvmb7ZqxYN+y z9L;s~#e6R_{U{QF7npRwWo=s@>ZFGV&#iX?p4#em;++^nLJ~jAV<8i8)O^}t z*bM~5IKN3U(7{cG-Xce9lj_DSZWuFC&MYM7Ok8MOu$@9m3cjyl^31PH-+5WN_3jyc zyX_^TZ*}zy6Y5dr zPgoDjU0|7jZ2y8uzomK8(#V5Q-`7R^P*FojP6Rwy^uTERPaeI*d!>S>h0F9cs)jxL z@89tl9!W`w2;I!=sLwbgnQ72h7cDV3P$iu?4MfexxURRWvV zbv%oaydQ3pXDa`pJaP8zea!^BT2IBweW7Lub@?xxh=}Q2>tZXv$LeQgkLE*Rz?SQB9N+e+$5-a3>=*#BIPkoQ)gwLO^#BJ`Kydav}HXYNQdH)N*}o zp1$JDtg1jd_M0u>;bUK;^pO3h%3RB)hvFeUH(!?8-+1Vh?5np5Q%6O+LX-BbFwPvB z?@!kxx1v%zpVdDvI`>W>(+mag{{hQw$9}i>_{k~OgLh8F`s1qqgQ-87ebW4-vd`p0 zjn#BfXs}yd$HL7yyRL;7R(iG95fl}*HU&5sG$Q+Afr6ma4y>FhVz|?Cg9@3wrth&; z@zhlXb~0Pes63?gO_xG|bvfYEqZ8g1DI@TbZP8YhkWOU=NZGZ^vec7fM|~o(w=DB4 zL@B<0!07AK1A9w-$)z;1uzn)g$Nk=?l-R#aRKNza7E?D38J^gRqI5HSMPP86(byz`O^r>SO<>;I+^%IhWyb`)T_14 z;6nffRfCa_|X@r7*;g|yBYsrLgbOy zG#si88@z%z^-^>*m5n-e?&*~NKs*6t_jvvSY=Y0kY|lrU$IC0&@1#LH>tzK$;SUqs z%>i;$PC1fj>J4JvgldX`3I+GZm=U0_^xdtSvjW;_I-a}Z2Z(fvuY|&{fTLbY_n*K_ zL)f?R7EJdUq3Zgx(1F_6J5Z;wzZxpttijnVT4_Iwe$D}&3N`FV9O zergt?B@aoBx1C#l?LL&vYxJ{lwk zMva|J&)t?+lE8bq__}qq(thU&-Z^?vq0(ccOE+4Vuzyz`Q6uy{>i^YX&2v5%>R`h!CTg zEgTmGVJJ^=kzglFiA!UTLbX=#Gz9v*$B?rs;D`-QbbeShXDxDc6Q(nW2E3zUtfSMs6Tc^ z{uExzo6ZJF#Foy?_l9XNh#!e*3VoP9uV&YQ{)LVkj5mg+-bU^D{auH1z`UP4b$g{d zEKqf>(3BbuPhWN9rY7n7PT`#=<3t46#IXc{9A{nHCqcGcIHmt>TCBPLXLG}B z+3-{5;R1MiYLdPWHey#1h=(cYPf3QJy4k$tl|VSGdL=|k^qMnK;mszT120i&H%IzY zx+fOX=eiw2x~e2x@|ot7COQRDw~G>2P83_|9bAJeT`RCy@!@bCMFDoM5uzeD9Y#Xg z`swOiQ2+mqFyfHP&2JbEhts6*QNbM=WK*tmNw@PmYGH(IC<^@NAiB8BHErGTld$o@ z#C4_Kepi#M5rXeVtA+Rfd`Q{(SY%%mR!w?CZt5EA54HPt;U4V~)78+PYID(A;ab`3 zc#JC?me(a!%Z=l-mCmICm$P9Uf6}AV=q?i?nbs#O-hXQ4xL!ge z9}>|7n#}4E|LKr$*~GvOLWkw$-WA#?!7IW9Uw;7^f2!xBP&h6pOuB02X<8Z1mc`qD ze}bA#_DuK?$Ak!2EI|o*2)f9b25?ubzXpjkUQ@+46)&qL$1L9g-e6MR?^J}HeX;qdphJh&@he8kwHwW)%-@vME znL~x_=nOS$2_5Sp5R?)MGBaxEC_c*@SH89oE9zs$!c|Nb9n@-y>EXSa5MXIOF9NWdKPmV=OjeY^;qsQPdmSx zr{Z0rE$IaK#s<_{*MeXDEn-aIb-6!inLZnzkfK7G4fu@*EUCRi<~s#`UU*}9y5jj! zHA$exQNYrqFMEtHXVrpXcin>4*P!b!pTY>&dUi%o<|O0yqpF}v5(^WVXEQv_FpWJ7 z6`O2Lsq6KMi077$L9&bPjUZkBw8s$pm-G{kUs(+w zG6P-$Yk&;b-UV53&-i(aPhCa78@kDCvQ{G8+Dp?|aB1madLRs8>Os z*%Wkn?A}^2_o_r^z*W-;f*=Gv3PD2rQ>yfM4)1sAGh}~YyO9wDobM`}2s+qgE#rd& z_q7y5zZDG$y*f-}h}f+Q%t;OXy&?aozi!@61iRZ9}5 zaiLtz?!<9h_4&{v(P)?ZW_`%5`1WnkNEXTGCqxoljat0$fZL677Qb6>_mREE0~u{K zQBKBc=G3Wq>d!ttptREV=}CFU#&!uIDxcYzRKjTV!4~m!Kpt%Kmm`FPY?S zH4K(0jDP}n0Sa|fL04v+cF)3nFJpExN-GlK;C+}b+yr7Bo_2a#;~`*Ob%GhVaCR?G zY6}?Cv0TJp-oR>zlaakyM(zJKG+LAa4w*N;}oB>KPSxCL1Q9Zs9_cpIxLnlV15K%0y^Z{zT+ zHynqQT`cyz_x^cgGRIYdGcPwfoRnnmNM# zyf%M;4#GTJhodd`s!GqXQxJ(9ozhVwUvLjNW7TShmAqLgNkj@pefBP_oBLDRS&Z+3 zWp)@uclkw-dWT&t@Ao(wUV;_!5pXKq&Qp9PJ_~ono)2ulW5nb_Alyb+fs5m#iVC+f zHmz)=INRTa%lIg(hGvF|!Wnc1^ z%_rCyj&vX2SLC+u0>G8QMGoXh;ui!L4g;;pmu%z|mb0=-HwVhV-hG`k@^NY3EHJi^ zwlyU89ckFC zmQ%^A+Oa`{+>AJ3LnjKok$K@wfEQPgm)$9y5`@{`A-`s) z`&7fVQE=FcxF8bO^OSD9oWbIV9PQn80tli77e*KwqR2?a3Z%Oot8DJG-Jj=K z^Hd&;98YxGnp)nuQZo6-JsjY;d-u(nCcuUqq}G%J zDZp%U6iOnn$g9ms>k`{?geo_sCz^XsDJqktn)oaBvUZ4xs3(c{rIc-{itf7+pQoKX znB@E>GVmc9%X_p(aheh>8DsFP#<2Ms$-jG#`sGhKe)FE08Hf4%Ai z*%xqa8z+^!fcEI0?d#u@+1|@nSiZMM?&3({wUxs#W!6tsWPXy{5C|*Ce*< zvJ{2ZGX(>pgs2++qDPMVBRuJ)Qre;j5kLtf>+NG*!pC=KD7-JijhV^5~4gm z;Oio(DRKyeavsvgzho?A+v`T0zD(CYk+R^K_{C-RYw2jR`&6if!n^D#I5?&(5gkr6 zyXZT3o0o@qUO-Ge@Ng0R^%7AtgEOV3R5vmn`F)sXQ$Uh;lt#TQct9e8pGbvj_rFK^~#btiLRM5>BCu40#87yd%{dL~y}rb3f|8l7o9v^_>=RrBFXe zenP7=uqqs+G?sgm3T}cTW3Tr-DEE9qe8SdVO4rb;u0atc+gJy?e~4~Gumbh8;_!2O zWV$u~bz6DrUPL1pp=Uk|5R{M1xPI=&u^nye=-c5M#_ntVg~A4k)NX& z#@_}Z7J4qe2XH`dxthYKZQEs>?p-du-vMIyr5lu`^CdJbKUBBpO#CSE)y@9@|Nr4&6bve%l zV)epW3JZgl&Fl@2iu1rSSLL3vmEWEt$b_MJ^+dg829xmD4t*aNkc#k{1dzKlepy?l zDxUi|GhMV`YulOtDT0@{;v|$=qaih!h#7iT&DY7He>9>boOX|H2D!xwx*Nps%Uu^R z0Kr|)%RhEd4h2ZlH5bH|Yc=qOHv`~a16iSPZ{`AMZ_hYmM6pYjI-F-p_Q%0iJC{4% z6v-mfl#+UW`Law|b(gg$wIhmD&M+?mwhB!)=fb4}Mk@~3hL`i2Cd+!-^&;uwp6t<$tZXp)|z4mxX2sm_A`Aci&v+#JE{ z!7rmYo()h-NC}7)_z){QSa5}*1$Dn&eGJ3v(!gXuh~!PEroTba`$;$@H@^1LzQ=`q>? zC@0m@9UY?+EQL3=FWWromXjwH`+UJcH(v{(?l2B9!CN#bTWvkE@&Qqgl9AOH-P(?x zm_{Q~r#2v+#-RI#B{jql2he^?rN)WFsM*Bb3Yfspb~pJvxMOF{kPC(Gk|~xVm3Y27 zgHHwY71KqU|zk+|+G4cO5Gd_(I z#oqmy4Cm5Y6u5{NiTJ-zMJm=;#kp7YVEJ6blaAy2$M$6Ac9$@11+zsoZczx|)D=^B z!^H4t?U-HiH0HKw)n)C+GN=SgsB=0qAXquH-YCMhVuE@>?fSzU_YNP%&3d7Z16u$S zo8dbH1hgtnC4uJS{XiB4FEU_bLi%1n%Dl)=KFwLk<^$`)9p+5M-3oQ`b6#H96LVs7 zLmWYh?s#spUh*+idy@jmyqKMMZ*G$&k9E5KvAAv?g3kk83L2$ea+wZ!TdA{Xt)YwH zNN%-P`OHYT*ATuSuq~53-bNaJk2&#%T5+1G*%~>8{|qTmmNXV=?Ix{&X8c%bGK(gk zh}fr`n?=R9qmspuV3n4-x@jDiITPG@PQrVB@3(8?Yu~>*N5Y}0IZdJ>Zhp)eVBgBZ ze<$e}reU*?qo!Om5LK9*H$kx2I0H$7UF`d)y{i6ip;o9E>@N+>GJ#1TmM(ggY&OeC zsD9<0NPE48M{usJo*!<-3TO&tZe(+Ga%Ev{3T19&Z(?c+ zI5ajOFd%PYY6?6&3NK7$ZfA68F(5ZGH3~0GWo~D5Xfhx(HaIaj3NK7$ZfA68GaxVu zFHB`_XLM*FGdD9dG9VxzARr1aMrmwxWpW@dMr>hpWkh9TZ)9Z(K0XR_baG{3Z3=kW zY`bG{Zr!#m9NTuD*mkmF+qP|I#kR9z+qPG1+qUid?!E6mx6W5z%|D$rT5qGzIeOKo zNk$}QZ|9=o>0ru4$3)M_4Nw+SQDNj_WCSqMv%rv%2|Jk@x>(xVi5R+=as$*&O#sTK z4ge-*05c;a6AT$Z*xtd@$-mpk{Al?`COi0r=(S<|g3g z>`L$C%18fClCr5Oz{SE8U}kA!3J{i8&;VsXn!l8k69-U=%c%myP3=sb3~c}ku0}SN z#sC>hV^ce4Q!0R&y%WIZKMKIu-p<7GUznWf{|&&-&D6=|A7Exq_O<|7Q58Wkc{vq; zs4#5x1Rx{vPr99pGxtByrp7KV|Ei7_;PO9`jp6@DM*k!IkJriLKN39*6BEG1 z(%1!HWNL0{2gC3$-X!hJ>;dfmF`KwL{MYplAm@MZ0Vx0BkP2X8YW7dGtBsAEp{*%^ zQrO&BP3l6{~<%r&io(x82@9k zbQZJpFf~!IboqyG7bjQK|CrTH|Fbu;rY4rIw*N^t{fCo(cGbk*&c^fquJ}(W|6Y$l zOi4maMv&%zn&97VQ9EOM6H7aDfU?U!d>T5L{Ey+^ZUsZj|8&rQvHZ8A08IZ+mo;>8 zvh)CGGt&R7MHv6}{8!Tbe^Ek0_8!0Kn3)&>bS!LK045d=b^s?UtIz*}YwYUeWNPQ~ zZ_@v%<-hvBo5|GF!_*jNZQ0(KC)g^rCA8dEv~acpoMv{~K$T{h33z3y=SCaZa?rv= z|L_XuUIi!59S(mcz=(JEa!2yMnbl@B= zpQajV)*__f+KB&kZw(|YFK8F;h74QZqM$s$;V?`qzy8WfSX)zJj=kD>IF(Q+O2|g| z#yU?NYsi{kx@)uDt`N)8MmG>!IF4=VnEp2w11X_PaLu5 zkF%+mD*0ZcTJwA6wLw~v(p^c1bMQ+z!v|u6I?Yh{pBY=7zRzhxxs+OMGc2R$^7A7F zybsoP?I8Yse+vH97?KZ*>M(lAcd{4jG2(pume>A1i&RjV$tSuO?3|G~cgN9V0jS7* z?>kXB*1GMP_syzPIBXYTHSQkPE+Oi-VMW2^0`&9^(o-%!-?qXBavgzR5~#$~^L)Z; zwdFn0x#MU-IrdElbuK2q8C$pXMBKy>>0s1Kc@?jGwcMPf1n6|C-m29g$O3-h5{WpN z{@n=?xsFTfsyd_OL2Ij*+^moe|B5CCsg`6d1zlT=wMb#G@XkWu4obKSWMzkuaDATI zF>v$E$!d=uvHHAbIbu%JkQno619p06WD}|4^B#WLR(s}X{FvLCba(!VRe%}19Z3Hb zOhAjGdzJ_CK_*A2S9zA3SV+Ix6VbIqvQjyFc3;eB-CPc`k#Zg{AEX7gyfx=7&1eAOPa^k@RZpG6kb8hsslJYagX^gPVk&Y;B(`ZX7N1N}HnD zxu&0gkFzL4tnI$CvVw}+JCcl(x&91FMQieBR;f47b6qX_(xHK-F*GDrrI;KYxd1FXR^dfwB!W`|a$*CJo<)ddmQ}75*5h70F%CRCi9o!K z{vmbu807AC6hE`@DpTA&B1Dv1i&)6sHdQ>s31EUHS69)EWkpbCe?df`l(QZ%l=qd1 zNpWVE`JGIh4+n({wS?0eQEn*h&xFmV9^>mIV90}&eP)S+&`GIlUL)CqVoM-yuH*y< zchy(1e+>}$Y|SrcpkfZLBkOGX!%=I9`?w2Iy>KZZb!@b2E!B12XH}D;AIT`&Z+DkR zVi;5+R+s$n?au)Hv`FX926^S0mjb zgYx=A3ExMWzyHyxJc(-L$Z!SLAqTGx`iAUL)Gben+Vr;4(&)~f9$zj}t6r5dr_A$2 z76~IfGclvgH*oT0o$pCBxobtP_p`Ej(A14XAGgo9Y3k^?d3zHY0dkj1r((9W7~RQq zoaephw-lzQUk5wrDAF5Rd_rs;MvRqgrQsA%b8_MG!k1VK=OWSIJxIA&8G%ISk3bg8 z=H-Mql1Gyvvu~*AqZD4ttXPmxk1wCtHX@=01$y)i_I*dV`8#55X!(RX^h`8)k#DN> zBhz7lgSXO=UKanL_O0?gIjuh>W&cZ-rxlN+GGag&?#6y4+<{u zKw<-e#^BSbcm?kl_UYUt6R@~j<4xW&@$|(!+j`B3zIRg^b(mVQ^L+cpSCW!32*Vy7 zuV|ZA3DX?ILAX z2vVVdaC(ZICwz%VSozeSXP$&Be?;YhS$Bvv<-sR^%<_)A`PQ@2m)%j)DPn;D+!eW~ zw^#%Gw_iWJ4qK8X;TQ@L5eACnAvQ~|qtpiI37Yax-5R~9Wr_7-MfB??)YW()IbymxZMGHV_Lpd!k7Bfq?^TRv$zzZ8$ zB+y2yc2MDO#q?d0!6L3$$gE8U{hm3g8D;3WcYB6N=p@X2wk3-4_Jzo;%O?$-RLp)4 zsjF1EzK#>Yc*Kw0!c@EeJp<)thfLV?BX|6+rSNk z%^>l%C07O;%Y1pV(UolSbvjwzVO@|dU#v*Q-Q4^^R0&e9*&*@v7@ugK+>>bU1Wq;J zBj_dgqnf6*|}nuK{2@U7-{M|k6uG^NS$k)TgbqIWTj2iz1DoW&iG z+D9u@s8vX^m}>s+M}PFyq6mQunnGB+&_0$4;~mCfXhrzu!K<@(ZmvE} zQTH-Wosu|LCQ&O8u{+w32ri>O+SJ3>5((_(XE%q{zePc8$z%jY*`DjpsLfrW=Rn31 z<)GN1!Y2a(vEaj-P~KO#%-uTg-KXOg?}8V^jdP_(6l@f28dcldXu%ovU5zTHd%Fxe z7zDC%9Mp?K)F%Rpg2|mkHt`7eq~Q?k1|Ho`UQFI*#K};VB1GKu&R~XZbG~nYK`?A< z%M90tE>3cFlK#_dT6t|UuA;EJ2MC7YX$tYu5NBO?B(3*FOdJx(OzxvL6!Xc?__kGHLX6k>g*d{qV_9HcRHzU1#~fr;q8Lm*C1dI{etNM85T8-lp6nr!DUw67GeK6XO8 zzM{K>-N@2mzK$iiE1L{XfW_?~%UE-3&_)OteGcMbD?G1jUW2o7^$iv6!V~_@X67Vx zKfB`SS9GxC(jhubOX!jkaN$eFaM-9ri$d@iQoh1y zm?j$hn?3Uokvnv9O`_$Q($`_Z@0??z@fUk_!g8-bJhyardbtD>#%J43oZ<@}&d`~D z+J~A6z+%fU>u351fz{EA!i4-H@)GoZx6d=X2EP6K!Z*95g`6IMcX<~D)GhV_1TQhI z!MN0g=Vd1INmZ_9ul7!ra1l%Af&0be6lsuk1ly2%#rTEK;5m|5Bd8_p26>C8Wx}qmBy1HR>@B*F$JF#K& zM0^5FHt(JzmY%!EYV0;Z0~6$A%ER=gY8PdA&FvyNfvfH7R&2p{3Y(%kq|^_C^_PQG z9`9)z@@~LFU0vr!zV(0x=hDysk)f+jq2C*GWIy-1kK|YAeePUZ{4ayhj3x}Vol=S2 zsoB0)1gpb+#k)_6`5*cC(0i_}W4=maeMV%r6ZtG6R%}b5wy_2>QNjqW~}6l*N6mXZafKP z+ch=d4>3>g-LtwXNrGwwlGZf3$%wynU zv-?Pr*&e$uON=f(kOz_I{*$@2Vnn)8hWK}nPkI{VH@4WcB=QglS1=1%o7|iQZ|b98 zq)dY1a;&)cCIHpxTIfqxTucAkMgPRjpvvB~T_p)}MlYRKhWB_*CDTea0`U@><#2@_$`IDCnFAI_hX*XOQ=I(6Nj3WYe< zd-M=y+=qXqoVeZ!tRKZSMASi{!Z!K-NW3~z9I1akg_%Dfr;c-XFPfxxlp&shz^Qj( z=3)y1Vz%(;?+Gc-eTSk4cr==8c!{7kCldv@6}FntzgA_D6k=Izv3{y9ZbuDOcyRP; z)&os|1$MTN*ltjX-bt>6$h;_C6}w&hQ`LhHvnWI2TGz;2lw(IHKX1nngo&VEf)ha? zfEbATzM4(PPm)+Lm>XB)nAAU4CSw$tj!{?5KR>lB!x$yg&_(a8S43H~OI|R7INbc7 zc3~9V?pw|1?$A9=gyc2bTnj3WfGWSTk^x~$;uZT}%v#YK&c=mz`?2S^Hj?Jzx>~{Q z+sUSk7S#4}^W?$i`jXv2@xDXc->01seA*XTq7KDaXh4gOoj`+MYFTF)zt5sJPAY0e z@OJ}@c0>#!P@{;_k^N~RwyB56q6C5ZdFU?8A(TQ$;6g;{wQN3*NA7f|tHMK9-UZTB z`lW>>vOb(^yXtGYg;M~beiUS!7O87LQXY1{o9!h)m+1cTt>zcpSG@mGaVX^q^VDrN zQba&%P}I<8Ug#1Jx>g5r@BCX=IGYr7^NcN?OkCZ{C~33NfX;3w1M$pO=|D?vy}Z6S zwn8S56sK@XG(3a%vQX~Gtt5!`jW~YBV{Veu70^_qYVj9LdRLhm9UBiA#N1fJBzXLO zttZx8KAW?IU3qeR+9k~5;P8^L|^XRBI2HL36^?$ z?FIdAF!!oH@-!DQIrSdg-ydk6T%TQzN#*?9S8c4^>f+K<`{lEB>Zap*J{?YEeJugk z)I5ag(zW$gIhTc37g*EB7hK2ud&eD*W~!<PSX3aQt>tC~T|bVP(E7Hk}P>3EL-T z`;YeSQ>jQFal0}7Z(50itgcnYIo(GqBY`>QTjhm;#)6eQDNIqJ1xl}x zm-gO%31Ka{=vya^<$DnsA3jeBBLnXXAXOy{j09utk@?vO*|h-}vXOtHlA)oN^)XxU zAw@dB9q;T5k#{vj?GVsR?Aj#Ix-IB#&fD8)Ll?UD37ES!M@~riS@%vTzHg>qB?zAA zlLo0uqWs0t_WPlIaxDmnv?SNny z-Q8m0-8oMRJ-iuIw~`0crqIgH%EHe2nP}F!sMjnn-tLvo_)y2mM z$sf*cNHTZ?x=1oK-=9OSB4GS#2<|rx505!Eo4WX<5fNSvK zc5DB*?3y_o@E6sV8s@}Jk~=cHI(#(H{}Lm6)Y1-3`|0d~vi8@llVU6DeFi1q@!8?Q8Ri-g{^r7j`Uk^x`BJME_ z20Nzo-e}?;TJm&6x_~&zvtPjkhi$ulqR@Y@J7;&Ko6_PlnPUbQW8%bNqoXE z7>N>#GDyhnoNmQC?Vaj7{_i1G_p>c?Pb+JYz#mm>G*fV6h6HUVEfFPyd^IZDOM{;$ z=LYtA_@CLR%4ox4F%Kk!a9Z*CjiFMQOpbvjB&Lh4dMz)RApZTt4w-PGj`#i${lF~j z#s1NVm^VDrMMClM2SV8DFj*+{%%la;Nj&1G#`oSe^mPi8X=0pZE@|chV?QzVk@W%Y z*MWY{+_k3xB&(0aijkR%e&z?%sGYp9z)|LXbmd8Y<@+AqKxP3m9&KA5`m&b;7 zo2S)KO!=-OFwz{psW+2}m2PFtT4ELsh+q{rIeq2+!Tc99C^Ld!iF`O9uGP!L|I95D zDvkR^glWndFH(ufpL*(r2T~oF0;GSUX)vm@(q9)k4XRhmrIk`XSfp2a1ob;Fq1SEz zqw`?2qPG&<9_6AOg0J+Xg=1k=QrttL?7l5zA$3$BvXJ5F?Z>~_TfRlSoYZ8rb!dx@ zy|JLQnn+jIr{*EeR;2cNxjyW$qPLu;ng-n^c4g10!DV=)zXMEe#+?t1y(hi`s8Rn?Fq_nImdJ(YiMVuHYd@u#ge^ zr+jHGDeB$^DnPJ*TU!YU$;L^tAiWOcl!@ZnI8ItlPAz}c9+(eqV?&amYdbH`qOe%r zeYiw2fmsL2Gq|T63fS==$0izx4VO``A2rk0>Ejjc-+EeEb5>E{LQE_Dq(pWO2XDp( zo#UUx5Au(08uEhbw1-6SjRT$yYG(Rfnh&vyU0jlST7pPR?4|0cPDdOSdq0BYlQnVl zYd(Bvf`O?34_L$KxRaiw9iBzVe4SNLUezxq_@5LuV(({xCk>t3kA-E5+rb z-rf+f~Pm&KkR&N1GS!a(_XB)NEyK88ssmjK0+ccM4hdGnikXi=>!yaUr zYwg$_hugpyie!((?K&y?+G^vAvP{gi5%NL(@Cx zABa}U@U{wgV{-;a&ms>Bf<33m_!iqv+`-vpktgeZ6{2>%Z9N_Vme= znL&rG&1rvuwK<9XalCZGRo4Q7`!p`aOoteXORTiIo$edj(0m-!{Mm=aXvlkmak=ZX_SBNY; z4#jPmFPtY2R$&R|M{%Z6d!(m|P;R;YROX&0ct*S;{zr z*A>xAi%my`B`u0eGx77R3yZGP767_t?i~SC$Fcq>4tDaH!1`bd1TYQNI#QY zEDeX5SZGQ6O0#_+as|7#KBbxC-=m#O8+Wz=30t7zV7H__>EzTva0xvs{a4TzsT23CZ@b{Zrr9lb02!)F#Vvq z$|dlaP_4yX6xN4w#J3&ve)MNET`>hkZ>0V_yX6%_t(F*BnfN;gr(MY@gWJCATh|96 zPBf5`ZJwwx1pM6?g4{y9MKnd}?_%361mEbU58K++XK?Gv5v(I(?@HZonrma2t-v-p zA*DW$l7T?otg%WSK7Z5Uc`Sb-y%IHJv(!(C)c`*SOF5mON*&q=vO+5)bWpbR5xq^> z@PMP=UcEHjH|#pT^vdD9s94c;bAyYyC(MIkCsq4~K}UO_JPG7;y0n3sHU{7AOxHE; zH`e5X`T`7Po-i*fhCdJ+@wY29SF;a^5ncu%IJmrbt95KT!XPL9VXH?UeCt+BM%E?Q z-)yIMjXtHXgsgjp;21)9psnOI`=guLy#8m_mxksD1bf(JJ4;{FwrUT9c&W>U8t}L& zl?Wq@cM>90V_J>~#`+<-i`FY*xza*i$CcQ9Sm68Dh|GCWeJ@9-M55$OC6I&SL&iKE zUmhqqI5(Rpz~T1KLuI;YFTgFwoS-$%m8q2{Ccy4s(0Nt&q5)mNYq$MocMCp+B3D*o zcj>R{tcn3!)FVdN33H}dg(5I26NN*vF0YMUMz3M3r0KV7$H=Fb1SPiq}LN;+rl?j+QD7krJ zzTyC(GPOhePb(0{RrYq!&w~0@30Y}mSpsV1JHn)9Gfx?a9kTm)kXAM0b#*?>#4}xB z@xvgksCFdwdgpRcV0Dcr8c_TwzbyE%v1q9}P^=m{qUo;z1BAo0 zw3nSd3Sib3PAb}Q;nt>~6bmr}6|DRBe&ui=i_9L=oBSXAJnM~x$Mt*-fMe~_-H?lj zD?d@+7+f=wq;SK4KCH;C$H9Hs_Wp=iI0~^UE|1GqIFCPy6^oEo+abV7jXzLtZmHt~ zXXek>YqL3w_CUpZhln$G3T)^UOwhGWm^@)0zdgqDJ5@+V3&&|HR`XE+=?ang4;WIP zyP9kbh<0Tec1S#uI>`vO@q;C=f^zEt7Wn$C@I)oj56M0kaRe%G_W*L*0{l%`Bm_$v zawiwPgdJaSx-)`sdf%TvWxPbAm65!iysE;K^Mfr-h*8a(FhrH0<<^DDwYPIn7SOQc zFPzKyrzwpbEtdY^Tg;fF9zikxpPQ^uu&Q}NJ?{+a>qqf%(AheAVq3+(v>nsd)WkH` zZf>iUeR2(V@hQ0F*59KD^#@@O?2jv}+2VJW*?FIfG%@)0hp8mQDL#L+j5F#xAZnK= zrW8vRYeajH*j+{gzWw&8x_22|#uuyA1uzJhsIReT zGk!gH{;+wR_C1KLL=EkI{R3*07Lim=+lBA^c+T+F;pC6p?Vqj_J?Ln4DJ04b_HgS` zlv6xhTPi#p-O+cRgAiF@=a`4Ue84u!Xx2N9D4XA`>%vGycQ(P&aF-77UT7j)YOX8F zb9f9P{;0~Q`)m$!X@#4@C_yDEbc3qn4@uY=DHKbvSqiP;bx@GcAf;oN3Qqi}mC>VNq`;uv}>4$5kN8LbSy#=@4=*pDTr~czO@bssB(UI~#*>AKU zxVyACP7g+4>=*93WUgQW%_y{W^#PjYT?Q+ zTkH;o>S!&G03uE_6`rx*W09s`(WDPW;vO$;E!D2Oh}4hSj)5aDu=UfQCixTJPv79J zZ}%78_r>0P=HTx7zRcT5@=3xvd?h?~{9)QO-cK>j8hF~Q`(_?@-Be(TPPFOP{G_pcAj>N@QQ5@n=0;Qe z6Nna=R`AQe{k2iv0SSvZcn7JuQGg6FgTX+2JeVU-P4B{O-Zb5h8txp8Ny-ZY1ccM&NZ@`PI>d{E)#lJ8N|F@sJn^&(C4+>fNUIlT;^Q;f0v5KcV@kEVtx5-2o8in1 zT;nP=)+3?4M)_ezpt~EEwMgi?kn)B*S`UMb8Xam2d(cQ5LCR-EXCA0if>7H(6T9;^ z6l^(4Ffn)u#;UnfW6PQs(3G!&X3c+#%LY5TQ=qjg^?`1^>&OV#o@>0C6-+KZN+W-R z@5r!Qp9N;nz{4=9^m9#e!X@rI5`t$aw%-uBV*?Ki0fzz6*gUP46`=%60POXj1{l@^~z8 z2!+?O{hlE|;x7w>LDFq-Rd4N}_p|eU{SX_JMd*h)3AsFI7xyQ>q?G%U3iq7SiALfv z{Rmi3!6>a(m9;>7A=A4neu2{pk;_Di!NXA7UN(|-FwgWYNV|0&m+5;KoNq#Puov7w z_7pp{RJkanVMu|Pq2i?{v{QgVyQ~RHY*bF)$VcfjAGs=P7dyF6Y49$ z5i*yrNe>``V-A}s9KJim-=_+-j7&sm?&7J6>TePIn&dUo717z0M?ecE7p)|`sNEDp zqgonlKXhH+((djepH_c7G}xLmYRZH9DA#@p8=M~I3jWahSx+Q3W=+||kHql|rO4vd@8 zF~uIM(Y)7r>&Ivx&IZ1sCN})Rx>}Q6~SAw^*L7d_f zM@E$CKjrdpx*~ug_yu*QG|oNczUEma^X_DIHXT<}D^&4;KVK*-+b=N0J0CAxO>=$? zd{h*`ujCTz&@?*72mBrqMrhtb$DZ)A%VP7svSlm=?$Ie4e~@0@%!EhpT+Kre>FlB1 zsMq|3^jAU$st2*k0j)(Q}clD`-hoaM9W7%@uKa594! z_5Ftov!ZPj**UkPxb4QTMGJTi26!c~9i=+*_IE?2803CnpKDlL;n`kCP&abf!GmpWP=sY=#J!A?9h00d^a;55@LvtJ8^D>o%95SVGC zo)uOF61}`KG%TK3G4f%BRgcCnzYCfcWtLJrQ4o;hi53naz552U9b;c(CXaht2l+qa zo`@8zM>V%xtNG<9?3t#kTwlu7n5$+)ZzcMGbcKGuH(2t5RqhuFEljIWx)#BAP|ONk zx+!IHd_)oQcYV2qsp!}+HT;0jFx5OSW09PC=Y_mKO-(PTk>aSC+3_m#E26D25hV=` z=j&-sh9!V#|CMg$FX~!uN@~ijO<9(lVev+&{CXr*s}#v2n0TDLvI$o}=#4!7A_Bs# z5y5WF5YbZm(BSOD)6_fphGDiM3J+ev;tcYSBe{|4ml5i&U^b@l)q2DtQb2>i6VM|J zHET3!RiZb*Lw}Y(h>vW1cKzNVi$-2By#hx=*P3Xm_*1E((%4Y(lyg8rigGBq^BQAV z`RHAK`w5_lt;tQ9|3*1ovjgg%^F zA{15PiZQka2tHqfWe)gJ7<1N+x|R(Y3k$_z>fUFH8<{);tpcx5+8c9BH&EU-M*j#r zE-~>5;J|R;;^c9^w?RR!P%G1{WLZZN5i8@~^JVxDj{cm!xONKT_t$^oU*Z)zBDft> zy9Q43-bYc6V8f2nli@Ge&(LnL*RNryfx7)Y!2qNTQFiF;3F5%E;fZIEs)D;1b&pP> zWjpeU+d1BeBeb*K8!iLWSWQ^HAfo(mPX^x}Cg)eaAyd5RPT>tb>e~4b&RuHOzk~Xv zNo5L5E?K6!1(d~|bA^!lPNJw^4DbLu4Yp;78L0Y=QmazLow`_a@xadm zK%;^m|)#oES|gNbojuP3)wO=I16dj zZdG)@C`%Y>dZ!#mB{@?pX^CtvPiV*{J;~KmeOe0MWIdb_ZXI@m&?Y0}`FA0@^nynu z?>eGu)Kkz$Bz>NGC$ZLFT63Mo52(^ve^i=0@)MzBd_)H8d98O1fl_+fdtrGgH;1K2 zl8`9be`Si38_G*5PZg>iQVWEH)7|Q=Q@w9@y27|#{8NBgE<3}TQ z3^sxDd`HThcI=e-X2m=iJS8EBsL`N|C_cwXc4jL~aaT2Enp-lyq7#Bfi0$-3vusU% zS5Z3u&@UR-1yKQ(W>!Q zwDRkYIMUc}Sfp;=m{=kE+WR~>m+v#j7YZ|0@GXZ|M-;p40#k@+6_RW8v?v5t)CPs- zGczcRzYC5q8f%;jgMj_kS+`T|n{awc@cOSFoR)+NJ@4WD*Mqql_;DN;8W~IKUsdu-AE+Bat*66`)W5F^_}o1y6EqTqbCPr-I7J=&bybo)qo`@I@#$a#QcbCFklZnw@kgSB)P2!wWYEz zwrqgLy5;?H65w0sl7G+_IXc0$jZ9;~9re2+orRa ztiH3gnn!wcs4qn*NTpxaPU2F|l0f5xCQ_w0LO=Jbk)#8rj-R3?NLbOXO&}MK8$UIWaCOTy`xtyKs zKoQowsfBv3gnYJWYOh1n@LwsLU_Rq!Xkh_tqQSE1)mp?48$q3<(2*0w=QbRM9_Haf za|V?+Q!F=x;5HDCQ%hW>e=I_~k=f=?uy|@e%u_8nYAMJBOLggudZ+t?!@bQ@WNDu? z4f_=7my{ZP!kE&(AX;1YMEve=USl)^J6+^t(3%e5cm@okg8+PH&JbD<@@Z^yRJtlb$nNN0x_|S zzw{C&-`cvE-yYLokcncg8u-o`v}_{%VjCVE3qv7l!>~=Pk!6a)+Wr{ZU>LEkw`n{K z3!3)&QH7$2kSSG@80qE0Iay3U2wK5*ih;o`&=oqD(#4^Yd$4HqB`O9NcHL3ETK zz>T875dMv5+#QGDG%C4Doat;CdcFpzQTU`X;s@w>y0bjmg+J*cF13hZx)Acx2#pCK z1#gFS?Gj1Mdx~oMj8_ef1OjF%r}=#7@K<7Ry$naVDv)E>Q)9mIXh=lnXPM6YBC;x? zr%V}UXE*7Yv81#PS{*iaDOb~l5GQ%O4gmNInt87TbMxio;5Xb+R@ zNwbqkFO>bRDn(F9h0$_&VMzB0!P~^ZH+3IL1MuF6;*V z{H$rnSZ>3U{4@6JD>$-_JQt{}z>{pOkFgyd52Q7;loJH1Sz{m(S_h1sG=u5IHEjJj z^)?ClqeElU4;XjB5+*m^V-YOtOe6c9fg`F|9t59P^{qM^07Ck1G5>H!4+H zjiDJnWe-km;i3b^r`lh2L<ttMsL)7-^gjHz9^gVy#@6~Birv5Uz0^fP;iEq zztUV`7fmzyd3bL#AV=4DO(w%%Ysj@zAcDiywEr0a{h=!8TDqJ3?3(L(y1xo|LC^OX z-mO)bd(_=)x06^Cw|)?u`>m7JV@E94<+jqS%^m1`C^sy{vZOkmF%x?#vYpOqn$zgir(ZZ9T77#zy2Xyu zkO6+)AUP<zQRb=@w`e0tGt=e;Q^Flf-%D zi5IL7RaDE*z$CJ5lQj{z!q(biAFk1$A0i&W(epK{#H8s&(y2P3Pjs z$X4|WSb1aeS3m}Gfq7Z_aQL`eUO)9F*0ZcQ2p4SpKYM~&=qCGW#^hYsR%Wd?KZf*O zEubD#gMwYhm}E8AbBuILxs-_e&$_72itpOYw*_#aFHZ1^x8(qlC8Zs1os1|qg*T|p z6Ds93!jUw$Q=Q7SxuvhER+IZoW3+BUkNhgsMvM$m*rPA!r^-DRMc)NyONshd;LGqK z96Bm?{O)H(!I5thXSAAtKQb1!M5*Zwsg`J9=4X?=c? zeyywv)u$+kMkKRF@fyW;r@T5oL}-z|NF&q~7h^8Ggwnsi8yC zjt4Wc0csxmxK6+=ppv3DV z9y@K$cO!AqC<5h6z7>6AqyKx@xdJeRje0RFvtw27M|7Q0E-;21m6ogIPGR20t8r0Y z{Kj4=N>ixyF!C-De2zf}Vn}Yac zv@_mWNGNrxD15&rn5rjh`)!>dKcckFcl9e1?@5A5BZl4+?WaKETL;%VBPj<8V@LP0 zvY>?Fw970ic*1>+e$~A2uV+;VpGjrSpbcf*k(p)T9*_`7~`vts!Z)C530>Tj-;0+Ty*~jPmOVYC62*+N3vpRZO0z?s0Xjzh9pJV%n;H#(55)2fz0A zwX>0|-O0|PX@22eYc?=IL;ln^*ME-5rxWd3OVMxRi}Lg_>HeuXDiqdDQR$}?Z&Xv? z=7ASY4dvOe2f?_sOsOk&;r;`c&Xxg`A7{`v0*?@9SHg1ZPc?cDzqC$BVAqq@n8(Jo z$_)hK8?Ig%bu@p2F?O6~)ca^{QPEHJNfmwzq6Se(f}m28hvoG6q1Oi*?6K+4hCx?V zl0H~<;%ht(Wpp$wigaIImGh3_$_N|+yMPlV;}yZm^slcym_Nrsf6Kx;wrLtkAJx*z zYA>3&tN}A(-dzyaZ4MBUGEcvp+TR4hUkbP%91D&(B&3)&{F4dGII1uV-VDDgBBpjTN7a9zb*Jf?B z-yJ&o(P`t2Ci>Q&zi|Xx1UqpQtU<@I2eR5+3*Ed1q!=hR5#i%cl;Y6COfECTh_Uhq z#fyM~LkWu~G8*N-A}c!Al{+vca93UlPAi$W-3d_?8uDQ`J7wF1$LYuX%+QX!no$S` zcT9S*k<{|6C8&o+a>gesM0imoX@m8O_31+N8N_w;GMk29a_Yd+;f#Bs_u9Q+?f5g9 zN14t0&O>R4j3H!;vw}51XhVp_4CO*@o_nx;x#@l5QO|vB0Ew6VNpiiB`c(02O>kPGHaxzv$H~30JB4*F#l3~nc zz9?gB=poR70%DPObgLK1aY|FpI-ir({b=7~^Etm?N6Ko`+=19Li!P>60nMYP{8)^w zihparxyndZ|K-f#jiVm@(_@i`Vpi=h)BUuOf~2xT5NYwngo@~?V<+V&B%l#AfrwSu zaoIu|hy$bnH^t$KW>$AgZR|Yd zv0yCjLZCw7flO_XJ%cfljQaX|<@CAo$yb&IKlS%rNw&7PV(zknnm0J6J(S1um+>$a zH1^X0)kLV5N6*~3FI2p`_5yoTs?NWDeDVHud2#h=cRY?NTpf00C{+}6Y zk-)3q-?>7Kj_WC37zOuSIib|#dDcIkp#x_6kHzNwCV9~dRk$l&FBkHbT_BG3@sDsI z6YJ>D6eefin~wCjx4}a=oSo6-+kXy@7r|gKTtKxE;#5C1eid8?u~H-fK)MotZ4D4H zq-^5gtI|YAK=^*mX#g6aAYuhu2CS<(*2s(}q+kQ&$bT}Lv(^6?NAEOBSv-=#ziP95 z@I@tmQX2Khj?OOD&TU)mXF59!AtyB8qR720^J)G3Rv2jCpE)6Om}>sj5AuSD zPdbVyq?RdY(8>sc2_uU)@`^m*YdR;-4ri@!k z?xqwH#B>ek7+xyGS`9Xiu7{>f!L@~XeGi|hRCSa{^|2XI7w$`zr#uJc=f;q7O7J~gVLCQO4RBb}rXWXhN*-|bq zt)_IO3Oum9iq|WhVEh;Z_eIs40K&?4JSt^q+GH(%9d2?_{|?`0UbNbUOh>B^%kSSe z`nee|Vku#~j@=EV0)qXesQex~tK$Su$;Fc`#@hU6w*oyZebkbN(+5Wl&qHU1#J`Hw zNTRkw;M*p0iN{ff!R-h_xp*g(iP~gK)D)?qLP`yVX;9ZC1e+GoaMfohDkj&UZYlmF z+&loLRvi6+i$m9-tjVR3;lsz~TOpf(HtE|7D&#}kU$jjFQ z;vg{nUp3qhS~Oc!?lu+qP}nwr$(CZQHhO`;=|l)%UJ>neLy+ zT(L89GcrwSfTl2^Ns+a}M_-ZNy~6r}k1jK9i!*q*x%W2JIR0mDzcpWfIvvg%O4^6# zcPC;ks`*;tsv`^@c)!~@8Jk&F%OLsTAW~V3gi3S(H$ce0irqA0iCu1%1UVXX0I+LFxRO@w!X8XiXFp_Vcer3%M4~tSn|=zk@q*Mfp?H0B zU_p7ZU%sgA#$x<|69BAZ>VI|iEB$5IwG?HCT2OHs=27BLUKY-eVM;;3UBhXD$Jj-s zr4Itj#OgU-5-#LfRdi#s)}|=VyF|&Y-iiIr?N)?6nsD7&_nSc z5fzsX+n^zbX=vU4^(&s9d4kL%MU;qDOuy(V=2R%}kO#~;JzUNB$C%Ik<69@8F!r;p zT3TdQee3Ni=z53Xl1|46$3r{xwq8acB@ax~2yn>)@f1 zE$o|b?3zt)FT%@~-cym!(k)6j@Yo-k~R-LXu%&2FzTT9PqC+1S3shI7t`i!9eL$u0`Xk`TZW zEv@GEh7<%j4}IlllF;jTY<#MNb)MOwdWIdzfzVTdY#9YVoRFe>j(i%;np`Onv?#_F z&REhq*#i(TkMH<$TF@NDCM?A`j#5B|E@Q~6bLijl)~z7jNtaeSe(iKE@g|kX=h7Xf z;&Q$LCplT37boV9`VenI(Q|no9cy7=tM5Yp8-8bOyrPZ`C0W`&*t&6UU=3czd?HjP zy)UMlcKwR_1-kTH>8y(G<(mIqb9IBb}0Pe(_6d5IX}nQACm{} z<>E{bhoifFq-XyL#lvq?s$y@Xs(;G`SF55j!fP{(4Att^`cJp(38#z>8{mPBj|}(F zyuOq2moC)>*EuL=J1rvfRN{RWgM1mZGPTuV2-^P69cOXGafL}u*3-sLVo9g}9Q+nL zT_790K|`@vB|?*AQ5U($zHE>DpJYBwD+Rp655sPIwZP!U`Clzwi4?;`lYuS`hkowq z8R!#Dcl(jMTvUt)*zktTveOTq>!6yB7x*)d1 z@cXZEU!-5(l`&g83~9o?<3ADCaD6`&iR1GS~HZOlbf)|nLb)RudYryhFS-kfx__VX~hoy#618ob0cwGKW;1N zUZAQZ;Wl$plwEIq9~VYRr5D-TDOESMFOmDLtird%mOC~G-LKm zBJIOlEO~8a!`k}8tO@AHO7rc`bfRC<;vk(kMT?G=%}4*>Cq9UshC55+Q&@1$%x*UN z@(}I=;Y$fjrlr*WBC0TBv5KsI`4)Q$DUYlb)EXBHkZiJ#v za3k4J|CabEdNNE<{Dy!ThEL@8u`V-QS0cr_&(eXR_^b4$!ixL)c~|B@bcG}1_Fd=R zJJLYbSO-)WgZSpOZl_ivUOZU?r=oAn^jsEEugZ@4FHfGU2)(pp5JZ{66P%5I2!hVo zxD9E$M+wW%D2}gt!#IqVC=QjR(XrcFGIi@IxHmi7T`U<7_Akh`Z0T#dc-Di2r4eKV zFK*I;X2+|rJ=M1dnUOhW%{dxdV3m)JG|^N9Y!{xkO7S~Jcm$Y=FCN|7{5Sx`&vOW< zjoY!84!WBlMvKc~!6f&)cdL%&txL0Q22ciYGX#jcCp^bIhM_n4fLE%y!^>mca+O@nSR5VVfm3q-4DxS;2-ooEweW>;4k64uE>l> z@NRy`z9GY5BsZQ2!3;1aKh5D2qfdS~0$s#_wxKNirEG>zwg%VQWmp+u*4y4^K6)zi zdk-eO$uouL3s3xm=O0+tnw`wa^Zj4+kw7i^h=%FMlX;T-2rWuFQd!^bX=|?75NcW_ z*479ev}lG>O@DJTfX=7s4H=_;ay)9N7?RdHX=C=yM?YyvH8m}-m}pU*6+J)C4?eg= zt_tZ@RGH)Pf+=X$DK@ePtuIiZS`!BK3{cBl)pTCgCst7)^^YZ-v}--_BnP`_V2%fk z4A-b%q!PB#X0~Xlu~UuiwcA`D;GX2(Rc4V#^zMNNCFxQ^peWtfMq@%if}SlIkV8!c z1>{>E<-NFYKuSbDrEc&W#HLe!pH~X2tFSUvM*`yt)8Q5|6F> zD=du<7^rI}oNqlY9h@{I#1o0QJ+3+#hovsI$)ZNdX{_m>c@c(sA?Cm~ja269`&xP6 zzF1j1UXs-rFVjb8cpKZ#Hh`16*|aK~;ic`OtpsbF8!9=R1Rhl(4HYY+{X_MB3mDED z6ZHx(VOntNMGGiYp9C@(HCa^*8VK^&-m|KvQa!0DwzF^Y+X}?VGbmC+>Tm~Y1zw}E z&k&3eH6J8yEBn)`aIKt+9oh9OW{hxFAq;9AwRjGWh2=V{8^{FK^8Pf6`pASA;Umsa=(CW|S%>+)94y zZupxx4Ayn70>*?GJ1FGc$u^zM9c~{>U1qm1aeWV8B&?&H0_u6NgLdWJiySH&vQ^(d zH){S{rvOd!=Cq-5^%qY%>lmmw%1gus7k5DT;}W?Fwn=*5ralDR;=tuPN@IdW5}slN z@U$26tB~Lij#+GqYEFbvoxiDqiMVta7vg1_em>)@VN<9*zeMjKivy3->UzySh2SRo zD8B?92ckw`vYt_iN$?EIHc>+aUUB-ZEc%tlTPcZ@4^L-x_!*3rsWy&}f=dI__ROA8 zZeMe2F%#adlo%u1cOO9Kdc`f>;mAxyWQqs5`T^l@$yM1;*(tFmyP)Ma}Q^S2K!F(0LbO z-)2&Lz$2kgGjVSB-ne)pAi>y$SL)awR~8k#UN|^-xqVi9K&58d@{!u~?H3I#85wfq zUa&Fq;2ToSCH8GrC`X-#<8o^Lu-*x%CleU}643lUP3W$#OR=+zo8nNjzxE-W34^3z zTMgf6-&RI7i1=B>_Jz=+onm&62-ULv#Yph6F0pdtl2o8iRVKoWHH4k+9(Xb@@@3N@ z^QcVNh^ZJKi57Z}uwdRNT%b?kV=-QyT~}3!nzEEwN(t!$xCI=8X_bv_m109Tf#LBM z{L3fJ-iH3#EAO6+l!Z!)*eO=l%rE?Lo!H4`2rlk%)gph2Pb=t&n;(N(70s^ABcfxD zw66Fh%umZ}BD}WsJTUIeWg|Sqd1{|*mBaQboo~=P`V%e$+Z}_WW7(@W69#o-9+3h= zmyCt!REW&xDhbE3Z@ih90(P4sYz;z=|7dNJcSD*GN01TUBU%msC5B9I-faDt+p>Z& zu};z3STtzQ1}#G39}?;C(z7SrHuJn4&DD zC02{5YL%D5HO#zvsgkZyHF8f5F5|%>Qq3|DJWVGlxlK!pwTphtA7aBIJjAMXGk@6+ z)bh-Sp@S7p{rSk3lVpSQ#> zM?-L-)s)$JPke79&72C>9a7Xr--7S^b`1>`OhtSt&5tuPea7V35v8&rWcj066t3)F z<}p|5#4@LtY8YqPUM&m<_-oK}JLd_59MNo1I~2sg{Mh(0Ba2c+y`yb)WinPRCA@l- z?!XWH&9Em^c}h>T=Gaq}-?<;X15>n}J&?VbJWZ{l-3uJwDQ)1Lj$vbk&dw%;(IRro z|LHCnngBc@u02TRhJ8HRZ3pryZ2%@EFgb>`=lwdhO%LoA*U%cicolkW{)n z>vJaia>FeE-6}M_EB6}}M+zqayoqCHn3{Itm_t=lPclx<3_tQ>@Np!cJGd6`Q(~gD zXl(@HPz=udiw+$9&Fg27n2kBTN9m^XQ5w5(Nsbk0)GqU2_NUA*U&%)ig( zNAoJhu8)x!U{Mi2F7YA{>E$R-Ap)nFIOzE)wQahJ6PB7ii)x0Ceg zWjDykq<#w>^?g6Nif1MzX@MQ@D<)xM2(bc#$w+g3%hBspk%l;=|9-Z=7v0WW|<@d0)5eJuQ!?N9YxtnaFl%K(@G+4O5{2q6&8%K+Bh7NWVu(y$wW;iAXCM*!0!{HZ6{}i0Abzi zCw=*yrxyuvFtrYw&U^7l*+DXkT^MkS4SZOZzK%Khw~)WNIc-PaKblxY*C`V{GNoh7 z%V0z-4gV0ei(la>HhmBAMTyW-%`_l2A5R@ZAu0ZymgQ{fA;kV_*5r(cqndr*gmd&Q zIP5}$Hlk)Epmhx|%CUUz)>y3E@3b%a4+~{JU8Af=&Gu1r;xccNkAN2Foq!d7KGLJ` z{I+w-YG!BJ{7`CgP!uGy}JwyeEvOWF6JMqn7r5+8K z74(ulc)!G{>ExiSJDv|-w+cchmSHgd<)`e$p8)&O6;q^)#~J}QUtgysSPTg9cO|e) zTA(6(G`2x=cd?&RvGYI?R!B3uf4pu3#^JaybFWMmu3(3aZ{jn)X7euS?vS)%S9;)y zuV1v@R|H<`vPN{rk6v}}G!m4=w|+45MwWuIk>bdpO>zx_0&6rn4TyM?#Y;*!p{)cF z(!HjC9A%d!Y0t?YS6apVsoP)n=h5#A+&d7if1nU#9nhB$fns2VjhLqBvN`-SFNn&C z&fn3nCYd7Pqctx^iEj#Rrvb?qI-X9qN{UUYCsG8{4hU(=HN8QKQ6nlb z(QH=xK%=hc?kpe4MWeklw8nlgktjOyt|mP%ysurzQWu~yWVxJWU}9e?@I-0}7pgio zG-EcFXvnfgwXMUL(nnmpXsqN7!`^2~&%(PMgT9W`e(?ruSf;a>auFva;ak+R3Kq@> z(tN;+n0KL}ZGsfft-2XK?>6>maKrfb=dA{b)n>Sb=kXey=FVz4mM1Dy77>ljUk`Jf zcNt1?-LF$MIsS!U`(&y>msk{N)Z{Oh1{Y^Di8f}94|{}sj5mq`bxA8+pXeJKe$QNM z_23+YV*ZCI_V^DokopAAfeuQlZ6>=>eNDGeFH1S0Ru$~kQR;WO?AbY;5GFD&q};i9 z_c_5FXnsR{?1E+(zsY@~oVO}7@lb7ua?@mW>Yv8A7p7cOW4n&>U#gvEQn^HzpT4rv z1*V#%UyENZAzP2?H1%zqco(rz23> zs}hkaBUZ(ek(_B$2tgLrrgaEepdF+b5Y5ZrT%|*p*Bh@j=)5 z`0CHC{}dKlrK~A01p9Cgz~e|+ZIamnh1qu99z197Nw}BKUslB5SbJAwnf@F-ZK*)& z6=*%9*FKpbMh;(xbVpzCLe4w0HMB8WRF5AQcrGWyrwAI;m+QRsxWP+a}~D*%HXQJr~G$DA%4wFa+z_NaYNr*dZ@kQsl_d!BNtuRrZ2)iA3iX= z0uAH;+PB~;C$20C`d|=`2 zNFuzP(^c6MhF%m)Ygg?|-)+YWKcK|ww|{C8VFFZINri`-f=@BD*kyUd=Rvr3%cSu| z0pn5#M?TbsRX!xS)YTMzw`?zx67q13eYu=+m99r8i4Cdiy;u1E>l7V%%$jzQ(U!^= zm1W?Mw}2QTbIXw5dit_9A=i2VfmNl%<5cG9tnj|rpEp%A6PC;RsHbr7!3>y+)Dy6g zBSfP>pAZ7&xG|+#P4>sTh zLMY&9M~g*38c<}qx~Q$6fIK*-9Ioqzit!?1qGwjJP*)Ky*&eB`pk3$I8M@YYviELD zN5gd_jwa(AfU;3P{{IGI`X~Ii2pa(;HrDFfKTNOk-JFo~k6H*wuEe$C%tAtY0k(b? zT5Y8|>tlR3;bx-)QK$B~D%WbkiG{%DD>3Mc1C%`gf-UvSf_lV?G zK!b%G$`(#D2CiU}^HdMvxm!bnA8DnaPPv=&pxb)e21hcZbNR4lEHBcWeTctZz(8jv zv96Qp7oP+7Z0RxcM;t}!pMkqY3|UQTjXU=n4?p{dHI-bed->fSWIw#79j^V z@tA3ncw2J%9y8{M6_AMx%$+;CWcltAP_{J<0ERp+3*LQJ)!f8@!B@@O9j!axuA>vLTfbT+n4aIFF>xBkq9WNHBT!$@* z+ti;ci~V0=uHKS-H5|7NKJaioX`$m>+^-4s*D_iJ*@5so(j}NY4I*hP_W3;*3@}~_ zXPb7oKv(b1V50HYxB+OJU8VlzJU38J{(Dvf0XYK4MNtd|oJ=3y~3xHNP}gL?YK8{)H4< z)QQ!M9H6Hy9d;C}gUcZ^4kEYr5SgD<;DDIgMS)=9`aFz|_EI*n1)RO5{FFrsp6rg> zW0Z>D`3U)wgcdg_k6Nx6TEbsY29iZ~fPkF*-$4~^7V>q$YIdh11*xcU#3(ZpYj(JE zC=Tf~x_{A5LTF5J8D`hZbH#-B$f>=5b`)XpGUiLsuu7yom!vBqLI_~)!RM06VQYp* zkL1mHUYlptgOw+br$R&_U}ycKPAsZ20QBTm$FlL|6VqUJYf8#c&s(cYxjwz!YCKt; z^@RmIO`7W=Lj#gmV3r;EI1VQa(}gn)PtCv#*CNx-26*lZlz6TW%`k_gj@|$!z%qMj z3fvTf+pK+qWqIK^x=Epd#SAER{f(tg1-;I^tcJ!~uw7eDtqN~}rZkpY`b28j+f3mV zlDW=QBY7S^w>iZOhM;Isyfr9fc=$its9a|ueHEOQgm-}AkhthSSh4;)AQDEjvaP;` zNe?MuiSdfsjz7gE`rhH^pAyQNydE$uwQ8zTYG+rw6nRG%nl#B&az0F+(3@rc990;y zOzO#^elEv&INP-Sf6K_wojs`5Fd7%GH!0K!<7@`X5ZTLwroaZL2nc@S(u!^h&Vkwy82O+UPQK1jcP>F3 z*i`o!^DVpCge3>h39ts7@zSj7w67ZMn${F^dUlh#~8cBye@d`tW&m>jKz?L zF-m<%8}b?O`v`f%>ME9LV@klilJ=wCpW17roF+TMle8C|Ye z^9{X6)2a7xsauY)vR356D8O}=|CnAX-!Nfm4z?O9NLIH8Zf_cxZ2E-)P@e{=X5*Ss z$gC?Le`PgT-@4t@=dqyhyuEcTe9HU5*rTr_1x7T=;7M4a0>T|7UOVeQ&@nsip!Jye zf|~h7q1t35Guxg2M-4M|8LfCBG(LBu^oj)}w&ioq!p74i0ajBK-#*Znh96)Fu`n$1 zeg#1KdtbdKGC`y$pniy8>SJ@w&jlz2BlAPE21nEYvNK7}oSpZ7`eT{9>iq`6S|LN> z$1zZM!Yih2Nw&oNg;B@#hifgnAZ+DRBcffqWr^SEsdO-3T5VIZu^w-T&gfFBKS%DZ zj-XNyIcGD?fyUA<(9~vfg|bH>xzF3yzZJxJk_=L5Ny{a>NvO-hAtr2){VD#FBY0kNalJ5;00xJw;L5;5}cgeY~(-l%h1#6_CsVC2o- ztI#7X^x$l2nD*w@b{r;l(&kyR4RH17$73>A&XINEI553qQj~vf0**aIc*1IlO(q2YK9A5abvNis?>^E}mSZ{*2RmC%fg?@f zY()Rl&`x@ukeg|{h+GY??sU|Vq$c%J6wHxwoAJo1g15W&B@4G9yW!^a>DDgVsaCYc78}9>rwvaEj-u^2|!Yb*i`Dr z)^9oWoM;qyY|pF~>Kvt$*HP+kV|*^AQBi`u3T!ABu{ZAlF0bra;AnM6Ir3MSAzD2u zcIr~#RGlC4G%$J;na0~lH6Zg6w;|t54mqRXdlKp=D2vqYCWWU7e~H8%A=IS|*2j4r z%ed*-@s$)4Z%fkL?NH&By8yV{_r8!ocwC_5U2iZ;d4?FXt9l>*TvR1 z25}Ua%$JqTca#gSjVHESl?~lM>Zl|YLLrB6-2FPw~2tT@V{F zs_8+-hE&vPd58omaM7l4e1)IKNd26-8FV!oQLa{+QQ5{b>j-t{`(g+}&!8Tv-S_fH z#`x2K2l8hrJiYlyGS$jsBxn2?9Pe`%-gV&M&YC27q$O%cYKIajed zda@rg7^{OfE>JIY;t$A%J?^X4VqMQ$spo_@RxF_?3J)VA4TAf~Qg)2j-}D!Pr)$w# zhJgo1s@mcpY%2?ajnsDW_(AE{iebMXHCsmEq9affaq`9NU$rzXr89GGMou<#|2}PQ z=dgi>^F`vl1x*iHLTc(pGD_Fwetfi9SPz6x+I&7{O>X02mK)#C15frQb2u@mOW-5z zaG1cerACWurK!FTuP}^svqP7F4+E%2YcP@f65y_HQ?bbNGnPa4G`#H?HkQc}DILk< z5o53fQND%;mRH+91yc{+N*nF{A2<0T`Ql%?m;6!HvMYa zI`v@wMBZO(h~W?FOz1L52rPFpU}|xs)`&QK$e&lreof@s%iuVKQ~0jGEh(A@z8{3Y zLgrC=o3Le8Y2%QIxud-!OTnSCeb92HUb5U?Jc1t_}wI%_uPWh04Xs>b;qoZ6WgY10tr!3?~aOJbN;9 z#q0xuJ(Y5JscktZ2d)Ok7nNFd5=Lpc8EdVFC9u)jB2p{1HRKsNNU<4pf6h@F2JD3b zju{b!RUO2*v=VMqhay03FnJB%D(|4|@1aQ<>Obw^&cvj7K3+M()D!v-x&i22W+nz( zzAu9jG*=_DQ-^A@f)HoYmgtT$m(MemWQ;|?=QNB(KNm&NGq!{5jz~5*TiJ;e+7?sI2i5L-xAU7s32A^Yvoz~cAl9+X1%(|ogqH)plosS;@cKPgipNzig%eS*&nw-~YJi3$54&hq(a#I4 ztp(1GP@;Fa{313TKpSV8Hg4hwQQXGKB%Thz=`*Ec?8qhv;N|wSi>4?&EP=W_p$4PFo zI!(`(oJ*+E?Bp&MF4MRFpKtwobRL|~%&lfE z`VU1o8`7^2TjO^;3@*GjvJ8E%0Qx9%hh$A&W6U#h3a6{uAcPzsRS75L)`IbX9)`2V zdL(sL=@LZzCq&TIE~N&V@AS?QfkvD{OoRNXihpKe7{hX};IWzTCOK<(5gaAzCn=V& zEP=w_LoSA}z&Pa~oQ>20ZW#3A9mo&vXi%((^Qk6e0t&##G>q8yW;|&lQpY{y) zlyw23hg5p!JzkowBbwj5F#7@Tii+zjxkJv8E?qoW`Jk?oipajw_G{9*1>PSIK6DUn z|NPc)`F1Y^xk0|>qQkxU2nTtF?RooNi1Q|X{zIxM;gPO`^ifv^i`M9@uh?JjHYlks z@`qv&zx;!;5~wFEi5rtumWSZTveXJR=&mt|g_inb{424uz76*N zC0@OK>9=I`b-HH_v}dte5SQI;B@nlnTTBWh+Mh@q|}zY;&sa8i5n83Q3}wpgrKGdR;5hN$`_ zEw%)AbVi+Rz`fh@1-Kmp>UZum7kNE+5ERiDR38IYx`KxJ##=WPDqVxQ{zA|fQSw}Y_bwSp0A=RGx< zxLmsp$Y2@ot4 z@GAkvV4D4V=k+cVDhXL_>`l|9$;1*?YPMK!W!&kC-x*lx#g;ykBFPqq0>f^LjG8@j z+Xw@oMj^J~Bts6;S)?^A{Jl*7aj{>!xoSneXvNZC={2LR(s~v}4sJta@!e9#y4tDBe`X)~J?*=SL^vJ7chu|OKMn|YHNudNwY;j1=;KP&#L z)YfXuw-KbrwrHG8IR-|mM^w5d#>|9zAX{HDv82&{q6n-!oqoV@(8;-Mo~Dl9`l-l` z9lF1d@&ddQI_Ct&lNIXgLm-!`DHV0XNSFnVEfc+ZMACaj2Z+^Sqb;O*8@!hYzlPa^ z$R*+M_Ypj*;9stKENb)=2YYpZXgaj`qb!w5yr@m?Yj8jy74*%|JX3|(>NcV>5Mv0Ie|v^x$XwdByj+9h~AD}H{}UWqqJO$bN3cp z=X+%3ei&$J*;pvxPDM*}$&*zz{foyzw-R>c)qcwo=G%+{JMZMQjeoIw9Ch-hxYbFf zi(Tu4TeT@Z{%1y}Czay7pl3l8OKU{&$-7anXh#Ea$3Piw?jBTx0uNlxJz9Cn3oe) zlAI`*sk>VBWLkKV=@7u}Zx+tk_=04`7XmAtxEQ{wP@vXr_>AfRW*iRozL^DKeLAU# zl3w+O~L8zzg8Lmh`GKQK*$&rM2&nAs0D*Y=&gfN3VIEaS7Z56lp&?) z$&v#>OZp3n)V3061r)FYxEm7hgACcEKno0l-XHHLOZDQsv5r|2$-tU;&yQ_^g7}Q3 zi7x{q8T|nT(vN-1+sWG#dGGCY|0T7;UIInJTc>vO+fege;q_rR##?ke$Dp4V1saiv z<8V^t0|)+@)Tc=aSWV{(kpyz$ zPc2AKEc2#5PXU0H8BA07hx2us;Lp9Szo{XM6)3JGks!4OX23#pLKC}$ss_x~Zxl`% zBwd+x8D(CF&Dr)JyG=y%5M`f3T5|sYZTcpQq}Azqd~I>xyz( zBrRD@6y4|D{Izwp(6ShJ=+j<3tc6VZ0mP)~a7L^WUR_d?lF@{o9?!2^qfx5v+YE~` z5(%yy*Fl@JdKnEhzk&clCApa#G5QgSHttIHZ88^)Z>%I<1$`P+4@><_fv-CzEQy!; zR9l3mIu1vDY|?1&PJxnCbW8hRpI@rnCUvB>fg4XHQN&M4Ehue6z*L=g6q`WH-y|-f zsNaChszYLcr{fRI!@E)wS}Nd%>I%_5+R?*I6q~6f#O>~ZtuM(?M{f~d`S`_H%mXu| zTWRuUNwxhKfX{>s1T+tebIH+frDt-R9mZKRxxipz#A% zGM3(mH2b2HL8P6T0}J#*)Shg_Ia5R975X5{UD52nlAelug%T{4RTVx_zNb~CnP)JI zq~$&2KA}iJZ+#gTp_z-Vdv-78ab?`8Up?)pSQaet`PE0dTi{Arn!d4Xa>6w?f-bT$ z*~CMx`4LlVq0rrtksQbYM}Y12a6Qeqy2l2boQJ!f z%<=fCE=qLTZGh5oLZB(wA;H9w2dG|eY5r3-&gX{xVrN{&ENbR@dXrrH`m<=)q@Ef6 z+br)n58o@s(vFqup$&n5hn`;BdmE)CCsErAO2EKjUV5f2t z9w+#4lJtGdCsK`Qn_S+aQu4#154~3faQTU9I@11S!j-N{?)Du3BJkJAL9Nm05Pc*O zU9bwZ2yk(|!gyh|MKAYQm#2aruhjww3GmvDBE-%gYSm$alMv#Q82LP#pza3O+O>fj zVkOVV+tQ$4*+wnFNHIgR1H zpb^pQ~1+ac& z;|dSF2V3pMEa4!wC32GBdEAgTae9B4b$@R-*=i&Sc(}>&UTf4t!GBJ9yMXEyH!}oj zs71H(;JSlJAhmOF_6Jo>1{re7&JFAfy^DoS6Xlxu3WOZad4!*rK2+W~^i_Z)ykyN8 zb5troUBp9e(8V+^mBHm7#A0>~Iy8=Q#9qlMSd;e_$76yMNs8``hDUfC-W)-=8By@G z85%nnp-{^&NuPI}Wek*@tno)rgSEd1a;AGto2(fUspWeb-G&;tmt@o-EX!3tyQrpB zv71Nf;XeruWisn8lLNhukRlzya4Rr`wy?HDh51P;_^}i_1wL3 z;?=^v+sY^zX8xLZ*E-biY)uRza2o(G>DvGLHW|cZo!Xclz;(k|{Kh<^&th<6AIEx) zLrxEe(0$scrz|WNy?INf5K5j>Z+u6iwEzbl@*+K*?3Z70%RAT9&2}i~{rv}cmKL?; zqWa}24ZR0^RtqNNSmI{+{dk=7j}RZ_Zt2oH(=f2HYp}6Q#jn!fyB= z88DIafF~Hd5aOrkh;IM-?8o0FY0w?e4N4@T_cup=o*UpIeR&e3ewKEWI(i}ED{!jw zY1t-zz$*<~adOA^dWaI4u`BqTU!`q~D&41y?cyv@`A!SXoJaq)#ccSu@e{rcAc*(M z+4?o(1B{uVJGz1BqGUf|vU+W4h*6F-b8RoxKjrt%yV49)v226(ZSB1%9$$nl9^<2B z{Xr;C)R=QqaLPd$CcM2CvjMcZ6>3SX&cnIY53@PHMaqc?{nebxA{q?g2}E2xI^OF` z!@@HLsw=)YH^&(@$+T$I$zK0?w$AM?4v#>=ND9#Gp=vX6w*xoN((drtrD6iTGLaYV zNC7VQc)?&k*;3pUu4T{XVke=mcH7&FhDx{{jw9N(v+0Y;4PW2n1~>t6HQOMQ=vSji z%@z{F${Kk$t*biA3_Uj| ztCxFPv}>$tr+$kEx2q>-2!oc;`>ls#$kpncj>p+)oMvRH1}PF5q_LQuJ4Uyy`4Gfh z`#;|7d>>9){VjU-F<7OKv8`#mnWm_$!UK1Aj}t@e?bxRqAuPwJ$aU?lYx{yR zLj~Z7lJ6FsqP%mt*1@JbquqsQr=}XC6%HTeaULRA9MabJcd~oq^*MONb#deajf))K%!*7BS~9gW)THz3zf93scVO_9jX=ebM^`s2n7kq za?R!P#Jp_IFpB-@qe4m9&4HrH2e!#jzb;_!8CX;Ls`IK8qL?%_CEdQ>n~G`w_6`Y| zAa58_*=0(PFrU~~kH6(6!v|$RHLg{Bz`VpJDeak0=>L^aE=Lj^_XxGEL0yTuRT14E z-9$GH)7{j;sHDG!_GF@NnMndfz?}CqN&93SWlLT$$IB9J53jh(1|xC!Pu@EB@vqf} z7Tah3oaN3v`3I_1+dP+loEPh>1ixCH??hNDt=iR*j=0cq8sFsdl-xYb<$@zt_wXo}$iO#k z8rtFFbMLWuIQlzz!3T8?$GEN1E;^<(Dih^qO|6b`GH^NIpur+PDEYTUmV2a>C}=3*(oU)*d=-BaUV1arWB zp@gi7cEmYSU>vWyS;yFenT!e;Zm^kFi1H^(16H0#mrCP35)-gV%Qj6AJ#`Nvv@T+Tj%k zJ5y<45OJ+N2x#+o449h|(TDaptmKT1Szo_w1GIMJVg?tCc=Zb!B#ekVZ89z{ERso3 z@!s`0Jn(rehq-+Z&T>XP&qs(Xq;-m4cj17%_J-%>cz&8Eg>NgK;~^eyd@IR_Hgf)h zWx0kqleX)C0bQhIl$hqIk|da&N8JJ6lio#-n<;FV%cN)gTi;D?zvuh)T^Fi>T{1Se zJBKDFQ;7EMJ^dQ&f7dc#tlGt`jE+|+>wh$;Ld3q~V(T%Knh8%F&$0orOU(VZRJz8I z6ijIKvL@&&nmF(i4iSm7yMJVeQ`|p4_#C%2O;DGT;mBL;Y3Z#ffF$sp_slQ`_{TLIXB-Ak~eOded9nD@XeX5EsBV z;4JL?x@F@@UCF9&Wm0asc8Rn=Cqh8t<9s~AAzz(7d+dahzub6g z!K)7Hb{Zv0K}@V1ESLcI1f&*R>3!6%pXXph8j19x=a*!ms`GT!8`Zq!>PcLIwt@!U zvFgeG*BDN)ylwaq0g?N83V2BGYh`K7^?Ot+o=PE_Hz@wmc;sLf6IwPGhko8NI&)hTsG2r zNv{R1+~TBgTO)pEUeNjF1i8C88{EY6q!U*(P;w3#F0Q)@FYQ+)RyN4!9w3mJ*7!AW z*%e~X<;u&l!kD!!nJ|6kv%6%TM}xmr0hsj8^;Mjfe4KfbmAaJ4NFU0;lnOMDW^Ack z6~NYP17J&sSKpohfXVyn2e(G80piK5?J#U&THV(r#a|<6B+GbW0X5;7A3euY3&J`F zKogterp)X!Ru43$b?5ZxB<9-5#kZ)YLRU!SJeR_P{E0t*A$jwG18R;yz|r ztT%hcTi*HUF*cfhr4-B)er@>wZm6aHY#Nz8%%tgOc}a8|rrU?N@&)2Ae(*Z~0s_2;Jl1D{Bkr4K%~ zpI1uA-pttv%F}dMf4|@Lc^;pP_&r@S*toMaZoXYOqM+0r1+_q58vt7KjkT2_v&F_g z{rk?{j5^*mGBpuZi;|>iqyV!%nUA^Zx?lyCMHsMXwa(=NseAU3HUWQz% zl762WR)rCFip(WQB}`=m;L2KaxavK$^A$$l=&UD?M^S+jIfKeFod^0cqW* zxPBOk-2LWRO^}2~wZt9RfZmw>&Hy!ZZDyvY=VN?-2ib5ma37+l-Vb%XycBt|!<%j* zn|>{(@EXskDqBJE{_CZYw@{ooz4t7A_nv}{o^AW<0Kfc}VdONZ@hG5+9`PB3w{zEy zSCSiW5!6!CG}UGln7t1ICc)f_dSM+TzmzbPcMdCHlZ9rlNr_9t!f9Thue@08brkY1 z5g&8}Va?RrYzSj0q6vrZsMmG0J|FKnXL%;@aEIaHEW$p#>S@QiDENrB3Kmj4^7u?k z#!w*2_U9b_WOmh4r;#yBKGtNW#tol~$VVY8l> z_p)uoEnwNSPK;7yQ`ke6DB;Y5mTmY z74E1a5lyR})@LNj6`_24{?AhbMBnMKID78tki=uS^e;xs??AJpG+e%RFohcvyd>J) z`-638Y9K8Sf1#@i&FjB&O#p zPp{U@t`pg0qTn*~6$4x67en=6{P8rCCkIGkEZMKnnkD5>eqfZgcJvoE)$F=G|3e&) z=dIfVfsT?IBBsQ65P>r9+Iuw$MIP==l$<~x%UFIYd{vy85p=Uc-o7k*ddZRXQ4Ixi#(V5eX%%;t7KE^T)4 zhUIIq_oW$PGLbzz(SN{H?p_h79Oer*Cq|?*`;)yn9ilq$>1FpDjqO*~x$9s7ULR?R zbfk8P0fuMQQy}zhhRLA#Jpx9VM5-;q=iAX23f1ZRhx9SRm^ZOXU8B?P*5uY7Ih&Nq)+E4b`NGp2xYZsAWCw!PzPm%TDrEm+z2m8K#^=cXr?CUt{G2V(6az#)9HaNl0aFD)EqZp4s81ZC$dZhg) za^g$3VrD5SnRprO0|*Ozfnm;it!41;=Tv>$!IUEB;YJKcyo-`P~9T zi95#YV&Gnb1%ZTc#xv2dyeX3d<5z5&-h+iu!i)1@cslpaF|W)#ZKt|gEHJw2_gRW_ z!*1PI-d|E7lhX`?h2@e$gk+dODH*CY&p^2iJA7gE#eP9|TUGr0mJ;wU@Bn%5n;_X=RuDsfZ$gU>*e)kUphd zC=&D`nE1ZvT+hp)CjcT6s~_HQh`c!NZ>sIBFyKQH^#;c*VsYh>r-yZ;m}G_Z*j{sk zfYOT5a*+r2opVHR8?9-PmaG0m2^71NVBX`-@vxq|AY6{h5Z)-%2%Jx1jSUIMkyM>5 z8BxT&ZreHdN7QWSkwte?--a`jXhsbwV@kV$wIRHRRarP{28h>CFr3+STbmbbv~Idd zAQO}FvPkJ``52KPzN09$@{BN>v1^Vy775tE+bxs}Cy|+z4DjsgPC%Y|0JOCmehdPBf*QuDdya3fNr7W>@mDFpz{f~15qAk zk>0E-%8(NSvK{yc(0_;P}VV%lb)a=fL2${CQ7 z%56w|wpiL}R<*s{JNhH1gsRrpEF}GNT2-%E4^_1h>uF0+r2Z}ZIcgR_DQis=UL!SV zV}Z+9m+P2#%)+y#6oOk2RXfYFV9k>RpTvLC}( zl(zq2B_lFwUVBpwwnUf|%=jtpPi?~B;*<~(%z}lv|n!UqV-vxo3x{)h}tf-iAp*WPhtWsU(@9` zF`W3!(PXGXK=KAV1a3)dHA*$C(!>C|`*x$;zt|f8m{e<=Ux*vz$glxMaEP!NMb=M?s&U&-U&4{ECsOR=9qyrai9T(QH(=df?Ls&(v7UTG? zY)k4n?aUFwKrx8&SOE+uz-|%vm@^g{0w| zD7Mjaxz3!Eg5-iIwq+wV<0ws=lUvq$DOAa+eug}W>{EdiQ(RhqmmD`I0WiOI+nOpEk$gI0&^|v z6tG||J{S(_Bi7W6#RSpD;gZK`ex#wi^f9$Mw}Wk5Kc4^y za%_3ca){iRkb-8#7vn;t5A@!-6<&3@rw4_%lJMF&>ME%8-C7Il=(Ym8ndQavfDYI5 zb3|sd`;-J&Be?{~$YK8vpu*T2J5As{!IW|}V-1f;AD!o2?BDbt*S$Y0%s6D|Pe@CD zz>k)e7xp~0+Y3?6=jZIgQvZq?xjY_k$hq$vtM^!Rd(xM@QsBtP-)pwP?xY+E5OSw+ zFPFa121g52wLL3-APa!Z8oTi9SS(SxbW7}nfdh~}hd$6WJM1Ftu`I ze@ku)syCaW8K6b6yQKRaFMzWndyjvoE4uv8a3Zd*lU$f~bsQ0{0XMBU05e3=x!E!I zBpU-7g^b-1g~r@NC$+9fF`-w|+S?%MT)Q)cb7qpzwD{xFZhe~fdS=X`}_jJl9V z@Uyo}0~d;VWeFux31nHmKdZAE=e_#xCOpJaYWeR2$oR%TC}6`fZHQ|^_A{(A8|-Cj z)B?fq%sdi~l?UKg)xf(ekcKIN<5%R(Cm2VxK@!xI=q~wq-;je>QMGD-a=ctwKbeuE z&SL6x|6Ph?S#)~#n>;wh`)Oju%dsqJkW@8SRgw{Z_6P#cuPAB6tw{4x0J-w!m_*Nm zKmK7rknLV%YHbk3s^Sf$GQpKrm686KivbP(NOfF%{Oh5MB0x36)GnWp%)pK!8Nw3% z`4QOg@TeV<{w<7-a~S0a*B~&MQ^xI}?}!?u_kJz=1Ht1h%+Tvb;cFV7y--Z-D%Vap zPs%-h_D3oQy|||&w!7hogb$d|(#@Uwq3A4tDmDHO*sX_G%c0mXrQPJfE1Xzo(NRH= zDT#a&`^|#e*@F-OSbHP1*Fg_5G>ZD#K{ z02TR+++O(Z&G@}WN8+}EySsLAo6EP%KwKG`_96s8&`6~oS36}%_d%8BYnR$Q`!TvM z*3V)1mg?<|!H12SeQ|FUIZWj>YL>bnPWQsE=fLu-(&GC|i@vKu!k+KeVdXq4!-?t? zQVfzT{$4`A=?@7adVbHqgrwo+T{gvmTCe;JdEx#HlOZkU>0nclQm?BR?0~>K{nYR! zg{3`Y&Ka=ceDg&O{4TU~eDnvKE}U*Y`KLpfWNB;aS!Zn(gMD zh^s)YcpNPNCgTtzN`r=;S|aC94JUi{UEpG04=|kMWm83k8k-pQ1R5!hEkbCp3)wya)ijfE8&VT9r7rstwUVBa7XSt zk6x8^qU{`xHmNhGn}rMOb1h& zV1PeWRxNC+L1w(WsMP0zS3U;rHy1(c7*JoACC25_>htAUlFt+R8FVGRmmwU`i4awY6J}pYvewd@EdV>CMXGq^`m6j0k$Wm+D{=hwy%?>7nXs zc)IiAY{QpmKFB5he3-eTh3!2EJ>|bN_cW}lAI8*LnFNBOQ&)Z{Iqly-Tn4ch0Htw3 zkkUDO4F<9B$rplfr0jQs@g_>Wv$Lde@iY)Q8yq7<~Arbon_cTW{I`F zD?ucqvEyg{4i0p9mf(4y_K(lzcK1A1kl_xXq@a<31Bt!=tVCBpT|nDNw4aNvTCl_F z+o8!%qG*ovWJlS(ylAdI}~S-G+-P*KLN&?Y-yr=e2j& z%!C5^#9e|M;i*JCbkL=5OTa!{-vnSroC63f4Z#o|(gIWY;#OCVyCjJ*cgR84$=G(;jejczb*}=Mu~veboY5Z2m^S0y#|p;;sm} zIMU=;Xk3LEfyQL3KZ>9pWs?AN{zCR)VJ zS3^Ne_zy4T!^6IJ2GBoBXscLR1kM$ptR#Op@{a?KHwH4(Q+PNk7iWq1Q=~UzCO&~@ ziUJJ|1c8Xvu1EmqqoZECt!-_2U3yY$9bj;JX)v?$mmg4iYLyqv9!XLFLcE|Dh=mX* zu4Fv3I<$m1QI>e~lYVh6KPbK?xX3uN|EWKRK0=!`?Qpw(K(fKnO>8V-AOgiOL%c)& znYmaNN!VB>B03AF zn4AO>ggy%=`XP|?XE%C{fNzR?u`~-T+>jB0J@n(fUZdmvmKyLg(DAhliN7#x+9@>q z%%cwAY{V&~wgUW8N2Fl3yDkE&ENZ+0GJh^!g?3?boC@AAw?}K8$Qy(QA zl1d$*!;wb{?URZ$I(E#3BYI8p{*x7AKb@ED6FMEE=8Iv3{2L;KJRvc91G4b`8Eerc zl{iGPNqLH(q=5M*06Xm(l@@`bAhu9pXg~vvHi4)G$Yb6tfhX3s=UZ`lqWSiSQ^p_r z%n=o8Xp`jA10ck9fBp#w0MdL#Y#i}O0c3nNMoWLf*@ctAVHEa>1Q+rM*PN0f8r216 zPH$qVv%Llnm*8fqc4Y2 zx6&r7AndKHwD8Gt$*^^-Otxyt4KmVPiBOLdQ-xoF$5ZsfIBb;(=m`)c@=yrBb z2ngXcrAussHCj#4V5Y7HuUA>OIm`~;H3%;yl1?z|I4n%xA|{~*e3QGPR_~OB1`7%@ zScU=HM+|JzdVZdQgh)d0V6D@4(mUUy@7F6$Rx+26rYnw1SO@y)>wNu+8bc>sT|&vt zE~dmLQe4;NT5T}9ESBFA@I9@31hZO3I-9C23AR5sx0EvLpW7@x0@ANPsV`MgPQYkm zxL@+WEU&Zod1gj)C?VM5E@c<6UQ#*uaCIzgEt_O~8AHt&>nd|$Euwl?XU-$F8?DT%?FRzkUsM1l}mi)2#!>Q^4yW6Eo zu6W{u_EdhaRix#CdMZ;TH^-vYNEsE2x+v4-=Q?wc>{j3ETzoynGRv2R=h)SGlv>L8 z&gfp6{v=JAs5_SAy{_2p)#_vVZJ5>(W!n=X!(cXri#hq4=We-XM@dPmec#hAQM6RX zLFH}}ERy+Grv6X6=UIR!tWnJdBERkp60_QtsKfa%lV< za#ElRh7w{8pTf8OgRjCHMbr3cD605{QrIl7y28~RPZW>P_Ziz@8Q*3DA13`4`cYbO z7nX*r>N1jR!Q)_MBn8|XV4NGtbMwuX{@48jY!R?~N}9!)*7dfO=2q>hwTei2ShT+J zy!Urqo@mmdVwm50wS=Zep`Jcph1jihamIG&(5R|cmVoL7b7v;_;WftZ&34=Ier&ab zF4Ow1_DbC~EG)D7rd-M2=dXC96x>hA~CB>~sBvUU=EO1I@0qnGV; zZuIqZ85timgQnZA{CUIH;{fOSPzqbLsa-nEOUPR`2#p;8>hZSNGsFuLc{}^ z03073HA+2T1v6p@G(Ix?1ABa|NWHkEX2O~7-ma4dv7emk?_Y8q%J32)0Ul}`AS`(a ze~O_v0C>p@auOF}ME(JUa=r(0WtYD6@MjMQ?QF#6JnOuwU&U#&=-^ z=-32s1_%JLfO8RhraAy4aDPfXKJ~|m<4OO5#+1cd5M$;DzW|Wm^a3__3s6GDkpOoH z&tYl01EwN#LliR|wPM>D2qY0ecHrS`5%Tm+B;EP*t_KN&6;yofZ3qSw z$g`aa25~;F_7E;DDHrq%C}jDtknC3=L!%Ub|AOyjt<|goGd2Pun_2FtXO49NyT`s=GAN20;-Q}&_k)vD9s5uyTOlPsL`UeKe*3Xi_;^9XbR zgajLoKWaS=PZoxyX%Mo8yL`ycJYBoJBB_<=ErxV^DR!-@8AP0vNE&U*YiBENquLO770Os z1RgCb@A-2}A~*tR%V2ooEAZc`%0j0;dCA=6nKQ5F0P$D;*0=`d&Eh?O{@(Cp^k&@A z*QcyR16d$}82f&VL)3zd3c(Hi4y*ibN&K$y{LV4_&XN4euJLg_>3!e#3jTI7`F8B< znVIgL9zSPw8UM_o+;!Ieq(+1o&#q;D)^W7%!TtRqgPiP*gq0cfOt{-HhO6TfBF+S) zfG5@$cjiX09~E4ENBB#M#9xWFBn2HJx^V@JUkCD=MnpvjaVrtZ3HId>T(VCf1Vq_; zD`3v9bvaLVND(a4PLPreNSzXCQr}0AMVON8j}O8hm<|j`4^IhN%3nH10KRu91_y?} z+GLF>3<27=CGoRo`XmMb0ZQ(>#0MNH-Uc zqCoMgvGClNkntBHdwQ_5%z5Q|pY1W&j7%HU)D|GP9x5A%n}O~|qC&M30z^$@+^VyV&_cf&~4 zH{hqfka@iCjmmbp4ekfBgk^S82PbKr7e*0L-RaL{Ij~s=S@wW@Ts#kgslZB6PxrpV ziN8dZ#XHWmujxP1SXOhH9VAB@*5|_H5JcK#uvLdu<~E z!1GC789NS*g?hm?4AX5W8@Ctcnw3+qD`b7wwUsOk*E%3!~w6*#j)pFneRx^{%C#G~fwafm$A zD|}P#w3{d?VTUX9OMOx3b!8dbM+L0q)6p1WGT9~Vx;Qjv4tfe6LhX|metbvU%;%5c zxJ0I$;M4w5sa?f1W7N-UmR^_^wEZvJp4PXGbyxehQu~&^M<7d`p_aG7qLm$DZuduS0b$zOb@_@0iRt|E$tG$B zx8amUkAAVc^uWl|@yY0!I#N$2-CeqqCg_1IL`f-XQ+4L;?H<%wstXer8Qlb(c~8aa zky*EX$d-h_MaARCr`z2&*5gcq6Nb4fr?P@;TqGLOvg$7!;FN4JP`cb-ZxXwX$B5*WrW83+QvZFUX$ZBT?}2N|#{G;} z=sbp3W9c2;hZHn)SK0I!rC8SNV-IA3%KUElg~M$prJfj$piLrn{Bpgj<)Gdxlg3T( z%66#O7;*OPES4a6B-95zg!*~%FY7!uOL@xbXLB~J!zLf6u!Ga(T0vJC85f=xdl#Zb zwNqlHLLlpLNh=T}u+}|JhbeCtksT0&p(dLyN@}`HE&5Bvg=uuXijVBd{yp4#z>M}! z-E4)|t1!%kx~?Gvjk8Bg%xi@VfiOWFB)R?pPT5^-zs@>}z*TKa_GO=CPT#y?i)Dex z?NgZZJpGj9yuH4VN#lVx2V)wyJ4J74Cm!*`-iA(<68*q+=z3$!;J zk;u%v$favd1qm`^Jz%M3IekWCg%^UzfkQaVZwjEE~uPB>yC@14zZp?ns8rb zRdY^pxQz>FcgyNNh|h-z9QQ>%-EFt~QuHLnwUc(BazAscoR>}TN`^YpY#yonus5r? zTuYc!IE}Juyv-I))Z?G8vl*K-ho~;S9trNn5Rda%avq?4m%NQdm05>L3N@t58Qqsp zR+Mb@swa_eI}X@2!xD$Ls1>Q_t&TC=^8+h(JYx{fKJWCs zdP6Kbm9>t$ssMClTx5pgZq>3?Zx?!imw9eINfTKdp$YE|od#~v@`kT0V$Q~Pj~`sy zg_Un>w5J{}NlZt%<$AFmMr@&MJkpp7xo(=b{g$SCd{Fgi>1va!7(1XA9Uz9GO_m)G z7uANr)w&xRW*HNXk4dUjhgA17g+e6%D0De643x8=D6QX*g^T-ErrHY{yRJfs*?z?e zULe$ZsO|oxTRSRmKafuS`zX8I3c=a%h8j%#$JjHx7`Fl0LnG1Fk!4L+AKYiay?@R~ z*WD2#R%O|C)8eZ@W6jXnl2CN*nXhsk6GI|5z*U3D$R3<(&=Swr7z#X=Hg-93=c#%feFlNLC{3PTmf0ka-A@0RS{Jk{?SHXg zXj^0>ojAP3KtFFr{N3bc)U5N_Y5`ksE6(q{+Xvm$D!G>-O*aTOZabs|W**K!@Z| z<#sPa`6FduP2?fO`nTLAyr`x(2fh;wsS=35z6*D$|1K%Vj@QP@UmXC zvzy}8Q-V@D97N#jfo!zM-mG|^QhN3!Ug}A?VkTy|2hs^J*`(@Cb5NYapGO<5YbfiGD(Z#>r%D? zyI7X}OtzF)wRw6^l;6z6deGOfz2?6olb$S?1O^{2 zqo2O(9DXkuHhaTG*?Ar6#ITs{(GVkv0gv+5b>G8?nUgCVl&y?!JXVWdWI z*%QHN8dmu8JSfs9CSu;eOT)UB(~aZ>uEDsv6K(SDk1a_Z=dIVxO%!PJK7S!6<8G@M zIm6^!H9yBr>>X#s7ID351|lqObYTzJZL_=2&sWh{J9Q~!@bJ{&#)UU+#BNYdecS?n zll+_t!g_9%Jpv;trAiOP6Rysj>7qw7jZ9LsIof|fh{s7*eEdZ%!ccW4NLYV(&C zqt{*{xj4FlJ873qfDisyi{Yx{B68JC%%#eIA)df}*BGpHN}YG`@Wf!@QtmkYGcw|N zUq)(i=hYXR%9k-VZw^_Or4x zv+9S9?Qy+FJabRhspqkn4D}haiPJ8aN@B;|vu#G$u5+wReE!(C|E#%4A>rjLJVc=w zXd_(*e~;kv5sEf~6ZS9K8sjPSi!HqLV`*Lq-&e7bM=4w91{d2Mf601T+tSi{eW=ou zW~WC>$ZqanVe(;INI!DhlG_VYkd@5vA_bDn@`+NYRV|NZGc&@;O~(%09#nr+dOv(C zqWTawuZ-JLEFRJ6R_d>$RxtBl?HyWJtCi2OCUOrG3Z;%6uo5kOYfOit4_aB-6H#iy zy{iUPJ-Jp8pB~iRucd?FuN&D2!EKOtu?grMAlw=itzDKjsnTb2FUVUr3x{QM+_@X+ z^7)8maOovSsc6bkj_IjEqeZt|HZjs2($Sn)!I) zT^+vz`wO_M3b)RGx-^XCPuF<_&?jma9a^LCS}Aa^Z+`~XJLl(R<2g*-8dC}nVD6eM zeY1UC8)r86b$aV)-EfQjJ6Sms3)+nZT+%) zzBPZB(GDX?uzc*AwlYkV0(*I03rO&gEjWA!I}Ci^ zp~swUS>G1Ui_4Pa8ruoqP!$DtNeKT;;7Ese6@>!Yro;lR${LU8D+;)SsuEjD2=l_@klN!PROZ&=F|=u<<(uW6X#^Nrg23X>GOFRAQyo%olk5c zlB~J!ITlluzGJE`SB{+?dyMYW(|O$%FOuJnSsdOT5*^c2GB^>P1|PW%Z#MO{2}QbG zV!oW}GRV2FY{VPC-yKh|bUJC)$tM*U4A1@po}$!n*o&h@X{TGY=7e5}EFX zg(WGCfIKDnmsAbTdkd*9K8}l_zhNG!1>}HSJs_y(`2rZE99_>Rclhb@yHz{ka#K9# z?nlNwSf4xK;ZQcTX@(A?FTBi1$OYGGiiUN46*jqHdHVoR)Dn4>vC2(eeN#n{u`-%= zBwndAykEH5m))1080G)`HN2*{?KakNaMc?`a;Q?nv3U-Qetc)A9GNbI&*idna7kff zzfL8A@pWbMzO4Iwi+X3hIhShqM=M{|raq+D9SE#jSazd# zOzgLvSA_k!)IG0eELZaV$uZi-&j*zOosFafa_SX!6pbbaIp%ha#n8^nG2S$ByW>N( zUj^ks>+F()N$aO&{(g@FaRhPy%oFw5DAZK+V0+YHZctTEilR90>D~-jbU(QcCj$0< z>4@OO(+Texd;t9drZ{<=JUmKfN=(b+-6p?lbMijiv?ZOa<|SrrBob@%$^jD_h;1fW zms4UlMwc`H%9lJMrzO00%>vu*{i&st)3Lh4%-WN!ne{d*5EmJmcedCjZq;mMy z6O!f1eQ-eIcF?QRApYq0_uRk@D(;TbG_ibtr=A$b2R?=Wn1-4e<_B)#up#FE>`St7 zu>5a*No5av6MQ;3LrW!R8%R1?{QsU}idr~2IpcFMu>PkviO>B1F~z*rwsP7WN&K$W z3y8blK?HluU3V<0rPhiy;&LG7axHW$F^5bJbYmhA!?9(qLOkaHh)U~(=_Xt$ZXeBKyVv>;pwI~PPDHa*s?DmJk z0iK3D6V60oGNLgJP|)(HC(qERG8Zvi(PQ9_#{OraT<%3X=;-exAZ;4tT7Yk|Kr~%z%U*h=rMs8I00Cz%3PRJ)T z*%rog1}VqHt2nm^_u9ZmfJcU>n%~tZD4=a^SX5mtUn>Cy0GVP?;1t7R!UN@n8Q~9kdi4ruqatDKO5fOc zEDn3@5!90A1&AOvP6*Dpl=&lo=Q#`riHek6_m0<_y&U(9tPj2Y^r3Xu=k+VJYaEJW z7)8;#{hROY=WPTnQrO|XyQAawW!fD8so!!{r6XgY-raE$-ST2mrCQ1z8s-|3*r7rS zk9T?mkz-+Dt}Ak)=VC~tHJNij&QNC_-kvX}MhKSSs&utlDnXtP!OB4-zR%$SBdiZJ?vctLa@MR2Lro*vg{mvTNMo}Dea zi&=TU(&to=gYTE2qWh!jZ2Gcculpc(Qdl_(-tkvrEPJlykjWgOWOC=5{p$MKY=D=A zV^;RLoGD&qb)_!!Xx_-6FgTAt4s&&2hY9QmcCmT$yKZSJEF!oo^sRKhXYtf*Y9p$ZeLojz0_ltJjQO83|kw+Ez8RLn{M(} zGJmZVtUrq~$|KH~3@oO{sJPOK44oi3&|Q3F6LLSmSP(=5g{)l0bWqDB7_sK9X5XmBPI1 z(;&Pqx+fA!nBj~Un7p`h2h@Q~cEHe2xO1oIGT;8V*~ZuO2erOh*Wf9Ew~FVRdb+fsUsnu#rJ)75T}2 zm0}>?tDd;pgglP@2T#k!m7oV^*_{wOAZsMk_K{F`}ac#@rwL(86eHP!X}NriY( z>feJ8v)1gP^o8S!Jhr@=^8Qz)Yfvnv4(0vV>NYz^+*89wl=8GDazltQ+G7^#*&blC zd0LLO$G^*Y)>SXK1o_lwG!vbwUTm_=1Iws0ZVs%)Q3t=BU$r(oWjJYK8Jm zWkoOVm7PlXe?Q9fMeKkUQw1g1&p$C%{A;QkeBD zkru*3oH(mF70dq5`q(bgZm(d@(8oGe8>!gq5`c=u5+%nGpRz^PL@<^IT15uxWLDwM zAjv91r-dYIZ^J9_ACw-8Q@P~zcr0ayas%$IGcBGpf@33D$+ppy=R(kASIp``y3sea zR_JJ|l=UoBAE8R%9+O#HOXpTKePn2%Lcy9@n1=DTa7xZ-5Vs_h;)rR7_Lp!@EaIsY z23#&^HEU}8NO`$wwV|pYQD5s2vr7FlWc=%a9J(D z$e9-QRqSFtgm&0jKq$Ht?~>aaCT544dr?5uN?Yo-rIf;c)NpUf9ZJ9^#tL$S0#2gf z*(H8NS`tn#3uoqysOS&%bDZlqosqNGBWt7GZNd6j$|%^A2n39g!`en5a!P4Jbjj&| zve`(jAZ1Pjf0mbL<|qUhq?t+dt>nS$OdLtOr=Vir1(p zQzc3Db1FWUpnQUaxX$YCzd0Wucd8aX<=X5xq8}keQ>|^V7$;lv@h+csrCvP=aZ)Um z1}4dM*HJTfT1|uefl^If360W44gR$7hDAYPQf@5~+;oVG6!aV#Xy6hEQ20R9Bf&%s zt_@1F5S0?~%iQ)yhEoyQ-IAzJS3YrkIZW*V6R6NFFa_;U33_-z8=?^dLP~nXEF7Yr7%(*^vL8(ETe4r%5Z}+s+tE=v zF)xLoLUo$@KKZIRv>1iAn4yVVd|O*c7dQFLpFBwi-dvd>b9%~Qbic(1B@V>Jel!Ig z*$GAEywL-_W8*GzpEZ$>(>lCf_eU(LUX9(#_?D-7;xn$P61_QBhP19Voh#sb@Je6m z+;F1%j1#Yw9Ut(X>x}gSkgt}p@`zm*;orqn1*zT%JN5<=z8R0rayrD3Oy5ENC z&|{C~Co<^cuyuQN)%x5YcXr%@?v9HF5|ZLcx^IJ9$?Pbn4>tI(xIR46ukjt)UR^z) z&ww{2Z{tNQl9p&wHN3vTJwp&9VjP_)s}B|krvC0BAatDQ*&)4yy7e~7SzhRj{C06> z@01QChLF}eu!#NkowC85Cqz=d)!*u$nJT{AYnhr1HCHKf+(G-gVQ9voo?^6 zDM1@Y$Pd>ZR;UjNjb@#)@YgHkan4wMBszV#aZJus{*T)_^VH?G{2r{7v?phtY?*@U z;?R|IRQ=!Nc-?-D>%hnREWBNAKUwzP%>&=aKseOYa*6Zvz8Z&>zy0eYGP-Zk^Si3mly?hqP?KIej`%=a}--wE4K-A1C9BdPwD1F=~Kv=ycziGxI@dUaY!U zr~)$ar1%gcAcVkdXT;0{Ws3rYB&r0)5e86!lilLiX;IVTI5u#SGM-6ej96EMYu7<)Q}SEDhh+PIrzevJ(f$DZ zBV-aH*Dv|7P(ooH@l?14v1Y7B!(Q~IjUmc6w1Y&u*W|Ebg9INrse zLDAdRuNUe!ah=o{<-=xat$#-*j2c1Z<}qUY)zxxuU?r|@3545B@wR%tQEa!N>C`CO zg zXJ@V4nZFb~T4>BgQXNz_8|UlCm3GzEl@8;T^js(+_cBqJC+vwQd>(79ob77d)MHi8 zctyLpWm^kICVTHVTkF#i?$=z+TQfPiD-!Uk)sKo=ZHy%BqBGVfM(&=Hx1_jfc$Xs{Z|or?mj zqBF_#WdH2@+PO;SyLj)rlFiu{Uot4XHqLV~(a)*vBx61B^A1Y;i*$TmpRs04pXra4 z-+UEav9Q3StG%j@>^lo%sZIKkTKx*=8EdL4o+V8aa+(HX!62fC(PTmgT&yY{GmS&> zF{9Xmi$EdvN`3K7NXc>-_9XSWNouo>zJ#kf=*pclyGGg=Yqd zAFz~8@{vz{vuCi5DaB1+Vh>!ZDx9Mfbq2~~sgOMxSTL;A39q^)j~PurgIs*pXPH84j-*tUZ2E4lJ=YCFex$H4+6E1>fPQFw&=IT z<<)&rpD`J)rMf!ntSXbLt|vi;-mDpbPq5%(?$a!^;KNK2zg!iezpP`=5%mH>Fy4&xCK& zALDYX;^kUhD%xC09E(=?sx(8ETK4MdrCNo|SHyr>Nzyd=nj8Nn_nJ#WYTWH3*~(R5 z=WKFU8?Bl~n~ndRN~f!wWxR0c8bdg1wTP#+fS|Uxz6DfH!tC;{7ULuvvTWQlP`P6ePzVrYucn) zHeUYp+6LZD;lF$NB!C5k{|H&o@o+_BZGq4OZa1`@0mg)1NI(QGfDnR_3Esha*}Hmh z!vqZ+yqqz>Rv&BQh_UqoN(w*>gcop30|iupdOLX8L+t@~p@#>?4koCM@%47~Kznin zI{pwHTwN4_um&i%q9g*2K){8BM1;ge#NZ;laB(g;oD1M-x}yItih&2p%?*PFVkA(` zo)|Jg9Rnp30cEVSvkl6{<)Q-y_70v<;PY2U_@G7@4^O}}R9FD8hm=5wBKZ*lqJQro zzz3SH;qVXx1sVm1L7m)CUiO|C6!hWW>WK;n3m{+@VHkf8_CSjL)0z8M|EL7=B8=n0 zJt{6C@elVXTv+ViUaxuYeH=?;;_QU+%BM!RC-DoM1f7pi{z$>jeQQVr9j0u?0%u0u zR4$a>_FVi%wb!=~orTlnbuPm6F}>_zF;IQv>W2r&F@AB^;H_IPU69TEk=DWH=C5x{ zIM10*WG=6TK~C7Sw1uYPUmqpi>CZAAi_Clvk?-ObEeF@JHHA}aXt|r~fXq%ItxwOc znx|M3J!|OB{-{!KGNvrxK*Q#|k|g#-LV8qB^c`hklPWE4>)Aa`^C}nh>p2zkdI(xa zAR!gJxQAa#2w9$P=*SVn&NXTH^O@#Rq}lstn!ZkD=A<7rs+(w4MdO50oWl(F%ylCn zCv5Su!-#s>OKkZ?Wuebn%A$*FCDawR^uH`;HI)a1ZkLKNTu;8!`VPks8gxs6ny z|1`F82<|E*)?nDW8a!DIqDv2yO)b3U=!xgrC~ili(>@NNSFFeFMHnO)#T{`+*@!6( zWdYoWwY;H(vX5vm$u!4W(VO3nA`Cb01`gXJ)E={l$^<4}Du2iQZr9j7{T*IiL%DrM zSBQZaQf|6XA^gSh+3{v#yse@)O;r8Q1EIPh?P_DdT;gU?6zfFu~ut$NN9NH1}SWPrzSY3mc7fE9xeHt;b;qZs|Ki=u}FZQg^h_&C^;O0lY;$~l&6(zT;)Kn&oDPU|L?@Y9=mF)I% zOxz}6wHq#Z9&|YUGk#a@C*P$Zr5PkFBn1WwGvFqz*jD@Pq(`g@Qw`w^+tQlgoNo*n z)X_?x8BnAWjzX|Qs74-}09n*I@a5q&3g!>?Mkn*cmMs{War@<3k4gA6RHDvx7l6cF zSFG$;L>lD7M;1smd2Pey8MYd$&V|}jGs{-c3U+|?)k;F%fPvp7g8Lg^i0+gb_wAhmptA#-{kpFkS_(E3V^M%0Jw z{wJTdKayU*LM+BEpSM6aF8`p%&qd(ax;`A982bgX^f>AWf|lK8yj4T;u2cfGvi+KW7-tsIX?s_T-@2U+#I(g z0YNSW2wo|zae4D8_obEk`hu4rEr*hp^()it;5i+3%P$Aa))rBI2T+z4ccUM>=#=FM2=4p|RHYnjl#M!T%N=r$H{5p?w5lB=dHT z26YR9G=uH~XD~!#vF|lrPaMJj5)4py!?lkdqPb^k9`p)gF!rAr*87KzIJlWJK1sjzgeu1hu7Gc>}6c znz3TV@9Pe;!&%=2D2(F2pDFqfxL-=XbnAAADq(UO>2Eu&yU=3t+VTWi58iC_HQh z&_julf1IpfK|k}$uEi-VL_dAuv82Tlnrxjx9`{h1a+jMC04a`!>&=vTN>O{0{#;Qz zw`YoYJLzf$HJ5mvwEog%u9W*~l{A1gE-hu>;yxaGV(n0)t6MK`QJ* zq*{dH@6bY*#Z7N%QM$dV1UNw@7dDeM+{o~%x5SATQf}?40HRY_TtYJ<*6qgyyA#Dk#G3_wI9O=h$XjjmjZmaE~$bLjAq;jV(CFY$3$gwYPhjAj4=pv2uN76^@b zt;1j%Yi?E=vmGGFZ=n3JDGkEIDK)K5o|>4mUDO@#WBK`O6YCM=3WtHRy8*WySZYZ9 zTI#llpp3z*+Lm8Bu+a?uaaBn%cz4cj73eZVzQ#UJj~l{oK-Qffu4c5E#>zv3wTs5S z69kRs?DB)0^AMhScn96^rY*k}bNZ+$cRnz=L7Z)#$>{!J zlubycYbDyI#4;(m@;JxurqJf4PCqs~$>p-xGCB@UDZ>)W$e3-D96tucD^KjEVP7BR zc$x7Mhd)P>AED4DEJXpBd*H8Wp`20{C6>W4+desdN4nX|A}y4jxg%hauO@}hmzEmy zGyxg{d{iMG2l`=*GNx`El0&6YUPy1s#%1>He)a0x{gV!KnVb%U4pW zUR~RNl!vv~5Z9*QZ+**G`NP7`*K{(Y{@3O!oWg@I-56BK)F-F+9dUI<6UH}l=lCuZ z_UnwMh8wnQ6}UP@q+;a4^eXv?7<(#{g+fH9E#!!%)|=lCr@Q4cJ{3q8aP}vpu&>=A z7J2cZo^JS&=(Ht3aP}86i*8zaiFhWN$dKo2aGVc z-X+OfIk&$t{~6m2gBMTV>1?n#qG8~o*qjaCNEzChCfp=K7beYg4ETVQDmE=1FjU=; zL?*7O=I?U?%RxV=sPQ~8i%&72MzX@n3Ikjg^Zbm{#+s)PW~yFl93PSu@88hVQw4(x z3zNPCD5~*fNYcQ{R&a1QaBrfZ2(x!!@*BQMFvwlioBDhSNovL9%&;=_riQe9(!C*y z%3j+${OUv@O2sA%XG!3v#Fm1pdF4xl@!+RYxh$%AuXZ=?ZrWTQZ@L)dJ~cN|wU}Cr zlhh`lmb|J(4R2;D^=8Z+jbLB-g)5?wrNC66PgK_?tiEkfb(UdjQ{uRzT}531aSCRC zHkoH~LR8a5_I7GM@}|VBa752zPYn02TBTj(nXjphlI_lCFB`)@a_IK!`y;BQw&tQa zg?yl~*TRG0dHiCUdX3gl&VC2ETM}AC2xq}hxtb+laf&#ZV6K-pvc|EZRWf3lstwjq z;Au>lG2pNh{b4}YY2I?J!@+IaH^wkY(;Jv#`Rn?a>zdAyd7-DR_cLkYl9{K{iabh zKlLnoG5&Oxy{YiLKuzx*yF$bfb&MZ5t2x_zP(bQ&-GpMzKJG}FdrrQ{Nn?t))?>C; zWY1%^s1;c;;m1z*ea^GB|GbKB;yvHN7r!4j0=@+DBbEzxot_X|)mcf6g1)DzsW{=i zzx8@_D$NxQ-N~C+KR9dt{x;zF(LAG&@ygrltmOx>={t+{Le>KtUzw(77h3bh{ARpz z%V*v?q)BC*`S0sps~Ug9dR$-oEzq_iaYn4(BDmPAMVB#0JH^H7#{9MUx0B7T&Q`;~ zk%L1(Sr<|9o07J`)BPbrg0|)HhXn&6%P&qIkh}=~Z0!O|p9t53xAPV)5F3ee`y}`* z9G9=OwFbcBBJ(4RJPo(Ebg_eZNk52*ALoGN2W*OUAg9muCa59RS=a+ekzuf zw_tH<5U_+M#ee=LOW)eZYukeAnzYtKM%yEVARy%vHjTRFFn0tA;A6hC^*J_tQMQvAfYNsKLonFR&68EQbY4?VZ9{ z1y!sjLL(a7&x#A~l`W4J+8&JPdW-{)XK@N4an7bn=TGX8KPSF-kKO(j=?)~HJ~xu6^Ol_YmTOg2yPtjd>2Uq` z$&Z%SlO5m^^bXC-w48*&_8d>{37;*_2A`p&K9`JB`>W4?sAGHJ_xtzZ>Eh9BaGR`^ zB-3=-x^|mGWLOmm&)t(?D}?>V|Kx4~!Z-gjL&RTB0~0-r9hso23mW4CHHSkbkRldj zg8B}An2RErpfS{32r3K}0>0F9bp@7NA%y@HdKWe9T!Fm{|INjoBGgJUt?EICv0*Vkq{M#uhSSD3V?Nn&-->csq zSPq@}X$^hx&7Irw&0U}H^u~JcrLY>QiMoU)DB)ApsNUq0C(2)473i^`N@?(*^-2!E z+!d>n6aE4!AJA5Nq>p`jGFIh3_c`I?_LO5WG`AkENy6K_&J+Gei(yWR{MR<4=ZH}`eCB`T?+xB8lRQDa_}U%~z_ zniUwzxhzz zo5}fk+@89P7}guFRa0Uk=H=b)GMRkEGl-RThJ?le?)-6Vi?C_)8A5Hn%s|eFr$4&3=j~Y{x^dh^*Me3O*3RwS1wr~|dudUP7MWRv;ioCC zdD3Om11a@0PnXx2c=}oL^&8z=!iUK9Gf(}Q>H6Ddt~;fm(r@enIi^j)B^Nckk{xNc*{RCWL`(Z;9=f!v!X0*j(itm;xF9 zAhWwlv*_39gphO=V_;@;vwNxOwaoB*(>sg~jMbUlr5{T^mUK&OjL1Jvv%@l6v7_Sh zvrS}>3uRZFwJiBH%kaJPYD@?Hz@rQ}(;EI>I>}EIGXyVhayc4B$`_8Is+jwc60|=p zp4k212epRN_m8nrRabatR?K|p#@qcS37Akc&Jp}L+WPi~lY~+zy6p%V9Nm8VWsQy? zaRQP>D&`1IH*j3LyEq}&A~-uj*bOq+?%O~>_qQvUPnM>C{BEmZ1J*z&wg{PtkaDB@ z+8*dbz`)wU=>sCp#q0ZA8CoQ6ArV}pWw7**(s`lxLhXJ|(B`>E8L1(e!QU`yiVy4m zU(v)Y{c}?-iYsSx!sl&Skl|VRvEg3D=0q&)?8sU}Z?U4oIJ}z7YOKmd>r3*%G8OCJ z)&BE#Q~_}Vby3ZDtlGmWzVO$VWcplCD#^cKV-Eq(NBn^v(AIy(oVQdj!8MtFP7;Zt z`LytknV?L0`AJbG>TXXeo~QMj*(wypD2GvkGF3 z+z$QcYZF4U9JzRvIo#HbS?eDojM=XkdtIO%({SlvQC=11heTA?#z=m=Apo5)wbrgyyFN&ia->~l$*{njsLn@0x=H%-7ju!J))edq<^ix=nE zx~`Q!H@yAcDmU@dZ`mhoeF^XWA6UjbB=6$o<3#)g;vX&xcZ|*|k4^V#v)2M0#D8`+ z@FCEw|0}51$mJq5{@_og&HH0R7tN{&`b*1CnFXC7YndoQc|zonWA2!Ag|E@iQ%2U} z#ZS+BFuH$w)0-8_xM$B#y!z$)64g83v7w>PiD5VYLyDuP9;^pzYNilRP5RoqzFQ%i0<-k&6 zkAIO^f8U57nKW*DN-@qo@Mtn?FrtwvD+B}A=qxJ}_W{{;FsGADK=+e)QM8p2NGhfs z1*+*SERIzauRM7<3q|g%sW2fkJM}DrEr`o(dSsXGXF(k&#qaM9uOAjC*0HHL88aT8 z-~Tw3qx`mkzDmZytCy{yPAqn9UeU>l@$7q%y=GyJ1)Gu+A~x`R!hT2FHaL@}YBJF> z5*F23du9Z@EXDPFAtA~7Dkt=blE+gG2m=rBlEm6R!^9B|l#)$!JT-=p@3E3Km+`Yl z%{6_2-%|?@)%1)Wf$3lZdO*s%yY7jz9L-7(qqiZS`Cpl%-}JeBCY!dF+9qIQ>KE9R z$lDHS#a+9F&u!f%c?avaFsPdhh4|;$EL%EvJ&nKB{jz29Bc1<=&2RHTyeY1LN45}b zrPZ&5tK!)gSS7nh>_J<^t)}aO*K8nuvq(8Z%qIKvO_9wLzWv$m-om9^SbV#Te(obd z`c($$NIHk@oogjqCp*Dcev=qzO2Gd6FD6efl!uoO@K+L diff --git a/lib/morpho-utils/lib/aave-v3-core/audits/27-01-2022_ABDK_AaveV3.pdf b/lib/morpho-utils/lib/aave-v3-core/audits/27-01-2022_ABDK_AaveV3.pdf deleted file mode 100644 index 7e212a7523cc257c58ebb5306c66d13f0e18fc44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1405807 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

    3`ZS5O(d)D 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�h(%q?LsAHx_Tg6~jXKiDn1{ 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